diff --git a/gajim/common/connection.py b/gajim/common/connection.py
index 7e72bfead..87b7d9a11 100644
--- a/gajim/common/connection.py
+++ b/gajim/common/connection.py
@@ -78,6 +78,7 @@ from gajim.common.modules.bookmarks import Bookmarks
from gajim.common.modules.pep import PEP
from gajim.common.modules.user_avatar import UserAvatar
from gajim.common.modules.user_activity import UserActivity
+from gajim.common.modules.user_tune import UserTune
from gajim.common.connection_handlers import *
from gajim.common.contacts import GC_Contact
from gajim.gtkgui_helpers import get_action
@@ -670,6 +671,7 @@ class Connection(CommonConnection, ConnectionHandlers):
self.register_module('Bookmarks', Bookmarks, self)
self.register_module('UserAvatar', UserAvatar, self)
self.register_module('UserActivity', UserActivity, self)
+ self.register_module('UserTune', UserTune, self)
app.ged.register_event_handler('privacy-list-received', ged.CORE,
self._nec_privacy_list_received)
diff --git a/gajim/common/connection_handlers.py b/gajim/common/connection_handlers.py
index 5f768721e..1ce8ba741 100644
--- a/gajim/common/connection_handlers.py
+++ b/gajim/common/connection_handlers.py
@@ -296,7 +296,6 @@ class ConnectionPEP(object):
def reset_awaiting_pep(self):
self.to_be_sent_mood = None
- self.to_be_sent_tune = None
self.to_be_sent_nick = None
self.to_be_sent_location = None
@@ -306,8 +305,6 @@ class ConnectionPEP(object):
"""
if self.to_be_sent_mood:
self.send_mood(*self.to_be_sent_mood)
- if self.to_be_sent_tune:
- self.send_tune(*self.to_be_sent_tune)
if self.to_be_sent_nick:
self.send_nick(self.to_be_sent_nick)
if self.to_be_sent_location:
@@ -337,42 +334,6 @@ class ConnectionPEP(object):
# not all client support new XEP, so we still retract
self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_MOOD, '0')
- def send_tune(self, artist='', title='', source='', track=0, length=0,
- items=None):
- if self.connected == 1:
- # We are connecting, keep tune in mem and send it when we'll be
- # connected
- self.to_be_sent_tune = (artist, title, source, track, length, items)
- return
- if not self.pep_supported:
- return
- item = nbxmpp.Node('tune', {'xmlns': nbxmpp.NS_TUNE})
- if artist:
- i = item.addChild('artist')
- i.addData(artist)
- if title:
- i = item.addChild('title')
- i.addData(title)
- if source:
- i = item.addChild('source')
- i.addData(source)
- if track:
- i = item.addChild('track')
- i.addData(track)
- if length:
- i = item.addChild('length')
- i.addData(length)
- if items:
- item.addChild(payload=items)
- self.get_module('PubSub').send_pb_publish('', nbxmpp.NS_TUNE, item, '0')
-
- def retract_tune(self):
- if not self.pep_supported:
- return
- self.send_tune(None)
- # not all client support new XEP, so we still retract
- self.get_module('PubSub').send_pb_retract('', nbxmpp.NS_TUNE, '0')
-
def send_nickname(self, nick):
if self.connected == 1:
# We are connecting, keep nick in mem and send it when we'll be
diff --git a/gajim/common/const.py b/gajim/common/const.py
index 2ea55eb7b..e17331604 100644
--- a/gajim/common/const.py
+++ b/gajim/common/const.py
@@ -132,6 +132,7 @@ class PEPHandlerType(IntEnum):
@unique
class PEPEventType(IntEnum):
ACTIVITY = 0
+ TUNE = 1
ACTIVITIES = {
diff --git a/gajim/common/modules/user_tune.py b/gajim/common/modules/user_tune.py
new file mode 100644
index 000000000..3110e1de2
--- /dev/null
+++ b/gajim/common/modules/user_tune.py
@@ -0,0 +1,96 @@
+# This file is part of Gajim.
+#
+# Gajim is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation; version 3 only.
+#
+# Gajim is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Gajim. If not, see .
+
+# XEP-0118: User Tune
+
+import logging
+
+import nbxmpp
+from gi.repository import GLib
+
+from gajim.common.const import PEPEventType
+from gajim.common.exceptions import StanzaMalformed
+from gajim.common.modules.pep import AbstractPEPModule, AbstractPEPData
+
+log = logging.getLogger('gajim.c.m.user_tune')
+
+
+class UserTuneData(AbstractPEPData):
+
+ type_ = PEPEventType.TUNE
+
+ def __init__(self, tune):
+ self._pep_specific_data = tune
+
+ def asMarkupText(self):
+ tune = self._pep_specific_data
+
+ artist = tune.get('artist', _('Unknown Artist'))
+ artist = GLib.markup_escape_text(artist)
+
+ title = tune.get('title', _('Unknown Title'))
+ title = GLib.markup_escape_text(title)
+
+ source = tune.get('source', _('Unknown Source'))
+ source = GLib.markup_escape_text(source)
+
+ tune_string = _('"%(title)s" by %(artist)s\n'
+ 'from %(source)s') % {'title': title,
+ 'artist': artist,
+ 'source': source}
+ return tune_string
+
+
+class UserTune(AbstractPEPModule):
+
+ name = 'tune'
+ namespace = nbxmpp.NS_TUNE
+ pep_class = UserTuneData
+ store_publish = True
+ _log = log
+
+ def __init__(self, con):
+ AbstractPEPModule.__init__(self, con, con.name)
+
+ self.handlers = []
+
+ def _extract_info(self, item):
+ tune_dict = {}
+ tune_tag = item.getTag('tune', namespace=self.namespace)
+ if tune_tag is None:
+ raise StanzaMalformed('No activity node')
+
+ for child in tune_tag.getChildren():
+ name = child.getName().strip()
+ data = child.getData().strip()
+ if child.getName() in ['artist', 'title', 'source',
+ 'track', 'length']:
+ tune_dict[name] = data
+
+ return tune_dict or None
+
+ def _build_node(self, data):
+ artist, title, source, track, length = data
+ item = nbxmpp.Node('tune', {'xmlns': nbxmpp.NS_TUNE})
+ if artist:
+ item.addChild('artist', payload=artist)
+ if title:
+ item.addChild('title', payload=title)
+ if source:
+ item.addChild('source', payload=source)
+ if track:
+ item.addChild('track', payload=track)
+ if length:
+ item.addChild('length', payload=length)
+ return item
diff --git a/gajim/common/pep.py b/gajim/common/pep.py
index 5283717f4..a250a4006 100644
--- a/gajim/common/pep.py
+++ b/gajim/common/pep.py
@@ -109,8 +109,6 @@ MOODS = {
'weak': _('Weak'),
'worried': _('Worried')}
-TUNE_DATA = ['artist', 'title', 'source', 'track', 'length']
-
LOCATION_DATA = {
'accuracy': _('accuracy'),
'alt': _('alt'),
@@ -234,47 +232,6 @@ class UserMoodPEP(AbstractPEP):
return mood
-class UserTunePEP(AbstractPEP):
- '''XEP-0118: User Tune'''
-
- type_ = 'tune'
- namespace = nbxmpp.NS_TUNE
-
- def _extract_info(self, items):
- tune_dict = {}
-
- for item in items.getTags('item'):
- tune_tag = item.getTag('tune')
- if tune_tag:
- for child in tune_tag.getChildren():
- name = child.getName().strip()
- data = child.getData().strip()
- if child.getName() in TUNE_DATA:
- tune_dict[name] = data
-
- retracted = items.getTag('retract') or not ('artist' in tune_dict or
- 'title' in tune_dict)
- return (tune_dict, retracted)
-
- def asMarkupText(self):
- assert not self._retracted
- tune = self._pep_specific_data
-
- artist = tune.get('artist', _('Unknown Artist'))
- artist = GLib.markup_escape_text(artist)
-
- title = tune.get('title', _('Unknown Title'))
- title = GLib.markup_escape_text(title)
-
- source = tune.get('source', _('Unknown Source'))
- source = GLib.markup_escape_text(source)
-
- tune_string = _('"%(title)s" by %(artist)s\n'
- 'from %(source)s') % {'title': title,
- 'artist': artist, 'source': source}
- return tune_string
-
-
class UserNicknamePEP(AbstractPEP):
'''XEP-0172: User Nickname'''
@@ -390,5 +347,5 @@ class AvatarNotificationPEP(AbstractPEP):
SUPPORTED_PERSONAL_USER_EVENTS = [
- UserMoodPEP, UserTunePEP,
+ UserMoodPEP,
UserNicknamePEP, UserLocationPEP, AvatarNotificationPEP]
diff --git a/gajim/gtkgui_helpers.py b/gajim/gtkgui_helpers.py
index 3e9c72a47..6ffd59b17 100644
--- a/gajim/gtkgui_helpers.py
+++ b/gajim/gtkgui_helpers.py
@@ -629,7 +629,7 @@ def get_pep_as_pixbuf(pep_class):
mood = received_mood if received_mood in pep.MOODS else 'unknown'
pixbuf = load_mood_icon(mood).get_pixbuf()
return pixbuf
- elif isinstance(pep_class, pep.UserTunePEP):
+ elif pep_class == PEPEventType.TUNE:
icon = get_icon_pixmap('audio-x-generic', quiet=True)
if not icon:
path = os.path.join(configpaths.get('DATA'), 'emoticons', 'static',
diff --git a/gajim/gui_interface.py b/gajim/gui_interface.py
index 370480e63..db4d84519 100644
--- a/gajim/gui_interface.py
+++ b/gajim/gui_interface.py
@@ -2169,7 +2169,8 @@ class Interface:
continue
if app.connections[acct].music_track_info == music_track_info:
continue
- app.connections[acct].send_tune(artist, title, source)
+ app.connections[acct].get_module('UserTune').send(
+ (artist, title, source, None, None))
app.connections[acct].music_track_info = music_track_info
def read_sleepy(self):
@@ -2477,7 +2478,7 @@ class Interface:
received_mood = pep_obj._pep_specific_data['mood']
mood = received_mood if received_mood in pep.MOODS else 'unknown'
return gtkgui_helpers.load_mood_icon(mood).get_pixbuf()
- elif isinstance(pep_obj, pep.UserTunePEP):
+ elif pep_obj == PEPEventType.TUNE:
path = os.path.join(
configpaths.get('DATA'), 'emoticons', 'static', 'music.png')
return GdkPixbuf.Pixbuf.new_from_file(path)
diff --git a/gajim/roster_window.py b/gajim/roster_window.py
index 285343b94..ed98b4573 100644
--- a/gajim/roster_window.py
+++ b/gajim/roster_window.py
@@ -3594,7 +3594,7 @@ class RosterWindow:
if active:
app.interface.enable_music_listener()
else:
- app.connections[account].retract_tune()
+ app.connections[account].get_module('UserTune').retract()
# disable music listener only if no other account uses it
for acc in app.connections:
if app.config.get_per('accounts', acc, 'publish_tune'):