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