Author: tack
Date: Sun Apr 15 19:23:08 2007
New Revision: 2623

Modified:
   trunk/epg/src/config.cxml
   trunk/epg/src/server.py
   trunk/epg/src/sources/config_epgdata.cxml
   trunk/epg/src/sources/config_xmltv.cxml
   trunk/epg/src/sources/config_zap2it.cxml
   trunk/epg/src/sources/epgdata.py
   trunk/epg/src/sources/xmltv.py
   trunk/epg/src/sources/zap2it.py

Log:
Fix zap2it xml parser (some data was not being handled in end tag but in
characters() callback which is incorrect); remove backend-specific days config
variable and make it global; add expired_days config option and add logic to
use it (prunes database of expired programs); remove unused 'activate' config
option from each backend and make a global sources config var that accepts a
comma delimited list of sources to use; make update() accept no arguments: with
no backend specified it will use all sources specified in config.



Modified: trunk/epg/src/config.cxml
==============================================================================
--- trunk/epg/src/config.cxml   (original)
+++ trunk/epg/src/config.cxml   Sun Apr 15 19:23:08 2007
@@ -1,5 +1,20 @@
 <?xml version="1.0"?>
 <config>
+    <var name="days" default="7">
+        <desc lang="en">How many days of EPG data you want to fetch.</desc>
+    </var>
+    <var name="expired_days" default="1">
+        <desc lang="en">How many days of expired EPG data you want to keep in 
the database.</desc>
+    </var>
+    <var name="sources" type="str">
+        <desc lang="en">
+            Comma separated list of EPG data sources to use.  If you specify a
+            source here, you will need to configure it below.
+            
+            Valid sources are: xmltv, zap2it, or epgdata.
+        </desc>
+    </var>
+
     <code>
         from sources import *
 

Modified: trunk/epg/src/server.py
==============================================================================
--- trunk/epg/src/server.py     (original)
+++ trunk/epg/src/server.py     Sun Apr 15 19:23:08 2007
@@ -42,6 +42,7 @@
 import kaa.notifier
 
 # kaa.epg imports
+from config import config
 from sources import *
 
 # get logging object
@@ -96,13 +97,16 @@
         self._rpc_server.append(s)
 
 
-    def sync(self, result=False):
+    def sync(self):
         """
         Sync database. The guide may changed by source, commit changes to
         database and notify clients. Load some basic settings from the db.
-        The result parameter is not used but given by the InProgress callback
-        when this function is called after an update.
         """
+        # Prune obsolete programs from database.
+        expired_time = time.time() - config.expired_days * 60 * 60 * 24
+        count = self._db.delete_by_query(type = "program", stop = QExpr('<', 
expired_time))
+        if count:
+            log.info('Deleted %d expired programs from database' % count)
         self._db.commit()
 
         # Load some basic information from the db.
@@ -162,18 +166,53 @@
 
 
     @kaa.rpc.expose('guide.update')
-    def update(self, backend, *args, **kwargs):
+    def update(self, backend = None, *args, **kwargs):
         """
-        Start epg update calling the source_* files.
+        Start epg update calling the source_* files.  If backend is specified,
+        only call update() from that specific backend.  Otherwise call update
+        on all enabled backends in the 'sources' config value.
+        """
+        if backend:
+            backends = [backend]
+        elif config.sources:
+            backends = config.sources.replace(' ', '').split(',')
+        else:
+            backends = []
+
+        finished_signal = kaa.notifier.Signal()
+        finished_signal._backends = backends
+
+        for backend in backends[:]:
+            if backend not in sources:
+                log.error("No such update backend '%s'" % backend)
+                backends.remove(backend)
+                continue
+
+            log.info('update backend %s', backend)
+            result = sources[backend].update(self, *args, **kwargs)
+            if isinstance(result, kaa.notifier.InProgress):
+                # sync when guide is updated
+                result.connect(self._update_finished, finished_signal, backend)
+            else:
+                log.error("Backend '%s' does not implement threaded update()" 
% backend)
+
+        if not backends:
+            log.warning('No valid backends specified for update.')
+
+        return finished_signal
+
+
+    def _update_finished(self, result, signal, backend):
+        """
+        Callback for update().  This method is called when each backend is
+        finished.  When all invoked backends have called this callback,
+        sync() is called and we emit the finished signal to notify the user.
         """
-        if not sources.has_key(backend):
-            raise ValueError, "No such update backend '%s'" % backend
-        log.info('update backend %s', backend)
-        result = sources[backend].update(self, *args, **kwargs)
-        if isinstance(result, kaa.notifier.InProgress):
-            # sync when guide is updated
-            result.connect(self.sync)
-        return result
+        signal._backends.remove(backend)
+        if not signal._backends:
+            # All the backends are finished.
+            self.sync()
+            signal.emit()
 
 
     @kaa.rpc.expose('guide.query')

Modified: trunk/epg/src/sources/config_epgdata.cxml
==============================================================================
--- trunk/epg/src/sources/config_epgdata.cxml   (original)
+++ trunk/epg/src/sources/config_epgdata.cxml   Sun Apr 15 19:23:08 2007
@@ -8,13 +8,7 @@
         such a test key will work and if it will be possible after that to use
         the service.
     </desc>
-    <var name="activate" default="False">
-        <desc lang="en">Get epg data from epgdata.com</desc>
-    </var>
     <var name="pin" type="str" >
         <desc lang="en">You will need a pin from epgdata.com to use this 
service</desc>
     </var>
-    <var name="days" default="7">
-        <desc lang="en">How many days of epg data you want to fetch.</desc>
-    </var>
 </config>

Modified: trunk/epg/src/sources/config_xmltv.cxml
==============================================================================
--- trunk/epg/src/sources/config_xmltv.cxml     (original)
+++ trunk/epg/src/sources/config_xmltv.cxml     Sun Apr 15 19:23:08 2007
@@ -3,15 +3,12 @@
     <desc lang="en">
         XMLTV settings
 
-        You can use a xmltv rabber to populate the epg database. To activate 
the
-        xmltv grabber you need to set 'activate' to True and specify a 
data_file
-        which already contains the current listing or define a grabber to 
fetch the
-        listings. Optionally you can define arguments for that grabber and the
-        location of a sort program to sort the data after the grabber has 
finished.
+        You can use a xmltv rabber to populate the epg database.  Specify a
+        data_file which already contains the current listing or define a
+        grabber to fetch the listings. Optionally you can define arguments for
+        that grabber and the location of a sort program to sort the data after
+        the grabber has finished.
     </desc>
-    <var name="activate" default="False">
-        <desc lang="en">Use XMLTV service to populate database.</desc>
-    </var>
     <var name="data_file" type="str">
         <desc lang="en">Location of XMLTV data file.</desc>
     </var>
@@ -23,9 +20,6 @@
             ($PATH).
         </desc>
     </var>
-    <var name="days" default="7">
-        <desc lang="en">How many days of XMLTV data you want to fetch.</desc>
-    </var>
     <var name="sort" type="str">
         <desc lang="en">
             Set this to the path of the tv_sort program if you want to sort 
your

Modified: trunk/epg/src/sources/config_zap2it.cxml
==============================================================================
--- trunk/epg/src/sources/config_zap2it.cxml    (original)
+++ trunk/epg/src/sources/config_zap2it.cxml    Sun Apr 15 19:23:08 2007
@@ -1,13 +1,12 @@
 <?xml version="1.0"?>
 <config>
     <desc lang="en">
-        Zap2It settings
+        Zap2it Settings.
 
-        FIXME: more documentation here.
+        Zap2it provides EPG data for North American television providers.  A
+        Zap2it Labs subscription is needed, which can be obtained at no cost at
+        http://labs.zap2it.com.
     </desc>
-    <var name="activate" default="False">
-        <desc lang="en">Use Zap2It service to populate database.</desc>
-    </var>
     <var name="username" type="str" />
     <var name="password" type="str" />
 </config>

Modified: trunk/epg/src/sources/epgdata.py
==============================================================================
--- trunk/epg/src/sources/epgdata.py    (original)
+++ trunk/epg/src/sources/epgdata.py    Sun Apr 15 19:23:08 2007
@@ -212,6 +212,7 @@
     """
     Interface to source_epgdata.
     """
+    from kaa.epg.config import config as epg_config
     if not config.pin:
         log.error('PIN for epgdata.com is missing in tvserver.conf')
         return False
@@ -285,7 +286,7 @@
     address+= '&dayOffset=%s&dataType=xml'
 
     # get the file for each day
-    for i in range(0, int(config.days)):
+    for i in range(0, int(epg_config.days)):
             # remove old file if needed
             try:
                 os.remove(tmpfile)

Modified: trunk/epg/src/sources/xmltv.py
==============================================================================
--- trunk/epg/src/sources/xmltv.py      (original)
+++ trunk/epg/src/sources/xmltv.py      Sun Apr 15 19:23:08 2007
@@ -286,6 +286,7 @@
     """
     Interface to source_xmltv.
     """
+    from kaa.epg.config import config as epg_config
     if config.grabber:
         log.info('grabbing listings using %s', config.grabber)
         xmltv_file = os.path.join(TEMP, 'TV.xml')
@@ -296,7 +297,7 @@
         # nicer using kaa.notifier.Process later. We are inside a thread so it
         # seems to be ok.
         ec = os.system('%s --output %s --days %s >%s 2>%s' % \
-                       (config.grabber, xmltv_file, config.days, log_file, 
log_file))
+                       (config.grabber, xmltv_file, epg_config.days, log_file, 
log_file))
         if not os.path.exists(xmltv_file) or ec:
             log.error('grabber failed, see %s', log_file)
             return

Modified: trunk/epg/src/sources/zap2it.py
==============================================================================
--- trunk/epg/src/sources/zap2it.py     (original)
+++ trunk/epg/src/sources/zap2it.py     Sun Apr 15 19:23:08 2007
@@ -250,16 +250,9 @@
 
     def characters(self, content):
         if self._obj_type == 'program':
-            if self._node_name in ('title', 'description'):
+            if self._node_name in ('title', 'description', 'year', 
'originalAirDate',
+                                   'syndicatedEpisodeNumber', 'mpaaRating'):
                 self._obj[self._node_name] = self._obj.get(self._node_name, 
'') + content
-            elif self._node_name == 'year':
-                self._obj['date'] = time.strptime(content, '%Y')
-            elif self._node_name == 'originalAirDate':
-                self._obj['date'] = time.strptime(content, '%Y-%m-%d')
-            elif self._node_name == 'syndicatedEpisodeNumber':
-                self._obj['episode'] = content
-            elif self._node_name == 'mpaaRating':
-                self._obj['rating'] = content
 
         elif self._obj_type == 'station':
             if self._node_name in ('callSign', 'name'):
@@ -281,6 +274,15 @@
             if program['id'] not in self._schedule_by_program:
                 # program defined for which there is no schedule.
                 return
+
+            if 'year' in program:
+                program['date'] = time.strptime(program['year'], '%Y')
+            if 'originalAirDate' in program:
+                program['date'] = time.strptime(program['originalAirDate'], 
'%Y-%m-%d')
+            if 'syndicatedEpisodeNumber' in program:
+                program['episode'] = program['syndicatedEpisodeNumber']
+            if 'mpaaRating' in program:
+                program['rating'] = program['mpaaRating']
             if 'date' in program:
                 program['date'] = int(calendar.timegm(program['date']))
 
@@ -303,14 +305,15 @@
 @kaa.notifier.execute_in_thread('epg')
 def update(epg, start = None, stop = None):
     from gzip import GzipFile
+    from kaa.epg.config import config as epg_config
 
     if not start:
         # If start isn't specified, choose current time (rounded down to the
         # nearest hour).
         start = int(time.time()) / 3600 * 3600
     if not stop:
-        # If stop isn't specified, use 24 hours after start.
-        stop = start + (24 * 60 * 60)
+        # If stop isn't specified, use config default.
+        stop = start + (24 * 60 * 60 * epg_config.days)
 
     filename = request(str(config.username), str(config.password), 
ZAP2IT_HOST, ZAP2IT_URI, start, stop)
     if not filename:

-------------------------------------------------------------------------
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-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to