I'm kind of talking to myself (again); i've done some work on the duplicate
detection and it seems to be working fine. You can add a new favorite via
the OSD but I broke the ability to add from the WWW. If someone can take a
look at it, it would be greatly appreciated, since I can't seem to figure it
out. I had to add some attributes to the Favorite and TvProgram classes, so
it kind of breaks all old favorites.
Attached is what I have done up to this point.
On 12/31/06, Justin Wetherell <[EMAIL PROTECTED]> wrote:
I've redone my previous work using two sql statements instead of an
iteration; i've also implemented a removeDuplicate for use when a scheduled
recording is removed.
On 12/31/06, Justin Wetherell <[EMAIL PROTECTED]> wrote:
>
> I was torn between doing this (sudo code):
>
> query=('SELECT * FROM tv WHERE title = \'%s\'' % (prog.title))
> results=db.runQuery(query)
> for row in results:
> if row['title'] == prog.title and row['sub_title'] ==
> prog.sub_title:
> duplicateProgram=True
> if row['title'] == prog.title and row['desc'] == prog.desc:
> duplicateProgram=True
>
> or doing this:
>
> query1=('SELECT * FROM tv WHERE title = \'%s\' AND sub_title = \'%s\'' %
> (prog.title, prog.sub_title))
> results1=db.runQuery(query1)
> query2=('SELECT * FROM tv WHERE title = \'%s\' AND desc = \'%s\'' % (
> prog.title, prog.sub_title))
> results2=db.runQuery(query2)
> if results1 or results2:
> duplicateProgram=True
>
> I'm not sure if 2 sql statements are better than one sql statement and
> an iteration over a set. I'm guessing that the two sql statements would be
> better but that's just a hunch.
Index: local_conf.py.example
===================================================================
--- local_conf.py.example (revision 8883)
+++ local_conf.py.example (working copy)
@@ -1028,6 +1028,9 @@
# XXX the path doesn't work from the www cgi scripts!
# TV_RECORD_DIR = None
+# This will enable duplicate recording detection
+# DUPLICATE_DETECTION = True
+
#
# Watching TV
#
Index: src/www/htdocs/favorites.rpy
===================================================================
--- src/www/htdocs/favorites.rpy (revision 8883)
+++ src/www/htdocs/favorites.rpy (working copy)
@@ -64,15 +64,16 @@
dow = fv.formValue(form, 'dow')
mod = fv.formValue(form, 'mod')
priority = fv.formValue(form, 'priority')
+ allowDuplicates = False
if action == 'remove':
ri.removeFavorite(name)
elif action == 'add':
- ri.addEditedFavorite(name, title, chan, dow, mod, priority)
+ ri.addEditedFavorite(name, title, chan, dow, mod, priority,
allowDuplicates)
elif action == 'edit':
ri.removeFavorite(oldname)
- ri.addEditedFavorite(name, title, chan, dow, mod, priority)
+ ri.addEditedFavorite(name, title, chan, dow, mod, priority,
allowDuplicates)
elif action == 'bump':
ri.adjustPriority(name, priority)
else:
Index: src/helpers/recordserver.py
===================================================================
--- src/helpers/recordserver.py (revision 8883)
+++ src/helpers/recordserver.py (working copy)
@@ -27,10 +27,16 @@
# -----------------------------------------------------------------------
-import sys, string, random, time, os, re, pwd, stat, threading
+import sys, string, random, time, os, re, pwd, stat, threading, pickle
import config
from util import vfs
+##sql database util
+try:
+ from util.dbutil import *
+except ImportError:
+ pass
+
appname = os.path.splitext(os.path.basename(sys.argv[0]))[0]
appconf = appname.upper()
@@ -270,7 +276,74 @@
return TRUE
-
+ def removeDuplicate(self, prog=None):
+ # Geta sql object
+ db = MetaDatabase()
+ _debug_('Database is available')
+ if db.checkTable('tv'):
+ query=('SELECT * FROM tv WHERE title LIKE \'%s\' AND sub_title
LIKE \'%s\'' % \
+ (util.escape(prog.title), util.escape(prog.sub_title)))
+ _debug_('%s' % (query))
+ results=db.runQuery(query)
+ if results:
+ row=results[0]
+ query=('DELETE FROM tv WHERE id=\'%s\'' % (row['id']))
+ query=('SELECT * FROM tv WHERE title LIKE \'%s\' AND desc LIKE
\'%s\'' % \
+ (util.escape(prog.title), util.escape(prog.desc)))
+ _debug_('%s' % (query))
+ results=db.runQuery(query)
+ if results:
+ row=results[0]
+ query=('DELETE FROM tv WHERE id=\'%s\'' % (row['id']))
+ _debug_('%s' % (query))
+ db.runQuery(query)
+ db.close()
+
+ def duplicate(self, prog=None):
+
+ # Geta sql object
+ db = MetaDatabase()
+ _debug_('Database is available')
+
+ # Create initial table, if needed
+ dbschema = """CREATE TABLE tv (id INTEGER PRIMARY KEY, \
+ title VARCHAR(255), \
+ sub_title VARCHAR(255), \
+ desc VARCHAR(255), \
+ categories VARCHAR(255), \
+ ratings VARCHAR(255))"""
+ if not db.checkTable('tv'):
+ _debug_('Create TV table')
+ db.runQuery(dbschema)
+ _debug_('Databse is available and TV table exists')
+
+ # Check for duplicates
+ query1=('SELECT * FROM tv WHERE title LIKE \'%s\' AND sub_title LIKE
\'%s\'' % \
+ (util.escape(prog.title), util.escape(prog.sub_title)))
+ _debug_('%s' % (query1))
+ results1=db.runQuery(query1)
+ query2=('SELECT * FROM tv WHERE title LIKE \'%s\' AND desc LIKE \'%s\''
% \
+ (util.escape(prog.title), util.escape(prog.desc)))
+ _debug_('%s' % (query2))
+ results2=db.runQuery(query2)
+ if results1 or results2:
+ _debug_('Found Duplicate')
+ db.close()
+ return TRUE
+ else:
+ _debug_('Not Duplicate')
+ values = "(null,\'%s\',\'%s\',\'%s\',\'%s\',\'%s\')" % \
+ (util.escape(prog.title), \
+ util.escape(prog.sub_title), \
+ util.escape(prog.desc), \
+ util.escape(pickle.dumps(prog.categories)), \
+ util.escape(pickle.dumps(prog.ratings)))
+ sql = 'INSERT OR IGNORE INTO tv VALUES '+values
+ _debug_(sql)
+ db.runQuery(sql)
+ db.close()
+ return FALSE
+
def scheduleRecording(self, prog=None):
global guide
@@ -288,9 +361,23 @@
_debug_('scheduleRecording: "%s"' % (prog))
prog.tunerid = chan.tunerid
- scheduledRecordings = self.getScheduledRecordings()
- scheduledRecordings.addProgram(prog, tv_util.getKey(prog))
- self.saveScheduledRecordings(scheduledRecordings)
+ if config.DUPLICATE_DETECTION and not
self.doesFavoriteAllowDuplicates(prog):
+ _debug_('Duplicate Detection enabled')
+ _debug_('Title: "%s" AllowDups: "%s"' % \
+ (prog.title, self.doesFavoriteAllowDuplicates(prog)))
+ if not self.duplicate(prog):
+ scheduledRecordings = self.getScheduledRecordings()
+ scheduledRecordings.addProgram(prog,
tv_util.getKey(prog))
+ self.saveScheduledRecordings(scheduledRecordings)
+ else:
+ return (FALSE, 'duplicate recording')
+ else:
+ _debug_('Duplicate Detection is disabled or ')
+ _debug_('"%s" allows duplicates:"%s"' % \
+ (prog.title, self.doesFavoriteAllowDuplicates(prog)))
+ scheduledRecordings = self.getScheduledRecordings()
+ scheduledRecordings.addProgram(prog, tv_util.getKey(prog))
+ self.saveScheduledRecordings(scheduledRecordings)
# check, maybe we need to start right now
self.checkToRecord()
@@ -318,6 +405,8 @@
print 'prog.isRecording:', e
recording = FALSE
+ if config.DUPLICATE_DETECTION:
+ self.removeDuplicate(prog)
scheduledRecordings = self.getScheduledRecordings()
scheduledRecordings.removeProgram(prog, tv_util.getKey(prog))
self.saveScheduledRecordings(scheduledRecordings)
@@ -562,7 +651,7 @@
(status, favs) = self.getFavorites()
priority = len(favs) + 1
- fav = tv.record_types.Favorite(name, prog, exactchan, exactdow,
exacttod, priority)
+ fav = tv.record_types.Favorite(name, prog, exactchan, exactdow,
exacttod, priority, allowDuplicates)
scheduledRecordings = self.getScheduledRecordings()
scheduledRecordings.addFavorite(fav)
@@ -572,7 +661,7 @@
return (TRUE, 'favorite added')
- def addEditedFavorite(self, name, title, chan, dow, mod, priority):
+ def addEditedFavorite(self, name, title, chan, dow, mod, priority,
allowDuplicates):
fav = tv.record_types.Favorite()
fav.name = name
@@ -581,6 +670,7 @@
fav.dow = dow
fav.mod = mod
fav.priority = priority
+ fav.allowDuplicates = allowDuplicates
scheduledRecordings = self.getScheduledRecordings()
scheduledRecordings.addFavorite(fav)
@@ -688,6 +778,13 @@
# if we get this far prog is not a favorite
return (FALSE, 'not a favorite')
+ def doesFavoriteAllowDuplicates(self, prog, favs=None):
+ if not favs:
+ (status, favs) = self.getFavorites()
+ for fav in favs.values():
+ if Unicode(prog.title).lower().find(Unicode(fav.title).lower())
>= 0:
+ if fav.allowDuplicates == True:
+ return TRUE
def removeFavoriteFromSchedule(self, fav):
# TODO: make sure the program we remove is not
@@ -920,12 +1017,12 @@
return (status, message)
- def xmlrpc_addEditedFavorite(self, name, title, chan, dow, mod, priority):
+ def xmlrpc_addEditedFavorite(self, name, title, chan, dow, mod, priority,
allowDuplicates):
(status, message) = (FALSE, 'RecordServer::addEditedFavorite: cannot
acquire lock')
try:
self.lock.acquire()
(status, response) = self.addEditedFavorite(unjellyFromXML(name), \
- unjellyFromXML(title), chan, dow, mod, priority)
+ unjellyFromXML(title), chan, dow, mod, priority, allowDuplicates)
message = 'RecordServer::addEditedFavorite: %s' % response
finally:
self.lock.release()
Index: src/tv/program_display.py
===================================================================
--- src/tv/program_display.py (revision 8883)
+++ src/tv/program_display.py (working copy)
@@ -64,6 +64,8 @@
else:
self.scheduled = False
+ self.allowDuplicates = prog.allowDuplicates
+
self.overlap = prog.overlap
self.favorite = False
@@ -137,7 +139,7 @@
def add_favorite(self, arg=None, menuw=None):
- fav = Favorite(self.prog.title, self.prog, True, True, True, -1)
+ fav = Favorite(self.prog.title, self.prog, True, True, True, -1, False)
fav_item = FavoriteItem(self, fav, fav_action='add')
fav_item.display_favorite(menuw=menuw)
@@ -216,6 +218,7 @@
self.name = self.origname = fav.name
self.title = fav.title
self.fav_action = fav_action
+ self.allowDuplicates = fav.allowDuplicates
self.week_days = (_('Mon'), _('Tue'), _('Wed'), _('Thu'), _('Fri'),
_('Sat'), _('Sun'))
@@ -250,6 +253,7 @@
items.append(menu.MenuItem(_('Modify channel'),
action=self.mod_channel))
items.append(menu.MenuItem(_('Modify day of week'),
action=self.mod_day))
items.append(menu.MenuItem(_('Modify time of day'),
action=self.mod_time))
+ items.append(menu.MenuItem(_('Modify duplicate flag'),
action=self.mod_dup))
# XXX: priorities aren't quite supported yet
if 0:
@@ -281,7 +285,16 @@
self.menuw.refresh()
+ def mod_dup(self, arg=None, menuw=None):
+ items = []
+ items.append(menu.MenuItem('Allow Duplicates',
action=self.alter_prop,arg=('dup', 'True')))
+ items.append(menu.MenuItem('Deny Duplicates',
action=self.alter_prop,arg=('dup', 'False')))
+ favorite_menu = menu.Menu(_('Modify Duplicate Flag'), items,item_types
= 'tv favorite menu')
+ favorite_menu.infoitem = self
+ menuw.pushmenu(favorite_menu)
+ menuw.refresh()
+
def mod_channel(self, arg=None, menuw=None):
items = []
@@ -328,6 +341,14 @@
gmtime(float(val * 60)))
self.fav.mod = val
+ elif prop == 'dup':
+ if val == 'True':
+ self.allowDuplicates=TRUE
+ self.fav.allowDuplicates=TRUE
+ else:
+ self.allowDuplicates=FALSE
+ self.fav.allowDuplicates=FALSE
+
if menuw:
menuw.back_one_menu(arg='reload')
@@ -381,7 +402,8 @@
self.fav.channel,
self.fav.dow,
self.fav.mod,
- self.fav.priority)
+ self.fav.priority,
+
self.fav.allowDuplicates)
if not result:
AlertBox(text=_('Save Failed, favorite was lost')+(': %s' %
msg)).show()
else:
Index: src/tv/epg_types.py
===================================================================
--- src/tv/epg_types.py (revision 8883)
+++ src/tv/epg_types.py (working copy)
@@ -64,6 +64,8 @@
date = None
scheduled = None
overlap = None
+ previouslyRecorded = None
+ allowDuplicates = None
def __init__(self):
@@ -83,6 +85,8 @@
# to a boolean type.
self.scheduled = 0
self.overlap = 0
+ self.previouslyRecorded = 0
+ self.allowDuplicates = 0
def __str__(self):
Index: src/tv/record_types.py
===================================================================
--- src/tv/record_types.py (revision 8883)
+++ src/tv/record_types.py (working copy)
@@ -134,7 +134,7 @@
class Favorite:
def __init__(self, name=None, prog=None, exactchan=FALSE, exactdow=FALSE,
- exacttod=FALSE, priority=0):
+ exacttod=FALSE, priority=0, allowDuplicates=FALSE):
self.TYPES_VERSION = TYPES_VERSION
translation_table = \
' ' \
@@ -158,6 +158,7 @@
if name:
self.name = string.translate(name,translation_table)
self.priority = priority
+ self.allowDuplicates = allowDuplicates
if prog:
self.title = prog.title
Index: src/tv/record_client.py
===================================================================
--- src/tv/record_client.py (revision 8883)
+++ src/tv/record_client.py (working copy)
@@ -168,11 +168,11 @@
return (status, message)
-def addEditedFavorite(name, title, chan, dow, mod, priority):
+def addEditedFavorite(name, title, chan, dow, mod, priority, allowDuplicates):
try:
(status, message) = \
server.addEditedFavorite(jellyToXML(name), \
- jellyToXML(title), chan, dow, mod, priority)
+ jellyToXML(title), chan, dow, mod, priority, allowDuplicates)
except Exception, e:
print e
traceback.print_exc()
Index: src/tv/edit_favorite.py
===================================================================
--- src/tv/edit_favorite.py (revision 8883)
+++ src/tv/edit_favorite.py (working copy)
@@ -311,7 +311,8 @@
self.chan_box.list.get_selected_item().value,
self.dow_box.list.get_selected_item().value,
self.tod_box.list.get_selected_item().value,
- self.fav.priority)
+ self.fav.priority,
+ self.fav.allowDuplicates)
if result:
#tv.view_favorites.ViewFavorites(parent=self.parent,
text='Favorites').show()
self.destroy()
Index: freevo_config.py
===================================================================
--- freevo_config.py (revision 8883)
+++ freevo_config.py (working copy)
@@ -1459,6 +1459,9 @@
# XXX the path doesn't work from the www cgi scripts!
TV_RECORD_DIR = None
+# This will enable duplicate recording detection
+DUPLICATE_DETECTION = None
+
#
# Watching TV
#
-------------------------------------------------------------------------
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