Hi again,

of course, there have been errors in the patch :-(
Here is a corrected version.

I also found some better way for this:

         # 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))


It is possible, to use the kaa.epg.search function in a way to
just get programs in a give time intervall:

future = (int(time.time()), sys.maxint)
query_data = kaa.epg.search(title=self.title, time=future)


I will continue to test ;-)

Tanja
Index: tvserver/src/favorite.py
===================================================================
--- tvserver/src/favorite.py	(Revision 9594)
+++ 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 9594)
+++ 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 9594)
+++ 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/guide.py
===================================================================
--- ui/src/tv/plugins/guide.py	(Revision 9594)
+++ ui/src/tv/plugins/guide.py	(Arbeitskopie)
@@ -175,13 +175,13 @@
         if event == MENU_LEFT:
             if self.selected.start == 0:
                 return True
-            self.get_program(self.selected.program.start - 1)
+            self.get_program(self.selected.start - 1)
             return True
 
         if event == MENU_RIGHT:
             if self.selected.stop == sys.maxint:
                 return True
-            self.get_program(self.selected.program.stop + 1)
+            self.get_program(self.selected.stop + 1)
             return True
 
         if event == MENU_PAGEUP:
@@ -205,6 +205,7 @@
             return True
 
         if event == TV_START_RECORDING:
+            # TODO: make this schedule or remove
             self.selected.submenu(additional_items=True)
             return True
 
Index: ui/src/tv/plugins/genre.py
===================================================================
--- ui/src/tv/plugins/genre.py	(Revision 9594)
+++ ui/src/tv/plugins/genre.py	(Arbeitskopie)
@@ -34,6 +34,8 @@
 
 # python imports
 import logging
+import time
+import sys
 
 # kaa imports
 import kaa.notifier
@@ -75,14 +77,18 @@
             MessageWindow(_('TVServer not running')).show()
             return
         items = []
+        # time tuple representing the future
+        future = (int(time.time()), sys.maxint)
         # query epg in background
         if self.cat:
             if self.name==ALL_GENRE:
-                query_data = kaa.epg.search(category=self.cat)
+                query_data = kaa.epg.search(category=self.cat, time=future)
             else:
-                query_data = kaa.epg.search(genre=self.name, category=self.cat)
+                query_data = kaa.epg.search(genre=self.name, 
+                                            category=self.cat,
+                                            time=future)
         else:
-            query_data = kaa.epg.search(genre=self.name)
+            query_data = kaa.epg.search(genre=self.name, time=future)
         yield query_data
         # fetch epg data from InProgress object
         query_data = query_data()
Index: ui/src/tv/plugins/scheduled.py
===================================================================
--- ui/src/tv/plugins/scheduled.py	(Revision 9594)
+++ 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 9594)
+++ 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 9594)
+++ ui/src/tv/program.py	(Arbeitskopie)
@@ -32,6 +32,7 @@
 # -----------------------------------------------------------------------------
 
 # python imports
+import sys
 import time
 
 # kaa imports
@@ -53,32 +54,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 +114,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 +130,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 +157,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 +286,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,28 +303,34 @@
         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
         items = []
+        # time tuple representing the future
+        future = (int(time.time()), sys.maxint)
         # query the epg database in background
-        query_data = kaa.epg.search(channel=self.channel)
+        channel = kaa.epg.get_channel(self.channel)
+        query_data = kaa.epg.search(channel=channel, time=future)
         yield query_data
         # get data from InProgress object
         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 +338,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
+        # time tuple representing the future    
+        future = (int(time.time()), sys.maxint)
+        # create an empty list for ProgramItems    
+        items = []
+        # query the epg database in background
+        query_data = kaa.epg.search(title=self.title, time=future)
+        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:
+            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