Permalink
Browse files

Reworks internal structure for databaseSearch decorator. Adds ParseEn…

…um and ParseSet classes for handling such data over protocol and database, respectively.

git-svn-id: http://svn.mythtv.org/svn/trunk@26888 7dbf422c-18fa-0310-86e9-fd20926502f2
  • Loading branch information...
wagnerrp committed Oct 19, 2010
1 parent 21c7ea0 commit de679e435c1a451a5c9688769c89fc77154d78a9
@@ -10,7 +10,7 @@
from altdict import OrdDict, DictData
from logging import MythLog
from msearch import MSearch
from utility import datetime
from utility import datetime, _donothing
from exceptions import MythError, MythDBError
from connections import DBConnection, LoggedCursor, XMLConnection
@@ -68,18 +68,24 @@ def _setClassDefs(cls, db=None):
db = DBCache(db)
log = MythLog('DBData Setup (%s)' % cls.__name__)
if cls._table is None:
# pull table name from class name
cls._table = cls.__name__.lower()
log(log.DATABASE|log.EXTRA,
'set _table to %s' % cls._table)
if cls._logmodule is None:
# pull log module from class name
cls._logmodule = 'Python %s' % cls.__name__
log(log.DATABASE|log.EXTRA,
'set _logmodule to %s' % cls._logmodule)
if cls._field_order == []:
# pull field order from database
cls._field_order = db.tablefields[cls._table]
if (cls._setwheredat is None) or (cls._where is None):
if cls._key is None:
# pull primary key fields from database
with db.cursor(log) as cursor:
cursor.execute("""SHOW KEYS FROM %s
WHERE Key_name='PRIMARY'""" \
@@ -96,6 +102,9 @@ def _setClassDefs(cls, db=None):
log(log.DATABASE|log.EXTRA,
'set _setwheredat to %s' % cls._setwheredat)
# class has been processed, turn method into no-op
cls._setClassDefs = classmethod(_donothing)
@classmethod
def getAllEntries(cls, db=None):
"""cls.getAllEntries() -> tuple of DBData objects"""
@@ -458,18 +467,24 @@ def __and__(self, other):
data.append(dat)
return self.fromCopy(data)
@classmethod
def _setClassDefs(cls, db=None):
db = DBCache(db)
fields = list(db.tablefields[cls._table])
for f in cls._ref:
if f in fields:
fields.remove(f)
cls._datfields = fields
cls._setClassDefs = classmethod(_donothing)
def __init__(self, where, db=None, bypass=False):
list.__init__(self)
if bypass: return
self._db = DBCache(db)
self._refdat = where
self._setClassDefs(self._db)
if bypass: return
fields = list(self._db.tablefields[self._table])
for f in self._ref:
if f in fields:
fields.remove(f)
self._datfields = fields
self._data = None
self._refdat = where
self._populated = False
def _populate(self, force=False, data=None):
@@ -582,7 +597,7 @@ def _picklelist(self):
class DBDataCRef( DBDataRef ):
"""
DBDataRef.__init__(where, db=None) --> DBDataRef object
DBDataCRef.__init__(where, db=None) --> DBDataRef object
Class for managing lists of referenced data, such as recordedmarkup
Subclasses must provide:
@@ -597,23 +612,31 @@ class DBDataCRef( DBDataRef ):
class SubData( DBDataRef.SubData ):
_localvars = DBDataRef.SubData._localvars+['_cref']
def __init__(self, where, db=None, bypass=False):
list.__init__(self)
if bypass: return
self._db = DBCache(db)
self._refdat = list(where)
@classmethod
def _setClassDefs(cls, db=None):
db = DBCache(db)
rfields = list(db.tablefields[cls._table[0]])
crfields = list(db.tablefields[cls._table[1]])
rfields = list(self._db.tablefields[self._table[0]])
crfields = list(self._db.tablefields[self._table[1]])
for f in self._ref+self._cref[:1]:
for f in cls._ref+[cls._cref[-1]]:
if f in rfields:
rfields.remove(f)
if self._cref[-1] in crfields:
crfields.remove(self._cref[-1])
if cls._cref[-1] in crfields:
crfields.remove(cls._cref[-1])
self._rdatfields = rfields
self._crdatfields = crfields
self._datfields = crfields+rfields
cls._rdatfields = rfields
cls._crdatfields = crfields
cls._datfields = crfields+rfields
cls._setClassDefs = classmethod(_donothing)
def __init__(self, where, db=None, bypass=False):
list.__init__(self)
self._db = DBCache(db)
self._setClassDefs(self._db)
if bypass: return
self._refdat = list(where)
self._populated = False
def _populate(self, force=False, data=None):
@@ -12,7 +12,7 @@
from database import *
from system import Grabber, InternetMetadata, VideoMetadata
from mythproto import ftopen, FileOps, Program
from utility import CMPRecord, CMPVideo, MARKUPLIST, datetime
from utility import CMPRecord, CMPVideo, MARKUPLIST, datetime, ParseSet
import re
import locale
@@ -198,6 +198,10 @@ def _postinit(self):
def fromProgram(cls, program):
return cls((program.chanid, program.recstartts), program._db)
@classmethod
def fromJob(cls, job):
return cls((job.chanid, job.starttime), job._db)
def _push(self):
DBDataWrite._push(self)
self.cast.commit()
@@ -309,7 +313,6 @@ def _allow_change(self, tag, overwrite):
be.downloadTo(image.url, group, image.filename)
exists[image.type] = True
self.update()
def __getstate__(self):
@@ -366,6 +369,11 @@ def __init__(self, data=None, db=None):
data = [data[0], datetime.duck(data[1])]
DBDataWrite.__init__(self, data, db)
def _postinit(self):
self.AudioProp = ParseSet(self, 'audioprop')
self.VideoProp = ParseSet(self, 'videoprop')
self.SubtitleTypes = ParseSet(self, 'subtitletypes')
@classmethod
def fromRecorded(cls, recorded):
return cls((recorded.chanid, recorded.progstart), recorded._db)
@@ -485,7 +493,12 @@ def getRecStatus(self):
(prog.starttime == self.starttime):
return prog.recstatus
return 0
def _postinit(self):
self.AudioProp = ParseSet(self, 'audioprop', False)
self.VideoProp = ParseSet(self, 'videoprop', False)
self.SubtitleTypes = ParseSet(self, 'subtitletypes', False)
@classmethod
def fromEtree(cls, etree, db=None):
dat = {'chanid':etree[0]}
@@ -606,12 +606,19 @@ def searchRecorded(self, init=False, key=None, value=None):
if init:
# table and join descriptor
return ('recorded', Recorded, ('livetv',),
('recordedprogram','recorded',('chanid','starttime')), #1
('recordedcredits','recorded',
('chanid','starttime'),
('chanid','progstart')), #2
('people','recordedcredits',('person',))) #4
init.table = 'recorded'
init.handler = Recorded
init.required = ('livetv,')
init.joins = (init.Join(table='recordedprogram',
tableto='recorded',
fields=('chanid','starttime')),
init.Join(table='recordedcredits',
tableto='recorded',
fieldsfrom=('chanid','starttime'),
fieldsto=('chanid','progstart')),
init.Join(table='people',
tableto='recordedcredits',
fields=('person',)))
# local table matches
if key in ('title','subtitle','chanid',
@@ -658,7 +665,9 @@ def searchOldRecorded(self, init=False, key=None, value=None):
"""
if init:
return ('oldrecorded', OldRecorded, ())
init.table = 'recorded'
init.handler = Recorded
if key in ('title','subtitle','chanid',
'category','seriesid','programid','station',
'duplicate','generic','recstatus'):
@@ -678,8 +687,12 @@ def searchJobs(self, init=False, key=None, value=None):
title, subtitle, flags, olderthan, newerthan
"""
if init:
return ('jobqueue', Job, (),
('recorded','jobqueue',('chanid','starttime')))
init.table = 'jobqueue'
init.handler = Job
init.joins = (init.Join(table='recorded',
tableto='jobqueue',
fields=('chanid','starttime')),)
if key in ('chanid','type','status','hostname'):
return ('jobqueue.%s=%%s' % key, value, 0)
if key in ('title','subtitle'):
@@ -710,9 +723,15 @@ def searchGuide(self, init=False, key=None, value=None):
endbefore, endafter
"""
if init:
return ('program', Guide, (),
('credits','program',('chanid','starttime')),
('people','credits',('person',)))
init.table = 'program'
init.handler = Guide
init.joins = (init.Join(table='credits',
tableto='program',
fields=('chanid','starttime')),
init.Join(table='people',
tableto='credits',
fields=('person',)))
if key in ('chanid','title','subtitle',
'category','airdate','stars','previouslyshown','stereo',
'subtitled','hdtv','closecaptioned','partnumber',
@@ -754,7 +773,9 @@ def searchRecord(self, init=False, key=None, value=None):
recgroup, station, seriesid, programid, playgroup
"""
if init:
return ('record', Record, ())
init.table = 'record'
init.handler = Record
if key in ('type','chanid','starttime','startdate','endtime','enddate',
'title','subtitle','category','profile','recgroup',
'station','seriesid','programid','playgroup'):
@@ -774,7 +795,9 @@ def searchInternetContent(self, init=False, key=None, value=None):
country, description
"""
if init:
return ('internetcontentarticles', InternetContentArticles, ())
init.table = 'internetcontentarticles'
init.handler = InternetContentArticles
if key in ('feedtitle','title','subtitle','season','episode','url',
'type','author','rating','player','width','height',
'language','podcast','downloadable', 'description'):
@@ -1070,21 +1093,37 @@ def searchVideos(self, init=False, key=None, value=None):
"""
if init:
return ('videometadata', Video, (),
('videometadatacast','videometadata',
('idvideo',),('intid',)), #1
('videocast','videometadatacast',
('intid',),('idcast',)), #2
('videometadatagenre','videometadata',
('idvideo',),('intid',)), #4
('videogenre','videometadatagenre',
('intid',),('idgenre',)), #8
('videometadatacountry','videometadata',
('idvideo',),('intid',)), #16
('videocountry','videometadatacountry',
('intid',),('idcountry',)), #32
('videocategory','videometadata',
('intid',),('category',))) #64
init.table = 'videometadata'
init.handler = Video
init.joins = (init.Join(table='videometadatacast',
tableto='videometadata',
fieldsfrom=('idvideo',),
fieldsto=('intid',)),
init.Join(table='videocast',
tableto='videometadatacast',
fieldsfrom=('intid',),
fieldsto=('idcast',)),
init.Join(table='videometadatagenre',
tableto='videometadata',
fieldsfrom=('idvideo',),
fieldsto=('intid',)),
init.Join(table='videogenre',
tableto='videometadatagenre',
fieldsfrom=('intid',),
fieldsto=('idgenre',)),
init.Join(table='videometadatacountry',
tableto='videometadata',
fieldsfrom=('idvideo',),
fieldsto=('intid',)),
init.Join(table='videocountry',
tableto='videometadatacountry',
fieldsfrom=('intid',),
fieldsto=('idcountry',)),
init.Join(table='videocategory',
tableto='videometadata',
fieldsfrom=('intid',),
fieldsto=('category',)))
if key in ('title','subtitle','season','episode','host',
'director','year'):
return('videometadata.%s=%%s' % key, value, 0)
@@ -1106,14 +1145,6 @@ def searchVideos(self, init=False, key=None, value=None):
return ('videometadata.insertdate>%s', value, 0)
return None
def getVideo(self, **kwargs):
"""legacy - do not use"""
videos = self.searchVideos(**kwargs)
try:
return videos.next()
except StopIteration:
return None
class MythMusic( MusicSchema, DBCache ):
"""
Provides convenient methods to access the MythTV MythMusic database.
@@ -1128,10 +1159,18 @@ def searchMusic(self, init=False, key=None, value=None):
genre, rating, format, sample_rate, bitrate
"""
if init:
return ('music_songs', Song, (),
('music_artists','music_songs',('artist_id',)), #1
('music_albums', 'music_songs',('album_id',)), #2
('music_genres', 'music_songs',('genre_id',))) #4
init.table = 'music_songs'
init.handler = Song
init.joins = (init.Join(table='music_artists',
tableto='music_songs',
fields=('artist_id',)),
init.Join(table='music_albums',
tableto='music_songs',
fields=('album_id',)),
init.Join(table='music_genres',
tableto='music_songs',
fields=('genre_id',)))
if key in ('name','track','disc_number','rating',
'format','sample_rate','bitrate'):
return ('music_songs.%s=%%s' % key, value, 0)
Oops, something went wrong.

0 comments on commit de679e4

Please sign in to comment.