Update of /cvsroot/freevo/freevo/lib/pyepg
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25624
Modified Files:
__init__.py channel.py guide.py program.py xmltv.py
Added Files:
db_sqlite.py source_vdr.py source_xmltv.py
Removed Files:
xmltv_parser.py
Log Message:
major cleanup and restructuring
Index: program.py
===================================================================
RCS file: /cvsroot/freevo/freevo/lib/pyepg/program.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** program.py 9 Dec 2004 20:23:00 -0000 1.4
--- program.py 10 Dec 2004 19:55:28 -0000 1.5
***************
*** 1,2 ****
--- 1,35 ----
+ # -*- coding: iso-8859-1 -*-
+ #
-----------------------------------------------------------------------------
+ # program.py - an epg program
+ #
-----------------------------------------------------------------------------
+ # $Id$
+ #
+ #
-----------------------------------------------------------------------------
+ # Freevo - A Home Theater PC framework
+ # Copyright (C) 2002-2004 Krister Lagerstrom, Dirk Meyer, et al.
+ #
+ # First Edition: Dirk Meyer <[EMAIL PROTECTED]>
+ # Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
+ # Rob Shortt <[EMAIL PROTECTED]>
+ #
+ # Please see the file freevo/Docs/CREDITS for a complete list of authors.
+ #
+ # This program is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License as published by
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful, but
+ # WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+ # CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ # Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License along
+ # with this program; if not, write to the Free Software Foundation, Inc.,
+ # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ #
+ #
-----------------------------------------------------------------------------
+
+
class Program:
"""
***************
*** 15,19 ****
self.description = description
self.episode = episode
!
# FIXME: remove that information
self.scheduled = False
--- 48,52 ----
self.description = description
self.episode = episode
!
# FIXME: remove that information
self.scheduled = False
***************
*** 23,26 ****
# TODO: add ratings support (from epgdb)
self.ratings = ''
-
-
--- 56,57 ----
--- xmltv_parser.py DELETED ---
Index: xmltv.py
===================================================================
RCS file: /cvsroot/freevo/freevo/lib/pyepg/xmltv.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** xmltv.py 4 Dec 2004 01:32:18 -0000 1.6
--- xmltv.py 10 Dec 2004 19:55:28 -0000 1.7
***************
*** 1,277 ****
- # -*- coding: iso-8859-1 -*-
- # -----------------------------------------------------------------------
- # xmltv.py - Freevo Electronic Program Guide module for XMLTV
- # -----------------------------------------------------------------------
- # $Id$
#
! # Notes:
! # Todo:
! #
! # -----------------------------------------------------------------------
[...1110 lines suppressed...]
!
! channels = [{'display-name': [(u'Channel 10 ELTV', u'')],
! 'id': u'C10eltv.zap2it.com',
! 'url': [u'http://www.eastlink.ca/']},
! {'display-name': [(u'Channel 11 CBHT', u'en')],
! 'icon': [{'src':
u'http://tvlistings2.zap2it.com/tms_network_logos/cbc.gif'}],
! 'id': u'C11cbht.zap2it.com'}]
!
!
! w = Writer(sys.stdout, encoding="iso-8859-1",
! date="20030811003608 -0300",
! source_info_url="http://www.funktronics.ca/python-xmltv",
! source_info_name="Funktronics",
! generator_info_name="python-xmltv",
! generator_info_url="http://www.funktronics.ca/python-xmltv")
! for c in channels:
! w.write_channel(c)
! for p in programmes:
! w.write_programme(p)
! w.end()
Index: channel.py
===================================================================
RCS file: /cvsroot/freevo/freevo/lib/pyepg/channel.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** channel.py 9 Dec 2004 20:23:00 -0000 1.3
--- channel.py 10 Dec 2004 19:55:28 -0000 1.4
***************
*** 1,5 ****
! from program import Program
class Channel:
--- 1,37 ----
! # -*- coding: iso-8859-1 -*-
! #
-----------------------------------------------------------------------------
! # channel.py - an epg channel
! #
-----------------------------------------------------------------------------
! # $Id$
! #
! #
-----------------------------------------------------------------------------
! # Freevo - A Home Theater PC framework
! # Copyright (C) 2002-2004 Krister Lagerstrom, Dirk Meyer, et al.
! #
! # First Edition: Dirk Meyer <[EMAIL PROTECTED]>
! # Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
! # Rob Shortt <[EMAIL PROTECTED]>
! #
! # Please see the file freevo/Docs/CREDITS for a complete list of authors.
! #
! # This program is free software; you can redistribute it and/or modify
! # it under the terms of the GNU General Public License as published by
! # the Free Software Foundation; either version 2 of the License, or
! # (at your option) any later version.
! #
! # This program is distributed in the hope that it will be useful, but
! # WITHOUT ANY WARRANTY; without even the implied warranty of MER-
! # CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
! # Public License for more details.
! #
! # You should have received a copy of the GNU General Public License along
! # with this program; if not, write to the Free Software Foundation, Inc.,
! # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
! #
! #
-----------------------------------------------------------------------------
+ from program import Program
+
class Channel:
***************
*** 20,24 ****
! def sort_programs(self):
f = lambda a, b: cmp(a.start, b.start)
self.programs.sort(f)
--- 52,56 ----
! def __sort_programs(self):
f = lambda a, b: cmp(a.start, b.start)
self.programs.sort(f)
***************
*** 101,105 ****
self.programs.append(i)
! self.sort_programs()
--- 133,137 ----
self.programs.append(i)
! self.__sort_programs()
***************
*** 159,163 ****
return self.get_relative(pos, prog)
return self.programs[new_pos]
!
--- 191,195 ----
return self.get_relative(pos, prog)
return self.programs[new_pos]
!
Index: __init__.py
===================================================================
RCS file: /cvsroot/freevo/freevo/lib/pyepg/__init__.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** __init__.py 9 Dec 2004 20:23:00 -0000 1.6
--- __init__.py 10 Dec 2004 19:55:28 -0000 1.7
***************
*** 1,9 ****
! from guide import EPGDB
from program import Program
! guide = EPGDB()
connect = guide.connect
! load = guide.init
channels = guide.channel_list
--- 1,9 ----
! from guide import Guide
from program import Program
! guide = Guide()
connect = guide.connect
! load = guide.load
channels = guide.channel_list
Index: guide.py
===================================================================
RCS file: /cvsroot/freevo/freevo/lib/pyepg/guide.py,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** guide.py 9 Dec 2004 20:23:00 -0000 1.13
--- guide.py 10 Dec 2004 19:55:28 -0000 1.14
***************
*** 1,36 ****
# -*- coding: iso-8859-1 -*-
! # -----------------------------------------------------------------------
! # guide.py - This contains EPGDB which is the pyepg interface to the
! # database.
! # -----------------------------------------------------------------------
! # $Id$#
! #
! # Notes:
! # Todo:
! #
! # -----------------------------------------------------------------------
! # $Log$
! # Revision 1.13 2004/12/09 20:23:00 dischi
! # merged freevo/src/tv/channels.py into the guide, needs much cleanup
#
! # Revision 1.12 2004/12/05 17:08:53 dischi
! # wait when db is locked
#
! # Revision 1.11 2004/12/04 01:31:49 rshortt
! # -get_channels() roughly sorts the channels returned. We will add sorting
! # options to Freevo.
! # -Some unicode fixes.
! # -remove_program() will purge a program from all tables (which aren't
! # actually in use yet)
! # -expire_programs(): new method to remove old data from the EPG to keep it
! # small (and faster). This will not remove a programs entry if is found in
! # the recorded_programs table (not in use yet either).
! # -add_data_xmltv(): pass along which channels to exclude. Call
expire_programs()
! # -add_data_vdr(): accept more VDR properties, also support SVDRP. This also
! # checks which channels to exclude. Call expire_programs().
#
- # -----------------------------------------------------------------------
- # Freevo - A Home Theater PC framework
- # Copyright (C) 2002 Krister Lagerstrom, et al.
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
--- 1,17 ----
# -*- coding: iso-8859-1 -*-
! #
-----------------------------------------------------------------------------
! # guide.py - interface to the database
! #
-----------------------------------------------------------------------------
! # $Id$
#
! #
-----------------------------------------------------------------------------
! # Freevo - A Home Theater PC framework
! # Copyright (C) 2002-2004 Krister Lagerstrom, Dirk Meyer, et al.
#
! # First Edition: Dirk Meyer <[EMAIL PROTECTED]>
! # Rob Shortt <[EMAIL PROTECTED]>
! # Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
! # Rob Shortt <[EMAIL PROTECTED]>
#
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
***************
*** 49,57 ****
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
! # ----------------------------------------------------------------------- */
import os
- import traceback
import time
from types import *
--- 30,40 ----
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
! #
-----------------------------------------------------------------------------
!
import os
import time
+ import logging
+
from types import *
***************
*** 66,69 ****
--- 49,56 ----
from program import Program
+ # get logging object
+ log = logging.getLogger('pyepg')
+
+
def escape_query(sql):
"""
***************
*** 81,147 ****
"""
Escape a SQL value in a manner to be quoted inside a query
! """
! # print 'RLS: val1 - %s' % val
if not type(val) in StringTypes:
- # print 'RLS: val not StringType'
return val
- val = val.replace('"', '')
- val = val.replace('\'', '')
- # print 'RLS: val2 - %s' % val
- return val
-
-
- def inti(a):
- ret = 0
- if a:
- try:
- ret = int(a)
- except ValueError:
- traceback.print_exc()
- ret = 0
-
- return ret
-
-
- try:
- import sqlite
- except:
- print "Python SQLite not installed!"
-
- from sqlite import IntegrityError, OperationalError
- import notifier
-
-
- class _SQLite:
- def __init__(self, dbpath):
- while 1:
- try:
- self.db = sqlite.connect(dbpath, client_encoding='utf-8',
- timeout=10)
- break
- except OperationalError, e:
- notifier.step(False, False)
- self.cursor = self.db.cursor()
-
-
- def commit(self):
- self.db.commit()
-
- def close(self):
- self.db.close()
-
- def execute(self, query):
- while 1:
- try:
- self.cursor.execute(query)
- return self.cursor.fetchall()
- except OperationalError, e:
- notifier.step(False, False)
!
! class EPGDB:
! """
! Class for working with the EPG database
"""
def __init__(self):
--- 68,80 ----
"""
Escape a SQL value in a manner to be quoted inside a query
! """
if not type(val) in StringTypes:
return val
+ return val.replace('"', '').replace('\'', '')
! class Guide:
! """
! Class for working with the EPG database
"""
def __init__(self):
***************
*** 149,179 ****
self.channel_dict = {}
- def connect(self, dbpath):
- if not os.path.isfile(dbpath):
- print 'epg database missing, creating it'
- scheme = os.path.join(os.path.dirname(__file__), 'epg_schema.sql')
- os.system('sqlite %s < %s 2>/dev/null >/dev/null' % (dbpath,
scheme))
- print 'done'
- self.db = _SQLite(dbpath)
- def init(self, TV_CHANNELS=[], TV_CHANNELS_EXCLUDE=[]):
# Check TV_CHANNELS and add them to the list
for c in TV_CHANNELS:
self.add_channel(Channel(c[0], c[1], c[2:], self))
! # Check the EPGDB for channels. All channels not in the exclude list
# will be added if not already in the list
! for c in self.get_channels():
if String(c['id']) in TV_CHANNELS_EXCLUDE:
# Skip channels that we explicitly do not want.
continue
if not c['id'] in self.channel_dict.keys():
! self.add_channel(Channel(c['id'], c['display_name'],
c['access_id'], self))
! def execute(self, query, close=False):
query = escape_query(query)
--- 82,120 ----
self.channel_dict = {}
+ def connect(self, frontent, *args):
+ """
+ Connect to the database frontent
+ """
+ exec('from db_%s import Database' % frontent)
+ self.db = Database(*args)
+
+ def load(self, TV_CHANNELS=[], TV_CHANNELS_EXCLUDE=[]):
+ """
+ Load channel listing from the database
+ """
# Check TV_CHANNELS and add them to the list
for c in TV_CHANNELS:
self.add_channel(Channel(c[0], c[1], c[2:], self))
! # Check the db for channels. All channels not in the exclude list
# will be added if not already in the list
! for c in self.sql_get_channels():
if String(c['id']) in TV_CHANNELS_EXCLUDE:
# Skip channels that we explicitly do not want.
continue
if not c['id'] in self.channel_dict.keys():
! self.add_channel(Channel(c['id'], c['display_name'],
! c['access_id'], self))
!
+ def close(self):
+ self.db.commit()
+ self.db.close()
! def sql_execute(self, query, close=False):
query = escape_query(query)
***************
*** 181,205 ****
result = self.db.execute(query)
except TypeError:
! traceback.print_exc()
return False
if close:
# run a single query then close
! self.db.commit()
self.db.close()
return result
else:
return result
-
- def close(self):
- self.db.commit()
- self.db.close()
! def commit(self):
self.db.commit()
! def checkTable(self,table=None):
if not table:
return False
--- 122,142 ----
result = self.db.execute(query)
except TypeError:
! log.exception('execute error')
return False
if close:
# run a single query then close
! self.db.commit()
self.db.close()
return result
else:
return result
! def sql_commit(self):
self.db.commit()
! def sql_checkTable(self,table=None):
if not table:
return False
***************
*** 211,248 ****
! def db_add_channel(self, id, display_name, access_id):
! query = 'insert or replace into channels (id, display_name,
access_id) \
values ("%s", "%s", "%s")' % (id, display_name, access_id)
- self.execute(query)
- self.commit()
-
! def get_channel(self, id):
query = 'select * from channels where id="%s' % id
! channel = self.execute(query)
if len(channel):
return channel[0]
! def get_channels(self):
query = 'select * from channels order by access_id'
! return self.execute(query)
! def remove_channel(self, id):
query = 'delete from channels where id="%s' % id
!
! self.execute(query)
! self.commit()
! def get_channel_ids(self):
id_list = []
query = 'select id from channels'
! rows = self.execute(query)
! for row in rows:
id_list.append(row.id)
--- 148,183 ----
! def sql_add_channel(self, id, display_name, access_id):
! query = 'insert or replace into channels (id, display_name,
access_id)\
values ("%s", "%s", "%s")' % (id, display_name, access_id)
+ self.sql_execute(query)
+ self.sql_commit()
! def sql_get_channel(self, id):
query = 'select * from channels where id="%s' % id
! channel = self.sql_execute(query)
if len(channel):
return channel[0]
! def sql_get_channels(self):
query = 'select * from channels order by access_id'
! return self.sql_execute(query)
! def sql_remove_channel(self, id):
query = 'delete from channels where id="%s' % id
! self.sql_execute(query)
! self.sql_commit()
! def sql_get_channel_ids(self):
id_list = []
query = 'select id from channels'
! rows = self.sql_execute(query)
! for row in rows:
id_list.append(row.id)
***************
*** 250,260 ****
! def add_program(self, channel_id, title, start, stop, subtitle='',
! description='', episode=''):
now = time.time()
title = escape_value(title)
subtitle = escape_value(subtitle)
description = escape_value(description)
- # print 'DESC: %s' % description
episode = escape_value(episode)
--- 185,194 ----
! def sql_add_program(self, channel_id, title, start, stop, subtitle='',
! description='', episode=''):
now = time.time()
title = escape_value(title)
subtitle = escape_value(subtitle)
description = escape_value(description)
episode = escape_value(episode)
***************
*** 263,271 ****
del_list = []
! #print 'add_program step 1: %f' % float(time.time()-now)
! rows = self.execute('select * from programs where channel_id="%s" \
! and start=%s' % (channel_id, start))
! #print 'add_program step 2: %f, %d rows' % (float(time.time()-now),
len(rows))
!
if len(rows) > 1:
# With the current schema this should NOT be possible. If we stay
--- 197,203 ----
del_list = []
! query = 'select * from programs where channel_id="%s" ' % channel_id
+\
! 'and start=%s' % start
! rows = self.sql_execute(query)
if len(rows) > 1:
# With the current schema this should NOT be possible. If we stay
***************
*** 274,285 ****
# Bad. We should only have one program for each chanid:start
# Lets end this right here.
- #rows = self.execute('select id from programs where
channel_id="%s" \
- # and start=%s' % (channel_id, start))
-
- # print 'RLS: add_program got %d rows - should delete' % len(rows)
for row in rows:
del_list.append(row.id)
!
! self.remove_programs(del_list)
elif len(rows) == 1:
--- 206,212 ----
# Bad. We should only have one program for each chanid:start
# Lets end this right here.
for row in rows:
del_list.append(row.id)
! self.sql_remove_programs(del_list)
elif len(rows) == 1:
***************
*** 296,335 ****
# that we should update
if old_prog['subtitle'] != subtitle:
! print 'different subtitles: %s - %s' %
(String(old_prog['subtitle']), String(subtitle))
! self.execute('update programs set subtitle="%s" where
id=%d' % (subtitle, old_prog.id))
! self.commit()
if old_prog['description'] != description:
! print 'different descs: %s - %s' %
(String(old_prog['description']), String(description))
! self.execute('update programs set description="%s" where
id=%d' % (description, old_prog.id))
! self.commit()
if old_prog['episode'] != episode:
! print 'different episodes: %s - %s' %
(String(old_prog['episode']), String(episode))
! self.execute('update programs set episode="%s" where
id=%d' % (episode, old_prog.id))
! self.commit()
!
! #print 'add_program step 3 (replace) took %f' %
float(time.time()-now)
return
else:
! print 'different titles: %s - %s' % (String(old_prog.title),
String(title))
# old prog and new prog have same times but different title,
# this is probably a schedule change, remove the old one
# TODO: check for shifting times and program overlaps
!
! #print 'add_program step 4: %f' % float(time.time()-now)
! print 'got old_prog with different title: %s - %s' % \
! (String(old_prog['title']), String(title))
! self.remove_program(old_prog['id'])
#
! # If we made it here there's no identical program in the table
# to modify.
#
# TODO:
! # Delete any entries of the same program title on the same channel
# within 10 minues of the start time to somewhat compensate for
# shifting times.
! # self.execute('delete from programs where channel_id="%s" and \
# title="%s" and abs(%s-start)<=600' % \
# (channel_id, title, start))
--- 223,264 ----
# that we should update
if old_prog['subtitle'] != subtitle:
! log.info('different subtitles: %s - %s' % \
! (String(old_prog['subtitle']), String(subtitle)))
! query = 'update programs set subtitle="%s" where id=%d'
! self.sql_execute(query % (subtitle, old_prog.id))
! self.sql_commit()
if old_prog['description'] != description:
! log.info('different descs: %s - %s' % \
! (String(old_prog['description']),
! String(description)))
! query = 'update programs set description="%s" where id=%d'
! self.sql_execute(query % (description, old_prog.id))
! self.sql_commit()
if old_prog['episode'] != episode:
! log.info('different episodes: %s - %s' % \
! (String(old_prog['episode']), String(episode)))
! query = 'update programs set episode="%s" where id=%d'
! self.sql_execute(query % (episode, old_prog.id))
! self.sql_commit()
return
else:
! log.info('different titles: %s - %s' % \
! (String(old_prog.title), String(title)))
# old prog and new prog have same times but different title,
# this is probably a schedule change, remove the old one
# TODO: check for shifting times and program overlaps
! self.sql_remove_program(old_prog['id'])
#
! # If we made it here there's no identical program in the table
# to modify.
#
# TODO:
! # Delete any entries of the same program title on the same channel
# within 10 minues of the start time to somewhat compensate for
# shifting times.
! # self.sql_execute('delete from programs where channel_id="%s" and \
# title="%s" and abs(%s-start)<=600' % \
# (channel_id, title, start))
***************
*** 337,341 ****
# if del_list.index(row[0]) >= 0: continue
# del_list.append(row[0])
! #self.remove_programs(del_list)
--- 266,270 ----
# if del_list.index(row[0]) >= 0: continue
# del_list.append(row[0])
! #self.sql_remove_programs(del_list)
***************
*** 344,372 ****
# program row.
#
- #print 'add_program step 5 took %f' % float(time.time()-now)
-
query = 'insert into programs (channel_id, title, start, stop, \
subtitle, episode, description) \
values ("%s", "%s", %s, %s, "%s", "%s", "%s")' % \
! (channel_id, title, start, stop,
subtitle, episode, description)
try:
! self.execute(query)
! self.commit()
except IntegrityError:
! print 'Program for (%s, %s) exists:' % (String(channel_id), start)
! rows = self.execute('select * from programs where channel_id="%s"
\
! and start=%s' % (channel_id, start))
! self.commit()
for row in rows:
! print ' %s' % row
! traceback.print_exc()
!
! #print 'add_program step 6 took %f' % float(time.time()-now)
!
def get_programs(self, channels, start=0, stop=-1):
- # print 'RLS: get_programs(%s,%d,%d)' % (channels, start, stop)
if not start:
start = time.time()
--- 273,297 ----
# program row.
#
query = 'insert into programs (channel_id, title, start, stop, \
subtitle, episode, description) \
values ("%s", "%s", %s, %s, "%s", "%s", "%s")' % \
! (channel_id, title, start, stop,
subtitle, episode, description)
try:
! self.sql_execute(query)
! self.sql_commit()
except IntegrityError:
! log.error('Program for (%s, %s) exists:' % \
! (String(channel_id), start))
! query = 'select * from programs where channel_id="%s" and
start=%s'
! rows = self.sql_execute(query % (channel_id, start))
! self.sql_commit()
for row in rows:
! log.error(' %s' % row)
! log.exception('trace:')
!
def get_programs(self, channels, start=0, stop=-1):
if not start:
start = time.time()
***************
*** 379,388 ****
for c in channels:
query = '%s channel_id="%s"' % (query, c)
! if channels.index(c) < len(channels)-1:
query = '%s or' % query
query = '%s and' % query
else:
query = 'select * from programs where'
!
if stop == 0:
# only get what's running at time start
--- 304,313 ----
for c in channels:
query = '%s channel_id="%s"' % (query, c)
! if channels.index(c) < len(channels)-1:
query = '%s or' % query
query = '%s and' % query
else:
query = 'select * from programs where'
!
if stop == 0:
# only get what's running at time start
***************
*** 401,410 ****
return []
! return self.execute('%s order by start' % query)
! def get_programs_by_id(self, id):
query = 'select * from programs where id="%s"' % id
! result = self.execute(query)
if result:
return result[0]
--- 326,335 ----
return []
! return self.sql_execute('%s order by start' % query)
! def sql_get_programs_by_id(self, id):
query = 'select * from programs where id="%s"' % id
! result = self.sql_execute(query)
if result:
return result[0]
***************
*** 412,435 ****
! def remove_program(self, id):
query = 'delete from programs where id=%d' % id
! self.execute(query)
query = 'delete from program_category where program_id=%d' % id
! self.execute(query)
query = 'delete from program_advisory where program_id=%d' % id
! self.execute(query)
query = 'delete from record_programs where program_id=%d' % id
! self.execute(query)
query = 'delete from recorded_programs where program_id=%d' % id
! self.execute(query)
! self.commit()
! def expire_programs(self):
EXPIRE_TIME = time.time() - 12*3600
--- 337,360 ----
! def sql_remove_program(self, id):
query = 'delete from programs where id=%d' % id
! self.sql_execute(query)
query = 'delete from program_category where program_id=%d' % id
! self.sql_execute(query)
query = 'delete from program_advisory where program_id=%d' % id
! self.sql_execute(query)
query = 'delete from record_programs where program_id=%d' % id
! self.sql_execute(query)
query = 'delete from recorded_programs where program_id=%d' % id
! self.sql_execute(query)
! self.sql_commit()
! def sql_expire_programs(self):
EXPIRE_TIME = time.time() - 12*3600
***************
*** 438,442 ****
id not in (select program_id from recorded_programs) \
and stop<%d)' % EXPIRE_TIME
! rows = self.execute(query)
query = 'delete from program_advisory where program_id in \
--- 363,367 ----
id not in (select program_id from recorded_programs) \
and stop<%d)' % EXPIRE_TIME
! rows = self.sql_execute(query)
query = 'delete from program_advisory where program_id in \
***************
*** 444,572 ****
id not in (select program_id from recorded_programs) \
and stop<%d)' % EXPIRE_TIME
! rows = self.execute(query)
query = 'delete from programs where \
id not in (select program_id from recorded_programs) \
and stop<%d' % EXPIRE_TIME
! rows = self.execute(query)
! self.commit()
! def remove_programs(self, ids):
clause = ''
for id in ids:
clause += ' id=%d' % id
! if ids.index(id) < len(ids)-1:
clause += ' or'
query = 'delete from programs where %s' % clause
! #print 'REMOVE: %s' % escape_query(query)
! self.execute(query)
clause = ''
for id in ids:
clause += ' program_id=%d' % id
! if ids.index(id) < len(ids)-1:
clause += ' or'
query = 'delete from program_category where %s' % clause
! #print 'REMOVE: %s' % escape_query(query)
! self.execute(query)
query = 'delete from program_advisory where %s' % clause
! #print 'REMOVE: %s' % escape_query(query)
! self.execute(query)
query = 'delete from record_programs where %s' % clause
! #print 'REMOVE: %s' % escape_query(query)
! self.execute(query)
query = 'delete from recorded_programs where %s' % clause
! #print 'REMOVE: %s' % escape_query(query)
! self.execute(query)
!
! #print 'REMOVE: %s' % escape_query(query)
! self.execute(query)
! self.commit()
!
!
! def add_data_xmltv(self, xmltv_file, exclude_channels=None, verbose=1):
! import xmltv
! xmltv.load_guide(self, xmltv_file, exclude_channels, verbose)
!
! self.expire_programs()
!
! return True
!
!
! def add_data_dd(self, dd_file):
! return False
!
!
! def add_data_vdr(self, vdr_dir=None, channels_file=None, epg_file=None,
! host=None, port=None, access_by='sid',
! exclude_channels=None, verbose=1):
! try:
! import vdr.vdr
! except:
! print 'vdrpylib is not installed:'
! print 'http://sourceforge.net/projects/vdrpylib/'
!
! if not (isinstance(exclude_channels, list) or \
! isinstance(exclude_channels, tuple)):
! exclude_channels = []
!
! print 'excluding channels: %s' % exclude_channels
!
! vdr = vdr.vdr.VDR(host=host, port=port, videopath=vdr_dir,
! channelsfile=channels_file, epgfile=epg_file,
! close_connection=0)
!
! if vdr.epgfile and os.path.isfile(vdr.epgfile):
! print 'Using VDR EPG from %s.' % vdr.epgfile
! if os.path.isfile(vdr.channelsfile):
! vdr.readchannels()
! else:
! print 'WARNING: VDR channels file not found as %s.' % \
! vdr.channelsfile
! vdr.readepg()
! elif vdr.host and vdr.port:
! print 'Using VDR EPG from %s:%s.' % (vdr.host, vdr.port)
! vdr.retrievechannels()
! vdr.retrieveepg()
! else:
! print 'No source for VDR EPG.'
! return False
!
!
! chans = vdr.channels.values()
! for c in chans:
! if c.id in exclude_channels: continue
! if access_by == 'name':
! access_id = c.name
! elif access_by == 'rid':
! access_id = c.rid
! else:
! access_id = c.sid
!
! if verbose:
! print 'Adding channel: %s as %s' % (c.id, access_id)
! self.db_add_channel(c.id, c.name, access_id)
! for e in c.events:
! subtitle = e.subtitle
! if not subtitle: subtitle = ''
! desc = e.desc
! if not desc: desc = ''
!
! self.add_program(c.id, e.title, e.start, int(e.start+e.dur),
! subtitle=subtitle, description=desc)
- self.expire_programs()
! return True
- # channel list code
def sort_channels(self):
--- 369,419 ----
id not in (select program_id from recorded_programs) \
and stop<%d)' % EXPIRE_TIME
! rows = self.sql_execute(query)
query = 'delete from programs where \
id not in (select program_id from recorded_programs) \
and stop<%d' % EXPIRE_TIME
! rows = self.sql_execute(query)
! self.sql_commit()
! def sql_remove_programs(self, ids):
clause = ''
for id in ids:
clause += ' id=%d' % id
! if ids.index(id) < len(ids)-1:
clause += ' or'
query = 'delete from programs where %s' % clause
! self.sql_execute(query)
clause = ''
for id in ids:
clause += ' program_id=%d' % id
! if ids.index(id) < len(ids)-1:
clause += ' or'
query = 'delete from program_category where %s' % clause
! self.sql_execute(query)
query = 'delete from program_advisory where %s' % clause
! self.sql_execute(query)
query = 'delete from record_programs where %s' % clause
! self.sql_execute(query)
query = 'delete from recorded_programs where %s' % clause
! self.sql_execute(query)
! self.sql_execute(query)
! self.sql_commit()
! def add_data(self, backend, *args, **kwargs):
! exec('import source_%s as backend' % backend)
! backend.add_data(self, *args, **kwargs)
! self.sql_expire_programs()
def sort_channels(self):
***************
*** 595,600 ****
pos = (cpos + pos) % len(self.channel_list)
return self.channel_list[pos]
!
!
def search_programs(self, subs, by_chan=None):
now = time.time()
--- 442,447 ----
pos = (cpos + pos) % len(self.channel_list)
return self.channel_list[pos]
!
!
def search_programs(self, subs, by_chan=None):
now = time.time()
***************
*** 607,616 ****
query = 'select * from programs %s order by channel_id, start' %
clause
result = []
! for p in self.execute(query):
if self.channel_dict.has_key(p.channel_id):
! result.append(Program(p.id, p.title, p.start, p.stop,
p.episode,
! p.subtitle,
description=p['description'],
channel=self.channel_dict[p.channel_id]))
return result
-
-
--- 454,462 ----
query = 'select * from programs %s order by channel_id, start' %
clause
result = []
! for p in self.sql_execute(query):
if self.channel_dict.has_key(p.channel_id):
! result.append(Program(p.id, p.title, p.start, p.stop,
! p.episode, p.subtitle,
! description=p['description'],
channel=self.channel_dict[p.channel_id]))
return result
--- NEW FILE: source_vdr.py ---
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------------
# source_vdr.py - Freevo Electronic Program Guide module for VDR
# -----------------------------------------------------------------------------
# $Id: source_vdr.py,v 1.1 2004/12/10 19:55:28 dischi Exp $
#
# -----------------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002-2004 Krister Lagerstrom, Dirk Meyer, et al.
#
# First Edition: Rob Shortt <[EMAIL PROTECTED]>
# Maintainer: Rob Shortt <[EMAIL PROTECTED]>
#
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# -----------------------------------------------------------------------------
import os
import vdr.vdr
def add_data(guide, vdr_dir=None, channels_file=None, epg_file=None,
host=None, port=None, access_by='sid',
exclude_channels=None, verbose=1):
if not (isinstance(exclude_channels, list) or \
isinstance(exclude_channels, tuple)):
exclude_channels = []
print 'excluding channels: %s' % exclude_channels
vdr = vdr.vdr.VDR(host=host, port=port, videopath=vdr_dir,
channelsfile=channels_file, epgfile=epg_file,
close_connection=0)
if vdr.epgfile and os.path.isfile(vdr.epgfile):
print 'Using VDR EPG from %s.' % vdr.epgfile
if os.path.isfile(vdr.channelsfile):
vdr.readchannels()
else:
print 'WARNING: VDR channels file not found as %s.' % \
vdr.channelsfile
vdr.readepg()
elif vdr.host and vdr.port:
print 'Using VDR EPG from %s:%s.' % (vdr.host, vdr.port)
vdr.retrievechannels()
vdr.retrieveepg()
else:
print 'No source for VDR EPG.'
return False
chans = vdr.channels.values()
for c in chans:
if c.id in exclude_channels: continue
if access_by == 'name':
access_id = c.name
elif access_by == 'rid':
access_id = c.rid
else:
access_id = c.sid
if verbose:
print 'Adding channel: %s as %s' % (c.id, access_id)
guide.sql_add_channel(c.id, c.name, access_id)
for e in c.events:
subtitle = e.subtitle
if not subtitle: subtitle = ''
desc = e.desc
if not desc: desc = ''
quide.sql_add_program(c.id, e.title, e.start, int(e.start+e.dur),
subtitle=subtitle, description=desc)
return True
--- NEW FILE: source_xmltv.py ---
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------------
# source_xmltv.py - Freevo Electronic Program Guide module for XMLTV
# -----------------------------------------------------------------------------
# $Id: source_xmltv.py,v 1.1 2004/12/10 19:55:28 dischi Exp $
#
# -----------------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002-2004 Krister Lagerstrom, Dirk Meyer, et al.
#
# First Edition: Dirk Meyer <[EMAIL PROTECTED]>
# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
# Rob Shortt <[EMAIL PROTECTED]>
#
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# -----------------------------------------------------------------------------
import re
import time
import os
import calendar
import logging
import _strptime as strptime
import xmltv
# get logging object
log = logging.getLogger('pyepg')
EPG_TIME_EXC = _('Time conversion error')
def format_text(text):
while len(text) and text[0] in (u' ', u'\t', u'\n'):
text = text[1:]
text = re.sub(u'\n[\t *]', u' ', text)
while len(text) and text[-1] in (u' ', u'\t', u'\n'):
text = text[:-1]
return text
def timestr2secs_utc(timestr):
"""
Convert a timestring to UTC (=GMT) seconds.
The format is either one of these two:
'20020702100000 CDT'
'200209080000 +0100'
"""
# This is either something like 'EDT', or '+1'
try:
tval, tz = timestr.split()
except ValueError:
tval = timestr
tz = str(-time.timezone/3600)
if tz == 'CET':
tz='+1'
# Is it the '+1' format?
if tz[0] == '+' or tz[0] == '-':
tmTuple = ( int(tval[0:4]), int(tval[4:6]), int(tval[6:8]),
int(tval[8:10]), int(tval[10:12]), 0, -1, -1, -1 )
secs = calendar.timegm( tmTuple )
adj_neg = int(tz) >= 0
try:
min = int(tz[3:5])
except ValueError:
# sometimes the mins are missing :-(
min = 0
adj_secs = int(tz[1:3])*3600+ min*60
if adj_neg:
secs -= adj_secs
else:
secs += adj_secs
else:
# No, use the regular conversion
## WARNING! BUG HERE!
# The line below is incorrect; the strptime.strptime function doesn't
# handle time zones. There is no obvious function that does. Therefore
# this bug is left in for someone else to solve.
try:
secs = time.mktime(strptime.strptime(timestr, xmltv.date_format))
except ValueError:
timestr = timestr.replace('EST', '')
secs = time.mktime(strptime.strptime(timestr, xmltv.date_format))
return secs
def add_data(guide, XMLTV_FILE, exclude_channels=None):
"""
Load guide data from a raw XMLTV file into the database, parsing using
the XMLTV using the xmltv.py support lib.
Returns: -1 = failed to load any data
0 = loaded channels and programs
1 = loaded channel data only
"""
# Is there a file to read from?
if os.path.isfile(XMLTV_FILE):
gotfile = 1
guide.timestamp = os.path.getmtime(XMLTV_FILE)
else:
log.error('XMLTV file (%s) missing!' % XMLTV_FILE)
gotfile = 0
new_channels = []
if not (isinstance(exclude_channels, list) or \
isinstance(exclude_channels, tuple)):
exclude_channels = []
log.info('excluding channels: %s' % exclude_channels)
xmltv_channels = None
if gotfile:
f = open(XMLTV_FILE)
xmltv_channels = xmltv.read_channels(f)
f.close()
# Was the guide read successfully?
if not xmltv_channels:
return -1 # No
for chan in xmltv_channels:
id = chan['id'].encode('latin-1', 'ignore')
if id in exclude_channels: continue
new_channels.append(id)
displayname = ''
tunerid = ''
if ' ' in id:
# Assume the format is "TUNERID CHANNELNAME"
tunerid = id.split()[0] # XXX Educated guess
displayname = id.split()[1] # XXX Educated guess
else:
displayname = chan['display-name'][0][0]
if ' ' in displayname:
tunerid = displayname.split()[0]
displayname = displayname.split()[1]
else:
tunerid = _('REPLACE WITH TUNERID FOR %s') % displayname
guide.sql_add_channel(id, displayname, tunerid)
xmltv_programs = None
if gotfile:
log.info('reading xmltv data')
f = open(XMLTV_FILE)
xmltv_programs = xmltv.read_programmes(f)
f.close()
# Was the guide read successfully?
if not xmltv_programs:
return 1 # Return the guide, it has the channels at least...
known_ids = guide.sql_get_channel_ids()
log.info('creating guide for %s' % new_channels)
for p in xmltv_programs:
if not p['channel'] in known_ids or p['channel'] in exclude_channels:
continue
try:
channel_id = p['channel']
title = Unicode(p['title'][0][0])
episode = ''
sub_title = ''
desc = ''
start = 0
stop = 0
date = None
ratings = {}
categories = []
advisories = []
if p.has_key('date'):
date = Unicode(p['date'][0][0])
if p.has_key('category'):
categories = [ cat[0] for cat in p['category'] ]
if p.has_key('rating'):
for r in p['rating']:
if r.get('system') == 'advisory':
advisories.append(String(r.get('value')))
continue
ratings[String(r.get('system'))] = String(r.get('value'))
if p.has_key('desc'):
desc = Unicode(format_text(p['desc'][0][0]))
if p.has_key('episode-num'):
episode = p['episode-num'][0][0]
if p.has_key('sub-title'):
sub_title = p['sub-title'][0][0]
try:
start = timestr2secs_utc(p['start'])
try:
stop = timestr2secs_utc(p['stop'])
except:
# Fudging end time
stop = timestr2secs_utc(p['start'][0:8] + '235900' + \
p['start'][14:18])
except EPG_TIME_EXC:
continue
# fix bad German titles to make favorites working
if title.endswith('. Teil'):
title = title[:-6]
if title.rfind(' ') > 0:
try:
part = int(title[title.rfind(' ')+1:])
title = title[:title.rfind(' ')].rstrip()
if sub_title:
sub_title = u'Teil %s: %s' % (part, sub_title)
else:
sub_title = u'Teil %s' % part
except Exception, e:
log.exception('error converting title')
guide.sql_add_program(channel_id, title, start, stop,
subtitle=sub_title, description=desc,
episode=episode)
except:
log.exception('error in xmltv file')
return 0
--- NEW FILE: db_sqlite.py ---
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------------
# db_sqlite.py - interface to sqlite
# -----------------------------------------------------------------------------
# $Id: db_sqlite.py,v 1.1 2004/12/10 19:55:28 dischi Exp $
#
# -----------------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002-2004 Krister Lagerstrom, Dirk Meyer, et al.
#
# First Edition: Dirk Meyer <[EMAIL PROTECTED]>
# Rob Shortt <[EMAIL PROTECTED]>
# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
# Rob Shortt <[EMAIL PROTECTED]>
#
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
# CHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# -----------------------------------------------------------------------------
# python imports
import os
import logging
# notifier
import notifier
# sqlite
import sqlite
from sqlite import IntegrityError, OperationalError
# get logging object
log = logging.getLogger('pyepg')
class Database:
"""
Database class for sqlite usage
"""
def __init__(self, dbpath):
if not os.path.isfile(dbpath):
log.warning('epg database missing, creating it')
scheme = os.path.join(os.path.dirname(__file__), 'epg_schema.sql')
os.system('sqlite %s < %s 2>/dev/null >/dev/null' % \
(dbpath, scheme))
while 1:
try:
self.db = sqlite.connect(dbpath, client_encoding='utf-8',
timeout=10)
break
except OperationalError, e:
notifier.step(False, False)
self.cursor = self.db.cursor()
def commit(self):
self.db.commit()
def close(self):
self.db.close()
def execute(self, query):
while 1:
try:
self.cursor.execute(query)
return self.cursor.fetchall()
except OperationalError, e:
notifier.step(False, False)
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
_______________________________________________
Freevo-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog