Author: dmeyer
Date: Mon Feb 13 21:57:36 2006
New Revision: 7918
Modified:
trunk/tvserver/src/favorite.py
trunk/tvserver/src/recording.py
trunk/tvserver/src/server.py
Log:
use libxml2 and not freevo.fxdparser
Modified: trunk/tvserver/src/favorite.py
==============================================================================
--- trunk/tvserver/src/favorite.py (original)
+++ trunk/tvserver/src/favorite.py Mon Feb 13 21:57:36 2006
@@ -36,8 +36,9 @@
import time
import logging
-# freevo imports
-from freevo import fxdparser
+# kaa imports
+from kaa.base import libxml2
+from kaa.base.strutils import unicode_to_str
# record imports
from config import config
@@ -55,13 +56,13 @@
Base class for a favorite.
"""
NEXT_ID = 0
-
+
def __init__(self, name = 'unknown', channels = [],
priority = 0, days = [], times = [], once = False,
- substring = False):
+ substring = False, node=None):
self.id = Favorite.NEXT_ID
Favorite.NEXT_ID += 1
-
+
self.name = name
self.channels = channels
self.priority = priority
@@ -79,56 +80,56 @@
self.start_padding = config.record.start_padding
self.stop_padding = config.record.stop_padding
+ if not node:
+ return
- def short_list(self):
- """
- Return a short list with informations about the favorite.
- """
- return self.id, self.name, self.priority
-
-
- def long_list(self):
- """
- Return a long list with every information about the favorite.
- """
- return self.id, self.name, self.channels, self.priority, self.days, \
- self.times, self.once, self.substring
-
-
- def parse_fxd(self, parser, node):
- """
- Parse informations from a fxd node and set the internal variables.
- """
- for child in node.children:
+ # Parse informations from a fxd node and set the internal variables.
+ for child in node:
for var in ('name', 'fxdname'):
if child.name == var:
- setattr(self, var, parser.gettext(child))
+ setattr(self, var, child.content)
if child.name == 'url':
- self.url = String(parser.gettext(child))
+ self.url = unicode_to_str(child.content)
if child.name == 'once':
self.once = True
if child.name == 'substring':
self.substring = True
if child.name == 'channels':
self.channels = []
- for v in parser.gettext(child).split(' '):
+ for v in child.content.split(' '):
self.channels.append(v)
if child.name == 'days':
self.days = []
- for v in parser.gettext(child).split(' '):
+ for v in child.content.split(' '):
self.days.append(int(v))
if child.name == 'times':
self.times = []
- for v in parser.gettext(child).split(' '):
+ for v in child.content.split(' '):
m = _time_re.match(v).groups()
start = int(m[0])*100 + int(m[1])
stop = int(m[2])*100 + int(m[3])
self.times.append((start, stop))
if child.name == 'padding':
- self.start_padding = int(parser.getattr(child, 'start'))
- self.stop_padding = int(parser.getattr(child, 'stop'))
+ self.start_padding = int(child.getattr('start'))
+ self.stop_padding = int(child.getattr('stop'))
if child.name == 'priority':
- setattr(self, 'priority', int(parser.gettext(child)))
+ setattr(self, 'priority', int(child.content))
+
+
+ def short_list(self):
+ """
+ Return a short list with informations about the favorite.
+ """
+ return self.id, self.name, self.priority
+
+
+ def long_list(self):
+ """
+ Return a long list with every information about the favorite.
+ """
+ return self.id, self.name, self.channels, self.priority, self.days, \
+ self.times, self.once, self.substring
+
def match(self, name, channel, start):
"""
@@ -223,38 +224,32 @@
(self.id, String(name), self.priority, once, substring)
- def __fxd__(self, fxd):
+ def __xml__(self):
"""
Dump informations about the favorite in a fxd file node.
"""
- node = fxdparser.XMLnode('favorite', [ ('id', self.id ) ] )
+ node = libxml2.Node('favorite', id=self.id)
for var in ('name', 'priority', 'url', 'fxdname'):
if getattr(self, var):
- subnode = fxdparser.XMLnode(var, [], getattr(self, var) )
- fxd.add(subnode, node)
+ node.add_child(var, getattr(self, var))
for var in ('channels', 'days'):
s = ''
for v in getattr(self, var):
s += '%s ' % v
- subnode = fxdparser.XMLnode(var, [], s[:-1])
- fxd.add(subnode, node)
+ node.add_child(var, s[:-1])
s = ''
for v in self.times:
s += '%02d:%02d-%02d:%02d ' % (v[0] / 100, v[0] % 100,
v[1] / 100, v[1] % 100)
- subnode = fxdparser.XMLnode('times', [], s[:-1])
- fxd.add(subnode, node)
+ node.add_child('times', s[:-1])
if self.once:
- subnode = fxdparser.XMLnode('once')
- fxd.add(subnode, node)
+ node.add_child('once')
if self.substring:
- subnode = fxdparser.XMLnode('substring')
- fxd.add(subnode, node)
- padding = fxdparser.XMLnode('padding', [ ('start', self.start_padding),
- ('stop', self.stop_padding) ])
- fxd.add(padding, node)
+ node.add_child('substring')
+ node.add_child('padding', start=self.start_padding,
stop=self.stop_padding)
return node
+
def __cmp__(self, obj):
"""
Compare basic informations between Favorite objects
Modified: trunk/tvserver/src/recording.py
==============================================================================
--- trunk/tvserver/src/recording.py (original)
+++ trunk/tvserver/src/recording.py Mon Feb 13 21:57:36 2006
@@ -41,9 +41,7 @@
# kaa imports
from kaa.base import libxml2
-
-# freevo imports
-from freevo import fxdparser
+from kaa.base.strutils import unicode_to_str, str_to_unicode
# record imports
from config import config
@@ -71,13 +69,14 @@
Base class for a recording.
"""
NEXT_ID = 0
-
+
def __init__(self, name = 'unknown', channel = 'unknown',
- priority = 0, start = 0, stop = 0, **info ):
+ priority = 0, start = 0, stop = 0, node=None,
+ **info ):
self.id = Recording.NEXT_ID
Recording.NEXT_ID += 1
-
+
self.name = name
self.channel = channel
self.priority = priority
@@ -96,7 +95,7 @@
self.scheduled_recorder = None
self.scheduled_start = 0
self.scheduled_stop = 0
-
+
self.start_padding = config.record.start_padding
self.stop_padding = config.record.stop_padding
for key, value in info.items():
@@ -113,6 +112,29 @@
self.respect_start_padding = True
self.respect_stop_padding = True
+ if not node:
+ return
+
+ # Parse informations from a fxd node and set the internal variables.
+ for child in node.children:
+ for var in ('name', 'channel', 'status', 'subtitle', 'fxdname',
+ 'episode', 'description'):
+ if child.name == var:
+ setattr(self, var, child.content)
+ if child.name == 'url':
+ self.url = unicode_to_str(child.content)
+ if child.name == 'priority':
+ self.priority = int(child.content)
+ if child.name == 'padding':
+ self.start_padding = int(child.getattr('start'))
+ self.stop_padding = int(child.getattr('stop'))
+ if child.name == 'timer':
+ self.start = _time2int(child.getattr('start'))
+ self.stop = _time2int(child.getattr('stop'))
+ if child.name == 'info':
+ for info in child.children:
+ self.info[info.name] = info.content
+
def short_list(self):
"""
@@ -140,34 +162,6 @@
info
- def parse_fxd(self, parser, node):
- """
- Parse informations from a fxd node and set the internal variables.
- """
- for child in node.children:
- for var in ('name', 'channel', 'status', 'subtitle', 'fxdname',
- 'episode', 'description'):
- if child.name == var:
- setattr(self, var, parser.gettext(child))
- if child.name == 'url':
- self.url = String(parser.gettext(child))
- if child.name == 'priority':
- self.priority = int(parser.gettext(child))
- if child.name == 'padding':
- self.start_padding = int(parser.getattr(child, 'start'))
- self.stop_padding = int(parser.getattr(child, 'stop'))
- if child.name == 'timer':
- self.start = _time2int(parser.getattr(child, 'start'))
- self.stop = _time2int(parser.getattr(child, 'stop'))
- parser.parse_info(node, self)
- if self.status == 'recording':
- log.warning('recording in status \'recording\'')
- # Oops, we are in 'recording' status and this was saved.
- # That means we are stopped while recording, set status to
- # missed
- self.status = 'missed'
-
-
def __str__(self):
"""
A simple string representation for a recording for debugging in the
@@ -189,12 +183,12 @@
start_padding = int(self.start_padding/60)
else:
start_padding = 0
-
+
if self.respect_stop_padding:
stop_padding = int(self.stop_padding/60)
else:
stop_padding = 0
-
+
return '%3d %10s %-25s %4d %s-%s %2s %2s %s' % \
(self.id, String(channel), String(name),
self.priority, _int2time(self.start)[4:],
@@ -202,28 +196,24 @@
stop_padding, String(status))
- def __fxd__(self, fxd):
+ def __xml__(self):
"""
Dump informations about the recording in a fxd file node.
"""
- node = fxdparser.XMLnode('recording', [ ('id', self.id ) ] )
- for var in ('name', 'channel', 'priority', 'url', 'status',
+ node = libxml2.Node('recording', id=self.id)
+ for var in ('name', 'channel', 'priority', 'status',
'subtitle', 'fxdname', 'episode', 'description'):
if getattr(self, var):
- subnode = fxdparser.XMLnode(var, [],
- Unicode(getattr(self, var)) )
- fxd.add(subnode, node)
- timer = fxdparser.XMLnode('timer', [ ('start', _int2time(self.start)),
- ('stop', _int2time(self.stop)) ])
- fxd.add(timer, node)
- padding = fxdparser.XMLnode('padding', [ ('start', self.start_padding),
- ('stop', self.stop_padding) ])
- fxd.add(padding, node)
- info = fxdparser.XMLnode('info')
- for i in self.info:
- subnode = fxdparser.XMLnode(i, [], Unicode(self.info[i]) )
- fxd.add(subnode, info)
- fxd.add(info, node)
+ node.add_child(var, getattr(self, var))
+ if self.url:
+ node.add_child('url', str_to_unicode(self.url))
+
+ node.add_child('timer', start=_int2time(self.start),
stop=_int2time(self.stop))
+ node.add_child('padding', start=self.start_padding,
stop=self.stop_padding)
+
+ info = node.add_child('info')
+ for key, value in self.info.items():
+ info.add_child(key, value)
return node
@@ -254,7 +244,7 @@
self.status == RECORDING):
# no update
return
-
+
if self.scheduled_recorder:
self.scheduled_recorder.remove(self)
self.scheduled_recorder = recorder
@@ -272,7 +262,7 @@
self.scheduled_recorder.remove(self)
self.scheduled_recorder = None
-
+
def create_fxd(self):
"""
Create a fxd file for the recording.
Modified: trunk/tvserver/src/server.py
==============================================================================
--- trunk/tvserver/src/server.py (original)
+++ trunk/tvserver/src/server.py Mon Feb 13 21:57:36 2006
@@ -40,9 +40,9 @@
import kaa.thumb
from kaa.notifier import Timer, OneShotTimer, Callback, execute_in_timer
+from kaa.base import libxml2
# freevo imports
-import freevo.fxdparser
import freevo.ipc
# record imports
@@ -67,7 +67,7 @@
schedule for recordings and favorites.
"""
LIVE_TV_ID = 0
-
+
def __init__(self):
mbus = freevo.ipc.Instance('tvserver')
@@ -78,10 +78,10 @@
mbus.connect('freevo.ipc.status')
self.status = mbus.status
self.send_event = mbus.send_event
-
+
self.scheduler = Scheduler(self.scheduler_callback)
self.epg = EPG()
-
+
self.last_listing = []
self.live_tv_map = {}
# add port for channels and check if they are in live-tv mode
@@ -89,7 +89,7 @@
for index, channel in enumerate(self.epg.channels()):
channel.port = port + index
channel.registered = []
-
+
# file to load / save the recordings and favorites
self.fxdfile = freevo.conf.datafile('recordserver.fxd')
# load the recordings file
@@ -128,7 +128,7 @@
# print only from the last 24 hours
maxtime = time.time() - 60 * 60 * 24
-
+
info = 'recordings:\n'
for r in self.recordings:
if all or r.stop > maxtime:
@@ -146,10 +146,10 @@
"""
self.scheduler.schedule(self.recordings)
-
+
def scheduler_callback(self):
log.info('answer from scheduler')
-
+
# send update
sending = []
listing = []
@@ -169,7 +169,7 @@
# print some debug
self.print_schedule()
-
+
# schedule recordings in recorder
self.schedule()
@@ -198,45 +198,19 @@
if r.status in (DELETED, CONFLICT):
r.remove()
return True
-
+
def epg_update(self):
"""
Update recordings based on favorites and epg.
"""
self.epg.check_all(self.favorites, self.recordings, self.reschedule)
-
-
+
+
#
# load / save fxd file with recordings and favorites
#
- def fxd_load_recording(self, parser, node):
- """
- callback for <recording> in the fxd file
- """
- try:
- r = Recording()
- r.parse_fxd(parser, node)
- if r.status == SCHEDULED:
- r.status = CONFLICT
- self.recordings.append(r)
- except Exception, e:
- log.exception('recordserver.load_recording')
-
-
- def fxd_load_favorite(self, parser, node):
- """
- callback for <favorite> in the fxd file
- """
- try:
- f = Favorite()
- f.parse_fxd(parser, node)
- self.favorites.append(f)
- except Exception, e:
- log.exception('recordserver.load_favorite:')
-
-
def load(self):
"""
load the fxd file
@@ -244,12 +218,36 @@
self.recordings = []
self.favorites = []
try:
- fxd = freevo.fxdparser.FXD(self.fxdfile)
- fxd.set_handler('recording', self.fxd_load_recording)
- fxd.set_handler('favorite', self.fxd_load_favorite)
- fxd.parse()
+ fxd = libxml2.Document(self.fxdfile, 'freevo')
except Exception, e:
log.exception('recordserver.load: %s corrupt:' % self.fxdfile)
+ sys.exit(1)
+
+ for child in fxd:
+ if child.name == 'recording':
+ try:
+ r = Recording(node=child)
+ except Exception, e:
+ log.exception('recordserver.load_recording')
+ continue
+ if r.status == RECORDING:
+ log.warning('recording in status \'recording\'')
+ # Oops, we are in 'recording' status and this was saved.
+ # That means we are stopped while recording, set status to
+ # missed
+ r.status = 'missed'
+ if r.status == SCHEDULED:
+ # everything is a conflict for now
+ r.status = CONFLICT
+ self.recordings.append(r)
+
+ if child.name == 'favorite':
+ try:
+ f = Favorite(node=child)
+ except Exception, e:
+ log.exception('recordserver.load_favorite:')
+ continue
+ self.favorites.append(f)
@execute_in_timer(OneShotTimer, 1, type='override')
@@ -257,22 +255,13 @@
"""
save the fxd file
"""
- if not len(self.recordings) and not len(self.favorites):
- # do not save here, it is a bug I havn't found yet
- log.info('do not save fxd file')
- return
- try:
- log.info('save fxd file')
- if os.path.isfile(self.fxdfile):
- os.unlink(self.fxdfile)
- fxd = freevo.fxdparser.FXD(self.fxdfile)
- for r in self.recordings:
- fxd.add(r)
- for r in self.favorites:
- fxd.add(r)
- fxd.save()
- except:
- log.exception('lost the recordings.fxd, send me the trace')
+ log.info('save fxd file')
+ fxd = libxml2.Document(root='freevo')
+ for r in self.recordings:
+ fxd.add_child(r)
+ for f in self.favorites:
+ fxd.add_child(f)
+ fxd.save(self.fxdfile)
#
@@ -294,7 +283,7 @@
# print some debug
self.print_schedule()
-
+
def stop_recording(self, recording):
if not recording:
log.info('live tv stopped')
@@ -329,8 +318,8 @@
self.save()
# print some debug
self.print_schedule()
-
-
+
+
#
# home.theatre.recording rpc commands
#
@@ -458,11 +447,11 @@
self.live_tv_map[id] = channel
return [ id, url ]
-
+
# Find a device for recording. The device should be not recording
# right now and for the next 5 minutes or recording on the same
# bouquet. And it should the recorder with the best priority.
-
+
# FIXME: right now we take one recorder no matter if it is
# recording right now.
rec = recorder.get_recorder(channel.id)
@@ -482,7 +471,7 @@
# return id and url
return [ id, url ]
-
+
@freevo.ipc.expose('home-theatre.watch.stop', add_source=True)
def rpc_watch_stop(self, source, id):
"""
@@ -492,24 +481,24 @@
log.info('stop live tv with id %s' % id)
if not id in self.live_tv_map:
return IndexError('invalid id %s' % id)
-
+
channel = self.live_tv_map[id]
del self.live_tv_map[id]
# remove watcher
if not source in channel.registered:
raise RuntimeError('%s is not watching channel', source)
-
+
channel.registered.remove(source)
if not channel.registered:
# channel is no longer watched
recorder, id = channel.recorder
recorder.stop_livetv(id)
-
+
return []
-
-
+
+
#
# home.theatre.favorite rpc commands
@@ -572,7 +561,7 @@
# something is recording, add busy time of first recording
busy = rec[0].stop + rec[0].stop_padding - ctime
self.status.set('busy', max(1, int(busy / 60) + 1))
-
+
# find next scheduled recordings for wakeup
# FIXME: what about CONFLICT? we don't need to start the server
# for a normal conflict, but we may need it when tvdev is not running
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog