class PluginInterface(plugin.DaemonPlugin): """ To activate this plugin, just put the following line at the end of your local_conf.py file: | plugin.activate('processevent') """ __author__ = 'Your Name' __author_email__ = '*****@*****.**' __maintainer__ = __author__ __maintainer_email__ = __author_email__ __version__ = '$Revision$' def __init__(self): """ init the events plug-in """ plugin.DaemonPlugin.__init__(self) plugin.register(self, 'processevent') self.plugin_name = 'processevent' self.event = EventHandler(self.event_handler) self.event.register() def event_handler(self, event): """ The event handler """ print '%s event_handler(%s) %s' % (time.strftime('%H:%M:%S'), event, event.__dict__) return True
def __init__(self, standalone=False): """ init the upsoon plugin """ logger.log( 9, 'upsoon.PluginInterface.__init__()') plugin.DaemonPlugin.__init__(self) plugin.register(self, 'upsoon') self.standalone = standalone self.lock = thread.allocate_lock() self.running = True self.timer = Timer(self.timer_handler).start(15) self.event = EventHandler(self.event_handler) #self.event.register(('VIDEO_START', 'VIDEO_END')) self.event.register() self.recordclient = RecordClient() self.fc = FreevoChannels() self.rdev = config.RADIO_DEVICE self.next_program = None self.announced = False self.seconds_before_announce = config.TV_UPSOON_ANNOUNCE self.seconds_before_start = config.TV_UPSOON_BEFORE_START self.pending_lockfile = config.FREEVO_CACHEDIR + '/record.soon' self.tv_lockfile = None # lockfile of recordserver self.stopped = None # flag that tells upsoon what stopped if os.path.exists(self.pending_lockfile): os.remove(self.pending_lockfile) logger.debug('%r lockfile removed', self.pending_lockfile)
def __init__(self, standalone=False): """ init the upsoon plugin """ _debug_('upsoon.PluginInterface.__init__()', 2) plugin.DaemonPlugin.__init__(self) plugin.register(self, 'upsoon') self.standalone = standalone self.lock = thread.allocate_lock() self.running = True self.timer = Timer(self.timer_handler).start(15) self.event = EventHandler(self.event_handler) #self.event.register(('VIDEO_START', 'VIDEO_END')) self.event.register() self.recordclient = RecordClient() self.fc = FreevoChannels() self.rdev = config.RADIO_DEVICE self.next_program = None self.seconds_before_announce = 120 self.seconds_before_start = 60 self.pending_lockfile = config.FREEVO_CACHEDIR + '/record.soon' self.tv_lockfile = None # lockfile of recordserver self.stopped = None # flag that tells upsoon what stopped
def __init__(self): logger.log( 9, 'detach.PluginInterface.__init__()') plugin.MainMenuPlugin.__init__(self) config.EVENTS['audio'][config.DETACH_KEY] = Event(FUNCTION_CALL, arg=self.detach) self.show_item = menu.MenuItem(_('Show player'), action=self.show) self.show_item.type = 'detached_player' self.event = EventHandler(self._event_handler) self.event.register()
def __init__(self): """ Init the autostart timeout and the plugin variables """ plugin.DaemonPlugin.__init__(self) self.active = True self.timer = OneShotTimer(self._timer_handler) self.event = EventHandler(self._event_handler) self.event.register()
def __init__(self): """ init the events plug-in """ plugin.DaemonPlugin.__init__(self) plugin.register(self, 'processevent') self.plugin_name = 'processevent' self.event = EventHandler(self.event_handler) self.event.register()
def __init__(self): """initialise the DaemonPlugin interface""" logger.log(9, 'detachbar.PluginInterface.__init__()') plugin.DaemonPlugin.__init__(self) self.plugin_name = 'audio.detachbar' self.player = None self.event = EventHandler(self._event_handler) self.event.register() self.state = DIALOG_NOTSET self.dialog = None self.update(DIALOG_HIDE)
def __init__(self): """initialise the DaemonPlugin interface""" logger.log(9, 'detachbar.PluginInterface.__init__()') plugin.DaemonPlugin.__init__(self) self.plugin_name = 'audio.detachbar' self.player = None self.timer = Timer(self._timer_handler) self.event = EventHandler(self._event_handler) self.event.register() self.state = BAR_NOTSET self.update(BAR_HIDE) # tunables self.wait_timeout = 3 # 3 seconds till we hide the bar
class PluginInterface(plugin.DaemonPlugin): """ The autostart plugin allows you to define an action that will be called when the user do not interact in the first few seconds. With this it is possible to define a default action e.g. starting radio if there is no other activity. To activate the autostart plugin add to local_conf.py:: plugin.activate('autostart') AUTOSTART_EVENTS = ( 'MENU_DOWN', 'MENU_DOWN', 'MENU_SELECT', 'MENU_SELECT', ) """ __author__ = 'Andreas Dick' __author_email__ = '*****@*****.**' __maintainer__ = __author__ __maintainer_email__ = __author_email__ __version__ = '$Revision$' def __init__(self): """ Init the autostart timeout and the plugin variables """ plugin.DaemonPlugin.__init__(self) self.active = True self.timer = OneShotTimer(self._timer_handler) self.event = EventHandler(self._event_handler) self.event.register() def config(self): return [ ('AUTOSTART_EVENTS', [], 'list of events to send to freevo at start up'), ('AUTOSTART_TIMEOUT', 5, 'Numbers of seconds to time out if there is no action'), ] def _event_handler(self, event): if self.active: if event == FREEVO_READY: self.active = True self.timer.start(config.AUTOSTART_TIMEOUT) elif event == MENU_PROCESS_END: if not self.active: self.timer.start(config.AUTOSTART_TIMEOUT) elif config.AUTOSTART_TIMEOUT: logger.info('Another event is closing the autostart plugin.') self.event.unregister() self.timer.stop() self.active = False def _timer_handler(self): if self.active: logger.info('Timeout reached without an event, posting events now.') for e in config.AUTOSTART_EVENTS: rc.post_event(Event(e)) self.event.unregister() self.timer.stop() self.active = False
def __init__(self): """initialise the DaemonPlugin interface""" logger.log( 9, 'detachbar.PluginInterface.__init__()') plugin.DaemonPlugin.__init__(self) self.plugin_name = 'audio.detachbar' self.player = None self.timer = Timer(self._timer_handler) self.event = EventHandler(self._event_handler) self.event.register() self.state = BAR_NOTSET self.update(BAR_HIDE) # tunables self.wait_timeout = 3 # 3 seconds till we hide the bar
class PluginInterface(plugin.MainMenuPlugin): """ plugin to detach the audio player to e.g. view pictures while listening to music """ detached = False def __init__(self): logger.log( 9, 'detach.PluginInterface.__init__()') plugin.MainMenuPlugin.__init__(self) config.EVENTS['audio'][config.DETACH_KEY] = Event(FUNCTION_CALL, arg=self.detach) self.menuw = None self.show_item = menu.MenuItem(_('Show Player'), action=self.show) self.show_item.type = 'detached_player' self.event = EventHandler(self._event_handler) self.event.register() def config(self): """ config is called automatically, freevo plugins -i audio.detach returns the info """ return [ ('DETACH_KEY', 'DISPLAY', 'Event to activate the detach bar, DISPLAY, ENTER, EXIT'), ] def detach(self): logger.debug('detach()') rc.post_event(plugin.event('DETACH')) def attach(self): logger.debug('attach()') rc.post_event(plugin.event('ATTACH')) def _event_handler(self, event): logger.log(9, '_event_handler(event=%s), event.arg=%r, event.context=%r, PluginInterface.detached=%r', event, event.arg, event.context, PluginInterface.detached) gui = audio.player.get() if gui: p = gui.player if event == BUTTON: if event.arg == 'FFWD': p.eventhandler(Event('SEEK', arg='10', context='audio')) elif event.arg == 'REW': p.eventhandler(Event('SEEK', arg='-10', context='audio')) elif event.arg == 'PAUSE': p.eventhandler(Event('PLAY', context='audio')) elif event.arg == 'STOP': PluginInterface.detached = False p.eventhandler(Event('STOP')) elif event.arg == 'NEXT': p.eventhandler(Event('PLAYLIST_NEXT', context='audio')) elif event.arg == 'PREV': p.eventhandler(Event('PLAYLIST_PREV', context='audio')) elif plugin.isevent(event) == 'DETACH': p.eventhandler(event) self._detach() elif plugin.isevent(event) == 'ATTACH': self._attach() p.eventhandler(event) elif event == VIDEO_START: PluginInterface.detached = False p.eventhandler(Event('STOP')) elif event == PLAY_START and gui.visible: rc.post_event(plugin.event('ATTACH')) def _detach(self, menuw=None): logger.debug('_detach()') if PluginInterface.detached: return PluginInterface.detached = True gui = audio.player.get() # preserve the menu self.menuw = gui.menuw # hide the menuw's gui.hide() gui.menuw.show() # set all menuw's to None to prevent the next title to be visible again gui.menuw = None gui.item.menuw = None if gui.item.parent: gui.item.parent.menuw = None def _attach(self, menuw=None): logger.debug('_attach()') if not PluginInterface.detached: return PluginInterface.detached = False gui = audio.player.get() # restore the menuw's if not menuw: gui.menuw = self.menuw gui.item.menuw = self.menuw else: gui.menuw = menuw gui.item.menuw = menuw if gui.item.parent: gui.item.parent.menuw = menuw # hide the menu and show the player if menuw: menuw.hide() gui.show() def items(self, parent): logger.log( 9, 'items(parent=%r)', parent) gui = audio.player.get() if gui and gui.player.is_playing(): self.show_item.parent = parent return [ self.show_item ] return [] def show(self, arg=None, menuw=None): logger.debug('show(arg=%r, menuw=%r)', arg, menuw) rc.post_event(plugin.event('ATTACH')) self._attach(menuw)
class PluginInterface(plugin.DaemonPlugin): """ This plugin enables a small bar showing information about audio being played when detached with the detach plugin. If the idlebar is loaded and there is enough space left there, this plugin will draw itself there, otherwise it will draw at the right bottom of the screen. """ detached = False def __init__(self): """initialise the DaemonPlugin interface""" logger.log(9, 'detachbar.PluginInterface.__init__()') plugin.DaemonPlugin.__init__(self) self.plugin_name = 'audio.detachbar' self.player = None self.event = EventHandler(self._event_handler) self.event.register() self.state = DIALOG_NOTSET self.dialog = None self.update(DIALOG_HIDE) def _event_handler(self, event): logger.log( 9, '_event_handler(event=%s), event.arg=%r, event.context=%r, PluginInterface.detached=%r', event, event.arg, event.context, PluginInterface.detached) player = audio.player.get() if plugin.isevent(event) == 'DETACH': PluginInterface.detached = True self.update(DIALOG_SHOW) elif plugin.isevent(event) == 'ATTACH': PluginInterface.detached = False self.update(DIALOG_HIDE) elif event == BUTTON and event.arg == 'STOP': PluginInterface.detached = False self.update(DIALOG_HIDE) elif PluginInterface.detached: # this event can only happen if video or game starts playing # hide the dialog now if event == VIDEO_START: PluginInterface.detached = False self.update(DIALOG_HIDE) elif event == PLAY_START and not player.visible: self.update(DIALOG_SHOW) def update(self, state=None): """ update the Dialog according to dialog state """ logger.log(9, 'state=%s', formatstate(state)) if state == DIALOG_SHOW: self.show() elif state == DIALOG_HIDE: # the dialog is visible, let's hide it self.stop() self.state = state def show(self): """ Used when showing the dialog """ logger.log(9, 'show()') self.player = audio.player.get() if self.player and self.detached: self.dialog = audio.show_play_state(dialog.PLAY_STATE_PLAY, self.player.item, self.get_time_info, type='play_state_mini') self.dialog.show() def hide(self): """ Used when hiding the dialog """ logger.log(9, 'hide()') self.player = None if self.dialog: self.dialog.hide() def stop(self): """ Stops the dialog """ logger.debug('stop()') if self.dialog and self.player and not self.detached: self.hide() self.dialog = None def get_time_info(self): """ Callback for PlayStateDialog @return: an array of audio info to be rendered on the dialog """ if self.player is None: return None try: if self.player.item.length: return (self.player.item.elapsed, self.player.item.length) else: return (self.player.item.elapsed) except AttributeError: return None
class PluginInterface(plugin.DaemonPlugin): """ This plugin enables a small bar showing information about audio being played when detached with the detach plugin. If the idlebar is loaded and there is enough space left there, this plugin will draw itself there, otherwise it will draw at the right bottom of the screen. A dot (graphvis) diagram of the states the bar has dot -Tpng -odetach.png detach.dot | digraph finite_state_machine { | rankdir=TB; | size="8,5" | node [shape = doublecircle]; Hide; | node [shape = circle]; | { rank = same; "Wait"; "Show"; } | Hide -> Show [ label = "detach(start timer)" ]; | Show -> Wait [ label = "play_end" ]; | Show -> Hide [ label = "stop(stop timer)" ]; | Wait -> Hide [ label = "stop(stop timer)" ]; | Show -> Show [ label = "play_start" ]; | Wait -> Show [ label = "play_start" ]; | Wait -> Hide [ label = "timeout(stop timer)" ]; | } """ detached = False def __init__(self): """initialise the DaemonPlugin interface""" logger.log( 9, 'detachbar.PluginInterface.__init__()') plugin.DaemonPlugin.__init__(self) self.plugin_name = 'audio.detachbar' self.player = None self.timer = Timer(self._timer_handler) self.event = EventHandler(self._event_handler) self.event.register() self.state = BAR_NOTSET self.update(BAR_HIDE) # tunables self.wait_timeout = 3 # 3 seconds till we hide the bar def _event_handler(self, event): logger.log( 9, '_event_handler(event=%s)', event) if plugin.isevent(event) == 'DETACH': PluginInterface.detached = True self.update(BAR_SHOW) elif plugin.isevent(event) == 'ATTACH': PluginInterface.detached = False self.update(BAR_HIDE) elif event == STOP: PluginInterface.detached = False self.update(BAR_HIDE) elif event == BUTTON and event.arg == 'STOP': PluginInterface.detached = False self.update(BAR_HIDE) elif PluginInterface.detached: if event == PLAY_START: self.update(BAR_SHOW) elif event == PLAY_END: self.update(BAR_WAIT) def _timer_handler(self): logger.log( 9, '_timer_handler()') self.update() def update(self, state=None): """ update the bar according to bar state """ logger.log( 8, 'update()') if state is not None: if state == BAR_SHOW: self.show() self.timer.start(1.0) elif state == BAR_HIDE: self.timer.stop() self.hide() elif state == BAR_WAIT: self.time = time.time() self.state = state if self.state == BAR_SHOW: skin.redraw() elif self.state == BAR_HIDE: skin.redraw() elif self.state == BAR_WAIT: if self.time and (time.time() - self.time) > self.wait_timeout: self.update(BAR_HIDE) def show(self): """ used when showing for the first time """ logger.log( 9, 'show()') self.player = audio.player.get() if self.player: self.getinfo() def hide(self): """ used when hiding the bar """ logger.log( 9, 'hide()') self.render = [] self.player = None self.time = None self.bar = None def stop(self): """ stops the player, waiting for timeout """ logger.log( 9, 'stop()') #self.state = BAR_WAIT #self.time = time.time() def draw(self, (type, object), osd): """ draws the bar called from the skin's redraw method """ logger.log( 8, 'draw((type=%r, object=%r), osd=%r)', type, object, osd) if self.player is None: return #if self.state == BAR_WAIT: # # when idle, wait for a new player # if audio.player.get(): # self.show() #elif self.state == BAR_SHOW: # if self.player and not self.player.running: # # player stopped, we also stop # # and wait for a new one # self.player = None # self.stop() # return # if type == 'player': # # Oops, showing the player again, stop me # self.stop() # self.hide() # return font = osd.get_font('detachbar') if font == osd.get_font('default'): font = osd.get_font('info value') self.calculatesizes(osd, font) if self.image: x = self.x - self.h width = self.w + 70 - 10 else: x = self.x width = self.w if not self.idlebar: y = self.y - 10 height = self.h osd.drawroundbox(x, y, width, height, (0xf0ffffffL, 5, 0xb0000000L, 10)) if self.image: osd.draw_image(self.image, (x+5, self.y, 50, 50)) y = self.t_y for r in self.render: osd.write_text(r, font, None, self.t_x, y, self.t_w, self.font_h, 'center', 'center') y += self.font_h try: if self.player.item.length: progress = '%s/%s' % (self.formattime(self.player.item.elapsed), self.formattime(self.player.item.length)) else: progress = '%s' % self.formattime(self.player.item.elapsed) except AttributeError: progress = '' osd.write_text(progress, font, None, self.t_x, y, self.t_w, self.font_h, 'center', 'center')
class PluginInterface(plugin.DaemonPlugin): """ This plugin enables a small bar showing information about audio being played when detached with the detach plugin. If the idlebar is loaded and there is enough space left there, this plugin will draw itself there, otherwise it will draw at the right bottom of the screen. """ detached = False def __init__(self): """initialise the DaemonPlugin interface""" logger.log(9, 'detachbar.PluginInterface.__init__()') plugin.DaemonPlugin.__init__(self) self.plugin_name = 'audio.detachbar' self.player = None self.event = EventHandler(self._event_handler) self.event.register() self.state = DIALOG_NOTSET self.dialog = None self.update(DIALOG_HIDE) def _event_handler(self, event): logger.log(9, '_event_handler(event=%s), event.arg=%r, event.context=%r, PluginInterface.detached=%r', event, event.arg, event.context, PluginInterface.detached) player = audio.player.get() if plugin.isevent(event) == 'DETACH': PluginInterface.detached = True self.update(DIALOG_SHOW) elif plugin.isevent(event) == 'ATTACH': PluginInterface.detached = False self.update(DIALOG_HIDE) elif event == BUTTON and event.arg == 'STOP': PluginInterface.detached = False self.update(DIALOG_HIDE) elif PluginInterface.detached: # this event can only happen if video or game starts playing # hide the dialog now if event == VIDEO_START: PluginInterface.detached = False self.update(DIALOG_HIDE) elif event == PLAY_START and not player.visible: self.update(DIALOG_SHOW) def update(self, state=None): """ update the Dialog according to dialog state """ logger.log(9, 'state=%s', formatstate(state)) if state == DIALOG_SHOW: self.show() elif state == DIALOG_HIDE: # the dialog is visible, let's hide it self.stop() self.state = state def show(self): """ Used when showing the dialog """ logger.log(9, 'show()') self.player = audio.player.get() if self.player and self.detached: self.dialog = audio.show_play_state(dialog.PLAY_STATE_PLAY, self.player.item, self.get_time_info, type='play_state_mini') self.dialog.show() def hide(self): """ Used when hiding the dialog """ logger.log(9, 'hide()') self.player = None if self.dialog: self.dialog.hide() def stop(self): """ Stops the dialog """ logger.debug('stop()') if self.dialog and self.player and not self.detached: self.hide() self.dialog = None def get_time_info(self): """ Callback for PlayStateDialog @return: an array of audio info to be rendered on the dialog """ if self.player is None: return None try: if self.player.item.length: return (self.player.item.elapsed, self.player.item.length) else: return (self.player.item.elapsed) except AttributeError: return None
class PluginInterface(plugin.DaemonPlugin): """ plugin to monitor if a recording is about to start and shut down the player if the video device is in use To activate this plugin, just put the following line at the end of your local_conf.py file: | plugin.activate('tv.upsoon') """ __author__ = 'Duncan Webb' __author_email__ = '*****@*****.**' __maintainer__ = __author__ __maintainer_email__ = __author_email__ __version__ = '$Revision$' def __init__(self, standalone=False): """ init the upsoon plugin """ logger.log( 9, 'upsoon.PluginInterface.__init__()') plugin.DaemonPlugin.__init__(self) plugin.register(self, 'upsoon') self.standalone = standalone self.lock = thread.allocate_lock() self.running = True self.timer = Timer(self.timer_handler).start(15) self.event = EventHandler(self.event_handler) #self.event.register(('VIDEO_START', 'VIDEO_END')) self.event.register() self.recordclient = RecordClient() self.fc = FreevoChannels() self.rdev = config.RADIO_DEVICE self.next_program = None self.announced = False self.seconds_before_announce = config.TV_UPSOON_ANNOUNCE self.seconds_before_start = config.TV_UPSOON_BEFORE_START self.pending_lockfile = config.FREEVO_CACHEDIR + '/record.soon' self.tv_lockfile = None # lockfile of recordserver self.stopped = None # flag that tells upsoon what stopped if os.path.exists(self.pending_lockfile): os.remove(self.pending_lockfile) logger.debug('%r lockfile removed', self.pending_lockfile) def config(self): return [ ('TV_UPSOON_BEFORE_START', 1*60, 'Number of seconds before start of recording to stop player'), ('TV_UPSOON_ANNOUNCE', 1*60+60, 'Number of seconds before start of recording to announce starting'), ] def getVideoForChannel(self, channel_id): """ get the video device given a channel id """ logger.log( 9, 'getVideoForChannel(channel_id=%r)', channel_id) return self.fc.getVideoGroup(channel_id, False, CHANNEL_ID).vdev def stopVideoInUse(self, vdev): """ stop the video device if being used """ logger.log( 9, 'stopVideoInUse(vdev=%r)', vdev) if vdev: try: dev_fh = os.open(vdev, os.O_TRUNC) try: os.read(dev_fh, 1) except: if (self.seconds_to_next > self.seconds_before_start): # just announce rc.post_event(Event(OSD_MESSAGE, arg=_('A recording will start in a few minutes'))) else: # stop the tv rc.post_event(STOP) self.stopped = _('TV') os.close(dev_fh) except Exception, why: logger.warning('cannot check video device %r: %s', vdev, why)
class PluginInterface(plugin.DaemonPlugin): """ plugin to monitor if a recording is about to start and shut down the player if the video device is in use To activate this plugin, just put the following line at the end of your local_conf.py file: | plugin.activate('tv.upsoon') """ __author__ = 'Duncan Webb' __author_email__ = '*****@*****.**' __maintainer__ = __author__ __maintainer_email__ = __author_email__ __version__ = '$Revision: 10559 $' def __init__(self, standalone=False): """ init the upsoon plugin """ _debug_('upsoon.PluginInterface.__init__()', 2) plugin.DaemonPlugin.__init__(self) plugin.register(self, 'upsoon') self.standalone = standalone self.lock = thread.allocate_lock() self.running = True self.timer = Timer(self.timer_handler).start(15) self.event = EventHandler(self.event_handler) #self.event.register(('VIDEO_START', 'VIDEO_END')) self.event.register() self.recordclient = RecordClient() self.fc = FreevoChannels() self.rdev = config.RADIO_DEVICE self.next_program = None self.seconds_before_announce = 120 self.seconds_before_start = 60 self.pending_lockfile = config.FREEVO_CACHEDIR + '/record.soon' self.tv_lockfile = None # lockfile of recordserver self.stopped = None # flag that tells upsoon what stopped def findNextProgramHandler(self, result): """ Handles the result from the findNextProgram call """ _debug_('findNextProgramHandler(result=%r)' % (result, ), 2) (status, self.next_program) = result if not status: return now = time.time() _debug_( 'now=%s next=%s ' % (time.strftime('%T', time.localtime(now)), self.next_program), 2) self.vdev = self.getVideoForChannel(self.next_program.channel_id) self.tv_lockfile = os.path.join(config.FREEVO_CACHEDIR, 'record.' + self.vdev.split('/')[-1]) self.seconds_to_next = self.next_program.start - config.TV_RECORD_PADDING_PRE - int( now + 0.5) _debug_('next recording in %s secs' % (self.seconds_to_next), 2) # announce 120 seconds before recording is due to start # stop the player 60 seconds before recording is due to start if (self.seconds_to_next > self.seconds_before_announce): return if (self.seconds_to_next <= self.seconds_before_start): if not os.path.exists(self.pending_lockfile): open(self.pending_lockfile, 'w').close() _debug_('%r lockfile created' % (self.pending_lockfile)) _debug_('stopping video or radio player') self.stopVideoInUse(self.vdev) self.stopRadioInUse(self.rdev) return def getVideoForChannel(self, channel_id): """ get the video device given a channel id """ _debug_('getVideoForChannel(channel_id=%r)' % (channel_id), 2) return self.fc.getVideoGroup(channel_id, False).vdev def stopVideoInUse(self, vdev): """ stop the video device if being used """ _debug_('stopVideoInUse(vdev=%r)' % (vdev), 2) if vdev: try: dev_fh = os.open(vdev, os.O_TRUNC) try: os.read(dev_fh, 1) except: if (self.seconds_to_next > self.seconds_before_start): # just announce rc.post_event( Event( OSD_MESSAGE, arg=_('A recording will start in a few minutes' ))) else: # stop the tv rc.post_event(STOP) self.stopped = _('TV') os.close(dev_fh) except Exception, e: print '%r: %s' % (vdev, e) _debug_('cannot check video device \"%s\"' % (vdev), DINFO)
class PluginInterface(plugin.DaemonPlugin): """ This plugin enables a small bar showing information about audio being played when detached with the detach plugin. If the idlebar is loaded and there is enough space left there, this plugin will draw itself there, otherwise it will draw at the right bottom of the screen. A dot (graphvis) diagram of the states the bar has dot -Tpng -odetach.png detach.dot | digraph finite_state_machine { | rankdir=TB; | size="8,5" | node [shape = doublecircle]; Hide; | node [shape = circle]; | { rank = same; "Wait"; "Show"; } | Hide -> Show [ label = "detach(start timer)" ]; | Show -> Wait [ label = "play_end" ]; | Show -> Hide [ label = "stop(stop timer)" ]; | Wait -> Hide [ label = "stop(stop timer)" ]; | Show -> Show [ label = "play_start" ]; | Wait -> Show [ label = "play_start" ]; | Wait -> Hide [ label = "timeout(stop timer)" ]; | } """ detached = False def __init__(self): """initialise the DaemonPlugin interface""" logger.log(9, 'detachbar.PluginInterface.__init__()') plugin.DaemonPlugin.__init__(self) self.plugin_name = 'audio.detachbar' self.player = None self.timer = Timer(self._timer_handler) self.event = EventHandler(self._event_handler) self.event.register() self.state = BAR_NOTSET self.update(BAR_HIDE) # tunables self.wait_timeout = 3 # 3 seconds till we hide the bar def _event_handler(self, event): logger.log(9, '_event_handler(event=%s)', event) if plugin.isevent(event) == 'DETACH': PluginInterface.detached = True self.update(BAR_SHOW) elif plugin.isevent(event) == 'ATTACH': PluginInterface.detached = False self.update(BAR_HIDE) elif event == STOP: PluginInterface.detached = False self.update(BAR_HIDE) elif event == BUTTON and event.arg == 'STOP': PluginInterface.detached = False self.update(BAR_HIDE) elif PluginInterface.detached: if event == PLAY_START: self.update(BAR_SHOW) elif event == PLAY_END: self.update(BAR_WAIT) def _timer_handler(self): logger.log(9, '_timer_handler()') self.update() def update(self, state=None): """ update the bar according to bar state """ logger.log(8, 'update()') if state is not None: if state == BAR_SHOW: self.show() self.timer.start(1.0) elif state == BAR_HIDE: self.timer.stop() self.hide() elif state == BAR_WAIT: self.time = time.time() self.state = state if self.state == BAR_SHOW: skin.redraw() elif self.state == BAR_HIDE: skin.redraw() elif self.state == BAR_WAIT: if self.time and (time.time() - self.time) > self.wait_timeout: self.update(BAR_HIDE) def show(self): """ used when showing for the first time """ logger.log(9, 'show()') self.player = audio.player.get() if self.player: self.getinfo() def hide(self): """ used when hiding the bar """ logger.log(9, 'hide()') self.render = [] self.player = None self.time = None self.bar = None def stop(self): """ stops the player, waiting for timeout """ logger.log(9, 'stop()') #self.state = BAR_WAIT #self.time = time.time() def draw(self, (type, object), osd): """ draws the bar called from the skin's redraw method """ logger.log(8, 'draw((type=%r, object=%r), osd=%r)', type, object, osd) if self.player is None: return #if self.state == BAR_WAIT: # # when idle, wait for a new player # if audio.player.get(): # self.show() #elif self.state == BAR_SHOW: # if self.player and not self.player.running: # # player stopped, we also stop # # and wait for a new one # self.player = None # self.stop() # return # if type == 'player': # # Oops, showing the player again, stop me # self.stop() # self.hide() # return font = osd.get_font('detachbar') if font == osd.get_font('default'): font = osd.get_font('info value') self.calculatesizes(osd, font) if self.image: x = self.x - self.h width = self.w + 70 - 10 else: x = self.x width = self.w if not self.idlebar: y = self.y - 10 height = self.h osd.drawroundbox(x, y, width, height, (0xf0ffffffL, 5, 0xb0000000L, 10)) if self.image: osd.draw_image(self.image, (x + 5, self.y, 50, 50)) y = self.t_y for r in self.render: osd.write_text(r, font, None, self.t_x, y, self.t_w, self.font_h, 'center', 'center') y += self.font_h try: if self.player.item.length: progress = '%s/%s' % (self.formattime( self.player.item.elapsed), self.formattime(self.player.item.length)) else: progress = '%s' % self.formattime(self.player.item.elapsed) except AttributeError: progress = '' osd.write_text(progress, font, None, self.t_x, y, self.t_w, self.font_h, 'center', 'center')