Skip to content
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)

0 comments on commit de679e4

Please sign in to comment.
You can’t perform that action at this time.