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

Reply via email to