Hi there,

OK, here is a big patch.
It improves the handling of scheduled recordings and favorites.
It includes Jose's patches and also the two patches that I sent before
(for genre and search).


Regards
Tanja



Jose schrieb:
Hi,

But favorites are a different business, as we need different infos
there as "day of week", "time of
day" and so on. So creating a new class seems to be the right way
here. But what I do not like in
the way it is now implemented is that you have a submenu "Favorite..."
for each ProgramItem and in
this "Add favorite" or "Remove favorite". I would like to have those
options top level.
Thus one would need to have the following extra actions in
ProgramItem:
"add to favorites"
"edit favorite"
"remove from favorites"
The first two should open the menu with the actions for a favorite
which are to change all the
points like "when" and "where" and so on.
That is in fact also what I was thinking. I guess the best way for that
is, when creating the programItem submenu create also the favorite class
and ask the class whether the favorite already exists or not. This way
you still keep the programItem and favorite functionality separated and
the programItem doesn't get to complex.

Jose, are you still working on this stuff?
Maybe I should look into something else, as I do not want to interfere
with you.
No, please continu looking into this. Some time I started looking into
the favorites, but at some point
I didn't have much time so it got stalled. I think, the sooner it has
better functionality the better.. :)
Al the changes I made on this I sent yesterday.

regards,
Jose




Index: tvserver/src/favorite.py
===================================================================
--- tvserver/src/favorite.py	(Revision 9584)
+++ tvserver/src/favorite.py	(Arbeitskopie)
@@ -86,11 +86,7 @@
         self.fxdname   = ''
         self.once      = once
         self.substring = substring
-        for t in times:
-            m = _time_re.match(t).groups()
-            start = int(m[0])*100 + int(m[1])
-            stop  = int(m[2])*100 + int(m[3])
-            self.times.append((start, stop))
+        self.times     = times
         self.start_padding = config.record.start_padding
         self.stop_padding  = config.record.stop_padding
 
@@ -119,10 +115,7 @@
             if child.name == 'times':
                 self.times = []
                 for t in child.children:
-                    m = _time_re.match(t.content).groups()
-                    start = int(m[0])*100 + int(m[1])
-                    stop  = int(m[2])*100 + int(m[3])
-                    self.times.append((start, stop))
+                    self.times.append(t.content)
             if child.name == 'padding':
                 self.start_padding = int(child.getattr('start'))
                 self.stop_padding  = int(child.getattr('stop'))
@@ -159,8 +152,11 @@
         if not int(time.strftime('%w', timestruct)) in self.days:
             return False
         stime = int(timestruct[3]) * 100 + int(timestruct[4])
-        for t1, t2 in self.times:
-            if stime >= t1 and stime <= t2:
+        for t in self.times:
+            m = _time_re.match(t).groups()
+            start = int(m[0])*100 + int(m[1])
+            stop  = int(m[2])*100 + int(m[3])
+            if stime >= start and stime <= stop:
                 return True
         return False
 
@@ -252,8 +248,7 @@
             channels.add_child('channel', chan)
         times = node.add_child('times')
         for t in self.times:
-            times.add_child('start', '%02d:%02d-%02d:%02d' % \
-                            (t[0] / 100, t[0] % 100, t[1] / 100, t[1] % 100))
+            times.add_child('start', t)
         if self.once:
             node.add_child('once')
         if self.substring:
Index: tvserver/src/server.py
===================================================================
--- tvserver/src/server.py	(Revision 9584)
+++ tvserver/src/server.py	(Arbeitskopie)
@@ -433,10 +433,10 @@
 
 
     @freevo.ipc.expose('home-theatre.recording.modify')
-    def rpc_recording_modify(self, int, info):
+    def rpc_recording_modify(self, id, info):
         """
         modify a recording
-        parameter: id [ ( var val ) (...) ]
+        parameter: id, [ ( var, val ) (...) ]
         """
         key_val = dict(info)
         log.info('recording.modify: %s' % id)
@@ -564,6 +564,12 @@
             return NameError('Already scheduled')
         self.favorites.append(f)
 
+        #Align favorites id(s)
+        next = 0
+        for r in self.favorites:
+            r.id = next
+            next += 1
+
         # update schedule
         self.epg_update()
         
@@ -586,6 +592,12 @@
             return NameError('Favorite not found!')
         log.info('favorite.remove: %s', f)
         self.favorites.remove(f)
+        
+        #Align favorites id(s)
+        next = 0
+        for r in self.favorites:
+            r.id = next
+            next += 1
 
         # send update to all clients
         msg = [ f.long_list() for f in self.favorites ]
@@ -593,6 +605,29 @@
         return []
 
 
+    @freevo.ipc.expose('home-theatre.favorite.modify')
+    def rpc_favorite_modify(self, id, info):
+        """
+        modify a recording
+        parameter: id, [ ( var, val ) (...) ]
+        """
+        key_val = dict(info)
+        log.info('favorite.modify: %s' % id)
+        for r in self.favorites:
+            if r.id == id:
+                cp = copy.copy(self.favorites[id])
+                for key in key_val:
+                    setattr(cp, key, key_val[key])
+                self.favorites[self.favorites.index(r)] = cp
+                # update schedule
+                self.epg_update()
+                # send update to all clients
+                msg = [ f.long_list() for f in self.favorites ]
+                self.send_event('home-theatre.favorite.list.update', *msg)
+                return []
+        return IndexError('Favorite not found')
+
+
     @freevo.ipc.expose('home-theatre.favorite.list')
     def rpc_favorite_list(self):
         """
Index: core/src/ipc/tvserver.py
===================================================================
--- core/src/ipc/tvserver.py	(Revision 9584)
+++ core/src/ipc/tvserver.py	(Arbeitskopie)
@@ -266,7 +266,7 @@
             info['subtitle'] = prog.subtitle
 
         result = self.rpc('home-theatre.recording.add', prog.title,
-                          prog.channel.name, 1000, prog.start, prog.stop, info)
+                          prog.channel, 1000, prog.start, prog.stop, info)
         yield result
         if not result():
             # FIXME: get real error message from tvserver
@@ -291,7 +291,7 @@
     """
     A favorite object from the recordserver.
     """
-    def __init__(self, id, title, channels, priority, days, time, one_shot,
+    def __init__(self, id, title, channels, priority, days, times, one_shot,
                  substring):
         """
         The init function creates the object. The parameters are the complete
@@ -302,7 +302,7 @@
         self.channels = channels
         self.priority = priority
         self.days = days
-        self.time = time
+        self.times = times
         self.one_shot = one_shot
         self.substring = substring
         self.description = {}
@@ -414,6 +414,33 @@
         yield self.SUCCESS
 
 
+    @kaa.notifier.yield_execution()
+    def modify(self, id, info):
+        """
+        remove a favorite
+        parameter: id of the favorite,
+                   info of the changed item [ ( var, val ) (...) ]
+        """
+        if not self.server:
+            yield _('tvserver unavailable')
+        result = self.rpc('home-theatre.favorite.modify', id, info)
+        yield result
+        if not result():
+            # FIXME: get real error message from tvserver
+            yield 'failed'
+        yield self.SUCCESS
+
+
+    def get(self, title, channel, start, stop):
+        for f in self.list():
+            if title == f.title:
+                if channel in f.channels:
+                    day = min(time.localtime(start)[6] + 1, 6)
+                    if day in f.days:
+                        return f
+        return None    
+    
+    
     def list(self):
         """
         """
Index: ui/src/tv/plugins/genre.py
===================================================================
--- ui/src/tv/plugins/genre.py	(Revision 9584)
+++ ui/src/tv/plugins/genre.py	(Arbeitskopie)
@@ -34,6 +34,7 @@
 
 # python imports
 import logging
+import time
 
 # kaa imports
 import kaa.notifier
@@ -87,7 +88,9 @@
         # fetch epg data from InProgress object
         query_data = query_data()
         for prg in query_data:
-            items.append(ProgramItem(prg, self))
+            if prg.stop > time.time():
+                # only add this to the list, if it has not already finished
+                items.append(ProgramItem(prg, self))
         # create menu for programs
         menu = Menu(self.name, items, type='tv program menu')
         self.get_menustack().pushmenu(menu)
Index: ui/src/tv/plugins/scheduled.py
===================================================================
--- ui/src/tv/plugins/scheduled.py	(Revision 9584)
+++ ui/src/tv/plugins/scheduled.py	(Arbeitskopie)
@@ -29,178 +29,67 @@
 # -----------------------------------------------------------------------------
 
 # python imports
-import time
 
 # kaa imports
-import kaa.notifier
-from kaa.strutils import unicode_to_str
 
 # freevo core imports
 import freevo.ipc
 
-# freevo ui imports
-from freevo.ui import config
-from freevo.ui.menu import Menu, ActionItem, Action, Item
-from freevo.ui.mainmenu import MainMenuPlugin
+# freevo imports
+from freevo.ui.mainmenu import Menu, MainMenuPlugin
+from freevo.ui.menu import ActionItem
 from freevo.ui.application import MessageWindow
+from freevo.ui.tv.program import ProgramItem
 
 # get tvserver interface
 tvserver = freevo.ipc.Instance('freevo').tvserver
 
-class RecordingItem(Item):
-    """
-    A recording item to remove/watch a scheduled recording.
-    """
-    def __init__(self, channel, start, stop, parent):
-        Item.__init__(self, parent)
-
-        self.scheduled = tvserver.recordings.get(channel, start, stop)
-        if self.scheduled.description.has_key('title'):
-            self.title = self.scheduled.description['title']
-            self.name  = self.scheduled.description['title']
-        else:
-            self.name  = self.title = ''
-        self.channel = channel
-        self.start = start
-        self.stop = stop
-
-
-    def __unicode__(self):
-        """
-        return as unicode for debug
-        """
-        bt = time.localtime(self.start)   # Beginning time tuple
-        et = time.localtime(self.stop)    # End time tuple
-        begins = '%s-%02d-%02d %02d:%02d' % (bt[0], bt[1], bt[2], bt[3], bt[4])
-        ends   = '%s-%02d-%02d %02d:%02d' % (et[0], et[1], et[2], et[3], et[4])
-        return u'%s to %s  %3s ' % (begins, ends, self.channel) + \
-               self.title
-
-
-    def __str__(self):
-        """
-        return as string for debug
-        """
-        return unicode_to_str(self.__unicode__())
-
-
-    def __cmp__(self, other):
-        """
-        compare function, return 0 if the objects are identical, 1 otherwise
-        """
-        if not isinstance(other, (RecordingItem)):
-            return 1
-
-        return self.start != other.start or \
-               self.stop  != other.stop or \
-               self.channel != other.channel
-
-
-    def __getitem__(self, key):
-        """
-        return the specific attribute as string or an empty string
-        """
-        if key == 'start':
-            return unicode(time.strftime(config.tv.timeformat,
-                                         time.localtime(self.start)))
-        if key == 'stop':
-            return unicode(time.strftime(config.tv.timeformat,
-                                         time.localtime(self.stop)))
-        if key == 'date':
-            return unicode(time.strftime(config.tv.dateformat,
-                                         time.localtime(self.start)))
-        if key == 'time':
-            return self['start'] + u' - ' + self['stop']
-        if key == 'channel':
-            return self.channel
-
-        return Item.__getitem__(self, key)
-
-
-    def actions(self):
-        """
-        return a list of possible actions on this item.
-        """
-        return [ Action(_('Show recording menu'), self.submenu) ]
-
-
-    def submenu(self):
-        """
-        show a submenu for this item
-        """
-        items = []
-        if self.start < time.time() + 10 and \
-               self.scheduled.status in ('recording', 'saved'):
-            items.append(ActionItem(_('Watch recording'), self,
-                                    self.watch_recording))
-        if self.stop > time.time():
-            if self.start < time.time():
-                items.append(ActionItem(_('Stop recording'), self,
-                                        self.remove))
-            else:
-                items.append(ActionItem(_('Remove recording'), self,
-                                        self.remove))
-
-        s = Menu(self, items, type = 'tv program menu')
-        s.submenu = True
-        s.infoitem = self
-        self.get_menustack().pushmenu(s)
-
-
-    def watch_recording(self):
-        MessageWindow('Not implemented yet').show()
-
-
-    @kaa.notifier.yield_execution()
-    def remove(self):
-        result = tvserver.recordings.remove(self.scheduled.id)
-        if isinstance(result, kaa.notifier.InProgress):
-            yield result
-            result = result()
-        if result != tvserver.recordings.SUCCESS:
-            MessageWindow(_('Scheduling Failed')+(': %s' % result)).show()
-        self.get_menustack().delete_submenu()
-
-
 class PluginInterface(MainMenuPlugin):
     """
     This plugin is used to display your scheduled recordings.
     """
-    def scheduled(self, parent):
+    def browse(self, parent):
+        """ 
+        Construct the menu
         """
-        Show all scheduled recordings.
-        """
         self.parent = parent
-        items = self.get_items(parent)
+        items = self.get_items()
         if items:
             self.menu = Menu(_('View scheduled recordings'), items,
-                             type='tv program menu',
-                             reload_func = self.reload_scheduled)
+                                 type='tv program menu',
+                                 reload_func = self.reload_scheduled)
             parent.get_menustack().pushmenu(self.menu)
         else:
             MessageWindow(_('There are no scheduled recordings.')).show()
-
-
+    
+    
     def reload_scheduled(self):
-        items = self.get_items(self.parent)
+        """
+        reload the list of scheduled recordings
+        """
+        items = self.get_items()
         if items:
             self.menu.set_items(items)
         else:
             self.parent.get_menustack().back_one_menu()
 
-    def get_items(self, parent):
+    
+    def get_items(self):
+        """
+        create the list of scheduled recordings
+        """
         items = []
         rec = tvserver.recordings.list()
-        for p in rec:
-            scheduled = tvserver.recordings.get(p.channel, p.start, p.stop)
+        for scheduled in rec:
             if scheduled and not scheduled.status in ('deleted', 'missed'):
-                items.append(RecordingItem(parent=parent, channel=p.channel,
-                                           start=p.start, stop=p.stop))
-
+                items.append(ProgramItem(scheduled, self.parent))
         return items
-
+        
+                   
     def items(self, parent):
         """
         Return the main menu item.
         """
-        return [ ActionItem(_('View scheduled recordings'), parent, self.scheduled) ]
+        return [ ActionItem(_('View scheduled recordings'), parent, self.browse) ]
+       
+    
Index: ui/src/tv/favorite.py
===================================================================
--- ui/src/tv/favorite.py	(Revision 9584)
+++ ui/src/tv/favorite.py	(Arbeitskopie)
@@ -32,6 +32,7 @@
 # -----------------------------------------------------------------------------
 
 # python imports
+import re
 import time
 
 # kaa imports
@@ -47,12 +48,17 @@
 # freevo imports
 from freevo.ui.menu import Item, Action, ActionItem, Menu
 from freevo.ui.application import MessageWindow
+from freevo.ui.tv.program import ProgramItem
 
 # get tvserver interface
 tvserver = freevo.ipc.Instance('freevo').tvserver
 
-DAY_NAMES = (_('Sun'), _('Mon'), _('Tue'), _('Wed'), _('Thu'), _('Fri'), _('Sat'))
+DAY_NAMES = [_('Sun'), _('Mon'), _('Tue'), _('Wed'), _('Thu'), _('Fri'), _('Sat')]
 
+#Define the time slots (when chnaging the time) in minutes
+TIME_SLOTS = 10
+TIME_RANGE = (1440 / TIME_SLOTS)
+
 class FavoriteItem(Item):
     """
     A favorite item to add/delete/change a favorite for the recordserver.
@@ -63,27 +69,31 @@
 
         self.new = True
         self.id = 0
-        if isinstance(fav, kaa.epg.Program):
-            # created with Program object
-            # Convert to 0=Sunday - 6=Saterday
-            day = min(time.localtime(fav.start)[6] + 1, 6)
-            self.days = [ day ]
-            self.name = self.title = fav.title
-            self.channels = [ fav.channel.name ]
+        self.start = float(0)
+        self.stop = float(1440*60)-1
+        
+        if isinstance(fav, ProgramItem):
             #check if already a favorite
-            for f in tvserver.favorites.list():
-                if fav.title == f.title:
-                    if fav.channel.name in f.channels:
-                        if day in f.days:
-                            self.new = False
-                            self.id = f.id
-        else:
+            f = tvserver.favorites.get(fav.title, fav.channel, fav.start, fav.stop)
+            if not f:
+                # create from ProgramItem
+                # Convert to 0=Sunday - 6=Saterday
+                day = min(time.localtime(fav.start)[6] + 1, 6)
+                self.days = [ day ]
+                self.name = self.title = fav.title
+                self.channels = [ fav.channel]
+            else:  
+                # there is already a existing ipc Favorite object 
+                fav = f      
+        if isinstance(fav, freevo.ipc.tvserver.Favorite):
             # created with ipc Favorite object
             self.name = self.title = fav.title
             self.days = fav.days
             self.channels = fav.channels
             self.new = False
             self.id = fav.id
+            for t in fav.times:
+                self.start, self.stop = self._str_to_time(t)
 
 
     def __getitem__(self, key):
@@ -102,6 +112,14 @@
             else:
                 channels = ', '.join(['%s' % chan for chan in self.channels])
                 return channels
+        if key == 'time':
+                return self['start'] + u' - ' + self['stop']
+        if key == 'start':
+            return unicode(time.strftime(config.tv.timeformat,
+                                         time.gmtime(self.start)))
+        if key == 'stop':
+            return unicode(time.strftime(config.tv.timeformat,
+                                         time.gmtime(self.stop)))
         return Item.__getitem__(self, key)
 
 
@@ -123,6 +141,15 @@
         else:
             items.append(ActionItem(_('Remove favorite'), self, self.remove))
         
+        items.append(ActionItem(_('Change day'), self, self.change_days))
+        items.append(ActionItem(_('Change channel'), self, self.change_channels))
+        action = ActionItem(_('Change start time'), self, self.change_time)
+        action.parameter('start')
+        items.append(action)
+        action = ActionItem(_('Change stop time'), self, self.change_time)
+        action.parameter('stop')
+        items.append(action)
+
         s = Menu(self, items, type = 'tv favorite menu')
         s.submenu = True
         s.infoitem = self
@@ -132,16 +159,16 @@
     @kaa.notifier.yield_execution()
     def add(self):
         result = tvserver.favorites.add(self.title, self.channels, self.days,
-                                        'ANY', 50, False)
+                                        [self._time_to_str()], 50, False)
         if isinstance(result, kaa.notifier.InProgress):
             yield result
             result = result()
         if result != tvserver.favorites.SUCCESS:
             text = _('Adding favorite Failed')+(': %s' % result)
         else:
-            text = _('"%s" has been scheduled as favorite') % self.title
+            text = _('"%s" has been added to your favorites') % self.title
         MessageWindow(text).show()
-        self.get_menustack().delete_submenu()
+        self.get_menustack().back_one_menu()
 
 
     @kaa.notifier.yield_execution()
@@ -152,5 +179,129 @@
             result = result()
         if result != tvserver.favorites.SUCCESS:
             text = _('Remove favorite Failed')+(': %s' % result)
+        else:
+            text = _('"%s" has been removed from you favorites') % self.title    
+            MessageWindow(text).show()    
+        self.get_menustack().back_one_menu()
+
+    @kaa.notifier.yield_execution()
+    def modify(self, info):
+        result = tvserver.favorites.modify(self.id, info)
+        if isinstance(result, kaa.notifier.InProgress):
+            yield result
+            result = result()
+        if result != tvserver.favorites.SUCCESS:
+            text = _('Modified favorite Failed')+(': %s' % result)
             MessageWindow(text).show()
-        self.get_menustack().delete_submenu()
+
+    def change_days(self):
+        items = []
+        action = ActionItem('ANY', self, self.handle_change)
+        action.parameter('days', 'ANY')
+        items.append(action)
+        for dayname in DAY_NAMES:
+            action = ActionItem(dayname, self, self.handle_change)
+            action.parameter('days', dayname)
+            items.append(action)
+            
+        s = Menu(self, items, type = 'tv favorite menu')
+        s.submenu = True
+        s.infoitem = self
+        self.get_menustack().pushmenu(s)
+
+    def change_channels(self):
+        items = []
+        action = ActionItem('ANY', self, self.handle_change)
+        action.parameter('channels', 'ANY')
+        items.append(action)
+        
+        list = kaa.epg.get_channels(sort=True)
+        for chan in list:
+            action = ActionItem(chan.name, self, self.handle_change)
+            action.parameter('channels', chan.name)
+            items.append(action)
+            
+        s = Menu(self, items, type = 'tv favorite menu')
+        s.submenu = True
+        s.infoitem = self
+        self.get_menustack().pushmenu(s)
+
+    def change_time(self, startstop):
+        items = []
+        action = ActionItem('ANY', self, self.handle_change)
+        action.parameter(startstop, 'ANY')
+        items.append(action)
+        if startstop == 'start':
+            starttime = self.start
+        else:
+            starttime = self.stop - (self.stop % (TIME_SLOTS * 60))
+        for i in range(TIME_RANGE):
+            newtime = float( (i * TIME_SLOTS * 60) + starttime) % (1440 * 60)
+            showtime = unicode(time.strftime(config.tv.timeformat,
+                                     time.gmtime(newtime)))
+            action = ActionItem(showtime, self, self.handle_change)
+            action.parameter(startstop, newtime)
+            items.append(action)
+            
+        s = Menu(self, items, type = 'tv favorite menu')
+        s.submenu = True
+        s.infoitem = self
+        self.get_menustack().pushmenu(s)
+
+    def handle_change(self, item, value):
+        
+        info = None
+        infovalue = None
+        if item == 'days':
+            info = 'days'
+            if value == 'ANY':
+                self.days = [0, 1, 2, 3, 4, 5, 6]
+            else:
+                self.days = [DAY_NAMES.index(value)]
+            infovalue = self.days
+        if item == 'channels':
+            info = 'channels'
+            if value == 'ANY':
+                self.channels = []
+                list = kaa.epg.get_channels(sort=True)
+                for chan in list:
+                    self.channels.append(chan.name)
+            else:
+                self.channels = [value]
+            infovalue = self.channels
+        if item == 'start':
+            info = 'times'
+            if value == 'ANY':
+                self.start = float(0)
+                self.stop = float(1440*60)-1
+            else:
+                self.start = value
+            infovalue = [self._time_to_str()]
+        if item == 'stop':
+            info = 'times'
+            if value == 'ANY':
+                self.start = float(0)
+                self.stop = float(1440*60)-1
+            else:
+                self.stop = value
+            infovalue = [self._time_to_str()]
+
+        if not self.new:
+            self.modify([(info, infovalue)])
+            
+        self.get_menustack().back_one_menu()
+
+    def _time_to_str(self):
+        start = time.strftime('%H:%M', time.gmtime(self.start))
+        stop = time.strftime('%H:%M', time.gmtime(self.stop))
+        return start + '-' + stop
+
+    def _str_to_time(self, t):
+        # internal regexp for time format
+        _time_re = re.compile('([0-9]*):([0-9]*)-([0-9]*):([0-9]*)')
+        
+        m = _time_re.match(t).groups()
+        start = float(m[0])*3600 + float(m[1])*60
+        stop  = float(m[2])*3600 + float(m[3])*60
+
+        return start, stop
Index: ui/src/tv/program.py
===================================================================
--- ui/src/tv/program.py	(Revision 9584)
+++ ui/src/tv/program.py	(Arbeitskopie)
@@ -53,32 +53,58 @@
 # get tvserver interface
 tvserver = freevo.ipc.Instance('freevo').tvserver
 
+import logging
+log = logging.getLogger()
+
 class ProgramItem(Item):
     """
     A tv program item for the tv guide and other parts of the tv submenu.
     """
     def __init__(self, program, parent):
         Item.__init__(self, parent)
-        self.program = program
-        self.title = program.title
-        self.name  = program.title
         self.start = program.start
         self.stop  = program.stop
-
-        self.channel = program.channel
-        self.subtitle = program.subtitle
-        self.description = program.description
-        self.episode = program.episode
         
-        self.scheduled = tvserver.recordings.get(program.channel.name,
-                                        program.start, program.stop)
-
-        # TODO: add category support
-        self.categories = ''
-        # TODO: add ratings support
-        self.ratings = ''
-
-
+        if isinstance(program, kaa.epg.Program):
+            # creation form epg Program object
+            self.channel = program.channel.name
+            self.title = program.title
+            self.name  = program.title
+            self.subtitle = program.subtitle
+            self.episode = program.episode
+            self.description = program.description
+            # TODO: add category/genre support
+            self.categories = ''
+            self.genre = ''
+            # TODO: add ratings support
+            self.ratings = ''
+            
+        
+        elif isinstance(program, freevo.ipc.tvserver.Recording):
+            # creation form ipc Recoring object
+            self.channel = program.channel
+            if program.description.has_key('title'):
+                self.title = program.description['title']
+                self.name  = program.description['title']
+            else: 
+                self.name = self.title = _(u'Unknown') 
+             
+            if program.description.has_key('subtitle'):
+                self.subtitle = program.description['subtitle']
+            else:               
+                self.subtitle = ''
+            if program.description.has_key('episode'):
+                self.episode = program.description['episode']
+            else:               
+                self.episode = ''
+            # TODO: check if this is also available    
+            self.description = ''
+            # TODO: add catergory/genre support
+            self.categories = ''
+            self.genre = ''
+            # TODO: add ratings support
+            self.rating = ''                      
+                        
     def __unicode__(self):
         """
         return as unicode for debug
@@ -87,8 +113,7 @@
         et = time.localtime(self.stop)    # End time tuple
         begins = '%s-%02d-%02d %02d:%02d' % (bt[0], bt[1], bt[2], bt[3], bt[4])
         ends   = '%s-%02d-%02d %02d:%02d' % (et[0], et[1], et[2], et[3], et[4])
-        return u'%s to %s  %3s ' % (begins, ends, self.channel.name) + \
-               self.title
+        return u'%s to %s  %3s ' % (begins, ends, self.channel) + self.title
 
 
     def __str__(self):
@@ -104,13 +129,17 @@
         """
         if not isinstance(other, (ProgramItem, kaa.epg.Program)):
             return 1
-
+        if isinstance(other, ProgramItem) and self.channel != other.channel:
+            return 1
+        if isinstance(other, kaa.epg.Program) and self.channel != other.channel.name:   
+            return 1
+    
         return self.title != other.title or \
                self.start != other.start or \
-               self.stop  != other.stop or \
-               self.channel != other.channel
+               self.stop  != other.stop 
+              
+               
 
-
     def __getitem__(self, key):
         """
         return the specific attribute as string or an empty string
@@ -127,58 +156,126 @@
         if key == 'time':
             return self['start'] + u' - ' + self['stop']
         if key == 'channel':
-            return self.channel.name
+            return self.channel
 
         return Item.__getitem__(self, key)
 
 
+    ### Submenu
+    
     def actions(self):
         """
         return a list of possible actions on this item.
         """
         return [ Action(_('Show program menu'), self.submenu) ]
 
+    
+    def reload_submenu(self):
+        """
+        reload function for the submenu
+        """
+        items = self.get_menuitems()
+        if items:
+            self.get_menustack()[-1].set_items(items)
+        else:
+            self.get_menustack().back_one_menu()
+        
 
-    def submenu(self, additional_items=False):
+    def get_menuitems(self):
         """
-        show a submenu for this item
+        create a list of actions for the submenu
         """
+        
+        # check if this is a recording
+        self.scheduled = tvserver.recordings.get(self.channel,
+                                                 self.start, 
+                                                 self.stop)
+        # check if this is a favorite
+        self.favorite = tvserver.favorites.get(self.title, 
+                                               self.channel,
+                                               self.start,
+                                               self.stop)   
+        
+        # empty item list
         items = []
-        if self.scheduled and not self.scheduled.status in \
-           ('deleted', 'missed'):
-            if self.start < time.time() + 10 and \
-                   self.scheduled.status in ('recording', 'saved'):
-                items.append(ActionItem(_('Watch recording'), self,
-                                        self.watch_recording))
-            if self.stop > time.time():
-                if self.start < time.time():
-                    items.append(ActionItem(_('Stop recording'), self,
-                                            self.remove))
-                else:
-                    items.append(ActionItem(_('Remove recording'), self,
-                                            self.remove))
+        
+        # scheduled for recording
+        if self.scheduled and not self.scheduled.status in ('deleted','missed'):
+                if self.start < time.time() + 10  \
+                and self.scheduled.status in ('recording', 'saved'):
+                    # start watching the recorded stream from disk
+                    txt = _('Watch recording')
+                    items.append(ActionItem(txt, self, self.watch_recording))
+                if self.stop > time.time():
+                    # not yet finished
+                    if self.start < time.time():
+                        # but already running
+                        txt = _('Stop recording')
+                        items.append(ActionItem(txt, self, self.remove))
+                    else:
+                        # still in the future
+                        txt =  _('Remove recording')   
+                        items.append(ActionItem(txt, self, self.remove))
+                    
+        # not scheduled for recording
         elif self.stop > time.time():
-            items.append(ActionItem(_('Schedule for recording'), self,
-                                    self.schedule))
-        if additional_items:
-            items.append(ActionItem(_('Show complete listing for %s') % \
-                                    self.channel.name, self,
-                                    self.channel_details))
-            items.append(ActionItem(_('Watch %s') % self.channel.name, self,
-                                    self.watch_channel))
-            txt = _('Search for programs with a similar name')
+            # not in the past, can still be scheduled
+            txt = _('Schedule for recording')
+            items.append(ActionItem(txt, self, self.schedule))
+        
+        
+        # this items are only shown from inside the TVGuide:
+        if self.additional_items:
+            # Show all programm on this channel
+            txt = ('Show complete listing for %s') % self.channel
+            items.append(ActionItem(txt, self, self.channel_details))
+            # Start watching this channel
+            txt = _('Watch %s') % self.channel
+            items.append(ActionItem(txt, self, self.watch_channel))
+            # Search for more of this program
+            txt = _('Search for more of this program')
             items.append(ActionItem(txt, self, self.search_similar))
-
-        items.append(ActionItem(_('Favorite...'), self, self.create_favorite))
-
-        s = Menu(self, items, type = 'tv program menu')
+        
+        # Add the menu for handling favorites
+        if self.favorite:
+            txt = _('Edit favorite')
+            items.append(ActionItem(txt, self, self.edit_favorite))
+            txt = _('Remove favorite')
+            items.append(ActionItem(txt, self, self.remove_favorite))
+        else:
+            txt = _('Add favorite')
+            items.append(ActionItem(txt, self, self.add_favorite))    
+        
+        return items    
+    
+    
+    def submenu(self, additional_items=False):
+        """
+        show a submenu for this item
+        
+        There are some items, that are only created if 'additional_items'
+        is set to TRUE, this items are useful in the TVGuide.
+        """
+        self.additional_items = additional_items
+        # get the item list
+        items = self.get_menuitems()
+        # create the menu
+        s = Menu(self, items, 
+                 type = 'tv program menu', 
+                 reload_func=self.reload_submenu)
         s.submenu = True
         s.infoitem = self
+        # show the menu
         self.get_menustack().pushmenu(s)
 
 
+    #### Actions
+
     @kaa.notifier.yield_execution()
     def schedule(self):
+        """
+        schedule this item for recording
+        """
         result = tvserver.recordings.schedule(self)
         if isinstance(result, kaa.notifier.InProgress):
             yield result
@@ -188,11 +285,14 @@
         else:
             msg = _('Scheduling failed: %s') % result
         MessageWindow(msg).show()
-        self.get_menustack().delete_submenu()
-
-
+        self.get_menustack().back_one_menu()
+                       
+        
     @kaa.notifier.yield_execution()
     def remove(self):
+        """
+        remove this item from schedule
+        """
         result = tvserver.recordings.remove(self.scheduled.id)
         if isinstance(result, kaa.notifier.InProgress):
             yield result
@@ -202,11 +302,14 @@
         else:
             msg = _('Removing failed: %s') % result
         MessageWindow(msg).show()
-        self.get_menustack().delete_submenu()
+        self.get_menustack().back_one_menu()
 
 
     @kaa.notifier.yield_execution()
     def channel_details(self):
+        """
+        Browse all programs on this channel
+        """
         if not kaa.epg.is_connected():
             MessageWindow(_('TVServer not running')).show()
             return
@@ -218,12 +321,12 @@
         query_data = query_data()
         for prog in query_data:
             items.append(ProgramItem(prog, self))
-        cmenu = Menu(self.channel.name, items, type = 'tv program menu')
+        cmenu = Menu(self.channel, items, type = 'tv program menu')
         # FIXME: the percent values need to be calculated
         # cmenu.table = (15, 15, 70)
         self.get_menustack().pushmenu(cmenu)
-
-
+   
+   
     def watch_channel(self):
         MessageWindow('Not implemented yet').show()
         
@@ -231,14 +334,53 @@
     def watch_recording(self):
         MessageWindow('Not implemented yet').show()
 
-
+    
+    @kaa.notifier.yield_execution()
     def search_similar(self):
-        MessageWindow('Not implemented yet').show()
+        """
+        Search the database for more of this program
+        """
+        if not kaa.epg.is_connected():
+            # we need the tvserver for this
+            MessageWindow(_('TVServer not running')).show()
+            return
+        # create an empty list for ProgramItems    
+        items = []
+        # query the epg database in background
+        query_data = kaa.epg.search(title=self.title)
+        yield query_data
+        # get data from InProgress object
+        query_data = query_data()
+        # and sort is concerning its start times
+        query_data.sort(lambda a,b:cmp(a.start,b.start))
+        for prog in query_data:
+            if prog.stop >time.time():
+                # only show programs that are not finished already
+                items.append(ProgramItem(prog, self))
+        # create the submenu from this        
+        resmenu = Menu(self.title, items, type = 'tv program menu')
+        self.get_menustack().pushmenu(resmenu)   
+                
 
-
-    def create_favorite(self):
-        favorite.FavoriteItem(self, self.program).submenu()
-
-
+    def add_favorite(self):
+        """ 
+        Create a new FavoriteItem and open its submenu
+        """
+        favorite.FavoriteItem(self, self).submenu()
+        
+        
+    def edit_favorite(self):
+        """ 
+        Create a FavoriteItem for a existing favorite
+        and open its submenu to edit this item
+        """
+        favorite.FavoriteItem(self, self.favorite).submenu()
+            
+    
     def remove_favorite(self):
-        MessageWindow('Not implemented yet').show()
+        """
+        Create a FavoriteItem for a existing favorite 
+        and delete this favorite.
+        """
+        favorite.FavoriteItem(self, self.favorite).remove()
+        
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Freevo-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-devel

Reply via email to