class DictData(OrdDict): """ DictData.__init__(raw) --> DictData object Modified OrdDict, with a pre-defined item order. Allows processing of raw input data. """ _field_order = None _field_type = None _trans = [ int, locale.atof, bool, lambda x: x, lambda x: datetime.fromtimestamp(x, datetime.UTCTZ())\ .astimezone(datetime.localTZ()), lambda x: date(*[int(y) for y in x.split('-')]), lambda x: datetime.fromRfc(x, datetime.UTCTZ())\ .astimezone(datetime.localTZ())] _inv_trans = [ str, lambda x: locale.format("%0.6f", x), lambda x: str(int(x)), lambda x: x, lambda x: str(int(x.timestamp())), lambda x: x.isoformat(), lambda x: x.utcrfcformat() ] def __setattr__(self, name, value): if name in self._localvars: self.__dict__[name] = value elif name not in self._field_order: object.__setattr__(self, name, value) else: try: self[name] = value except KeyError: raise AttributeError(str(name)) def __setitem__(self, key, value): if key not in self._field_order: raise KeyError(str(key)) if self._field_type != 'Pass': ind = self._field_order.index(key) if self._field_type[ind] in (4, 6): value = datetime.duck(value) dict.__setitem__(self, key, value) def __delattr__(self, name): if name in self.__dict__: del self.__dict__[name] else: raise AttributeError(str(name)) def __delitem__(self, name): raise NotImplementedError def __init__(self, data, _process=True): dict.__init__(self) if _process: data = self._process(data) dict.update(self, data) def _process(self, data): """ Accepts a list of data, processes according to specified types, and returns a dictionary """ if self._field_type != 'Pass': if len(data) != len(self._field_type): raise MythError('Incorrect raw input length to DictData()') data = list(data) for i, v in enumerate(data): if v == '': data[i] = None else: data[i] = self._trans[self._field_type[i]](v) return dict(zip(self._field_order, data)) def _deprocess(self): """ Returns the internal data back out in the format of the original raw list. """ data = self.values() if self._field_type != 'Pass': for i, v in enumerate(data): if v is None: data[i] = '' else: data[i] = self._inv_trans[self._field_type[i]](v) return data def _fillNone(self): """Fills out dictionary fields with empty data.""" field_order = self._field_order dict.update(self, zip(field_order, [None] * len(field_order))) def copy(self): """Returns a deep copy of itself.""" return self.__class__(zip(self.iteritems()), _process=False) def __getstate__(self): return dict(self) def __setstate__(self, state): for k, v in state.iteritems(): self[k] = v
""" from MythTV.static import * from MythTV.exceptions import * from MythTV.altdict import DictData, DictInvertCI from MythTV.database import * from MythTV.system import Grabber, InternetMetadata, VideoMetadata from MythTV.mythproto import ftopen, FileOps, Program from MythTV.utility import CMPRecord, CMPVideo, MARKUPLIST, datetime, ParseSet import re import locale import xml.etree.cElementTree as etree from datetime import date, time _default_datetime = datetime(1900,1,1, tzinfo=datetime.UTCTZ()) from UserString import MutableString class Artwork( MutableString ): _types = {'coverart': 'Coverart', 'coverfile': 'Coverart', 'fanart': 'Fanart', 'banner': 'Banners', 'screenshot': 'ScreenShots', 'trailer': 'Trailers'} @property def data(self): try: val = self.parent[self.attr] except: