Update of /cvsroot/freevo/freevo/src/record
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30565
Modified Files:
favorite.py recording.py server.py
Added Files:
recorder.py
Log Message:
first working version of the recordserver
Index: recording.py
===================================================================
RCS file: /cvsroot/freevo/freevo/src/record/recording.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** recording.py 6 Nov 2004 17:56:21 -0000 1.1
--- recording.py 7 Nov 2004 16:38:24 -0000 1.2
***************
*** 32,36 ****
--- 32,38 ----
import time
+ import copy
+ import config
import util.fxdparser as fxdparser
***************
*** 38,51 ****
def _int2time(i):
return time.strftime(_time_format, time.localtime(i))
def _time2int(s):
return int(time.mktime(time.strptime(s, _time_format)))
class Recording:
def __init__(self, id = -1, name = 'unknown', channel = 'unknown',
! priority = 0, start = 0, stop = 0, filename = '/dev/null',
! info = {}, status = 'scheduled' ):
self.id = id
self.name = name
--- 40,63 ----
def _int2time(i):
+ """
+ Helper function to create a time string from an int.
+ """
return time.strftime(_time_format, time.localtime(i))
+
def _time2int(s):
+ """
+ Helper function to create an int from a string created by _int2time
+ """
return int(time.mktime(time.strptime(s, _time_format)))
class Recording:
+ """
+ Base class for a recording.
+ """
def __init__(self, id = -1, name = 'unknown', channel = 'unknown',
! priority = 0, start = 0, stop = 0, info = {},
! status = 'scheduled' ):
self.id = id
self.name = name
***************
*** 54,62 ****
self.start = start
self.stop = stop
- self.filename = filename
- self.info = info
self.status = status
def short_list(self):
return self.id, self.channel, self.priority, self.start, \
self.stop, self.status
--- 66,87 ----
self.start = start
self.stop = stop
self.status = status
+ self.info = {}
+
+ self.subtitle = ''
+ self.url = ''
+ self.padding = config.TV_RECORD_PADDING
+ for i in info:
+ if i in ('subtitle', 'url'):
+ setattr(self, i, info[i])
+ if i == 'padding':
+ i.padding = int(info[i])
+ self.recorder = None
+
def short_list(self):
+ """
+ Return a short list with informations about the recording.
+ """
return self.id, self.channel, self.priority, self.start, \
self.stop, self.status
***************
*** 64,79 ****
def long_list(self):
return self.id, self.name, self.channel, self.priority, self.start, \
! self.stop, self.filename, self.status, self.info
def parse_fxd(self, parser, node):
self.id = int(parser.getattr(node, 'id'))
for child in node.children:
! for var in ('name', 'channel', 'status'):
if child.name == var:
setattr(self, var, parser.gettext(child))
! if child.name == 'priority':
! self.priority = int(parser.gettext(child))
if child.name == 'timer':
self.start = _time2int(parser.getattr(child, 'start'))
--- 89,116 ----
def long_list(self):
+ """
+ Return a long list with every information about the recording.
+ """
+ info = copy.copy(self.info)
+ if self.subtitle:
+ info['subtitle'] = self.subtitle
+ if self.url:
+ info['url'] = url
return self.id, self.name, self.channel, self.priority, self.start, \
! self.stop, self.status, self.padding, info
def parse_fxd(self, parser, node):
+ """
+ Parse informations from a fxd node and set the internal variables.
+ """
self.id = int(parser.getattr(node, 'id'))
for child in node.children:
! for var in ('name', 'channel', 'status', 'subtitle', 'url'):
if child.name == var:
setattr(self, var, parser.gettext(child))
! for var in ('priority', 'padding'):
! if child.name == var:
! setattr(self, var, int(parser.gettext(child)))
if child.name == 'timer':
self.start = _time2int(parser.getattr(child, 'start'))
***************
*** 83,92 ****
def __str__(self):
! return String(self.short_list())
def __fxd__(self, fxd):
node = fxdparser.XMLnode('recording', [ ('id', self.id ) ] )
! for var in ('name', 'channel', 'priority', 'filename', 'status'):
subnode = fxdparser.XMLnode(var, [], getattr(self, var) )
fxd.add(subnode, node)
--- 120,148 ----
def __str__(self):
! """
! A simple string representation for a recording for debugging in the
! recordserver.
! """
! channel = self.channel
! if len(channel) > 10:
! channel = channel[:10]
! diff = (self.stop - self.start) / 60
! name = self.name
! if len(name) > 23:
! name = name[:20] + u'...'
! name = u'"' + name + u'"'
! return '%3d %10s %-25s %4d %s-%s %s' % \
! (self.id, String(channel), String(name),
! self.priority, _int2time(self.start)[4:],
! _int2time(self.stop)[9:], self.status)
def __fxd__(self, fxd):
+ """
+ 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',
! 'subtitle', 'padding'):
subnode = fxdparser.XMLnode(var, [], getattr(self, var) )
fxd.add(subnode, node)
***************
*** 101,105 ****
--- 157,165 ----
return node
+
def __cmp__(self, obj):
+ """
+ Compare basic informations between Recording objects
+ """
if not isinstance(obj, Recording):
return True
Index: favorite.py
===================================================================
RCS file: /cvsroot/freevo/freevo/src/record/favorite.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** favorite.py 6 Nov 2004 17:56:21 -0000 1.1
--- favorite.py 7 Nov 2004 16:38:24 -0000 1.2
***************
*** 37,51 ****
import util.fxdparser as fxdparser
_time_re = re.compile('([0-9]*):([0-9]*)-([0-9]*):([0-9]*)')
class Favorite:
def __init__(self, id = -1, name = 'unknown', channels = [],
! priority = 0, days = [], times = []):
! self.id = id
! self.name = name
self.channels = channels
self.priority = priority
! self.days = days
! self.times = []
for t in times:
m = _time_re.match(t).groups()
--- 37,56 ----
import util.fxdparser as fxdparser
+ # internal regexp for time format
_time_re = re.compile('([0-9]*):([0-9]*)-([0-9]*):([0-9]*)')
class Favorite:
+ """
+ Base class for a favorite.
+ """
def __init__(self, id = -1, name = 'unknown', channels = [],
! priority = 0, days = [], times = [], once = False):
! self.id = id
! self.name = name
self.channels = channels
self.priority = priority
! self.days = days
! self.times = []
! self.once = once
for t in times:
m = _time_re.match(t).groups()
***************
*** 55,65 ****
def short_list(self):
return self.id, self.name, self.priority
def long_list(self):
return self.id, self.name, self.channels, self.priority, self.days, \
! self.times
def parse_fxd(self, parser, node):
self.id = int(parser.getattr(node, 'id'))
for child in node.children:
--- 60,81 ----
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
!
def parse_fxd(self, parser, node):
+ """
+ Parse informations from a fxd node and set the internal variables.
+ """
self.id = int(parser.getattr(node, 'id'))
for child in node.children:
***************
*** 67,70 ****
--- 83,88 ----
if child.name == var:
setattr(self, var, parser.gettext(child))
+ if child.name == 'once':
+ self.once = True
if child.name == 'channels':
self.channels = []
***************
*** 86,89 ****
--- 104,110 ----
def match(self, name, channel, start):
+ """
+ Return True if name, channel and start match this favorite.
+ """
if name != self.name:
return False
***************
*** 106,113 ****
def __str__(self):
! return String(self.short_list())
def __fxd__(self, fxd):
node = fxdparser.XMLnode('favorite', [ ('id', self.id ) ] )
for var in ('name', 'priority'):
--- 127,150 ----
def __str__(self):
! """
! A simple string representation for a favorite for debugging in the
! recordserver.
! """
! name = self.name
! if len(name) > 45:
! name = name[:45] + u'...'
! name = u'"' + name + u'"'
! if self.once:
! once = '(schedule once)'
! else:
! once = ''
! return '%3d %-45s %4d %s' % \
! (self.id, String(name), self.priority, once)
def __fxd__(self, fxd):
+ """
+ Dump informations about the favorite in a fxd file node.
+ """
node = fxdparser.XMLnode('favorite', [ ('id', self.id ) ] )
for var in ('name', 'priority'):
***************
*** 126,132 ****
--- 163,175 ----
subnode = fxdparser.XMLnode('times', [], s[:-1])
fxd.add(subnode, node)
+ if self.once:
+ subnode = fxdparser.XMLnode('once')
+ fxd.add(subnode, node)
return node
def __cmp__(self, obj):
+ """
+ Compare basic informations between Favorite objects
+ """
if not isinstance(obj, Favorite):
return True
--- NEW FILE: recorder.py ---
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------------
# recorder.py - base class for recorder plugins
# -----------------------------------------------------------------------------
# $Id: recorder.py,v 1.1 2004/11/07 16:38:24 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]>
#
# 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 time
import os
import string
# notifier
import notifier
# freevo imports
import config
import plugin
import childapp
# list of possible plugins
plugins = []
class Childapp(childapp.Instance):
"""
ChildApp wrapper for use inside a recorder plugin
"""
def __init__(self, app, control, debugname = None, doeslogging = 0,
prio = 0):
"""
Init the childapp
"""
childapp.Instance.__init__(self, app, debugname, doeslogging, prio, 0)
self.control = control
def finished(self):
"""
Callback when the child died
"""
self.control.stopped()
self.control = None
class Plugin(plugin.Plugin):
"""
Plugin template for a recorder plugin
"""
def __init__(self):
plugin.Plugin.__init__(self)
self.type = 'recorder'
# childapp running the external program
self.app = None
# recording item
self.item = None
# timer for stop the child when it's all done
self.timer = None
# reference to the recordserver
self.server = None
plugins.append(self)
def get_cmd(self, rec):
"""
Function for the plugin to create the command running the
external program.
"""
raise Exception('no record command function defined')
def create_fxd(self, rec):
"""
Create fxd file for the recording
TODO: write this function
"""
pass
def record(self, server, rec):
"""
Record 'rec', called from the recordserver 'server'
"""
if self.item:
print 'plugin.record: there is something running, stopping it'
self.stop()
# create a filename if it is missing
if not rec.url:
filename_array = { 'progname': String(rec.name),
'title' : String(rec.subtitle) }
filemask = config.TV_RECORDFILE_MASK % filename_array
filename = ''
for letter in time.strftime(filemask, time.localtime(rec.start)):
if letter in string.ascii_letters + string.digits:
filename += letter
elif filename and filename[-1] != '_':
filename += '_'
filename = filename.rstrip(' -_:') + config.TV_RECORDFILE_SUFFIX
rec.url = 'file:' + os.path.join(config.TV_RECORD_DIR, filename)
# get the cmd for the childapp
cmd = self.get_cmd(rec)
self.server = server
self.item = rec
self.app = Childapp(cmd, self)
rec.recorder = self
# Set auto stop for stop time + padding + 10 secs
if self.timer:
notifier.removeTimer(self.timer)
timer = max(0, int(rec.stop + rec.padding + 10 - time.time()))
print 'plugin.record: add stop timer for %s seconds' % (timer)
self.timer = notifier.addTimer(timer * 1000, self.stop)
# Create fxd file now, even if we don't know if it is working. It
# will be deleted later when there is a problem
self.create_fxd()
def stop(self):
"""
Stop the current running recording
"""
if not self.item:
return False
print 'plugin.stop: stop recording'
notifier.removeTimer(self.timer)
self.app.stop()
self.timer = None
return False
def stopped(self):
"""
Callback when the recording has stopped
"""
if self.timer:
notifier.removeTimer(self.timer)
if self.item.url.startswith('file:'):
filename = self.item.url[5:]
if os.path.isfile(filename):
self.item.status = 'saved'
# TODO: create thumbnail
else:
self.item.status = 'failed'
# TODO: delete fxd
else:
self.item.status = 'done'
print 'plugin.stopped: recording finished, new status'
print self.item
if self.server:
self.server.save()
self.item.recorder = None
self.item = None
self.app = None
self.server = None
Index: server.py
===================================================================
RCS file: /cvsroot/freevo/freevo/src/record/server.py,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** server.py 6 Nov 2004 17:56:21 -0000 1.12
--- server.py 7 Nov 2004 16:38:24 -0000 1.13
***************
*** 31,50 ****
--- 31,62 ----
#
-----------------------------------------------------------------------------
+
+ # python imports
import copy
import os
import time
+ import traceback
+ # notifier
import notifier
+
+ # pyepg
import pyepg
+ # freevo imports
import sysconfig
import config
import util
+ import plugin
+ # mbus support
from mcomm import RPCServer, RPCError, RPCReturn
+ # record imports
+ import recorder
from recording import Recording
from favorite import Favorite
+
# FIXME: move to config file
EPGDB = os.path.join(config.FREEVO_CACHEDIR, 'epgdb')
***************
*** 53,71 ****
CONFLICT = 'conflict'
SCHEDULED = 'scheduled'
MISSED = 'missed'
SAVED = 'saved'
class RecordServer(RPCServer):
def __init__(self):
RPCServer.__init__(self, 'recordserver')
self.epgdb = pyepg.get_epg(EPGDB)
self.fxdfile = sysconfig.cachefile('recordserver.fxd')
! self.load()
def resolve_conflict(self, recordings):
! # Sort by priority ans can all except the one with the
! # lowest priority again if the conflict is now solved.
! #
# FIXME:
# This is a very poor solution, maybe we have more than one card
--- 65,99 ----
CONFLICT = 'conflict'
SCHEDULED = 'scheduled'
+ RECORDING = 'recording'
MISSED = 'missed'
SAVED = 'saved'
+ DELETED = 'deleted'
+
class RecordServer(RPCServer):
+ """
+ Class for the recordserver. It handles the rpc calls and checks the
+ schedule for recordings and favorites. The recordings itself are
+ done by plugins in record/plugins.
+ """
def __init__(self):
RPCServer.__init__(self, 'recordserver')
+ plugin.init(exclusive = [ 'record' ])
+ # db access to match favorites
self.epgdb = pyepg.get_epg(EPGDB)
+ # file to load / save the recordings and favorites
self.fxdfile = sysconfig.cachefile('recordserver.fxd')
! # timer for record callback
! self.rec_timer = None
! # load the config file and rebuild index
! self.load(True)
def resolve_conflict(self, recordings):
! """
! Resolve a conflict for recordings. A higher priority wins. A
! conflict doesn't mean they can't be all recorded, maybe a plugin can
! record two programs at a time or there is more than one plugin.
! """
# FIXME:
# This is a very poor solution, maybe we have more than one card
***************
*** 73,81 ****
# a plugin can record two items at the same time. So this function
# needs a huge update!!!
recordings.sort(lambda l, o: cmp(l.priority,o.priority))
! self.scan_for_conflicts(recordings[:-1])
def scan_for_conflicts(self, recordings):
# Sort by start time
recordings.sort(lambda l, o: cmp(l.start,o.start))
--- 101,139 ----
# a plugin can record two items at the same time. So this function
# needs a huge update!!!
+ print 'recordserver.resolve_conflict'
+ for r in recordings:
+ print String(r)
recordings.sort(lambda l, o: cmp(l.priority,o.priority))
! # check if a conflict is recorded right now
! for r in recordings:
! if r.recorder:
! # This recording active right now. It wins against all
! # priorities, we don't stop a running recording
! r.status = RECORDING
!
! for r in recordings:
! if r.status == RECORDING:
! continue
! for c in filter(lambda l: l.status in (SCHEDULED, RECORDING),
! recordings):
! if c.start <= r.start <= c.stop or \
! r.start <= c.start <= r.stop:
! break
! else:
! # no conflict for this recording
! r.status = SCHEDULED
! print 'result:'
! for r in recordings:
! print String(r)
! print
def scan_for_conflicts(self, recordings):
+ """
+ Scan the scheudle for conflicts. A conflict is a list of recordings
+ with overlapping times. After scanning the conflicts will be
+ resolved by resolve_conflict.
+ """
+ print 'recordserver.scan_for_conflicts'
# Sort by start time
recordings.sort(lambda l, o: cmp(l.start,o.start))
***************
*** 132,135 ****
--- 190,198 ----
def check_recordings(self):
+ """
+ Check the current recordings. This includes checking conflicts,
+ removing old entries. At the end, the timer is set for the next
+ recording.
+ """
ctime = time.time()
# remove informations older than one week
***************
*** 145,151 ****
# scan for conflicts
self.scan_for_conflicts(filter(lambda r: r.stop > ctime and \
! r.status in (CONFLICT, SCHEDULED),
! self.recordings))
# print current schedule
--- 208,214 ----
# scan for conflicts
+ to_check = (CONFLICT, SCHEDULED, RECORDING)
self.scan_for_conflicts(filter(lambda r: r.stop > ctime and \
! r.status in to_check, self.recordings))
# print current schedule
***************
*** 153,185 ****
print 'recordings:'
for r in self.recordings:
! print ' ',
! for e in r.short_list():
! print String(e),
! print
print
print 'favorites:'
for f in self.favorites:
! print ' ',
! for e in f.short_list():
! print String(e),
! print
print
! print 'next record id', self.rec_id
! print 'next favorite id', self.fav_id
# save status
! if os.path.isfile(self.fxdfile):
! os.unlink(self.fxdfile)
! fxd = util.fxdparser.FXD(self.fxdfile)
for r in self.recordings:
! fxd.add(r)
! for r in self.favorites:
! fxd.add(r)
! fxd.save()
def check_favorites(self):
! print 'checking favorites against epg'
! for f in self.favorites:
for entry in self.epgdb.search_programs(f.name):
dbid, channel, title, subtitle, foo, descr, \
--- 216,248 ----
print 'recordings:'
for r in self.recordings:
! print r
print
print 'favorites:'
for f in self.favorites:
! print f
print
! print 'next ids: record=%s favorite=%s' % (self.rec_id, self.fav_id)
# save status
! self.save()
!
! # set wakeup call
! if self.rec_timer:
! notifier.removeTimer(self.rec_timer)
for r in self.recordings:
! if r.status == SCHEDULED:
! secs = max(0, int(r.start - time.time()))
! print 'recordserver.check_recordings: next in %s sec' % timer
! self.rec_timer = notifier.addTimer(secs * 1000, self.record)
! break
def check_favorites(self):
! """
! Check favorites against the database and add them to the list of
! recordings
! """
! print 'recordserver.check_favorites'
! for f in copy.copy(self.favorites):
for entry in self.epgdb.search_programs(f.name):
dbid, channel, title, subtitle, foo, descr, \
***************
*** 189,193 ****
--- 252,260 ----
r = Recording(self.rec_id, title, channel, 1000+f.priority,
start, stop)
+ r.favorite = True
if r in self.recordings:
+ # This does not only avoids adding recordings twice, it
+ # also prevents from added a deleted favorite as active
+ # again.
continue
print ' added %s: %s (%s)' % (String(channel),
***************
*** 195,202 ****
--- 262,337 ----
self.recordings.append(r)
self.rec_id += 1
+ if f.once:
+ self.favorites.remove(f)
+ break
+ # now check the schedule again
self.check_recordings()
+ def record(self):
+ """
+ Record a program now using one of the record plugins
+ """
+ # FIXME: handle not conflicting recordings when the padding
+ # has a conflict!
+ for r in self.recordings:
+ if r.status == SCHEDULED:
+ break
+ else:
+ print 'recordserver.record: unable to find the next recording'
+ # This should never happen
+ self.check_recordings()
+ return False
+ if not recorder.plugins:
+ print 'recordserver.record: no plugins found'
+ return False
+
+ # FIXME: find the correct recorder
+ record_plugin = recorder.plugins[0]
+
+ # remove timer that called this function
+ notifier.removeTimer(self.rec_timer)
+ self.rec_timer = None
+
+ if record_plugin.item and record_plugin.item.stop > time.time():
+ # The recorder is recording something. If we are at this point
+ # it means that the current recording has a padding overlapping
+ # the recording of the last recording. So just wait until the
+ # old recording is done
+ secs = record_plugin.item.stop - time.time()
+ self.rec_timer = notifier.addTimer(secs * 1000, self.record)
+ return False
+
+ print 'recordserver.record: start recording'
+ print r
+ # set status to recording
+ r.status = RECORDING
+
+ # schedule next recording
+ for next in self.recordings:
+ if next.status == SCHEDULED:
+ secs = max(0, int(next.start - time.time()))
+ print 'recordserver.record: next in %s sec' % timer
+ self.rec_timer = notifier.addTimer(secs * 1000, self.record)
+ break
+
+ # FIXME: handle more than one recorder
+ try:
+ record_plugin.record(self, r)
+ except:
+ print 'recordserver.record: plugin failed'
+ traceback.print_exc()
+ r.status = MISSED
+ return False
+
+
+ #
+ # load / save fxd file with recordings and favorites
+ #
+
def __load_recording(self, parser, node):
+ """
+ callback for <recording> in the fxd file
+ """
try:
r = Recording()
***************
*** 205,212 ****
self.rec_id = max(self.rec_id, r.id + 1)
except Exception, e:
! print 'server.load_recording:', e
def __load_favorite(self, parser, node):
try:
f = Favorite()
--- 340,350 ----
self.rec_id = max(self.rec_id, r.id + 1)
except Exception, e:
! print 'recordserver.load_recording:', e
def __load_favorite(self, parser, node):
+ """
+ callback for <favorite> in the fxd file
+ """
try:
f = Favorite()
***************
*** 215,222 ****
self.fav_id = max(self.fav_id, f.id + 1)
except Exception, e:
! print 'server.load_favorite:', e
! def load(self):
self.rec_id = 0
self.fav_id = 0
--- 353,363 ----
self.fav_id = max(self.fav_id, f.id + 1)
except Exception, e:
! print 'recordserver.load_favorite:', e
! def load(self, rebuild=False):
! """
! load the fxd file
! """
self.rec_id = 0
self.fav_id = 0
***************
*** 229,238 ****
fxd.parse()
except Exception, e:
! print 'FXDFile corrupt:', self.fxdfile
print e
self.check_favorites()
#
--- 370,397 ----
fxd.parse()
except Exception, e:
! print 'recordserver.load: %s corrupt:' % self.fxdfile
print e
+ if rebuild:
+ for r in self.recordings:
+ r.id = self.recordings.index(r)
+ for f in self.favorites:
+ f.id = self.favorites.index(f)
self.check_favorites()
+ def save(self):
+ """
+ save the fxd file
+ """
+ if os.path.isfile(self.fxdfile):
+ os.unlink(self.fxdfile)
+ fxd = util.fxdparser.FXD(self.fxdfile)
+ for r in self.recordings:
+ fxd.add(r)
+ for r in self.favorites:
+ fxd.add(r)
+ fxd.save()
+
#
***************
*** 241,244 ****
--- 400,407 ----
def __rpc_recording_list__(self, addr, val):
+ """
+ list the current recordins in a short form.
+ result: [ ( id channel priority start stop status ) (...) ]
+ """
self.parse_parameter(val, () )
ret = []
***************
*** 249,252 ****
--- 412,420 ----
def __rpc_recording_describe__(self, addr, val):
+ """
+ send a detailed description about a recording
+ parameter: id
+ result: ( id name channel priority start stop status padding info )
+ """
id = self.parse_parameter(val, ( int, ))
print 'recording.describe: %s' % id
***************
*** 258,268 ****
def __rpc_recording_add__(self, addr, val):
! name, channel, priority, start, stop, filename, info = \
self.parse_parameter(val, ( unicode, unicode, int, int, int,
! str, dict ) )
print 'recording.add: %s' % String(name)
r = Recording(self.rec_id, name, channel, priority, start, stop,
! filename, info)
if r in self.recordings:
return RPCError('Already scheduled')
self.recordings.append(r)
--- 426,447 ----
def __rpc_recording_add__(self, addr, val):
! """
! add a new recording
! parameter: name channel priority start stop optionals
! optionals: subtitle, url, padding, description
! """
! name, channel, priority, start, stop, info = \
self.parse_parameter(val, ( unicode, unicode, int, int, int,
! dict ) )
print 'recording.add: %s' % String(name)
r = Recording(self.rec_id, name, channel, priority, start, stop,
! info = info)
if r in self.recordings:
+ r = self.recordings[self.recordings.index(r)]
+ if r.status == DELETED:
+ r.status = 'scheduled'
+ r.favorite = False
+ self.check_recordings()
+ return RPCReturn(self.rec_id - 1)
return RPCError('Already scheduled')
self.recordings.append(r)
***************
*** 273,281 ****
def __rpc_recording_remove__(self, addr, val):
id = self.parse_parameter(val, ( int, ))
print 'recording.remove: %s' % id
for r in self.recordings:
if r.id == id:
! r.status = 'deleted'
self.check_recordings()
return RPCReturn()
--- 452,468 ----
def __rpc_recording_remove__(self, addr, val):
+ """
+ remove a recording
+ parameter: id
+ """
id = self.parse_parameter(val, ( int, ))
print 'recording.remove: %s' % id
for r in self.recordings:
if r.id == id:
! if r.status == RECORDING:
! r.status = SAVED
! r.recorder.stop()
! else:
! r.status = DELETED
self.check_recordings()
return RPCReturn()
***************
*** 284,291 ****
--- 471,484 ----
def __rpc_recording_modify__(self, addr, val):
+ """
+ modify a recording
+ parameter: id [ ( var val ) (...) ]
+ """
id, key_val = self.parse_parameter(val, ( int, dict ))
print 'recording.modify: %s' % id
for r in self.recordings:
if r.id == id:
+ if r.status == RECORDING:
+ return RPCError('Currently recording')
cp = copy.copy(self.recordings[id])
for key in key_val:
***************
*** 301,304 ****
--- 494,500 ----
def __rpc_favorite_update__(self, addr=None, val=[]):
+ """
+ updates favorites with data from the database
+ """
self.check_favorites()
return RPCReturn()
***************
*** 306,313 ****
def __rpc_favorite_add__(self, addr, val):
! name, channel, priority, day, time = \
! self.parse_parameter(val, ( unicode, list, int, list, list ))
print 'favorite.add: %s' % String(name)
! f = Favorite(self.fav_id, name, channel, priority, day, time)
if f in self.favorites:
return RPCError('Already scheduled')
--- 502,519 ----
def __rpc_favorite_add__(self, addr, val):
! """
! add a favorite
! parameter: name channels priority days times
! channels is a list of channels
! days is a list of days ( 0 = Sunday - 6 = Saturday )
! times is a list of hh:mm-hh:mm
! """
! print val
! name, channels, priority, days, times, once = \
! self.parse_parameter(val, ( unicode, list, int, list, list,
! bool ))
! print once
print 'favorite.add: %s' % String(name)
! f = Favorite(self.fav_id, name, channels, priority, days, times, once)
if f in self.favorites:
return RPCError('Already scheduled')
-------------------------------------------------------
This SF.Net email is sponsored by:
Sybase ASE Linux Express Edition - download now for FREE
LinuxWorld Reader's Choice Award Winner for best database on Linux.
http://ads.osdn.com/?ad_id=5588&alloc_id=12065&op=click
_______________________________________________
Freevo-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog