Hi Dischi,

I have never seen these patches get into svn. Maybe you forgot to put
them in? These are good patches, so if you can it would be great to put
them in.

Best regards,
Joost

-------Doorgestuurd bericht-------
Van: Tanja <[EMAIL PROTECTED]>
Antwoordadres: [EMAIL PROTECTED]
Aan: Dirk Meyer <[EMAIL PROTECTED]>
Cc: [EMAIL PROTECTED], freevo-devel@lists.sourceforge.net
Onderwerp: Re: freevo2: recordItem class
Datum: Mon, 21 May 2007 23:06:09 +0200

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: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Freevo-devel mailing list
Freevo-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freevo-devel

Reply via email to