Author: rshortt
Date: Wed Mar  8 18:58:19 2006
New Revision: 8061

Modified:
   trunk/WIP/RobShortt/tvserver-epg2/bin/freevo-epg
   trunk/WIP/RobShortt/tvserver-epg2/bin/freevo-tvserver
   trunk/WIP/RobShortt/tvserver-epg2/src/config.py
   trunk/WIP/RobShortt/tvserver-epg2/src/epg.py
   trunk/WIP/RobShortt/tvserver-epg2/src/recorder.py

Log:
A bunch of epg2 changes.


Modified: trunk/WIP/RobShortt/tvserver-epg2/bin/freevo-epg
==============================================================================
--- trunk/WIP/RobShortt/tvserver-epg2/bin/freevo-epg    (original)
+++ trunk/WIP/RobShortt/tvserver-epg2/bin/freevo-epg    Wed Mar  8 18:58:19 2006
@@ -35,6 +35,7 @@
 # python imports
 import logging
 import os
+import shutil
 import sys
 import textwrap
 import time
@@ -52,6 +53,7 @@
 
 # FIXME: create logger objects in conf
 import freevo.conf
+import freevo.ipc
 import freevo.ipc.epg as epg
 
 # get logging object
@@ -60,6 +62,8 @@
 # set log level TODO: get and do this in config
 log.setLevel(logging.DEBUG)
 
+TVSERVER = {'type': 'home-theatre', 'module': 'tvserver'}
+
 
 def update_progress(cur, total):
     n = 0
@@ -71,6 +75,20 @@
         print
 
 
+def updated(result):
+    if result:
+        log.info('updated favorites')
+    else:
+        log.info('unable to update favorites')
+    sys.exit(0)
+
+
+def new_entity(entity):
+    if not entity.matches(TVSERVER):
+        return True
+    entity.rpc('home-theatre.favorite.update', updated).call()
+
+
 if len(sys.argv) > 1:
     if sys.argv[1] == 'update':
         guide = epg.connect()
@@ -81,20 +99,71 @@
         # once the update is finished.
         guide.signals["updated"].connect(sys.exit)
 
-        if epg.config.use_xmltv == 1:
-            if not os.path.isfile(epg.config.xmltv_file):
-                log.error('problem with xmltv_file in config')
+        if epg.config.use_xmltv == 1 and \
+           os.path.isdir(os.path.dirname(epg.config.xmltv_file.split()[0])):
 
+            if epg.config.xmltv_grabber and \
+               os.path.isfile(epg.config.xmltv_grabber.split()[0]):
+                # NOTE: should the grabbing code be put into a seperate module
+                #       so other programs can cal it?
+
+                log.info('grabbing listings using %s', 
epg.config.xmltv_grabber)
+                xmltvtmp = '/tmp/TV.xml.tmp'
+                ec = os.system('%s --output %s --days %s' % 
(epg.config.xmltv_grabber,
+                                                             xmltvtmp,
+                                                             
epg.config.xmltv_days))
+
+                if os.path.exists(xmltvtmp) and ec == 0:
+                    if os.path.isfile(epg.config.xmltv_sort):
+                        log.info('sorting listings')
+                        os.system('%s --output %s %s' % (epg.config.xmltv_sort,
+                                                         xmltvtmp+'.1',
+                                                         xmltvtmp))
+
+                        shutil.move(xmltvtmp+'.1', xmltvtmp)
+
+                    else:
+                        log.info('not configured to use xmltv_sort, skipping')
+
+                    shutil.move(xmltvtmp, epg.config.xmltv_file)
+
+                else:
+                    log.error('xmltv grabbing failed and returned exit code 
%d.', ec >> 8)
+                    log.error('if you did not change your system, it is likely 
'+
+                              'that the site being grabbed did.  You might 
want to try '+
+                              'updating your xmltv: http://www.xmltv.org/')
+
+            else:
+                log.info('not configured to run xmltv_grabber')
+
+            if not os.path.isfile(epg.config.xmltv_file):
+                log.error('problem with xmltv_file, not updating EPG')
+           
             else:
                 log.debug('xmltv_file: %s', epg.config.xmltv_file)
+                log.info('loading data into EPG...')
                 guide.update("xmltv", str(epg.config.xmltv_file))
 
+        else:
+            log.info('not configured to use xmltv')
+
+
         if epg.config.use_zap2it == 1:
             guide.update("zap2it", username=str(epg.config.zap2it_username), 
                                    passwd=str(epg.config.zap2it_password))
+
+        else:
+            log.info('not configured to use Zap2it')
+
+ 
+        log.info('connecting to tvserver')
+        mbus = freevo.ipc.Instance()
+        mbus.signals['new-entity'].connect(new_entity)
+        kaa.notifier.OneShotTimer(updated, False).start(2)
+
         kaa.main()
 
-        print 'done'
+        log.info('done')
         sys.exit(0)
 
     elif sys.argv[1] == 'search':
@@ -111,12 +180,12 @@
             print "All programs currently playing:"
             programs = guide.search(time = (time.time(), time.time()+7200))
             # Sort by channel
-            programs.sort(lambda a, b: cmp(a.channel.channel, 
b.channel.channel))
+            programs.sort(lambda a, b: cmp(a.channel.tuner_id, 
b.channel.tuner_id))
         t1 = time.time()
         
         for program in programs:
             start_time = time.strftime("%a %H:%M", 
time.localtime(program.start))
-            print "  %s (%s): %s" % (program.channel.channel, start_time, 
program.title.encode('latin-1'))
+            print "  %s (%s): %s" % (program.channel.short_name, start_time, 
program.title.encode('latin-1'))
             if program.desc:
                 print "\t* " + "\n\t  
".join(textwrap.wrap(program.desc.encode('latin-1'), 60))
 
@@ -137,7 +206,25 @@
 
     elif sys.argv[1] == 'test':
         # developers can put testing code here
-        pass
+        guide = epg.connect()
+
+        if 1:
+            #print dir(guide)
+            cs = guide.get_channels()
+            cs.sort(lambda a, b: cmp(a.short_name, b.short_name))
+            cs.sort(lambda a, b: cmp(a.tuner_id, b.tuner_id))
+            for c in cs:
+                log.info('tuner_id: "%s" short_name: "%s" long_name: "%s"', 
c.tuner_id, c.short_name, c.long_name)
+
+        if 0:
+            programs = guide.search(keywords = keywords)
+            # Sort by start time
+            programs.sort(lambda a, b: cmp(a.start, b.start))
+
+        if 0:
+            programs = guide.search(time = (time.time(), time.time()+7200))
+            # Sort by channel
+            programs.sort(lambda a, b: cmp(a.channel.tuner_id, 
b.channel.tuner_id))
 
     else:
         sys.exit(1)

Modified: trunk/WIP/RobShortt/tvserver-epg2/bin/freevo-tvserver
==============================================================================
--- trunk/WIP/RobShortt/tvserver-epg2/bin/freevo-tvserver       (original)
+++ trunk/WIP/RobShortt/tvserver-epg2/bin/freevo-tvserver       Wed Mar  8 
18:58:19 2006
@@ -46,7 +46,6 @@
 # kaa imports
 import kaa
 import kaa.notifier
-import kaa.epg
 
 # FIXME: create logger objects in conf
 import freevo.conf
@@ -70,14 +69,6 @@
 # except Exception, e:
 #     log.warning('unable to set uid: %s' % e)
 
-# load the epg
-epg_filename = config.epg.database
-if epg_filename.find('$(DATADIR)') >= 0:
-    epg_filename = epg_filename.replace('$(DATADIR)', freevo.conf.DATADIR)
-
-kaa.epg.connect('sqlite2', epg_filename)
-kaa.epg.load()
-
 if len(sys.argv) > 1:
     if sys.argv[1] == '-i':
         # import interactive mode

Modified: trunk/WIP/RobShortt/tvserver-epg2/src/config.py
==============================================================================
--- trunk/WIP/RobShortt/tvserver-epg2/src/config.py     (original)
+++ trunk/WIP/RobShortt/tvserver-epg2/src/config.py     Wed Mar  8 18:58:19 2006
@@ -28,8 +28,6 @@
 
     # epg group
     Group(name='epg', desc=_('epg settings'), schema=[
-    Var(name='database', default='$(DATADIR)/epg.db',
-        desc=_('Filename for the sqlite database file')),
     Dict(name='mapping', type=unicode, schema=Var(type=unicode),
         desc=_('EPG channel mapping'))])
     ])

Modified: trunk/WIP/RobShortt/tvserver-epg2/src/epg.py
==============================================================================
--- trunk/WIP/RobShortt/tvserver-epg2/src/epg.py        (original)
+++ trunk/WIP/RobShortt/tvserver-epg2/src/epg.py        Wed Mar  8 18:58:19 2006
@@ -35,9 +35,11 @@
 import logging
 
 # kaa imports
-import kaa.epg
 from kaa.notifier import OneShotTimer, Timer, Signal, execute_in_timer
 
+# freevo imports
+from freevo.ipc.epg import connect as guide
+
 # record imports
 from record_types import *
 from recording import Recording
@@ -56,7 +58,7 @@
         """
         Return list of channels.
         """
-        return kaa.epg.channels
+        return guide().get_channels()
 
 
     def check_all(self, favorites, recordings, callback, *args, **kwargs):
@@ -101,13 +103,22 @@
         # same time, maybe it has moved +- 20 minutes. If the program
         # moved a larger time interval, it won't be found again.
         interval = (rec.start - 20 * 60, rec.start + 20 * 60)
-        results = kaa.epg.search(rec.name, rec.channel, exact_match=True,
-                                 interval = interval)
+
+        # results = kaa.epg.search(rec.name, rec.channel, exact_match=True,
+        #                          interval = interval)
+        # NOTE: How can we do the same as exact_match=True above? Do we need 
to?
+        #       So far the code below works fine.
+
+        log.debug('search: keywords="%s" channel="%s" time="%s"', rec.name, 
rec.channel, interval)
+        results = guide().search(keywords = rec.name, 
+                                 channel=guide().get_channel(rec.channel), 
+                                 time = interval)
 
         for epginfo in results:
             # check all results
             if epginfo.start == rec.start and epginfo.stop == rec.stop:
                 # found the recording
+                log.debug('found recording: %s', rec.name)
                 break
         else:
             # try to find it
@@ -124,11 +135,9 @@
                 log.info('unable to find recording in epg:\n%s' % rec)
                 return True
 
-        # check if attributes changed (Note: String() should not be
-        # needed here, everything has to be unicode, at least when
-        # kaa.epg2 is done)
+        # check if attributes changed 
         for attr in ('description', 'episode', 'subtitle'):
-            if String(getattr(rec, attr)) != String(getattr(epginfo, attr)):
+            if getattr(rec, attr) != getattr(epginfo, attr):
                 log.info('%s changed for %s', attr, rec.name)
                 setattr(rec, attr, getattr(epginfo, attr))
         return True
@@ -161,8 +170,9 @@
         fav = favorites.pop(0)
 
         # Now search the db
-        for p in kaa.epg.search(fav.name, exact_match=not fav.substring):
-            if not fav.match(p.title, p.channel.id, p.start):
+        # NOTE: do we need something like "exact_match=not fav.substring" here?
+        for p in guide().search(keywords=fav.name):
+            if not fav.match(p.title, p.channel.short_name, p.start):
                 continue
 
             rec = Recording(p.title, p.channel.id, fav.priority,

Modified: trunk/WIP/RobShortt/tvserver-epg2/src/recorder.py
==============================================================================
--- trunk/WIP/RobShortt/tvserver-epg2/src/recorder.py   (original)
+++ trunk/WIP/RobShortt/tvserver-epg2/src/recorder.py   Wed Mar  8 18:58:19 2006
@@ -4,6 +4,9 @@
 # -----------------------------------------------------------------------------
 # $Id$
 #
+# TODO: Handle unknown channels by letting user record them even with no EPG
+#       data.
+#
 # -----------------------------------------------------------------------------
 # Freevo - A Home Theater PC framework
 # Copyright (C) 2002-2005 Krister Lagerstrom, Dirk Meyer, et al.
@@ -41,10 +44,10 @@
 
 # kaa imports
 from kaa.notifier import OneShotTimer, Signal
-import kaa.epg
 
 # freevo core imports
 import freevo.ipc
+from freevo.ipc.epg import connect as guide
 
 # record imports
 from config import config
@@ -220,8 +223,8 @@
         self.rpc = self.entity.rpc
         self.rpc('home-theatre.device.describe', self.describe_cb).call(device)
         self.rating = 0
-        self.channel2epg = {}
-        self.epg2channel = {}
+        self.known_channels   = {}
+        self.unknown_channels = {}
 
 
     def __str__(self):
@@ -243,6 +246,19 @@
     def normalize_name(self, name):
         return String(name.replace('.', '').replace(' ', '')).upper().strip()
 
+    def add_channel(self, chan_obj, chan_id):
+        if chan_obj.short_name in self.known_channels:
+            # duplicate, skip it
+            return
+
+        if chan_id in self.unknown_channels:
+            # found a previously unknown channel
+            del(self.unknown_channels[chan_id])
+
+        chan_obj.tuner_id = chan_id
+        self.known_channels[chan_obj.short_name] = chan_obj
+        self.possible_bouquets[-1].append(chan_obj.short_name)
+
     def describe_cb(self, result):
         """
         RPC return for device.describe()
@@ -258,31 +274,59 @@
         for bouquet in result[2]:
             self.possible_bouquets.append([])
             for channel in bouquet:
+
+                # step 1, see config for override
                 if channel in config.epg.mapping:
-                    epgid = config.epg.mapping[channel] or channel
-                    if epgid in self.epg2channel:
-                        # duplicate id, skip it
+                    chan = guide().get_channel(config.epg.mapping[channel])
+
+                    if chan:
+                        self.add_channel(chan, channel)
                         continue
-                    self.possible_bouquets[-1].append(epgid)
-                    self.epg2channel[epgid] = channel
-                    self.channel2epg[channel] = epgid
-                else:
-                    error = True
-                    # ok, new channel, try to guess mapping
-                    for c in kaa.epg.channels:
-                        if Unicode(channel) == Unicode(c.access_id):
-                            epgid = c.id
-                            break
                     else:
-                        normchannel = self.normalize_name(channel)
-                        for c in kaa.epg.channels:
-                            if Unicode(normchannel) == \
-                                   Unicode(self.normalize_name(c.name)):
-                                epgid = c.id
-                                break
-                        else:
-                            epgid = ''
-                    config.epg.mapping[channel] = epgid
+                        # channel is there but unconfigured
+                        # a match may be found later
+                        self.unknown_channels[channel] = 
guide().new_channel(channel)
+
+                # step 2, try tuner_id
+                chan = guide().get_channel_by_tuner_id(channel)
+
+                if not chan:
+                    # step 3, try short_name
+                    chan = guide().get_channel(channel)
+
+                if chan:
+                    self.add_channel(chan, channel)
+                    continue
+
+                # ok, new channel, try to guess mapping
+                normchannel = self.normalize_name(channel)
+                chan = guide().get_channel(self.normalize_name(channel))
+                if chan:
+                    self.add_channel(chan, channel)
+                    continue
+
+                else:
+                    # if we got this far that means there is nothing to connect
+                    # the channel reported by tvdev to one in the EPG
+
+                    # server may have started with previously unknown channels
+                    # TODO: handle these unknown_channels, which are just
+                    #       channels with no EPG data
+
+                    if channel not in self.unknown_channels:
+                        error = True
+                        chan = ''
+
+                config.epg.mapping[channel] = chan
+
+        # TODO: remove this debugging when everything works good
+        log.debug('bouquets: %s', self.possible_bouquets)
+        n = 1
+        for b in self.possible_bouquets:
+            log.debug('bouquet %d', n)
+            for c in b:
+                log.debug('chan: %s', c)
+            n = n+1
 
         if error:
             OneShotTimer(self.sys_exit).start(1)
@@ -378,7 +422,7 @@
             if remote.id == UNKNOWN_ID:
                 # add the recording
                 rec      = remote.recording
-                channel  = self.epg2channel[rec.channel]
+                channel  = self.known_channels[rec.channel].tuner_id
                 filename = self.get_url(rec)
                 rec.url  = filename
                 log.info('%s: schedule %s' % (String(self.name), 
String(rec.name)))
@@ -443,7 +487,7 @@
         log.info('start live tv')
 
         rpc = self.rpc('home-theatre.vdr.record', self.start_livetv_cb)
-        rpc.call(self.device, self.epg2channel[channel], 0, 2147483647, url, 
())
+        rpc.call(self.device, self.known_channels[channel].tuner_id, 0, 
2147483647, url, ())
         id = Recorder.next_livetv_id
         Recorder.next_livetv_id = id + 1
         self.livetv[id] = channel, None


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to