Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: freevo/kaa-epg
base: 9dd4013
...
head fork: freevo/kaa-epg
compare: 872dd9d
  • 4 commits
  • 6 files changed
  • 0 commit comments
  • 2 contributors
Commits on May 13, 2012
@charrea6 charrea6 Add get_grid function to guide.
get_grid returns programs split into channels, with additional metadata added to the programs by registered callbacks.

The intention is that this is used to retrieve the grid for display with the programs also including information on whether they have been scheduled for recording/are a favorite.
f0b9234
Commits on May 20, 2012
@charrea6 charrea6 Remove get_grid and change search to call the callbacks instead.
This way all queries of the database will have access to the additional information. Also remove the meta object and instead apply the returned properties to the Program object as attributes.

 Modifiy the grid test program to separate the programs itself and then check the test value as before.
97c9fb9
Commits on May 22, 2012
@charrea6 charrea6 Remove (un)register_program_callback and replace with a signal.
Couple of small cleans and checks.
60969be
Commits on May 23, 2012
@jtackaberry jtackaberry Merge pull request #2 from charrea6/master
Add program-retrieved signal to Guide to allow custom Program attributes
872dd9d
View
73 src/guide.py
@@ -47,11 +47,31 @@
# get logging object
log = logging.getLogger('epg')
-class Guide(object):
+class Guide(kaa.Object):
"""
EPG guide with db access.
"""
+ __kaasignals__ = {
+ 'program-retrieved':
+ '''
+ Emitted when a program is retrieve from the database.
+
+ .. describe:: def callback(row, extra_info, ...)
+
+ :param row: the program that has been retrieved from the database.
+ :type row: dictionary type object
+
+ :param extra_info: dictionary object to which to add additional info.
+ :type extra_info: dictionary object
+
+ Callbacks can add additional information to the program by adding
+ keys to the extra_info dictionary.
+ '''
+ }
+
+
def __init__(self, database):
+ super(Guide, self).__init__()
db_dir = os.path.dirname(database)
if db_dir and not os.path.isdir(db_dir):
os.makedirs(db_dir)
@@ -176,17 +196,6 @@ def search(self, channel=None, time=None, cls=Program, **kwargs):
if isinstance(channel, (tuple, list)):
kwargs["parent"] = [ ("channel", c.db_id) for c in channel ]
- def convert(dt):
- 'Converts a time to a unix timestamp (seconds since epoch UTC)'
- import time as _time
- if isinstance(dt, (int, float, long)):
- return dt
- if not dt.tzinfo:
- # No tzinfo, treat as localtime.
- return _time.mktime(dt.timetuple())
- # tzinfo present, convert to local tz (which is what time.mktime wants)
- return _time.mktime(dt.astimezone(kaa.dateutils.local).timetuple())
-
if time is not None:
# Find all programs currently playing at (or within) the given
# time(s). We push in the boundaries by 1 second as a heuristic to
@@ -194,9 +203,9 @@ def convert(dt):
# 2 programs. e.g. if program A ends at 15:00 and B starts at 15:00,
# searching for start=15:00 should return B and not A.
if isinstance(time, (tuple, list)):
- start, stop = convert(time[0]) + 1, convert(time[1]) - 1
+ start, stop = to_timestamp(time[0]) + 1, to_timestamp(time[1]) - 1
else:
- start = stop = convert(time) + 1
+ start = stop = to_timestamp(time) + 1
if stop > 0:
kwargs["start"] = QExpr("range", (int(start) - self._max_program_length, int(stop)))
@@ -211,20 +220,32 @@ def convert(dt):
def combine_attrs(row):
return [ row.get(a) for a in attrs ]
[ combine_attrs(row) for row in query_data ]
+
+ if len(self.signals['program-retrieved']):
+ extra_data = []
+ for row in query_data:
+ extra_info = {}
+ self.signals['program-retrieved'].emit(row, extra_info)
+ extra_data.append(extra_info)
+ else:
+ extra_data = None
+
if cls is None:
# return raw data:
- yield query_data
+ yield query_data, extra_data
# Convert raw search result data from the server into python objects.
+ yield self._rows_to_programs(cls, query_data, extra_data)
+
+ def _rows_to_programs(self, cls, query_data, extra_data):
results = []
- channel = None
- for row in query_data:
- if not channel or row['parent_id'] != channel.db_id:
- if row['parent_id'] not in self._channels_by_db_id:
- continue
+ for i,row in enumerate(query_data):
+ if row['parent_id'] in self._channels_by_db_id:
channel = self._channels_by_db_id[row['parent_id']]
- results.append(cls(channel, row))
- yield results
+ else:
+ continue
+ results.append(cls(channel, row, extra_data[i] if extra_data else None))
+ return results
def new_channel(self, tuner_id=None, name=None, long_name=None):
"""
@@ -302,3 +323,11 @@ def get_genres(self, associated=None, prefix=None):
@property
def num_programs(self):
return self._num_programs
+
+def to_timestamp(dt):
+ """
+ Converts a time to a unix timestamp (seconds since epoch UTC)
+ """
+ if isinstance(dt, (int, float, long)):
+ return dt
+ return kaa.dateutils.to_timestamp(dt)
View
5 src/program.py
@@ -53,10 +53,11 @@ class Program(object):
# If this program has been previously shown
FLAG_PREVIOUSLY_SHOWN = 32
- def __init__(self, channel, dbdata):
+ def __init__(self, channel, dbdata, extrainfo):
self.channel = channel
self._dbdata = dbdata
-
+ if extrainfo:
+ self.__dict__.update(extrainfo)
def __getattr__(self, attr):
"""
View
33 src/rpc.py
@@ -41,7 +41,7 @@
# kaa.epg imports
from channel import Channel
from program import Program
-from guide import Guide
+from guide import Guide, to_timestamp
from util import EPGError, cmp_channel
# get logging object
@@ -142,37 +142,21 @@ def search(self, channel=None, time=None, cls=Program, **kwargs):
With the exception of ``keywords`` and ``genres``, a :class:`~kaa.db.QExpr`
object can be used with any of the above kwargs.
"""
- def convert(dt):
- 'Converts a time to a unix timestamp (seconds since epoch UTC)'
- import time as _time
- if isinstance(dt, (int, float, long)):
- return dt
- if not dt.tzinfo:
- # No tzinfo, treat as localtime.
- return _time.mktime(dt.timetuple())
- # tzinfo present, convert to local tz (which is what time.mktime wants)
- return _time.mktime(dt.astimezone(kaa.dateutils.local).timetuple())
-
if self.channel.status == kaa.rpc.DISCONNECTED:
raise EPGError('Client is not connected')
# convert to UTC because the server may have a different
# local timezone set.
if time is not None:
if isinstance(time, (tuple, list)):
- time = convert(time[0]), convert(time[1])
+ time = to_timestamp(time[0]), to_timestamp(time[1])
else:
- time = convert(time)
- query_data = yield self.channel.rpc('search', channel, time, None, **kwargs)
+ time = to_timestamp(time)
+ query_data, extra_data = yield self.channel.rpc('search', channel, time, None, **kwargs)
+ if cls is None:
+ yield query_data, extra_data
# Convert raw search result data from the server into python objects.
- results = []
- channel = None
- for row in query_data:
- if not channel or row['parent_id'] != channel.db_id:
- if row['parent_id'] not in self._channels_by_db_id:
- continue
- channel = self._channels_by_db_id[row['parent_id']]
- results.append(cls(channel, row))
- yield results
+ yield self._rows_to_programs(cls, query_data, extra_data)
+
def update(self):
"""
@@ -237,6 +221,7 @@ def client_connected(self, client):
"""
Connect a new client to the server.
"""
+ log.info('Client connected: %s', client)
client.rpc('_sync', self.guide._channels_by_name.values(), self.guide._num_programs)
client.signals['closed'].connect(self.client_closed, client)
self._clients.append(client)
View
48 test/grid.py
@@ -0,0 +1,48 @@
+import time
+import kaa
+import kaa.epg
+
+
+
+def local():
+ def callback(row, extrainfo):
+ extrainfo['test'] = 'db_id : %d' % row['id']
+ guide = kaa.epg.load('test.db')
+ guide.signals['program-retrieved'].connect(callback)
+
+
+@kaa.coroutine()
+def remote():
+ g = kaa.epg.connect(('localhost', 10000))
+ yield kaa.inprogress(g.signals['connected'])
+
+def test():
+ channels = kaa.epg.get_channels()
+ programs= kaa.epg.search(channels[:2], time=(time.time(), time.time() + (3 * 60 * 60))).wait()
+
+ #Separate into grid arrays
+ channel_programs = [[], []]
+ map_channel_programs = {channels[0]:channel_programs[0], channels[1]:channel_programs[1]}
+ for program in programs:
+ map_channel_programs[program.channel].append(program)
+
+
+ for i,programs in enumerate(channel_programs):
+ print channels[i].name, len(programs)
+ for program in programs:
+ print 'Title:', program.title, '(', program.start, '->', program.stop, ')'
+ assert(program.channel == channels[i])
+ assert(hasattr(program, 'test'))
+ assert(program.test == 'db_id : %d' % program.db_id[1])
+ print
+
+
+if 1:
+ print 'Local'
+ local()
+
+if 0:
+ print 'Remote'
+ remote().wait()
+
+test()
View
9 test/query.py
@@ -5,9 +5,9 @@
def local():
print 'Starting'
kaa.epg.load('test.db')
- print kaa.epg.get_channels()
+ channels = kaa.epg.get_channels()
t1 = time.time()
- result = kaa.epg.search(time=(time.time(), time.time() + 60*60)).wait()
+ result = kaa.epg.search(channel=channels[:2],time=(time.time(), time.time() + 60*60)).wait()
t2 = time.time()
for r in result:
print r.title, r.channel
@@ -39,9 +39,8 @@ def rpc():
print result
-if 0:
- rpc()
- kaa.main.run()
+if 1:
+ rpc().wait()
if 1:
local()
View
8 test/server.py
@@ -1,7 +1,13 @@
import time
import kaa.epg
-kaa.epg.load('test.db')
+
+def callback(row, extrainfo):
+ extrainfo['test'] = 'db_id : %d' % row['id']
+
+guide = kaa.epg.load('test.db')
+guide.signals['program-retrieved'].connect(callback)
+
print kaa.epg.get_channels()
kaa.epg.listen(('localhost', 10000))

No commit comments for this range

Something went wrong with that request. Please try again.