1# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
2#
3# This file is part of nbxmpp.
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU General Public License
7# as published by the Free Software Foundation; either version 3
8# of the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; If not, see <http://www.gnu.org/licenses/>.
17
18from nbxmpp.namespaces import Namespace
19from nbxmpp.protocol import Node
20from nbxmpp.structs import StanzaHandler
21from nbxmpp.structs import TuneData
22from nbxmpp.const import TUNE_DATA
23from nbxmpp.modules.base import BaseModule
24from nbxmpp.modules.util import finalize
25from nbxmpp.task import iq_request_task
26
27
28class Tune(BaseModule):
29
30    _depends = {
31        'publish': 'PubSub'
32    }
33
34    def __init__(self, client):
35        BaseModule.__init__(self, client)
36
37        self._client = client
38        self.handlers = [
39            StanzaHandler(name='message',
40                          callback=self._process_pubsub_tune,
41                          ns=Namespace.PUBSUB_EVENT,
42                          priority=16),
43        ]
44
45    def _process_pubsub_tune(self, _client, _stanza, properties):
46        if not properties.is_pubsub_event:
47            return
48
49        if properties.pubsub_event.node != Namespace.TUNE:
50            return
51
52        item = properties.pubsub_event.item
53        if item is None:
54            # Retract, Deleted or Purged
55            return
56
57        tune_node = item.getTag('tune', namespace=Namespace.TUNE)
58        if not tune_node.getChildren():
59            self._log.info('Received tune: %s - no tune set', properties.jid)
60            return
61
62        tune_dict = {}
63        for attr in TUNE_DATA:
64            tune_dict[attr] = tune_node.getTagData(attr)
65
66        data = TuneData(**tune_dict)
67        if data.artist is None and data.title is None:
68            self._log.warning('Missing artist or title: %s %s',
69                              data, properties.jid)
70            return
71
72        pubsub_event = properties.pubsub_event._replace(data=data)
73        self._log.info('Received tune: %s - %s', properties.jid, data)
74
75        properties.pubsub_event = pubsub_event
76
77    @iq_request_task
78    def set_tune(self, data):
79        task = yield
80
81        item = Node('tune', {'xmlns': Namespace.TUNE})
82        if data is not None:
83            data = data._asdict()
84            for tag, value in data.items():
85                if value is not None:
86                    item.addChild(tag, payload=value)
87
88        result = yield self.publish(Namespace.TUNE, item, id_='current')
89
90        yield finalize(task, result)
91