示例#1
0
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
示例#2
0
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
示例#3
0
    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)
示例#4
0
    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
示例#5
0
 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()
示例#6
0
 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()
示例#7
0
 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()
示例#8
0
 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)
示例#9
0
 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
示例#10
0
 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()
示例#11
0
 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)
示例#12
0
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
示例#13
0
 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
示例#14
0
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)
示例#15
0
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
示例#16
0
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')
示例#17
0
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
示例#18
0
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)
示例#19
0
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)
示例#20
0
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')