mpd_client.py 3.82 KB
Newer Older
louiz’'s avatar
louiz’ committed
1
2
3
4
# a plugin adding a command to manipulate an MPD instance

from plugin import BasePlugin
from common import shell_split
5
from os.path import basename as base
6
import tabs
louiz’'s avatar
louiz’ committed
7
import mpd
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import threading
from select import select
from time import sleep

class UpdateThread(threading.Thread):
    """
    Background thread that awaits mpd changes
    """

    def __init__(self, plugin, xmpp):
        threading.Thread.__init__(self)
        self.plugin = plugin
        self.xmpp = xmpp
        self.alive = False
        self.c = mpd.MPDClient()

    def run(self, *args, **kwargs):
        self.alive = True
26
        current = None
27
28
29
30
31
32
33
        while self.alive:
            try:
                self.c.connect(host=self.plugin.config.get('host', 'localhost'), port=self.plugin.config.get('port', '6600'))
                password = self.plugin.config.get('password', '')
                if password:
                    self.c.password(password)
                self.c.send_idle()
34
                select([self.c], [], [], timeout=600)
35
36
37
38
                self.c.fetch_idle()
                status = self.c.status()
                if status['state'] == 'play' and self.alive:
                    song = self.c.currentsong()
39
40
41
42
43
44
                    if current != song:
                        self.xmpp.plugin['xep_0118'].publish_tune(artist=song.get('artist'),
                                length=song.get('time'), title=song.get('title'),
                                track=song.get('track'), block=False)
                    current = song
                elif status['state'] != 'play':
45
                    self.xmpp.plugin['xep_0118'].stop(block=False)
46
                    current = None
47
48
49
50
51
52
53
54
55
                self.c.disconnect()
            except:
                pass
            finally:
                try:
                    self.c.disconnect()
                except:
                    pass
                sleep(8)
louiz’'s avatar
louiz’ committed
56
57
58

class Plugin(BasePlugin):
    def init(self):
59
        for _class in (tabs.ConversationTab, tabs.MucTab, tabs.PrivateTab):
60
            self.api.add_tab_command(_class, 'mpd', self.command_mpd,
61
62
63
64
                    usage='[full]',
                    help='Sends a message showing the current song of an MPD instance. If full is provided, the message is more verbose.',
                    short='Send the MPD status',
                    completion=self.completion_mpd)
65
66
67
68
69
70
71
72
73
        if self.config.get('broadcast', 'true').lower() != 'false':
            self.core.xmpp.register_plugin('xep_0118')
            self.thread = UpdateThread(plugin=self, xmpp=self.core.xmpp)
            self.thread.start()

    def cleanup(self):
        self.thread.alive = False
        self.thread.c.disconnect()
        self.core.xmpp.plugin['xep_0118'].stop(block=False)
louiz’'s avatar
louiz’ committed
74
75
76

    def command_mpd(self, args):
        args = shell_split(args)
louiz’'s avatar
typo  
louiz’ committed
77
        c = mpd.MPDClient()
78
        c.connect(host=self.config.get('host', 'localhost'), port=self.config.get('port', '6600'))
79
80
        password = self.config.get('password', '')
        if password:
81
            c.password(password)
louiz’'s avatar
louiz’ committed
82
        current = c.currentsong()
83
84
85
        artist = current.get('artist', 'Unknown artist')
        album = current.get('album', 'Unknown album')
        title = current.get('title', base(current.get('file', 'Unknown title')))
louiz’'s avatar
louiz’ committed
86

87
        s = '%s - %s (%s)' % (artist, title, album)
louiz’'s avatar
louiz’ committed
88
        if 'full' in args:
89
90
            if 'elapsed' in current and 'time' in current:
                current_time = float(c.status()['elapsed'])
91
92
                percents = int(current_time / float(current['time']) * 10)
                s += ' \x192}[\x191}' + '-'*(percents-1) + '\x193}+' + '\x191}' + '-' * (10-percents-1) + '\x192}]\x19o'
93
94
        if not self.api.send_message('%s' % (s,)):
            self.api.information('Cannot send result (%s)' % s, 'Error')
louiz’'s avatar
louiz’ committed
95
96

    def completion_mpd(self, the_input):
97
        return the_input.auto_completion(['full'], quotify=False)