Here is the first version of the tv/favorites plug-in. It took more
effort than I initially thought was necessary, and it is still not
finished. But with this version you can view your favorites and remove
them.
Stuff like changing the channels and days of a favorite will be
available in a next release...
I am aware of one problem. When you remove an favorite the removed
favorite is still in the list. I have applied the same mechanisme as in
removing scheduled recordings, but some how it doesn't work.
Maybe you can have a quick look, Dischi?
The changes:
* tvserver:
* favorite.py: I had a problem that a channel with a space
(' ') in the name was wrong read back from the
recordserver.fxd. When read back it returned 2 channels
iso. 1! So I replaced the space with a comma (',')
* server.py: Added an event, which report back when
favorites are changed/updated. Also added the favorite
remove function to be able to remove favorites from the
tvserver.
* core/ipc:
* tvserver.py: Added the favorite remove function.
Implemented receiving the 'changed favorites' event and
update the favorites accordingly. A few changes made to
the add favorite function.
* ui/tv:
* program.py: Changed the favorite menu item and the
favorite creation.
* favorite.py: More or less completely changed this.
* plugin/favorites.py: New plugin.
Jose
Index: favorite.py
===================================================================
--- favorite.py (revision 9398)
+++ favorite.py (working copy)
@@ -95,11 +95,11 @@
self.substring = True
if child.name == 'channels':
self.channels = []
- for v in child.content.split(' '):
+ for v in child.content.split(','):
self.channels.append(v)
if child.name == 'days':
self.days = []
- for v in child.content.split(' '):
+ for v in child.content.split(','):
self.days.append(int(v))
if child.name == 'times':
self.times = []
@@ -234,7 +234,7 @@
for var in ('channels', 'days'):
s = ''
for v in getattr(self, var):
- s += '%s ' % v
+ s += '%s,' % v
node.add_child(var, s[:-1])
s = ''
for v in self.times:
Index: server.py
===================================================================
--- server.py (revision 9398)
+++ server.py (working copy)
@@ -546,6 +546,9 @@
updates favorites with data from the database
"""
self.epg_update()
+ # send update to all clients
+ log.info('send update for %s favorites', len(self.favorites))
+ self.send_event('home-theatre.favorites.list.update', self.rpc_favorite_list(True) )
return []
@@ -567,6 +570,27 @@
return []
+ @freevo.ipc.expose('home-theatre.favorite.remove')
+ def rpc_favorite_remove(self, fav):
+ """
+ remove a favorite
+ parameter: id of the favorite
+ """
+
+ for f in self.favorites:
+ if fav == f.id:
+ fav = f
+ break
+
+ if not fav in self.favorites:
+ return NameError('Favorite not found!')
+
+ log.info('favorite.remove: %s', fav)
+ self.favorites.remove(fav)
+ self.rpc_favorite_update()
+ return []
+
+
@freevo.ipc.expose('home-theatre.favorite.list', add_source=True)
def rpc_favorite_list(self, source):
"""
Index: tvserver.py
===================================================================
--- tvserver.py (revision 9398)
+++ tvserver.py (working copy)
@@ -288,7 +288,7 @@
"""
A favorite object from the recordserver.
"""
- def __init__(self, id, title, channels, priority, day, time, one_shot,
+ def __init__(self, id, title, channels, priority, days, time, one_shot,
substring):
"""
The init function creates the object. The parameters are the complete
@@ -298,7 +298,7 @@
self.title = title
self.channels = channels
self.priority = priority
- self.day = day
+ self.days = days
self.time = time
self.one_shot = one_shot
self.substring = substring
@@ -311,6 +311,9 @@
Handling of favorites from the recordserver. The object will auto sync with
the recordserver to keep the list up to date.
"""
+
+ SUCCESS = 'SUCCESS'
+
def __init__(self, instance):
self.last_update = time.time()
self._favorites = []
@@ -318,6 +321,7 @@
instance.signals['new-entity'].connect(self.new_entity)
instance.signals['lost-entity'].connect(self.lost_entity)
+ instance.events['home-theatre.favorites.list.update'].connect(self.list_update_cb)
@kaa.notifier.yield_execution()
@@ -325,6 +329,7 @@
if not entity.matches(SERVER):
return
self.server = entity
+ self.server.register('home-theatre.favorites.list.update')
self.rpc = self.server.rpc
wait = self.rpc('home-theatre.favorite.list')
yield wait
@@ -347,31 +352,71 @@
return True
+ @kaa.notifier.yield_execution()
+ def list_update_cb(self, result):
+ log.info('got updated favorites list event')
+ wait = self.rpc('home-theatre.favorite.list')
+ yield wait
+ result = wait()
+ if not self.server:
+ return
+ if not result:
+ log.error(result)
+ return
+ self.last_update = time.time()
+ self._favorites = []
+ for l in result:
+ self._favorites.append(Favorite(*l))
+ log.info('got updated favorite list')
+
+
def add(self, prog):
+ """
+ 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
+ """
if not self.server:
- return False, 'Recordserver unavailable'
+ return _('tvserver unavailable')
- if prog.channel == 'ANY':
+ if prog.channels == 'ANY':
# FIXME: crash!!!!!!
channel = []
for c in kaa.epg.channels:
channel.append(c.id)
else:
- channel = [ prog.channel.id ]
- days = (_('Mon'), _('Tue'), _('Wed'), _('Thu'), _('Fri'),
- _('Sat'), _('Sun'))
- if prog.days in days:
- days = [ days.index(prog.dow) ]
+ channel = [ kaa.epg.get_channel(prog.channels[0]).id ]
+
+ if prog.days == 'ANY':
+ days = [ 0, 1, 2, 3, 4, 5, 6 ]
else:
- days = [ 0, 1, 2, 3, 4, 5, 6 ]
+ days = prog.days
self.rpc('home-theatre.favorite.add', prog.title, channel, 50, days,
[ '00:00-23:59' ], False)
+
+ # FIXME: get real error message from tvserver
+ return self.SUCCESS
- # FIXME: make it possible to return a failure
- return True, 'Scheduled'
+ @kaa.notifier.yield_execution()
+ def remove(self, id):
+ """
+ remove a favorite
+ parameter: id of the favorite
+ """
+ if not self.server:
+ yield _('tvserver unavailable')
+ result = self.rpc('home-theatre.favorite.remove', id)
+ yield result
+ if not result():
+ # FIXME: get real error message from tvserver
+ yield 'failed'
+ yield self.SUCCESS
+
def list(self):
"""
"""
Index: favorite.py
===================================================================
--- favorite.py (revision 9398)
+++ favorite.py (working copy)
@@ -31,29 +31,61 @@
#
# -----------------------------------------------------------------------------
+# python imports
+import time
+
+# kaa imports
+import kaa.epg
+from kaa.strutils import unicode_to_str
+
+# freevo ui imports
+from freevo.ui.config import config
+
# freevo core imports
import freevo.ipc
# freevo imports
-from freevo.ui.menu import Item, Action, Menu
+from freevo.ui.gui.windows.inputbox import InputBox
+from freevo.ui.menu import Item, Action, ActionItem, Menu
from freevo.ui.application import MessageWindow
# get tvserver interface
tvserver = freevo.ipc.Instance('freevo').tvserver
+DAY_NAMES = (_('Sun'), _('Mon'), _('Tue'), _('Wed'), _('Thu'), _('Fri'), _('Sat'))
+
class FavoriteItem(Item):
"""
A favorite item to add/delete/change a favorite for the recordserver.
"""
- def __init__(self, name, start, parent):
+
+ def __init__(self, parent, fav):
Item.__init__(self, parent)
- self.name = self.title = name
- self.start = start
- # FIXME: create correct informations here
- self.channel = 'ANY'
- self.days = 'ANY'
- self.time = 'ANY'
+ self.new = True
+ self.id = 0
+ if isinstance(fav, kaa.epg.Program):
+ # Convert to 0=Sunday - 6=Saterday
+ day = time.localtime(fav.start)[6]+1
+ if day > 6:
+ day = 6
+ self.days = [ day ]
+ self.name = self.title = fav.title
+ self.channels = [fav.channel.name]
+ #check if already a favorite
+ list = tvserver.favorites.list()
+ for f in list:
+ if fav.title == f.title:
+ if fav.channel.name in f.channels:
+ if day in f.days:
+ self.new = False
+ self.id = f.id
+ else:
+ self.name = self.title = fav.title
+ self.days = fav.days
+ self.channels = fav.channels
+ self.new = False
+ self.id = fav.id
def __getitem__(self, key):
@@ -61,11 +93,17 @@
return the specific attribute as string or an empty string
"""
if key == 'date':
- return self.days
+ if self.days == 'ANY':
+ return 'ANY'
+ else:
+ days = ', '.join(['%s' % DAY_NAMES[d] for d in self.days])
+ return days
if key == 'channel':
- if self.channel == 'ANY':
- return self.channel
- return self.channel.name
+ if self.channels == 'ANY':
+ return 'ANY'
+ else:
+ channels = ', '.join(['%s' % chan for chan in self.channels])
+ return channels
return Item.__getitem__(self, key)
@@ -73,7 +111,7 @@
"""
return a list of possible actions on this item.
"""
- return [ Action(_('Add as favorite'), self.add) ]
+ return [ Action(_('Show favorite menu'), self.submenu) ]
def submenu(self):
@@ -81,15 +119,50 @@
show a submenu for this item
"""
items = []
- for action in self.actions():
- items.append(Item(self, action))
+
+ if self.new==True:
+ items.append(ActionItem(_('Add favorite'), self, self.add))
+ else:
+ items.append(ActionItem(_('Remove favorite'), self, self.remove))
+ items.append(ActionItem(_('Change Day'), self, self.change_day))
+ items.append(ActionItem(_('Change Channel'), self, self.change_day))
+
s = Menu(self, items, type = 'tv favorite menu')
s.submenu = True
s.infoitem = self
self.pushmenu(s)
+ def add(self):
+ result = tvserver.favorites.add(self)
+ if result != tvserver.favorites.SUCCESS:
+ text = _('Adding favorite Failed')+(': %s' % result)
+ else:
+ text = _('"%s" has been scheduled as favorite') % self.title
+ MessageWindow(text).show()
+ self.get_menustack().delete_submenu()
- def add(self):
- tvserver.favorites.add(self)
- txt = _('"%s" has been scheduled as favorite') % self.title
- MessageWindow(txt).show()
+ @kaa.notifier.yield_execution()
+ def remove(self):
+ result = tvserver.favorites.remove(self.id)
+ if isinstance(result, kaa.notifier.InProgress):
+ yield result
+ result = result()
+ if result != tvserver.favorites.SUCCESS:
+ text = _('Remove favorite Failed')+(': %s' % result)
+ MessageWindow(text).show()
+ self.get_menustack().delete_submenu()
+
+ def change_day(self):
+ #(result, msg) = tvserver.favorites.remove(?)
+ input = InputBox(text='test', handler=self.handle_day)
+ #MessageWindow(_('Change day not implemented')).show()
+ #self.get_menustack().delete_submenu()
+
+ def handle_day(self, day):
+ print 'handle: ', day
+ self.get_menustack().delete_submenu()
+
+ def change_channel(self):
+ #(result, msg) = tvserver.favorites.remove(?)
+ MessageWindow(_('Change channel not implemented')).show()
+ self.get_menustack().delete_submenu()
Index: program.py
===================================================================
--- program.py (revision 9398)
+++ program.py (working copy)
@@ -170,7 +170,7 @@
txt = _('Search for programs with a similar name')
items.append(ActionItem(txt, self, self.search_similar))
- items.append(ActionItem(_('Add to favorites'), self,
+ items.append(ActionItem(_('Favorite...'), self,
self.create_favorite))
s = Menu(self, items, type = 'tv program menu')
@@ -236,7 +236,7 @@
def create_favorite(self):
- fav = favorite.FavoriteItem(self.name, self.start, self)
+ fav = favorite.FavoriteItem(self, self.program)
fav.submenu()
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------
# favorites.py - A plugin to view your list of favorites.
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002-2005 Krister Lagerstrom, Dirk Meyer, et al.
# Please see the file doc/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 freevo.ui.menu import Item, Menu, ActionItem
from freevo.ui.mainmenu import MainMenuPlugin
from freevo.ui.tv.favorite import FavoriteItem
from freevo.ui.application import MessageWindow
# freevo core imports
import freevo.ipc
# get tvserver interface
tvserver = freevo.ipc.Instance('freevo').tvserver
class PluginInterface(MainMenuPlugin):
"""
This plugin is used to display your list of favorites.
"""
def favorites(self, parent):
"""
Show all favorites.
"""
self.parent = parent
items = self.get_items()
if items:
self.menu = Menu(_('View Favorites'), items, type='tv favorite menu',
reload_func = self.reload_favorites)
parent.pushmenu(self.menu)
else:
MessageWindow(_("You don't have any favorites.")).show()
def reload_favorites(self):
items = self.get_items()
if items:
self.menu.set_items(items)
else:
self.parent.get_menustack().back_one_menu()
def get_items(self):
items = []
fav = tvserver.favorites.list()
for f in fav:
items.append(FavoriteItem(self.parent, f))
return items
def items(self, parent):
"""
Return the main menu item.
"""
return [ ActionItem(_('View Favorites'), parent, self.favorites) ]
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Freevo-devel mailing list
Freevo-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freevo-devel