Commit 7acf9179 authored by André's avatar André Committed by Philipp Hörist

Refactor publishing Tunes

parent c6f72a2b
......@@ -264,7 +264,6 @@ class Client(ConnectionHandlers):
def _after_disconnect(self):
self._disable_reconnect_timer()
app.interface.music_track_changed(None, None, self._account)
self.get_module('VCardAvatars').avatar_advertised = False
app.proxy65_manager.disconnect(self._client)
......@@ -418,7 +417,8 @@ class Client(ConnectionHandlers):
self.get_module('Blocking').get_blocking_list()
# Inform GUI we just signed in
app.nec.push_incoming_event(NetworkEvent('signed-in', conn=self))
app.nec.push_incoming_event(NetworkEvent(
'signed-in', account=self._account, conn=self))
modules.send_stored_publish(self._account)
def send_stanza(self, stanza):
......
......@@ -21,34 +21,19 @@
import logging
from gi.repository import GObject
from gi.repository import Gio, GLib
from gi.repository import Gio
from gi.repository import GLib
from nbxmpp.structs import TuneData
from gajim.common import app
from gajim.common.nec import NetworkEvent
log = logging.getLogger('gajim.c.dbus.music_track')
MPRIS_PLAYER_PREFIX = 'org.mpris.MediaPlayer2.'
class MusicTrackInfo:
__slots__ = ['title', 'album', 'artist', 'duration', 'track_number',
'paused']
def __init__(self, meta_info, status):
self.title = meta_info.get('xesam:title')
self.album = meta_info.get('xesam:album')
# xesam:artist is always a list of strings if not None
self.artist = meta_info.get('xesam:artist')
if self.artist is not None:
self.artist = ', '.join(self.artist)
self.duration = float(meta_info.get('mpris:length', 0))
self.track_number = meta_info.get('xesam:trackNumber', 0)
self.paused = status == 'Paused'
class MusicTrackListener(GObject.GObject):
__gsignals__ = {
'music-track-changed': (GObject.SignalFlags.RUN_LAST, None, (object,)),
}
class MusicTrackListener:
_instance = None
......@@ -59,9 +44,18 @@ class MusicTrackListener(GObject.GObject):
return cls._instance
def __init__(self):
super().__init__()
self.players = {}
self.connection = None
self._current_tune = None
def _emit(self, info):
self._current_tune = info
app.nec.push_incoming_event(
NetworkEvent('music-track-changed', info=info))
@property
def current_tune(self):
return self._current_tune
def start(self):
proxy = Gio.DBusProxy.new_for_bus_sync(
......@@ -100,6 +94,11 @@ class MusicTrackListener(GObject.GObject):
if name.startswith(MPRIS_PLAYER_PREFIX):
self._add_player(name)
for name in list(self.players):
info = self._get_playing_track(name)
if info is not None:
self._emit(info)
def stop(self):
for name in list(self.players):
if name.startswith(MPRIS_PLAYER_PREFIX):
......@@ -137,10 +136,6 @@ class MusicTrackListener(GObject.GObject):
self._signal_received,
name)
info = self.get_playing_track(name)
if info is not None:
self.emit('music-track-changed', info)
def _remove_player(self, name):
log.info('%s vanished', name)
if name in self.players:
......@@ -148,7 +143,7 @@ class MusicTrackListener(GObject.GObject):
self.players[name])
self.players.pop(name)
self.emit('music-track-changed', None)
self._emit(None)
def _signal_received(self,
_connection,
......@@ -160,14 +155,11 @@ class MusicTrackListener(GObject.GObject):
*user_data):
'''Signal handler for PropertiesChanged event'''
if 'PlaybackStatus' not in parameters[1]:
return
log.info('Signal received: %s - %s', interface_name, parameters)
info = self.get_playing_track(user_data[0])
info = self._get_playing_track(user_data[0])
self.emit('music-track-changed', info)
self._emit(info)
@staticmethod
def _get_music_info(properties):
......@@ -176,10 +168,19 @@ class MusicTrackListener(GObject.GObject):
return None
status = properties.get('PlaybackStatus')
return MusicTrackInfo(meta, status)
if status is None or status == 'Paused':
return None
def get_playing_track(self, name):
'''Return a MusicTrackInfo for the currently playing
title = meta.get('xesam:title')
album = meta.get('xesam:album')
# xesam:artist is always a list of strings if not None
artist = meta.get('xesam:artist')
if artist is not None:
artist = ', '.join(artist)
return TuneData(artist=artist, title=title, source=album)
def _get_playing_track(self, name):
'''Return a TuneData for the currently playing
song, or None if no song is playing'''
proxy = Gio.DBusProxy.new_for_bus_sync(
Gio.BusType.SESSION,
......@@ -205,14 +206,7 @@ class MusicTrackListener(GObject.GObject):
else:
return self._get_music_info(result[0])
# here we test :)
if __name__ == '__main__':
def music_track_change_cb(_listener, music_track_info):
if music_track_info is None or music_track_info.paused:
print('Stop!')
else:
print(music_track_info.title)
def enable():
listener = MusicTrackListener.get()
listener.connect('music-track-changed', music_track_change_cb)
listener.start()
GLib.MainLoop().run()
......@@ -20,11 +20,14 @@ from typing import Tuple
from nbxmpp.namespaces import Namespace
from gajim.common import app
from gajim.common import ged
from gajim.common.nec import NetworkEvent
from gajim.common.modules.base import BaseModule
from gajim.common.modules.util import event_node
from gajim.common.modules.util import store_publish
from gajim.common.const import PEPEventType
from gajim.common.dbus.music_track import MusicTrackListener
from gajim.common.helpers import event_filter
class UserTune(BaseModule):
......@@ -37,6 +40,12 @@ class UserTune(BaseModule):
def __init__(self, con):
BaseModule.__init__(self, con)
self._register_pubsub_handler(self._tune_received)
self._tune_data = None
self.register_events([
('music-track-changed', ged.CORE, self._on_music_track_changed),
('signed-in', ged.CORE, self._on_signed_in),
])
@event_node(Namespace.TUNE)
def _tune_received(self, _con, _stanza, properties):
......@@ -66,9 +75,44 @@ class UserTune(BaseModule):
@store_publish
def set_tune(self, tune):
if not self._con.get_module('PEP').supported:
return
if not app.config.get_per('accounts',
self._account,
'publish_tune'):
return
self._log.info('Send %s', tune)
self._nbxmpp('Tune').set_tune(tune)
def set_enabled(self, enable):
if enable:
app.config.set_per('accounts',
self._account,
'publish_tune',
True)
self._publish_current_tune()
else:
self.set_tune(None)
app.config.set_per('accounts',
self._account,
'publish_tune',
False)
def _publish_current_tune(self):
self.set_tune(MusicTrackListener.get().current_tune)
@event_filter(['account'])
def _on_signed_in(self, _event):
self._publish_current_tune()
def _on_music_track_changed(self, event):
if self._tune_data == event.info:
return
self._tune_data = event.info
self.set_tune(event.info)
def get_instance(*args: Any, **kwargs: Any) -> Tuple[UserTune, str]:
return UserTune(*args, **kwargs), 'UserTune'
......@@ -45,13 +45,12 @@ from gi.repository import GLib
from gi.repository import Gio
from nbxmpp import idlequeue
from nbxmpp import Hashes2
from nbxmpp.structs import TuneData
from gajim.common import app
from gajim.common import events
from gajim.common.dbus import location
from gajim.common.dbus import music_track
from gajim.common.dbus import logind
from gajim.common.dbus import music_track
from gajim import gui_menu_builder
from gajim import dialogs
......@@ -836,10 +835,6 @@ class Interface:
if obj.conn.get_module('MAM').available:
obj.conn.get_module('MAM').request_archive_on_signin()
# send currently played music
if (pep_supported and sys.platform not in ('win32', 'darwin') and
app.config.get_per('accounts', account, 'publish_tune')):
self.enable_music_listener()
# enable location listener
if (pep_supported and app.is_installed('GEOCLUE') and
app.config.get_per('accounts', account, 'publish_location')):
......@@ -1539,46 +1534,6 @@ class Interface:
### Other Methods
################################################################################
def enable_music_listener(self):
listener = music_track.MusicTrackListener.get()
if not self.music_track_changed_signal:
self.music_track_changed_signal = listener.connect(
'music-track-changed', self.music_track_changed)
listener.start()
def disable_music_listener(self):
listener = music_track.MusicTrackListener.get()
listener.disconnect(self.music_track_changed_signal)
self.music_track_changed_signal = None
listener.stop()
@staticmethod
def music_track_changed(unused_listener, music_track_info, account=None):
if not account:
accounts = app.connections.keys()
else:
accounts = [account]
if music_track_info is None or music_track_info.paused:
artist = title = source = ''
else:
artist = music_track_info.artist
title = music_track_info.title
source = music_track_info.album
for acct in accounts:
if not app.account_is_available(acct):
continue
if not app.connections[acct].get_module('PEP').supported:
continue
if not app.config.get_per('accounts', acct, 'publish_tune'):
continue
if app.connections[acct].music_track_info == music_track_info:
continue
app.connections[acct].get_module('UserTune').set_tune(
TuneData(artist=artist, title=title, source=source))
app.connections[acct].music_track_info = music_track_info
def read_sleepy(self):
"""
Check idle status and change that status if needed
......@@ -2158,6 +2113,7 @@ class Interface:
if sys.platform not in ('win32', 'darwin'):
logind.enable()
music_track.enable()
self.show_vcard_when_connect = []
......@@ -2180,8 +2136,6 @@ class Interface:
self.last_ftwindow_update = 0
self.music_track_changed_signal = None
self._network_monitor = Gio.NetworkMonitor.get_default()
self._network_monitor.connect('notify::network-available',
self._network_status_changed)
......
......@@ -2086,6 +2086,8 @@ class RosterWindow:
else:
connection.get_module('UserMood').set_mood(None)
connection.get_module('UserTune').set_tune(None)
def delete_pep(self, jid, account):
if jid == app.get_jid_from_account(account):
app.connections[account].pep = {}
......@@ -3431,19 +3433,7 @@ class RosterWindow:
def on_publish_tune_toggled(self, widget, account):
active = widget.get_active()
app.config.set_per('accounts', account, 'publish_tune', active)
if active:
app.interface.enable_music_listener()
else:
app.connections[account].get_module('UserTune').set_tune(None)
# disable music listener only if no other account uses it
for acc in app.connections:
if app.config.get_per('accounts', acc, 'publish_tune'):
break
else:
app.interface.disable_music_listener()
app.connections[account].get_module('Caps').update_caps()
app.connections[account].get_module('UserTune').set_enabled(active)
def on_publish_location_toggled(self, widget, account):
active = widget.get_active()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment