Commit b1cb29c0 authored by Philipp Hörist's avatar Philipp Hörist
Browse files

Add UserTune (XEP-0118) module

parent a1f0d26a
......@@ -58,6 +58,7 @@ from nbxmpp.modules.entity_caps import EntityCaps
from nbxmpp.modules.blocking import Blocking
from nbxmpp.modules.pubsub import PubSub
from nbxmpp.modules.activity import Activity
from nbxmpp.modules.tune import Tune
from nbxmpp.modules.mood import Mood
from nbxmpp.modules.misc import unwrap_carbon
from nbxmpp.modules.misc import unwrap_mam
......@@ -185,6 +186,7 @@ class XMPPDispatcher(PlugIn):
self._modules['PubSub'] = PubSub(self._owner)
self._modules['Mood'] = Mood(self._owner)
self._modules['Activity'] = Activity(self._owner)
self._modules['Tune'] = Tune(self._owner)
for instance in self._modules.values():
for handler in instance.handlers:
# Copyright (C) 2018 Philipp Hörist <philipp AT>
# This file is part of nbxmpp.
# This program 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; either version 3
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; If not, see <>.
import logging
from nbxmpp.protocol import NS_TUNE
from nbxmpp.protocol import NS_PUBSUB_EVENT
from nbxmpp.protocol import Node
from nbxmpp.structs import StanzaHandler
from nbxmpp.structs import TuneData
log = logging.getLogger('nbxmpp.m.tune')
class Tune:
def __init__(self, client):
self._client = client
self.handlers = [
def _process_pubsub_tune(self, _con, _stanza, properties):
if not properties.is_pubsub_event:
if properties.pubsub_event.node != NS_TUNE:
item = properties.pubsub_event.item
tune_node = item.getTag('tune', namespace=NS_TUNE)
if not tune_node.getChildren():
data = TuneData()
artist = tune_node.getTagData('artist')
length = tune_node.getTagData('length')
rating = tune_node.getTagData('rating')
source = tune_node.getTagData('source')
title = tune_node.getTagData('title')
track = tune_node.getTagData('track')
uri = tune_node.getTagData('uri')
data = TuneData(artist, length, rating, source, title, track, uri)'Received tune: %s - %s', properties.jid, data)
properties.pubsub_event = properties.pubsub_event._replace(data=data)
def set_tune(self, data):
item = Node('tune', {'xmlns': NS_TUNE})
if data is None:
return item
if data.artist:
item.addChild('artist', payload=data.artist)
if data.length:
item.addChild('length', payload=data.length)
if data.rating:
item.addChild('length', payload=data.rating)
if data.source:
item.addChild('source', payload=data.source)
if data.title:
item.addChild('title', payload=data.title)
if data.track:
item.addChild('track', payload=data.track)
if data.uri:
item.addChild('track', payload=data.uri)
jid = self._client.get_bound_jid().getBare()
jid, NS_TUNE, item, id_='current')
......@@ -65,6 +65,22 @@ MoodData = namedtuple('MoodData', 'mood text')
ActivityData = namedtuple('ActivityData', 'activity subactivity text')
class TuneData(namedtuple('TuneData', 'artist length rating source title track uri')):
__slots__ = []
def __new__(cls, artist=None, length=None, rating=None, source=None,
title=None, track=None, uri=None):
return super(TuneData, cls).__new__(cls, artist, length, rating,
source, title, track, uri)
def was_removed(self):
return (self.artist is None and
self.title is None and
self.track is None)
class MAMData(namedtuple('MAMData', 'id query_id archive namespace timestamp')):
__slots__ = []
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