def addSongs(self, base, file, sub=None): path = util.pathJoin(base, file) if util.isDir(path): paths = util.vfs.listdir(path) sub = sub and (sub + ':' + file) or file for p in paths: self.addSongs(path, p, sub) return name, ext = os.path.splitext(file) if ext.lower() in util.musicExtensions: if sub: name = sub + ':' + name try: DB.Song.get(DB.Song.path == path) self.owner.log('Loading Song (exists): [ {0} ]'.format(util.strRepr(name))) except DB.peewee.DoesNotExist: data = None try: data = mutagen.File(path) except: util.ERROR() if data: duration = data.info.length self.owner.log('Loading Song (new): [ {0} ({1}) ]'.format(util.strRepr(name), data.info.pprint())) else: duration = 0 DB.Song.create( path=path, name=name, duration=duration )
def getSlide(self, path, c, pack=''): name, ext = os.path.splitext(c) duration = 0 path = util.pathJoin(path, c) try: DB.Trivia.get(DB.Trivia.answerPath == path) self._callback('Loading Trivia (exists): [ {0} ]'.format(util.strRepr(name))) except DB.peewee.DoesNotExist: if ext.lower() in util.videoExtensions: ttype = 'video' parser = hachoir.hachoir_parser.createParser(path) metadata = hachoir.hachoir_metadata.extractMetadata(parser) durationDT = None if metadata: durationDT = metadata.get('duration') duration = durationDT and util.datetimeTotalSeconds(durationDT) or 0 self._callback('Loading Trivia (video): [ {0} ({1}) ]'.format(util.strRepr(name), durationDT)) elif ext.lower() in util.imageExtensions: ttype = 'fact' self._callback('Loading Trivia (single): [ {0} ]'.format(util.strRepr(name))) else: return DB.Trivia.get_or_create( answerPath=path, defaults={ 'type': ttype, 'TID': u'{0}:{1}'.format(pack, name), 'name': name, 'duration': duration } )
def cleanBumpers(self): cleaned = False for bumper, name in ((DB.AudioFormatBumpers, 'AudioFormatBumper'), (DB.VideoBumpers, 'VideoBumper'), (DB.RatingsBumpers, 'RatingBumper')): self.log('Cleaning: {0}'.format(name)) for b in bumper.select(): path = b.path if not path.startswith(self._contentDirectory) or not util.vfs.exists(path): cleaned = True b.delete_instance() self.log('{0} Missing: {1} - REMOVED'.format(util.strRepr(name), util.strRepr(path))) return cleaned
def __repr__(self): return ( 'FEATURE [ {0} ]:\n Path: {1}\n Rating: {2}\n Year: {3}\n Studios: {4}\n ' + 'Directors: {5}\n Cast: {6}\n Genres: {7}\n Tags: {8}\n 3D: {9}\n Audio: {10}' ).format(util.strRepr(self.title), util.strRepr(self.path), util.strRepr(self.rating), util.strRepr(self.year), ', '.join([util.strRepr(s) for s in self.studios]), ', '.join([util.strRepr(d) for d in self.directors]), ', '.join([util.strRepr(c['name']) for c in self.cast]), ', '.join([util.strRepr(g) for g in self.genres]), ', '.join([util.strRepr(t) for t in self.tags]), self.is3D and 'Yes' or 'No', util.strRepr(self.audioFormat))
def clean(self): self.logHeading('CLEANING DATABASE') cleaned = self.musicHandler.clean() cleaned = cleaned or self.triviaDirectoryHandler.clean() for bumper, name in ((DB.AudioFormatBumpers, 'AudioFormatBumper'), (DB.VideoBumpers, 'VideoBumper'), (DB.RatingsBumpers, 'RatingBumper')): for b in bumper.select(): path = b.path if not util.vfs.exists(path): cleaned = True b.delete_instance() self.log('{0} Missing: {1} - REMOVED'.format(util.strRepr(name), util.strRepr(path))) if not cleaned: self.log('Database clean - unchanged')
def _addDirectory(self, current, tree): if not util.vfs.exists(current): util.DEBUG_LOG('Creating: {0}'.format(util.strRepr(current))) util.vfs.mkdirs(current) for branch in tree: if isinstance(branch, tuple): new = util.pathJoin(current, branch[0]) self._addDirectory(new, branch[1]) else: sub = util.pathJoin(current, branch) if util.vfs.exists(sub): continue util.DEBUG_LOG('Creating: {0}'.format(util.strRepr(sub))) util.vfs.mkdirs(sub)
def createBumpers(self, basePath, model, type_name, sub_name, pct_start, sub_default=''): paths = util.vfs.listdir(basePath) total = float(len(paths)) for ct, sub in enumerate(paths): pct = pct_start + int((ct / total) * 20) if not self._callback(pct=pct): break path = util.pathJoin(basePath, sub) if not util.isDir(path): continue if sub.startswith('_Exclude'): util.DEBUG_LOG('SKIPPING EXCLUDED DIR: {0}'.format( util.strRepr(sub))) continue if util.vfs.exists(util.pathJoin(path, 'system.xml')): # For ratings self.loadRatingSystem(util.pathJoin(path, 'system.xml')) type_ = sub.replace(' Bumpers', '') self.addBumper(model, sub, path, type_name, sub_name, type_, sub_default)
def _getConditionValueString(itype, val): try: if itype == 'year': if len(val) > 1: return u'{0} - {1}'.format(val[0], val[1] if val[1] else 'Now') else: return u'{0}'.format(val[0]) elif itype == 'ratings': if len(val) > 1: return u'{0} - {1}'.format(val[0] if val[0] else 'Any', val[1] if val[1] else 'Any') else: return u'{0}'.format(val[0]) elif itype == 'dates': if len(val) > 1: return u'{0} {1} - {2} {3}'.format( calendar.month_abbr[val[0][0]], val[0][1], calendar.month_abbr[val[1][0]], val[1][1]) else: return u'{0} {1}'.format(calendar.month_abbr[val[0][0]], val[0][1]) elif itype == 'times': if len(val) > 1: return u'{0:02d}:{1:02d} - {2:02d}:{3:02d}'.format( val[0][0], val[0][1], val[1][0], val[1][1]) else: return u'{0:02d}'.format(val[0][0]) except Exception: util.ERROR() return util.strRepr(val)
def clean(self): self.logHeading('CLEANING DATABASE') cleaned = self.musicHandler.clean() cleaned = cleaned or self.triviaDirectoryHandler.clean() for bumper, name in ((DB.AudioFormatBumpers, 'AudioFormatBumper'), (DB.VideoBumpers, 'VideoBumper'), (DB.RatingsBumpers, 'RatingBumper')): for b in bumper.select(): path = b.path if not util.vfs.exists(path): cleaned = True b.delete_instance() self.log('{0} Missing: {1} - REMOVED'.format( util.strRepr(name), util.strRepr(path))) if not cleaned: self.log('Database clean - unchanged')
def clean(self): cleaned = False for s in DB.Song.select(): path = s.path if not util.vfs.exists(path): cleaned = True s.delete_instance() self.owner.log('Song Missing: {0} - REMOVED'.format(util.strRepr(path))) return cleaned
def clean(self): cleaned = False for t in DB.Trivia.select(): path = t.answerPath if not util.vfs.exists(path): cleaned = True t.delete_instance() self._callback('Trivia Missing: {0} - REMOVED'.format(util.strRepr(path))) return cleaned
def clean(self): cleaned = False for s in DB.Song.select(): path = s.path if not util.vfs.exists(path): cleaned = True s.delete_instance() self.owner.log('Song Missing: {0} - REMOVED'.format( util.strRepr(path))) return cleaned
def conditionsStr(self): ret = 'Sequence [{0}]:\n'.format(util.strRepr(self.name)) for key, val in self._attrs.items(): if val: if isinstance(val, list): ret += ' {0} = {1}\n'.format( key, ', '.join( [getConditionValueString(key, v) for v in val])) else: ret += ' {0} = {1}\n'.format(key, val) return ret
def clean(self, base): cleaned = False self._callback('Cleaning: Trivia') for t in DB.Trivia.select(): path = t.answerPath if not path.startswith(base) or not util.vfs.exists(path): cleaned = True t.delete_instance() self._callback('Trivia Missing: {0} - REMOVED'.format(util.strRepr(path))) return cleaned
def _fixTriviaSlidesDir(self): ts = util.pathJoin(self._contentDirectory, 'Trivia Slides' + util.getSep(self._contentDirectory)) util.DEBUG_LOG('Checking for the existence of {0}'.format(util.strRepr(ts))) if not util.vfs.exists(ts): util.DEBUG_LOG("No 'Trivia Slides' directory exists") return t = util.pathJoin(self._contentDirectory, 'Trivia') success = True if util.vfs.exists(t): success = util.vfs.rmdir(t) if success: success = util.vfs.rename(ts, t) else: util.DEBUG_LOG("Failed to remove existing 'Trivia' directory") if success: util.DEBUG_LOG("Renamed 'Trivia Slides' to 'Trivia'") else: util.DEBUG_LOG('Failed to rename {0} to {1}'.format(util.strRepr(ts), util.strRepr(t)))
def clean(self, base): cleaned = False self.owner.log('Cleaning: Music') for s in DB.Song.select(): path = s.path if not path.startswith(base) or not util.vfs.exists(path): cleaned = True s.delete_instance() self.owner.log('Song Missing: {0} - REMOVED'.format(util.strRepr(path))) return cleaned
def loadTrivia(self): self.logHeading('LOADING TRIVIA') basePath = util.pathJoin(self._contentDirectory, 'Trivia') paths = util.vfs.listdir(basePath) total = float(len(paths)) for ct, sub in enumerate(paths): pct = 20 + int((ct / total) * 20) if not self._callback(pct=pct): break path = os.path.join(basePath, sub) if util.isDir(path): if sub.startswith('_Exclude'): util.DEBUG_LOG('SKIPPING EXCLUDED DIR: {0}'.format(util.strRepr(sub))) continue else: continue self.log('Processing trivia: {0}'.format(util.strRepr(os.path.basename(path)))) self.triviaDirectoryHandler(path, prefix=sub)
def loadTrivia(self): self.logHeading('LOADING TRIVIA') basePath = util.pathJoin(self._contentDirectory, 'Trivia') paths = util.vfs.listdir(basePath) total = float(len(paths)) for ct, sub in enumerate(paths): pct = 20 + int((ct/total)*20) if not self._callback(pct=pct): break path = os.path.join(basePath, sub) if util.isDir(path): if sub.startswith('_Exclude'): util.DEBUG_LOG('SKIPPING EXCLUDED DIR: {0}'.format(util.strRepr(sub))) continue else: continue self.log('Processing trivia: {0}'.format(util.strRepr(os.path.basename(path)))) self.triviaDirectoryHandler(path, prefix=sub)
def addBumper(self, model, sub, path, type_name, sub_name, type_, sub_default, sub_val=None, prefix=None): for v in util.vfs.listdir(path): vpath = util.pathJoin(path, v) if util.isDir(vpath): if sub_name: if not sub_val: self.addBumper(model, sub, vpath, type_name, sub_name, type_, sub_default, v) else: self.addBumper(model, sub, vpath, type_name, sub_name, type_, sub_default, prefix=v) continue name, ext = os.path.splitext(v) is3D = '3D' in name if is3D and type_name == 'system': # Remove tags from rating bumpers name = re.sub(CONTENT_3D_RE, '', name).strip() isImage = False if ext in util.videoExtensions: isImage = False elif ext in util.imageExtensions: isImage = True else: continue name = prefix and (prefix + ':' + name) or name defaults = { type_name: TYPE_IDS.get(type_, type_), 'name': name, 'is3D': is3D, 'isImage': isImage } if sub_name: sub_val = sub_val or sub_default defaults[sub_name] = sub_val self.log('Loading {0} ({1} - {2}): [ {3}{4} ]'.format(model.__name__, util.strRepr(sub), sub_val, util.strRepr(name), is3D and ': 3D' or '')) else: self.log('Loading {0} ({1}): [ {2}{3} ]'.format(model.__name__, util.strRepr(sub), util.strRepr(name), is3D and ': 3D' or '')) model.get_or_create( path=vpath, defaults=defaults )
def createBumpers(self, basePath, model, type_name, sub_name, pct_start, sub_default=''): paths = util.vfs.listdir(basePath) total = float(len(paths)) for ct, sub in enumerate(paths): pct = pct_start + int((ct/total)*20) if not self._callback(pct=pct): break path = util.pathJoin(basePath, sub) if not util.isDir(path): continue if sub.startswith('_Exclude'): util.DEBUG_LOG('SKIPPING EXCLUDED DIR: {0}'.format(util.strRepr(sub))) continue if util.vfs.exists(util.pathJoin(path, 'system.xml')): # For ratings self.loadRatingSystem(util.pathJoin(path, 'system.xml')) type_ = sub.replace(' Bumpers', '') self.addBumper(model, sub, path, type_name, sub_name, type_, sub_default)
def getConditionValueString(itype, val): return util.strRepr(_getConditionValueString(itype, val))
def doCall(self, basePath, prefix=None): hasSlidesXML = False slideXML = util.pathJoin(basePath, self._formatXML) if util.vfs.exists(slideXML): hasSlidesXML = True # pack = os.path.basename(basePath.rstrip('\\/')) xml = None slide = None if hasSlidesXML: try: f = util.vfs.File(slideXML, 'r') xml = f.read() finally: f.close() try: slides = ET.fromstring(xml) slide = slides.find('slide') except ET.ParseError: util.DEBUG_LOG('Bad slides.xml') except: util.ERROR() slide = None if slide: rating = self.getNodeAttribute(slide, self._ratingNA[0], self._ratingNA[1]) or '' questionRE = (self.getNodeAttribute(slide, self._questionNA[0], self._questionNA[1]) or '').replace('N/A', '') clueRE = self.getNodeAttribute(slide, self._clueNA[0], self._clueNA[1]) or ''.replace('N/A', '') answerRE = self.getNodeAttribute(slide, self._answerNA[0], self._answerNA[1]) or ''.replace('N/A', '') else: rating = '' questionRE = self._defaultQRegEx clueRE = self._defaultCRegEx answerRE = self._defaultARegEx contents = util.vfs.listdir(basePath) trivia = {} for c in contents: path = util.pathJoin(basePath, c) if util.isDir(path): self.doCall(path, prefix=prefix and (prefix + ':' + c) or c) continue base, ext = os.path.splitext(c) if not ext.lower() in util.imageExtensions: if ext.lower() in util.videoExtensions: self.getSlide(basePath, c, prefix) continue ttype = '' clueCount = 0 ext = ext.lstrip('.') if re.search(questionRE, c): name = re.split(questionRE, c)[0] + ':{0}'.format(ext) ttype = 'q' elif re.search(answerRE, c): name = re.split(answerRE, c)[0] + ':{0}'.format(ext) ttype = 'a' elif re.search(clueRE, c): name = re.split(clueRE, c)[0] + ':{0}'.format(ext) try: clueCount = re.search(clueRE, c).group(1) except: pass ttype = 'c' else: # A still name, ext_ = os.path.splitext(c) name += ':{0}'.format(ext) # name = re.split(clueRE, c)[0] ttype = 'a' if name not in trivia: trivia[name] = {'q': None, 'c': {}, 'a': None} if ttype == 'q' or ttype == 'a': trivia[name][ttype] = path elif ttype == 'c': trivia[name]['c'][clueCount] = path for name, data in trivia.items(): questionPath = data['q'] answerPath = data['a'] if not answerPath: continue if questionPath: ttype = 'QA' self._callback('Loading Trivia (QA): [ {0} ]'.format(util.strRepr(name))) else: ttype = 'fact' self._callback('Loading Trivia (single): [ {0} ]'.format(util.strRepr(name))) defaults = { 'type': ttype, 'TID': u'{0}:{1}'.format(prefix, name), 'name': name, 'rating': rating, 'questionPath': questionPath } for ct, key in enumerate(sorted(data['c'].keys())): defaults['cluePath{0}'.format(ct)] = data['c'][key] try: DB.Trivia.get_or_create( answerPath=answerPath, defaults=defaults ) except: util.DEBUG_LOG(repr(data)) util.DEBUG_LOG(repr(defaults)) util.ERROR()
def __call__(self, basePath, prefix=None): hasSlidesXML = False slideXML = util.pathJoin(basePath, self._formatXML) if util.vfs.exists(slideXML): hasSlidesXML = True # pack = os.path.basename(basePath.rstrip('\\/')) xml = None slide = None if hasSlidesXML: try: f = util.vfs.File(slideXML, 'r') xml = f.read() finally: f.close() try: slides = ET.fromstring(xml) slide = slides.find('slide') except ET.ParseError: util.DEBUG_LOG('Bad slides.xml') except: util.ERROR() slide = None if slide: rating = self.getNodeAttribute(slide, self._ratingNA[0], self._ratingNA[1]) or '' questionRE = (self.getNodeAttribute(slide, self._questionNA[0], self._questionNA[1]) or '').replace('N/A', '') clueRE = self.getNodeAttribute(slide, self._clueNA[0], self._clueNA[1]) or ''.replace('N/A', '') answerRE = self.getNodeAttribute(slide, self._answerNA[0], self._answerNA[1]) or ''.replace('N/A', '') else: rating = '' questionRE = self._defaultQRegEx clueRE = self._defaultCRegEx answerRE = self._defaultARegEx contents = util.vfs.listdir(basePath) trivia = {} for c in contents: path = util.pathJoin(basePath, c) if util.isDir(path): self(path, prefix=prefix and (prefix + ':' + c) or c) continue base, ext = os.path.splitext(c) if not ext.lower() in util.imageExtensions: if ext.lower() in util.videoExtensions: self.getSlide(basePath, c, prefix) continue ttype = '' clueCount = 0 if re.search(questionRE, c): name = re.split(questionRE, c)[0] ttype = 'q' elif re.search(answerRE, c): name = re.split(answerRE, c)[0] ttype = 'a' elif re.search(clueRE, c): name = re.split(clueRE, c)[0] try: clueCount = re.search(clueRE, c).group(1) except: pass ttype = 'c' else: # A still name, ext = os.path.splitext(c) # name = re.split(clueRE, c)[0] ttype = 'a' if name not in trivia: trivia[name] = {'q': None, 'c': {}, 'a': None} if ttype == 'q' or ttype == 'a': trivia[name][ttype] = path elif ttype == 'c': trivia[name]['c'][clueCount] = path for name, data in trivia.items(): questionPath = data['q'] answerPath = data['a'] if not answerPath: continue if questionPath: ttype = 'QA' self._callback('Loading Trivia(QA): [ {0} ]'.format(util.strRepr(name))) else: ttype = 'fact' self._callback('Loading Trivia(single): [ {0} ]'.format(util.strRepr(name))) defaults = { 'type': ttype, 'TID': u'{0}:{1}'.format(prefix, name), 'name': name, 'rating': rating, 'questionPath': questionPath } for ct, key in enumerate(sorted(data['c'].keys())): defaults['cluePath{0}'.format(ct)] = data['c'][key] try: DB.Trivia.get_or_create( answerPath=answerPath, defaults=defaults ) except: print repr(data) util.ERROR()