Author: dmeyer
Date: Thu Mar 23 20:53:03 2006
New Revision: 1328
Modified:
trunk/epg/src/__init__.py
trunk/epg/src/channel.py
trunk/epg/src/client.py
trunk/epg/src/program.py
trunk/epg/src/server.py
trunk/epg/src/util.py
Log:
add more doc
Modified: trunk/epg/src/__init__.py
==============================================================================
--- trunk/epg/src/__init__.py (original)
+++ trunk/epg/src/__init__.py Thu Mar 23 20:53:03 2006
@@ -1,18 +1,51 @@
-import os
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# __init__.py - Interface to kaa.epg
+# -----------------------------------------------------------------------------
+# $Id$
+# -----------------------------------------------------------------------------
+# kaa.epg - EPG Database
+# Copyright (C) 2004-2005 Jason Tackaberry, Dirk Meyer, Rob Shortt
+#
+# First Edition: Jason Tackaberry <[EMAIL PROTECTED]>
+# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
+# Rob Shortt <[EMAIL PROTECTED]>
+#
+# 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
+#
+# -----------------------------------------------------------------------------
+
+__all__ = [ 'connect', 'Channel', 'Program', 'Client', 'Server', 'QExpr',
+ 'get_channels', 'get_channel', 'search', 'sources' ]
+
+# python imports
import logging
+# kaa imports
from kaa.db import QExpr
+# kaa.epg imports
from channel import Channel
from program import Program
from client import Client
from server import Server
-from util import cmp_channel
from source import sources
-__all__ = [ 'connect', 'Channel', 'Program', 'Client', 'Server', 'QExpr',
- 'get_channels', 'get_channel', 'search', 'sources' ]
+# kaa.epg import for internal use
+from util import cmp_channel
+# get logging object
log = logging.getLogger('epg')
# connected client object
@@ -20,9 +53,10 @@
def connect(address, auth_secret=None):
"""
+ Connect to the epg server with the given address.
"""
global guide
-
+
if guide and guide.connected:
log.warning('connecting to a new epg database')
@@ -31,6 +65,9 @@
def get_channels(sort=False):
+ """
+ Return a list of all channels.
+ """
if guide:
if sort:
channels = guide.get_channels()[:]
@@ -41,13 +78,19 @@
return []
-def get_channel(*args, **kwargs):
+def get_channel(name):
+ """
+ Return the channel with the given name.
+ """
if guide:
- return guide.get_channel(*args, **kwargs)
+ return guide.get_channel(name)
return []
def search(*args, **kwargs):
+ """
+ Search the epg.
+ """
if guide:
try:
return guide.search(*args, **kwargs)
Modified: trunk/epg/src/channel.py
==============================================================================
--- trunk/epg/src/channel.py (original)
+++ trunk/epg/src/channel.py Thu Mar 23 20:53:03 2006
@@ -1,11 +1,44 @@
-from kaa.strutils import str_to_unicode
-import weakref, time
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# channel.py - channel class
+# -----------------------------------------------------------------------------
+# $Id$
+# -----------------------------------------------------------------------------
+# kaa.epg - EPG Database
+# Copyright (C) 2004-2005 Jason Tackaberry, Dirk Meyer, Rob Shortt
+#
+# First Edition: Jason Tackaberry <[EMAIL PROTECTED]>
+# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
+# Rob Shortt <[EMAIL PROTECTED]>
+#
+# 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 weakref
+import time
+
class Channel(object):
+ """
+ kaa.epg channel class.
+ """
def __init__(self, tuner_id, name, long_name, epg):
self.db_id = None
self.tuner_id = tuner_id
- self.name = name
+ self.name = name
self.long_name = long_name
# kludge - remove
@@ -16,10 +49,18 @@
else:
self._epg = None
+
def get_epg(self):
+ """
+ Return the epg object this channel is created from.
+ """
return self._epg()
+
def get_programs(self, t = None):
+ """
+ Get programs from a specific time.
+ """
if not t:
t = time.time()
@@ -27,4 +68,3 @@
return self.get_epg().search(time = t, channel = self)
else:
return []
-
Modified: trunk/epg/src/client.py
==============================================================================
--- trunk/epg/src/client.py (original)
+++ trunk/epg/src/client.py Thu Mar 23 20:53:03 2006
@@ -1,18 +1,51 @@
-import libxml2, sys, time, os, weakref, cPickle
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# client.py - client part of the epg
+# -----------------------------------------------------------------------------
+# $Id$
+# -----------------------------------------------------------------------------
+# kaa.epg - EPG Database
+# Copyright (C) 2004-2005 Jason Tackaberry, Dirk Meyer, Rob Shortt
+#
+# First Edition: Jason Tackaberry <[EMAIL PROTECTED]>
+# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
+# Rob Shortt <[EMAIL PROTECTED]>
+#
+# 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
+#
+# -----------------------------------------------------------------------------
+
+__all__ = ['Client']
+
+# python imports
import logging
+# kaa imports
from kaa import ipc, db
from kaa.notifier import Signal, OneShotTimer, execute_in_timer
-from server import *
-from channel import *
-from program import *
-
-__all__ = ['Client']
-log = logging.getLogger()
+# kaa.epg imports
+from channel import Channel
+from program import Program
+# get logging object
+log = logging.getLogger('epg')
class Client(object):
+ """
+ EPG client class to access the epg on server side.
+ """
def __init__(self, server_or_socket, auth_secret = None):
self.connected = True
self._ipc = ipc.IPCClient(server_or_socket, auth_secret = auth_secret)
@@ -36,22 +69,34 @@
def _disconnected(self):
+ """
+ Signal callback when server disconnects.
+ """
self.connected = False
self.signals["disconnected"].emit()
execute_in_timer(OneShotTimer, 0)
def _updated(self):
+ """
+ Signal callback when update is done.
+ """
self._load()
self.signals["updated"].emit()
execute_in_timer(OneShotTimer, 0)
def _update_progress(self, *args, **kwargs):
+ """
+ Signal callback when update is in progress.
+ """
self.signals["update_progress"].emit(*args, **kwargs)
def _load(self):
+ """
+ (re)load some static information
+ """
self._channels_by_name = {}
self._channels_by_db_id = {}
self._channels_by_tuner_id = {}
@@ -79,6 +124,9 @@
def _program_rows_to_objects(self, query_data):
+ """
+ Convert raw search result data from the server into python objects.
+ """
cols = "parent_id", "id", "start", "stop", "title", "desc", \
"subtitle", "episode", "genre", "rating"
results = []
@@ -92,6 +140,11 @@
def search(self, **kwargs):
+ """
+ Search the db. This will call the search function on server side using
+ kaa.ipc. Notice: this will call kaa.notifier.step() until the result
+ arrives.
+ """
if not self.connected:
return []
@@ -102,6 +155,7 @@
elif type(ch) == tuple and len(ch) == 2:
kwargs["channel"] = db.QExpr("range", (ch[0].db_id,
ch[1].db_id))
else:
+ # FIXME: this is ugly. Why not a longer list?
raise ValueError, "channel must be Channel object or tuple of
2 Channel objects"
if "time" in kwargs:
@@ -155,30 +209,58 @@
def get_channel(self, name):
+ """
+ Get channel by name.
+ """
if name not in self._channels_by_name:
return None
return self._channels_by_name[name]
+
def get_channel_by_db_id(self, db_id):
+ """
+ Get channel by database id.
+ """
if db_id not in self._channels_by_db_id:
return None
return self._channels_by_db_id[db_id]
+
def get_channel_by_tuner_id(self, tuner_id):
+ """
+ Get channel by tuner id.
+ """
if tuner_id not in self._channels_by_tuner_id:
return None
return self._channels_by_tuner_id[tuner_id]
+
def get_max_program_length(self):
+ """
+ Get maximum program length
+ """
return self._max_program_length
+
def get_num_programs(self):
+ """
+ Get number of programs in the db.
+ """
return self._num_programs
+
def get_channels(self):
+ """
+ Get all channels
+ """
return self._channels_list
+
def update(self, *args, **kwargs):
+ """
+ Update the database. This will call the update function in the server
+ and the server needs to be configured for that.
+ """
if not self.connected:
return False
Modified: trunk/epg/src/program.py
==============================================================================
--- trunk/epg/src/program.py (original)
+++ trunk/epg/src/program.py Thu Mar 23 20:53:03 2006
@@ -1,10 +1,37 @@
-from kaa.strutils import str_to_unicode
-from channel import *
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# program.py - program class
+# -----------------------------------------------------------------------------
+# $Id$
+# -----------------------------------------------------------------------------
+# kaa.epg - EPG Database
+# Copyright (C) 2004-2005 Jason Tackaberry, Dirk Meyer, Rob Shortt
+#
+# First Edition: Jason Tackaberry <[EMAIL PROTECTED]>
+# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
+# Rob Shortt <[EMAIL PROTECTED]>
+#
+# 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(object):
+ """
+ kaa.epg program class.
+ """
def __init__(self, channel, start, stop, title, description=u'',
subtitle=u'', episode=u'', genre=u'', rating=u""):
- assert(type(channel) == Channel)
self.channel = channel
self.start = start
self.stop = stop
Modified: trunk/epg/src/server.py
==============================================================================
--- trunk/epg/src/server.py (original)
+++ trunk/epg/src/server.py Thu Mar 23 20:53:03 2006
@@ -1,29 +1,66 @@
-import sys, time, os, weakref, logging
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# server.py - server part of the epg
+# -----------------------------------------------------------------------------
+# $Id$
+# -----------------------------------------------------------------------------
+# kaa.epg - EPG Database
+# Copyright (C) 2004-2005 Jason Tackaberry, Dirk Meyer, Rob Shortt
+#
+# First Edition: Jason Tackaberry <[EMAIL PROTECTED]>
+# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
+# Rob Shortt <[EMAIL PROTECTED]>
+#
+# 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
+#
+# -----------------------------------------------------------------------------
+
+__all__ = [ 'Server']
+
+# python imports
+import logging
from types import ListType
+# kaa imports
from kaa.db import *
from kaa import ipc
from kaa.notifier import Signal
-__all__ = [ 'Server']
+# kaa.epg imports
+from source import sources
+# get logging object
log = logging.getLogger('epg')
-from source import sources
-
class Server(object):
+ """
+ Server class for the epg.
+ """
def __init__(self, dbfile):
log.info('start EPG server')
log.info('using database in %s', dbfile)
+ # create the db and register objects
+
db = Database(dbfile)
db.register_object_type_attrs("channel",
tuner_id = (list, ATTR_SIMPLE),
name = (unicode, ATTR_SEARCHABLE),
long_name = (unicode, ATTR_SEARCHABLE),
)
- db.register_object_type_attrs("program",
+ db.register_object_type_attrs("program",
[ ("start", "stop") ],
title = (unicode, ATTR_KEYWORDS),
desc = (unicode, ATTR_KEYWORDS),
@@ -44,17 +81,22 @@
self._clients = []
self._db = db
self._load()
-
+
+ # ipc connection
self._ipc = ipc.IPCServer('epg')
self._ipc.signals["client_connected"].connect_weak(self._client_connected)
self._ipc.signals["client_closed"].connect_weak(self._client_closed)
self._ipc.register_object(self, "guide")
self._ipc_net = None
-
+
def connect_to_network(self, address, auth_secret=None):
- # listen on tcp port too
+ """
+ Start a network connection (tcp) with the given address and secret.
+ The function will return addr/port so you can set port to 0 to let the
+ system choose one.
+ """
host, port = address.split(':', 1)
self._ipc_net = ipc.IPCServer((host, int(port)), auth_secret =
auth_secret)
@@ -66,13 +108,16 @@
def _load(self):
+ """
+ Load some basic information from the db.
+ """
self._max_program_length = self._num_programs = 0
q = "SELECT stop-start AS length FROM objects_program ORDER BY length
DESC LIMIT 1"
- res = self.get_db()._db_query(q)
+ res = self._db._db_query(q)
if len(res):
self._max_program_length = res[0][0]
- res = self.get_db()._db_query("SELECT count(*) FROM objects_program")
+ res = self._db._db_query("SELECT count(*) FROM objects_program")
if len(res):
self._num_programs = res[0][0]
@@ -96,6 +141,9 @@
def _client_closed(self, client):
+ """
+ Callback when a client disconnects from ipc.
+ """
for signal in self.signals.values():
for callback in signal:
if ipc.get_ipc_from_proxy(callback) == client:
@@ -108,6 +156,9 @@
def update(self, backend, *args, **kwargs):
+ """
+ Start epg update calling the source_* files.
+ """
if not sources.has_key(backend):
raise ValueError, "No such update backend '%s'" % backend
log.info('update backend %s', backend)
@@ -118,14 +169,14 @@
"""
This method requires at least one of tuner_id, name, long_name.
Depending on the source (various XMLTV sources, Zap2it, etc.) not all
- of the information we would like is available. Also, channels are
- perceived differently around the world and handled differently by
+ of the information we would like is available. Also, channels are
+ perceived differently around the world and handled differently by
differnent systems (DVB, analog TV).
Following the KISS philosophy (Keep It Simple Stupid) we can follow
some
simple rules.
- The most important field here is name. If there's no name
+ The most important field here is name. If there's no name
we make it based on tuner_id or long_name. If there's no long_name we
base that on name or tuner_id. If there's no tuner_id it does
not matter because we will then always have a value for name.
@@ -148,17 +199,17 @@
name = tuner_id[0]
else:
name = long_name
-
+
if not long_name:
# then there must be one of the others
if name:
long_name = name
elif tuner_id:
long_name = tuner_id[0]
-
+
if not tuner_id:
tuner_id = [ name ]
-
+
c2 = self._db.query(type = "channel", name = name)
if len(c2):
@@ -189,23 +240,25 @@
else:
self._tuner_ids.append(t)
- o = self._db.add_object("channel",
- tuner_id = tuner_id,
- name = name,
+ o = self._db.add_object("channel", tuner_id = tuner_id, name = name,
long_name = long_name)
return o["id"]
def _add_program_to_db(self, channel_db_id, start, stop, title,
**attributes):
+ """
+ Add a program to the db. This could cause removing older programs
+ overlapping.
+ """
start = int(start)
stop = int(stop)
-
+
# Find all programs that have a start or stop during this program
s1 = self._db.query(parent = ("channel", channel_db_id), type =
"program",
start = QExpr("range", (start, stop-1)))
s2 = self._db.query(parent = ("channel", channel_db_id), type =
"program",
stop = QExpr("range", (start+1, stop)))
-
+
# In a perfect world this program is already in the db and is in s1 and
# s2 and both lists have a length of 1
if len(s1) == len(s2) == 1 and start == s1[0]['start'] ==
s2[0]['start'] and \
@@ -233,7 +286,7 @@
# Now add the new program
log.info('adding program: %s', title)
o = self._db.add_object("program", parent = ("channel", channel_db_id),
- start = start, stop = stop, title = title,
+ start = start, stop = stop, title = title,
**attributes)
if stop - start > self._max_program_length:
@@ -242,6 +295,9 @@
def query(self, **kwargs):
+ """
+ Query the db.
+ """
if "channel" in kwargs:
if type(kwargs["channel"]) in (list, tuple):
kwargs["parent"] = [("channel", x) for x in kwargs["channel"]]
@@ -257,13 +313,15 @@
return res
- def get_db(self):
- return self._db
-
-
def get_max_program_length(self):
+ """
+ Get maximum program length
+ """
return self._max_program_length
def get_num_programs(self):
+ """
+ Get number of programs in the db.
+ """
return self._num_programs
Modified: trunk/epg/src/util.py
==============================================================================
--- trunk/epg/src/util.py (original)
+++ trunk/epg/src/util.py Thu Mar 23 20:53:03 2006
@@ -1,6 +1,37 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------------
+# util.py - Small helper functions
+# -----------------------------------------------------------------------------
+# $Id$
+# -----------------------------------------------------------------------------
+# kaa.epg - EPG Database
+# Copyright (C) 2004-2005 Jason Tackaberry, Dirk Meyer, Rob Shortt
+#
+# First Edition: Dirk Meyer <[EMAIL PROTECTED]>
+# Maintainer: Dirk Meyer <[EMAIL PROTECTED]>
+# Rob Shortt <[EMAIL PROTECTED]>
+#
+# 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
+#
+# -----------------------------------------------------------------------------
def cmp_channel(c1, c2):
-
+ """
+ Compare two channels for sorting.
+ FIXME: a channel should have an sort number as attribute the user
+ can change.
+ """
l1 = len(c1.tuner_id)
l2 = len(c2.tuner_id)
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog