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

Refactor publishing Tunes

parent c6f72a2b
......@@ -264,7 +264,6 @@ def _on_password(password):
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 @@ def _send_first_presence(self):
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 @@ def get(cls):
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 @@ def start(self):
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 @@ def _add_player(self, name):
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 @@ def _remove_player(self, name):
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 @@ def _signal_received(self,
*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 @@ def _get_music_info(properties):
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 @@ def get_playing_track(self, name):
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 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 @@ def _tune_received(self, _con, _stanza, properties):
@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 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 @@ def handle_event_signed_in(self, obj):
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 @@ def on_open_chat_window(self, widget, contact, account, resource=None,
### 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 @@ def __init__(self):
if sys.platform not in ('win32', 'darwin'):
logind.enable()
music_track.enable()
self.show_vcard_when_connect = []
......@@ -2180,8 +2136,6 @@ def __init__(self):
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 @@ def send_pep(self, account, pep_dict):
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 @@ def on_continue(message, pep_dict):
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