Example #1
0
class OSC_MPD(object):
    def __init__(self, osc=('0.0.0.0', 8000), mpd=('127.0.0.1', 6600)):
        self.mpc = MPDClient()
        self.mpc.connect(mpd[0], mpd[1])
        self.server = OSCServer(osc)

        def musicManage(addr, tags, data, client_address):
            cmd = addr.strip('/').split('/')[-1]
            self.mpc.__getattr__(cmd)(*data)

        self.server.addMsgHandler('/bearstech/music/play', musicManage)
        self.server.addMsgHandler('/bearstech/music/pause', musicManage)
        self.server.addMsgHandler('/bearstech/music/next', musicManage)
        self.server.addMsgHandler('/bearstech/music/previous', musicManage)
        self.server.addMsgHandler('/bearstech/music/stop', musicManage)

    def serve_forever(self):
        self.server.serve_forever()
Example #2
0
class __MPC(object):
    _mpdc   = None
    _host   = DEFAULT_CONFIG['host']
    _port   = DEFAULT_CONFIG['port']
    verbose = bool(int(DEFAULT_CONFIG['verbose']))
    debug   = bool(int(DEFAULT_CONFIG['debug']))

    # Switch automatically to created buffers
    autoswitch = bool(int(DEFAULT_CONFIG['autoswitch']))

    # State symbols
    state_chars = {
            'pause':DEFAULT_CONFIG['ch_pause'],
            'play':DEFAULT_CONFIG['ch_play'],
            'stop':DEFAULT_CONFIG['ch_stop'],
            }

    def __init__(self, wc_buffer=None):
        object.__init__(self)
        self._mpdc = MPDClient()
        self._commands = self._mpdc._commands
        self.wcb = wc_buffer

        self.verbose = bool(int((wc.config_get_plugin("verbose"))))
        self.debug = bool(int((wc.config_get_plugin("debug"))))
        self.autoswitch = bool(int((wc.config_get_plugin("autoswitch"))))

        for k, v in self.state_chars.iteritems():
            self.state_chars[k] = wc.config_get_plugin('ch_' + k)

        self._commands['np'] = None

    @property
    def shortstats(self): return wc.config_get_plugin("shortstats")

    def __getattribute__(self, attr):
        try:
            return object.__getattribute__(self, attr)
        except AttributeError:
            return self._mpdc.__getattr__(attr)

    def _get_status(self, key):
        return self._mpdc.status()[key]

    def _print_current(f):
        """Do `f`, then prints the short_status in the buffer.
        """
        def pf(self, *args, **kwargs):
            robj = f(self, *args, **kwargs)
            if not self.verbose: return robj

            # Show the status in the current buffer
            csong = self._mpdc.currentsong()
            csong.update({'state':self.state_chars[self._get_status('state')]})
            wc.prnt(self.wcb or wc.current_buffer(),
                    Template(self.shortstats).safe_substitute(csong))
            return robj

        return pf

    def connect(self):
        self._host = wc.config_get_plugin("host")
        self._port = int(wc.config_get_plugin("port"))
        self._mpdc.connect(host=self._host, port=self._port)
        pw = wc.config_get_plugin("password")
        if len(pw) > 0: self._mpdc.password(pw)

        if self.debug: wc.prnt(self.wcb or wc.current_buffer(),
                               'mpc debug: Connected')

    def currentsong(self):
        ds = self._mpdc.currentsong()
        itime = int(ds['time'])
        ipos  = int(ds['pos'])
        pct   = int(100 * (ipos / itime))

        ds.update({
            "title_or_file" : ds['title'] or splitext(basename(ds['file']))[0],
            "pos_sec"       : "%02d" % (ipos / 60),
            "pos_min"       : str(ipos / 60),
            "length_sec"    : "%02d" % (itime % 60),
            "length_min"    : str(itime / 60),
            "pct"           : "%2.0f" % pct,
            })

        return ds

    def np(self):
        """Pushes result of np template substitution to current buffer.
        """
        ds  = self.currentsong()
        if len(ds) == 0:
            wc.prnt(wc.current_buffer(), "MPC: ERROR: mpd is stopped")
            return
        wc.command(wc.current_buffer(),
                   Template(wc.config_get_plugin("format")).safe_substitute(ds))

    @_print_current
    def next(self):
        self._mpdc.next()

    @_print_current
    def pause(self):
        self._mpdc.pause()

    @_print_current
    def play(self, *args):
        self._mpdc.play()

    def playlist(self, *args):
        def ifn( b, s, d): wc.prnt(b, Template(s).safe_substitute(d))
        def cfn(): wc.prnt(None, "mpc closing playlist buffer")
        new_buf = wc.buffer_new('mpc: playlist', "ifn", "", "cfn", "")
        wc.buffer_set(new_buf, "localvar_set_no_log", "1")

        pl = self._mpdc.playlist()
        for line in pl:
            wc.prnt(new_buf, line)

        wc.buffer_set(new_buf, "display", "1")
        return pl

    def playlistinfo(self, sortkey='pos'):
        """Shows playlist information sorted by key
        """
        new_buf = wc.buffer_search("", "mpc: playlist")
        if len(new_buf) == 0:
            new_buf = wc.buffer_new('mpc: playlist', "", "", "", "")

        pl = self._mpdc.playlistinfo()
        try:
            # Numerical sort
            spl = sorted(pl,
                         cmp=lambda x,y: cmp(int(x), int(y)),
                         key=itemgetter(sortkey))
        except ValueError:
            # Alpha sort
            lcmp = lambda x,y: cmp(x.lower(), y.lower())
            spl = sorted(pl,
                         cmp=lambda x,y: cmp(x.lower(), y.lower()),
                         key=itemgetter(sortkey))

        t = Template(wc.config_get_plugin("playinfo"))
        for line in spl:
            wc.prnt(new_buf, t.safe_substitute(line))

        return pl

    @_print_current
    def previous(self):
        self._mpdc.previous()

    def random(self, *args):
        """Toggles randomness if no argument is given.
        """
        if len(args) == 0:
            args = [int(not int(self._get_status('random'))),]

        self._mpdc.random(*args)

    @_print_current
    def stop(self, *args):
        self._mpdc.stop()
Example #3
0
class __MPC(object):
    _mpdc   = None
    _host   = DEFAULT_CONFIG['host']
    _port   = DEFAULT_CONFIG['port']
    verbose = bool(int(DEFAULT_CONFIG['verbose']))
    debug   = bool(int(DEFAULT_CONFIG['debug']))

    # Switch automatically to created buffers
    autoswitch = bool(int(DEFAULT_CONFIG['autoswitch']))

    # State symbols
    state_chars = {
            'pause':DEFAULT_CONFIG['ch_pause'],
            'play':DEFAULT_CONFIG['ch_play'],
            'stop':DEFAULT_CONFIG['ch_stop'],
            }

    def __init__(self, wc_buffer=None):
        object.__init__(self)
        self._mpdc = MPDClient()
        self._commands = self._mpdc._commands
        self.wcb = wc_buffer

        self.verbose = bool(int((wc.config_get_plugin("verbose"))))
        self.debug = bool(int((wc.config_get_plugin("debug"))))
        self.autoswitch = bool(int((wc.config_get_plugin("autoswitch"))))

        for k, v in self.state_chars.iteritems():
            self.state_chars[k] = wc.config_get_plugin('ch_' + k)

        self._commands['np'] = None

    @property
    def shortstats(self): return wc.config_get_plugin("shortstats")

    def __getattribute__(self, attr):
        try:
            return object.__getattribute__(self, attr)
        except AttributeError:
            return self._mpdc.__getattr__(attr)

    def _get_status(self, key):
        return self._mpdc.status()[key]

    def _print_current(f):
        """Do `f`, then prints the short_status in the buffer.
        """
        def pf(self, *args, **kwargs):
            robj = f(self, *args, **kwargs)
            if not self.verbose: return robj

            # Show the status in the current buffer
            csong = self._mpdc.currentsong()
            csong.update({'state':self.state_chars[self._get_status('state')]})
            wc.prnt(self.wcb or wc.current_buffer(),
                    Template(self.shortstats).safe_substitute(csong))
            return robj

        return pf

    def connect(self):
        self._host = wc.config_get_plugin("host")
        self._port = int(wc.config_get_plugin("port"))
        self._mpdc.connect(host=self._host, port=self._port)
        pw = wc.config_get_plugin("password")
        if len(pw) > 0: self._mpdc.password(pw)

        if self.debug: wc.prnt(self.wcb or wc.current_buffer(),
                               'mpc debug: Connected')

    def currentsong(self):
        ds = self._mpdc.currentsong()
        itime = int(ds['time'])
        ipos  = int(ds['pos'])
        pct   = int(100 * (ipos / itime))

        ds.update({
            "title_or_file" : ds['title'] or splitext(basename(ds['file']))[0],
            "pos_sec"       : "%02d" % (ipos / 60),
            "pos_min"       : str(ipos / 60),
            "length_sec"    : "%02d" % (itime % 60),
            "length_min"    : str(itime / 60),
            "pct"           : "%2.0f" % pct,
            "bitrate"       : self._get_status('bitrate') + "kbps",
            })

        return ds

    def np(self):
        """Pushes result of np template substitution to current buffer.
        """
        ds  = self.currentsong()
        if len(ds) == 0:
            wc.prnt(wc.current_buffer(), "MPC: ERROR: mpd is stopped")
            return
        wc.command(wc.current_buffer(),
                   Template(wc.config_get_plugin("format")).safe_substitute(ds))

    @_print_current
    def next(self):
        self._mpdc.next()

    @_print_current
    def pause(self):
        self._mpdc.pause()

    @_print_current
    def play(self, *args):
        self._mpdc.play()

    def playlist(self, *args):
        def ifn( b, s, d): wc.prnt(b, Template(s).safe_substitute(d))
        def cfn(): wc.prnt(None, "mpc closing playlist buffer")
        new_buf = wc.buffer_new('mpc: playlist', "ifn", "", "cfn", "")
        wc.buffer_set(new_buf, "localvar_set_no_log", "1")

        pl = self._mpdc.playlist()
        for line in pl:
            wc.prnt(new_buf, line)

        wc.buffer_set(new_buf, "display", "1")
        return pl

    def playlistinfo(self, sortkey='pos'):
        """Shows playlist information sorted by key
        """
        new_buf = wc.buffer_search("", "mpc: playlist")
        if len(new_buf) == 0:
            new_buf = wc.buffer_new('mpc: playlist', "", "", "", "")

        pl = self._mpdc.playlistinfo()
        try:
            # Numerical sort
            spl = sorted(pl,
                         cmp=lambda x,y: cmp(int(x), int(y)),
                         key=itemgetter(sortkey))
        except ValueError:
            # Alpha sort
            lcmp = lambda x,y: cmp(x.lower(), y.lower())
            spl = sorted(pl,
                         cmp=lambda x,y: cmp(x.lower(), y.lower()),
                         key=itemgetter(sortkey))

        t = Template(wc.config_get_plugin("playinfo"))
        for line in spl:
            wc.prnt(new_buf, t.safe_substitute(line))

        return pl

    @_print_current
    def previous(self):
        self._mpdc.previous()

    def random(self, *args):
        """Toggles randomness if no argument is given.
        """
        if len(args) == 0:
            args = [int(not int(self._get_status('random'))),]

        self._mpdc.random(*args)

    @_print_current
    def stop(self, *args):
        self._mpdc.stop()
Example #4
0
class MPDPrinter(Printer):
    def __init__(self,**kwargs):
        self.PAGES = ['PLAYER', 'OPTIONS']
        # configurable variables
        self.mpdhost = 'localhost'
        self.mpdport = 6600

        super(MPDPrinter,self).__init__(**kwargs)
        self.TASKS = ['player', 'playlist', 'options', 'mixer', 'update']
        self.DEPS  = {
            self.PAGE.PLAYER:  ['player', 'playlist'],
            self.PAGE.OPTIONS: ['options', 'mixer', 'update'],
            }
        # internal variables
        self._mpd = MPDClient()
        self._thread = None

    def init_layout(self):
        super(MPDPrinter,self).init_layout()
        
        page = Page(self.lcd,idx=self.PAGE.PLAYER)
        self.statetext = page.add(Text(width=1))
        self.songtext  = page.add(ScrollText(width=page.cols-1))
        page.newline()
        
        self.plstext   = page.add(ScrollText(width=5))
        self.timetext  = page.add(ScrollText(width=page.cols-self.plstext.width))
        self.pages.append(page)
        
        page = Page(self.lcd,idx=self.PAGE.OPTIONS)
        self.opttext    = page.add(CycleText(width=11))
        self.volumetext = page.add(Text(width=page.cols-self.opttext.width))
        page.newline()
        
        self.updatetext = CycleText(
            [ chr(LCD.SYM_UP)   + "Update " + chr(LCD.SYM_DOWN) + "Up RAM ",
              chr(LCD.SYM_LEFT) + "Vol-   " + chr(LCD.SYM_RIGHT)+ "Vol+   ",
              ],
            width=page.cols-1)
        page.add(self.updatetext)
        self.updatestatus = page.add(Text(width=1))
        self.pages.append(page)

        self.set_active(self.PAGE.PLAYER)
        
    def __del__(self):
        self.stop()

    def stop(self):
        if not self._thread:
            return
        self._thread.stop()
        self._thread = None
        
    def init(self):
        if not self._thread:
            self._thread = MPDThread(self.mpdhost,self.mpdport,self.logger)
            self._thread.start()
        self.lcd.set_color(*self.color)
        self.set_active(self.PAGE.PLAYER)
        self.render(True)
    
    def render(self,force=False):
        changed = self._thread.pop_data()
        if not changed:
            changed = []
        deps = self.DEPS[self.active]
        changed = [ i for i in changed if i in deps ] 
        if force:
            changed += deps
                    
        self.update(list(set(changed)))
        super(MPDPrinter,self).render(force)
    
    def update(self,changed=[]):
        self._mpd.connect(self.mpdhost, self.mpdport)
        status = self._mpd.status()
        if len(changed):
            current = self._mpd.currentsong()
        self._mpd.disconnect()
        
        timetext = '/'.join( [ strtime(i) for i in status.get('time', '0:0').split(':') ])
        self.timetext.setText( timetext.rjust(self.timetext.width))

        if not len(changed):
            return
        
        if 'player' in changed and not 'playlist' in changed:
            changed.append('playlist')
        
        self.logger.debug( '%s updating %s' % (type(self).__name__,str(changed)))
        for i in changed:
            if i == 'player':
                #print current
                artist = current.get('artist',None)
                album  = current.get('album' ,None)
                title  = current.get('title' ,None)
                genre  = current.get('genre' ,None)
                items = []
                if artist:
                    items.append(artist)
                if album and genre and genre in ['Books & Spoken', 'Drama', 'Podcast']:
                    items.append(album)
                if title:
                    items.append(title)
                songtext = " - ".join(items)
                self.songtext.setText(songtext)
                state = status['state']
                if state == 'play':
                    state = LCD.SYM_PLAY
                elif state == 'pause':
                    state = LCD.SYM_PAUSE
                else:
                    state = LCD.SYM_STOP
                self.statetext.setText(chr(state))
            elif i == 'playlist':
                plstext = ("%d/%d" % (int(status.get('song', '-1'))+1,int(status.get('playlistlength', '-1'))))
                self.plstext.setText( plstext.ljust(self.plstext.width))
            elif i == 'options':
                self.opttext.setList(
                    [
                        'Repeat '.ljust(8) + strswitch(int(status['repeat'])).rjust(3),
                        'Consume'.ljust(8) + strswitch(int(status['consume'])).rjust(3),
                        'Random '.ljust(8) + strswitch(int(status['random'])).rjust(3),
                        'Single '.ljust(8) + strswitch(int(status['single'])).rjust(3),
                        ]
                    )
            elif i == 'mixer':
                volumetext = status['volume']+"%"
                self.volumetext.setText(volumetext.rjust(self.volumetext.width))
            elif i == 'update':
                self.updatestatus.setText( chr(LCD.SYM_CLOCK) if status.get('updating_db', False) else ' ')
            elif i == 'sticker':
                pass
            else:
                self.logger.debug( "%s unhandled event %s" %( type(self).__name__, i))
        
    def call_mpd(self,cmd, *args):
        self._mpd.connect(self.mpdhost, self.mpdport)
        ret = self._mpd.__getattr__(cmd)(*args)
        self._mpd.disconnect()
        return ret

    def toggle_play(self):
        self._mpd.connect(self.mpdhost, self.mpdport)
        status = self._mpd.status()
        if status['state'] == 'play':
            self._mpd.pause()
        else:
            self._mpd.play()
        self._mpd.disconnect()

    def button_clicked(self,btn):
        if self.active == self.PAGE.PLAYER:
            if btn == LCD.RIGHT:
                self.call_mpd('next')
            elif btn == LCD.LEFT:
                self.call_mpd('previous')
        super(MPDPrinter,self).button_clicked(btn)
        
    def button_pressed(self,btn,repeat):
        if self.active == self.PAGE.PLAYER:
            if (btn == LCD.LEFT or btn == LCD.RIGHT) and repeat:
                status = self.call_mpd('status')
                if not status.has_key('elapsed'):
                    return
                secs   = int(float(status['elapsed'])+0.5)
                songid = status['songid']
                if btn == LCD.RIGHT:
                    secs += 10
                    self.call_mpd('seek', songid, str(secs))
                elif btn == LCD.LEFT:
                    secs -= 10
                    self.call_mpd('seek', songid, str(secs))
            elif btn == LCD.DOWN and not repeat:
                self.call_mpd('stop')
            elif btn == LCD.UP and not repeat:
                self.toggle_play()
        elif self.active == self.PAGE.OPTIONS:
            volumetext = self.volumetext.text[:-1]
            if len(volumetext):
                volume = int(volumetext)
                if btn == LCD.RIGHT:
                    volume = min(volume+5,100)
                    self.call_mpd('setvol', volume)
                    self.volumetext.setText("%d%%" % volume)
                elif btn == LCD.LEFT:
                    volume = max(volume-5,0)
                    self.call_mpd('setvol', volume)
                    self.volumetext.setText("%d%%" % volume)
            if btn == LCD.UP and not repeat:
                if self.updatestatus.text == ' ':
                    self.show_splash('Updating all')
                    self.call_mpd('update')
                else:
                    self.show_splash('Update in\nprogress')
            elif btn == LCD.DOWN and not repeat:
                if self.updatestatus.text == ' ':
                    self.show_splash('Updating ramdisk')
                    self.call_mpd('update', 'RAMDISK')
                else:
                    self.show_splash('Update in\nprogress')
        super(MPDPrinter,self).button_pressed(btn,repeat)