Index: mirobridge.py =================================================================== --- mirobridge.py (revision 24947) +++ mirobridge.py (working copy) @@ -305,6 +305,7 @@ '''Create an instance of each: MythDB, MythVideo ''' MythLog._setlevel('important,general') # Set the proper bindings alert level + MythDB.searchOldRecorded.dbclass = delOldRecorded mythdb = MythDB() mythvideo = MythVideo(db=mythdb) except MythError, e: @@ -557,19 +558,7 @@ """ Delete video entry from database. """ - if (self._where is None) or \ - (self._wheredat is None) or \ - (self._data is None): - return - c = self._db.cursor() - query = """DELETE FROM %s WHERE %s""" % (self._table, self._where) - self._log(self._log.DATABASE, query, str(self._wheredat)) - try: - c.execute(query, self._wheredat) - except Exception, e: - logger.warning(u"Oldrecorded record delete failed (%s)" % (e, )) - pass - c.close() + DBDataWrite.delete(self) # end delOldRecorded() @@ -615,35 +604,6 @@ return u'' # end hashFile() - -class delRecordedProgram( RecordedProgram ): - '''Just delete a recordedprogram record. Never abort as sometimes a record may not exist. This routine is - not supported in the native python bindings but MiroBridge needs to clean up possibly orphaned records. - return nothing - ''' - def __init__(self, data=None): - super(delRecordedProgram, self).__init__(data) - - def delete(self): - """ - Delete video entry from database. - """ - if (self._where is None) or \ - (self._wheredat is None) or \ - (self._data is None): - return - c = self._db.cursor() - query = """DELETE FROM %s WHERE %s""" % (self._table, self._where) - self._log(self._log.DATABASE, query, str(self._wheredat)) - try: - c.execute(query, self._wheredat) - except Exception, e: - logger.warning(u"Recordedprogram record delete failed (%s)" % (e, )) - pass - c.close() -# end delRecordedProgram() - - def rtnAbsolutePath(relpath, filetype=u'mythvideo'): '''Check if there is a Storage Group for the file type (mythvideo, coverfile, banner, fanart, screenshot) and form an appropriate absolute path and file name. @@ -674,23 +634,22 @@ return False if there is an error ''' records = mythdb.getStorageGroup(hostname=localhostname) - if records: - for record in records: - if record.groupname in storagegroupnames.keys(): - try: - dirname = unicode(record.dirname, 'utf8') - except (UnicodeDecodeError): - logger.error(u"The local Storage group (%s) directory contained\ncharacters that caused a UnicodeDecodeError. This storage group has been rejected." % (record.groupname)) - continue # Skip any line that has non-utf8 characters in it - except (UnicodeEncodeError, TypeError): - pass + for record in records: + if record.groupname in storagegroupnames.keys(): + try: + dirname = unicode(record.dirname, 'utf8') + except (UnicodeDecodeError): + logger.error(u"The local Storage group (%s) directory contained\ncharacters that caused a UnicodeDecodeError. This storage group has been rejected." % (record.groupname)) + continue # Skip any line that has non-utf8 characters in it + except (UnicodeEncodeError, TypeError): + pass - # Add a slash if missing to any storage group dirname - if dirname[-1:] == u'/': - storagegroups[storagegroupnames[record.groupname]] = dirname - else: - storagegroups[storagegroupnames[record.groupname]] = dirname+u'/' - continue + # Add a slash if missing to any storage group dirname + if dirname[-1:] == u'/': + storagegroups[storagegroupnames[record.groupname]] = dirname + else: + storagegroups[storagegroupnames[record.groupname]] = dirname+u'/' + continue if len(storagegroups): # Verify that each storage group is an existing local directory @@ -872,7 +831,85 @@ continue # end setUserconfig +class FFMpeg_Details( DictData ): + _field_order = ['duration', 'width', 'height', 'aspect', + 'video', 'hdtv', 'audio', 'stereo'] + _field_type = 'Pass' + _duration = re.compile(u'Duration: (?P
[0-9]+):(?P[0-9]+):(?P[0-9]+)') + _video = re.compile(u' Video: ') + _video_HDTV_small = re.compile(u' 1280x', re.UNICODE) + _video_HDTV_large = re.compile(u' 1920x', re.UNICODE) + _width_height = re.compile(u'''^(.+?)[ ]\[?([0-9]+)x([0-9]+)[^\\/]*$''', re.UNICODE) + _audio = re.compile(u' Audio: ', re.UNICODE) + _audio_stereo = re.compile(u' stereo,', re.UNICODE) + _audio_mono = re.compile(u' mono,', re.UNICODE) + _audio_ac3 = re.compile(u' ac3,', re.UNICODE) + _audio_51 = re.compile(u' 5.1,', re.UNICODE) + _audio_2C = re.compile(u' 2 channels,', re.UNICODE) + _audio_1C = re.compile(u' 1 channels,', re.UNICODE) + _audio_6C = re.compile(u' 6 channels,', re.UNICODE) + + def _setDefs(self): + self._fillNone() + self.video = u'' + self.audio = u'' + self.duration = 0 + self.stereo = False + self.hdtv = False + + def __init__(self, output=None, screenshot=False): + dict.__init__(self) + self._setDefs() + if output is None: + return + for line in output.split('\n'): + try: + line = unicode(line, 'utf8') + except (UnicodeDecodeError): + continue + except (UnicodeDecodeError, TypeError): + pass + self.video = [] + self.audio = [] + if self._duration.search(line): + match = self._duration.search(line) + self.duration = match.group('sec') + 60*(match.group('min') + 60*match.group('hr')) + elif self._video.search(line): + match = self._width_height.match(line) + datacount+=1 + if match: + dummy, width, height = match.groups() + width, height = float(width), float(height) + aspect = height/width + if screenshot: + self.width = width + self.height = height + self.aspect = aspect + if width > 1300.0 or width > 800.0 or width == 720.0 or width == 1080.0 : + self.video.append(u'HDTV') + self.hdtv = 1 + elif aspect <= 0.5625: + self.video.append(u'WIDESCREEN') + if width > 1300.0: + self.video.append(u'1080') + elif width > 800.0: + self.video.append(u'720') + elif self._audio.search(line): + datacount+=1 + if self._audio_stereo.search(line) or self._audio_2C.search(line): + self.audio.append(u'STEREO') + self.stereo = True + elif self._audio_mono.search(line) or self._audio_1C.search(line): + self.audio.append(u'MONO') + elif (self._audio_51.search(line) and self._audio_ac3.search(line)) or self._audio_6C.search(line): + self.audio.append(u'DOLBY') + continue + elif len(audio_51.findall(data)): + self.audio.append(u'SURROUND') + self.video = u','.join(self.video) + self.audio = u','.join(self.audio) + def getVideoDetails(videofilename, screenshot=False): '''Using ffmpeg (if it can be found) get a video file's details return False if ffmpeg is cannot be found @@ -883,95 +920,20 @@ global ffmpeg if not ffmpeg and not screenshot: - return ffmpeg_details + return FFMpeg_Details() if not ffmpeg and screenshot: return False - video = re.compile(u' Video: ') - video_HDTV_small = re.compile(u' 1280x', re.UNICODE) - video_HDTV_large = re.compile(u' 1920x', re.UNICODE) - width_height = re.compile(u'''^(.+?)[ ]\[?([0-9]+)x([0-9]+)[^\\/]*$''', re.UNICODE) - audio = re.compile(u' Audio: ', re.UNICODE) - audio_stereo = re.compile(u' stereo,', re.UNICODE) - audio_mono = re.compile(u' mono,', re.UNICODE) - audio_ac3 = re.compile(u' ac3,', re.UNICODE) - audio_51 = re.compile(u' 5.1,', re.UNICODE) - audio_2C = re.compile(u' 2 channels,', re.UNICODE) - audio_1C = re.compile(u' 1 channels,', re.UNICODE) - audio_6C = re.compile(u' 6 channels,', re.UNICODE) - + fp = System(file='ffmpeg') try: - p = subprocess.Popen(u'ffmpeg -i "%s"' % (videofilename), shell=True, bufsize=4096, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) - except: + output = fp.command('-i "%s"' % videofilename) + except MythError, e: if not screenshot: - return ffmpeg_details + return FFMpeg_Details() else: return False - ffmpeg_found = True - alldata = 3 - datacount = 0 - while 1: - if datacount == alldata: # Stop if all the required data has been extracted from ffmpeg's output - break - data = p.stderr.readline() - if data == '': - break - try: - data = unicode(data, 'utf8') - except (UnicodeDecodeError): - continue # Skip any line that has non-utf8 characters in it - except (UnicodeEncodeError, TypeError): - pass - if data.endswith(u'command not found\n'): - ffmpeg_found = False - break - if data.startswith(u' Duration:'): - time = (data[data.index(':')+1: data.index('.')]).strip() - ffmpeg_details[u'duration'] = (360*(int(time[:2]))+(int(time[3:5])*60))+int(time[6:8]) - datacount+=1 - elif len(video.findall(data)): - match = width_height.match(data) - datacount+=1 - if match: - dummy, width, height = match.groups() - width, height = float(width), float(height) - aspect = height/width - if screenshot: - ffmpeg_details[u'width'] = width - ffmpeg_details[u'height'] = height - ffmpeg_details[u'aspect'] = aspect - if width > 1300.0 or width > 800.0 or width == 720.0 or width == 1080.0 : - ffmpeg_details[u'video']+=u'HDTV' - ffmpeg_details[u'hdtv'] = 1 - elif aspect <= 0.5625: - ffmpeg_details[u'video']+=u'WIDESCREEN' - if len(ffmpeg_details[u'video']): - comma = u',' - else: - comma = u'' - if width > 1300.0: - ffmpeg_details[u'video']+=comma+u'1080' - elif width > 800.0: - ffmpeg_details[u'video']+=comma+u'720' - elif len(audio.findall(data)): - datacount+=1 - if len(audio_stereo.findall(data)) or len(audio_2C.findall(data)): - ffmpeg_details[u'audio']+=u'STEREO' - ffmpeg_details[u'stereo'] = 1 - elif len(audio_mono.findall(data)) or len(audio_1C.findall(data)): - ffmpeg_details[u'audio']+=u'MONO' - elif (len(audio_51.findall(data)) and len(audio_ac3.findall(data))) or len(audio_6C.findall(data)): - ffmpeg_details[u'audio']+=u'DOLBY' - continue - elif len(audio_51.findall(data)): - ffmpeg_details[u'audio']+=u'SURROUND' - - if ffmpeg_found == False: - ffmpeg = False - return False - else: - return ffmpeg_details + return FFMpeg_Details(output, screenshot) # end getVideoDetails() @@ -985,26 +947,26 @@ ffmpeg_details = getVideoDetails(videofile, screenshot=True) except: return None - if not ffmpeg_details: + if ffmpeg_details is None: return None - elif not u'width' in ffmpeg_details.keys(): + elif ffmpeg_details.width is None: return None max_length = 2*60 # Maximum length of a video check if set at 2 minutes - if ffmpeg_details[u'duration']: - if ffmpeg_details[u'duration'] < max_length: - delay = (ffmpeg_details[u'duration']/2) # Maximum time to take screenshot into a video is 1 minute + if ffmpeg_details.duration: + if ffmpeg_details.duration < max_length: + delay = (ffmpeg_details.duration/2) # Maximum time to take screenshot into a video is 1 minute else: delay = 60 # For a large videos take screenshot at the 1 minute mark cmd = u'ffmpeg -i "%s" -y -f image2 -ss %d -sameq -t 0.001 -s %d*%d "%s"' - width = int(ffmpeg_details[u'width']) - height = int(ffmpeg_details[u'height']) + width = int(ffmpeg_details.width) + height = int(ffmpeg_details.height) if size_limit: width = 320 - height = (int(width * ffmpeg_details[u'aspect'])/2)*2 # ((xxxxx)/2) *2 + height = (int(width * ffmpeg_details.aspect)/2)*2 # ((xxxxx)/2) *2 if just_demensions: return u"%dx%d" % (width, height) @@ -1148,39 +1110,30 @@ global channel_icon_override global graphic_suffix, graphic_path_suffix, graphic_name_suffix - recorded_array = mythdb.searchRecorded(chanid=channel_id, hostname=localhostname) - if not recorded_array: - recorded_array = [] - oldrecorded_array = mythdb.searchOldRecorded(chanid=channel_id, ) - if not oldrecorded_array: - oldrecorded_array = [] - videometadata = mythvideo.searchVideos(category=u'Miro', custom=(('inetref=%s',u'99999999'),)) - if not videometadata: - videometadata = [] + recorded_array = list(mythdb.searchRecorded(chanid=channel_id, hostname=localhostname)) + oldrecorded_array = list(mythdb.searchOldRecorded(chanid=channel_id, )) + videometadata = list(mythvideo.searchVideos(category=u'Miro', custom=(('inetref=%s',u'99999999'),))) orphans = [] for record in oldrecorded_array: - for recorded in recorded_array: - if recorded[u'starttime'] == record[u'starttime'] and recorded[u'endtime'] == record[u'endtime']: - break + if record in recorded_array: + break + elif record in videometadata: + break else: - for video in videometadata: - if video[u'title'] == record[u'title'] and video[u'subtitle'] == record[u'subtitle']: - break - else: - orphans.append(record) + orphans.append(record) for data in orphans: if simulation: logger.info(u"Simulation: Remove orphaned oldrecorded record (%s - %s)" % (data[u'title'], data[u'subtitle'])) else: - delOldRecorded((channel_id, data['starttime'])).delete() + data.delete() try: # Attempt to clean up an orphaned recordedprogram record, there may not be one to clean up - delRecordedProgram((channel_id, data['starttime'])).delete() + RecordedProgram((channel_id, data.starttime)).delete() except Exception, e: pass # Attempt a clean up for orphaned recorded video files and/or graphics - (dirName, fileName) = os.path.split(u'%s%s - %s.%s' % (vid_graphics_dirs[u'default'], data[u'title'], data[u'subtitle'], u'png')) + (dirName, fileName) = os.path.split(u'%s%s - %s.%s' % (vid_graphics_dirs[u'default'], data.title, data.subtitle, u'png')) (fileBaseName, fileExtension)=os.path.splitext(fileName) try: dirName = unicode(dirName, u'utf8') @@ -1200,7 +1153,7 @@ except OSError: pass # Attempt a clean up for orphaned MythVideo screenshot and UNIQUE coverart - (dirName, fileName) = os.path.split(u'%s%s - %s%s.%s' % (vid_graphics_dirs[u'episodeimagedir'], data[u'title'], data[u'subtitle'], graphic_suffix[u'episodeimagedir'], u'png')) + (dirName, fileName) = os.path.split(u'%s%s - %s%s.%s' % (vid_graphics_dirs[u'episodeimagedir'], data.title, data.subtitle, graphic_suffix[u'episodeimagedir'], u'png')) (fileBaseName, fileExtension)=os.path.splitext(fileName) try: dirName = unicode(dirName, u'utf8') @@ -1222,7 +1175,7 @@ break # Remove any unique cover art graphic files if data[u'title'].lower() in channel_icon_override: - (dirName, fileName) = os.path.split(u'%s%s - %s%s.%s' % (vid_graphics_dirs[u'posterdir'], data[u'title'], data[u'subtitle'], graphic_suffix[u'posterdir'], u'png')) + (dirName, fileName) = os.path.split(u'%s%s - %s%s.%s' % (vid_graphics_dirs[u'posterdir'], data.title, data.subtitle, graphic_suffix[u'posterdir'], u'png')) (fileBaseName, fileExtension)=os.path.splitext(fileName) try: dirName = unicode(dirName, u'utf8') @@ -1242,7 +1195,7 @@ except OSError: pass break - displayMessage(u"Removed orphaned Miro video and graphics files (%s - %s)" % (data[u'title'], data[u'subtitle'])) + displayMessage(u"Removed orphaned Miro video and graphics files (%s - %s)" % (data.title, data.subtitle)) return orphans # end getOldrecordedOrphans() @@ -1348,7 +1301,7 @@ ''' global localhostname, simulation, verbose, storagegroups, ffmpeg, channel_id - tmp_oldrecorded={} + tmp_oldrecorded=delOldRecorded(db=mythdb) # Create the oldrecorded dictionary tmp_oldrecorded[u'chanid'] = channel_id @@ -1372,11 +1325,11 @@ ''' global localhostname, simulation, verbose, storagegroups, ffmpeg, channel_id - tmp_recorded={} - tmp_recordedprogram={} + tmp_recorded=Recorded(db=mythdb) + tmp_recordedprogram=RecordedProgram(db=mythdb) ffmpeg_details = getVideoDetails(item[u'videoFilename']) - start_end = getStartEndTimes(ffmpeg_details[u'duration'], item[u'downloadedTime']) + start_end = getStartEndTimes(ffmpeg_details.duration, item[u'downloadedTime']) if item[u'releasedate'] == None: item[u'releasedate'] = item[u'downloadedTime'] @@ -1476,7 +1429,7 @@ ffmpeg_details = getVideoDetails(item[u'videoFilename']) start_end = getStartEndTimes(ffmpeg_details[u'duration'], item[u'downloadedTime']) - videometadata = {} + videometadata = Video(db=mythdb) videometadata[u'title'] = item[u'channelTitle'] videometadata[u'subtitle'] = item[u'title'] @@ -1575,7 +1528,7 @@ logger.critical(u'The Miro channel icon file (%s) does not exist.\nThe variable needs to be a fully qualified file name and path.\ne.g. ./mirobridge.py -C "/path to the channel icon/miro_channel_icon.jpg"' % (icon)) sys.exit(1) - data={} + data=Channel(db=mythdb) data['chanid'] = channel_id data['channum'] = str(channel_num) data['freqid'] = str(channel_num) @@ -1592,7 +1545,7 @@ logger.info(u"Simulation: Channel icon file(%s)" % (icon)) else: try: - Channel().create(data) + data.create() except MythError, e: logger.critical(u"Failed writing the Miro channel record. Most likely the Channel Id and number already exists.\nUse MythTV set up program (mythtv-setup) to alter or remove the offending channel.\nYou specified Channel ID (%d) and Channel Number (%d), error(%s)" % (channel_id, channel_num, e.args[0])) sys.exit(1) @@ -1716,8 +1669,6 @@ filenames=[] recorded = mythdb.searchRecorded(chanid=channel_id, hostname=localhostname) - if not recorded: - return None for record in recorded: if record[u'watched'] == 0: # Skip if the video has NOT been watched @@ -1753,40 +1704,38 @@ # Deal with existing Miro videos already in the MythTV data base recorded = mythdb.searchRecorded(chanid=channel_id, hostname=localhostname) - if recorded: - for record in recorded: - if storagegroups.has_key(u'default'): - sym_filepath = u"%s%s" % (storagegroups[u'default'], record[u'basename']) + for record in recorded: + if storagegroups.has_key(u'default'): + sym_filepath = u"%s%s" % (storagegroups[u'default'], record[u'basename']) + else: + sym_filepath = u"%s%s" % (vid_graphics_dirs[u'default'], record[u'basename']) + # Remove any Miro related "watched" recordings (symlink, recorded and recordedprogram records) + # Remove any Miro related with broken symbolic video links + if record[u'watched'] == 1 or not os.path.isfile(os.path.realpath(sym_filepath)): + displayMessage(u"Removing watched Miro recording (%s) (%s)" % (record[u'title'], record[u'subtitle'])) + # Remove the database recorded, recordedprogram and oldrecorded records + if simulation: + logger.info(u"Simulation: Remove recorded/recordedprogram/oldrecorded records and associated Miro Video file for chanid(%s), starttime(%s)" % (record['chanid'], record['starttime'])) else: - sym_filepath = u"%s%s" % (vid_graphics_dirs[u'default'], record[u'basename']) - # Remove any Miro related "watched" recordings (symlink, recorded and recordedprogram records) - # Remove any Miro related with broken symbolic video links - if record[u'watched'] == 1 or not os.path.isfile(os.path.realpath(sym_filepath)): - displayMessage(u"Removing watched Miro recording (%s) (%s)" % (record[u'title'], record[u'subtitle'])) - # Remove the database recorded, recordedprogram and oldrecorded records - if simulation: - logger.info(u"Simulation: Remove recorded/recordedprogram/oldrecorded records and associated Miro Video file for chanid(%s), starttime(%s)" % (record['chanid'], record['starttime'])) - else: - try: # Attempting to clean up an recorded record and its associated video file (miro symlink) - rtn = Recorded((record['chanid'], record['starttime'])).delete(force=True) - except MythError, e: - pass - try: # Attempt to clean up an orphaned recordedprogram record, there may not be one to clean up - delRecordedProgram((record['chanid'], record['starttime'])).delete() - except Exception, e: - pass - try: # Attempting to clean up an orphaned oldrecorded record which may or may not exist - delOldRecorded((record['chanid'], record['starttime'])).delete() - except Exception, e: - pass + try: # Attempting to clean up an recorded record and its associated video file (miro symlink) + rtn = Recorded((record['chanid'], record['starttime'])).delete(force=True) + except MythError, e: + pass + try: # Attempt to clean up an orphaned recordedprogram record, there may not be one to clean up + RecordedProgram((record['chanid'], record['starttime'])).delete() + except Exception, e: + pass + try: # Attempting to clean up an orphaned oldrecorded record which may or may not exist + delOldRecorded((record['chanid'], record['starttime'])).delete() + except Exception, e: + pass recorded = mythdb.searchRecorded(chanid=channel_id, hostname=localhostname) - if recorded: - for record in recorded: # Skip any item already in MythTV data base - for item in items: - if item[u'channelTitle'] == record[u'title'] and item[u'title'] == record[u'subtitle']: - items_copy.remove(item) - break + for record in recorded: # Skip any item already in MythTV data base + for item in items: + if item[u'channelTitle'] == record[u'title'] and item[u'title'] == record[u'subtitle']: + items_copy.remove(item) + break # Add new Miro unwatched videos to MythTV'd data base for item in items_copy: @@ -1798,9 +1747,9 @@ logger.info(u"Simulation: Added recorded and recordedprogram records for (%s - %s)" % (item[u'channelTitle'], item[u'title'],)) else: try: - Recorded().create(records[0]) - RecordedProgram().create(records[1]) - OldRecorded().create(records[2]) + records[0].create() + records[1].create() + records[2].create() except MythError, e: logger.warning(u"Inserting recorded/recordedprogram/oldrecorded records non-critical error (%s) for (%s - %s)" % (e.args[0], item[u'channelTitle'], item[u'title'],)) else: @@ -1877,111 +1826,105 @@ # Remove any Miro Mythvideo records which the video or graphics paths are broken records = mythvideo.searchVideos(category=u'Miro', custom=(('inetref=%s','99999999'),)) - if records: - statistics[u'Total_Miro_MythVideos'] = len(records) - for record in records: # Count the Miro-MythVideos that Miro is expiring or has saved - if record[u'filename'][0] == u'/': - if os.path.islink(record[u'filename']) and os.path.isfile(record[u'filename']): - statistics[u'Total_Miro_expiring']+=1 - elif record[u'host'] and storagegroups.has_key(u'mythvideo'): - if os.path.islink(storagegroups[u'mythvideo']+record[u'filename']) and os.path.isfile(storagegroups[u'mythvideo']+record[u'filename']): - statistics[u'Total_Miro_expiring']+=1 - for record in records: - if checkVideometadataFails(record, flat): - delete = False - if os.path.islink(record[u'filename']): # Only delete video files if they are symlinks - if not record[u'host'] or record[u'filename'][0] == '/': - if not os.path.isfile(record[u'filename']): - delete = True - else: - if not os.path.isfile(vid_graphics_dirs[key_trans[field]]+record[u'filename']): - delete = True - else: + statistics[u'Total_Miro_MythVideos'] = len(records) + for record in records: # Count the Miro-MythVideos that Miro is expiring or has saved + if record[u'filename'][0] == u'/': + if os.path.islink(record[u'filename']) and os.path.isfile(record[u'filename']): + statistics[u'Total_Miro_expiring']+=1 + elif record[u'host'] and storagegroups.has_key(u'mythvideo'): + if os.path.islink(storagegroups[u'mythvideo']+record[u'filename']) and os.path.isfile(storagegroups[u'mythvideo']+record[u'filename']): + statistics[u'Total_Miro_expiring']+=1 + elif checkVideometadataFails(record, flat): + delete = False + if os.path.islink(record[u'filename']): # Only delete video files if they are symlinks + if not record[u'host'] or record[u'filename'][0] == '/': if not os.path.isfile(record[u'filename']): delete = True - if delete: # Only delete video files if they are symlinks - if simulation: - logger.info(u"Simulation: DELETE videometadata for intid = %s" % (record[u'intid'],)) - logger.info(u"Simulation: DELETE oldrecorded for title(%s), subtitle(%s)" % (record[u'intid'],record[u'title'], record[u'subtitle'])) - else: - Video(id=record[u'intid'], db=mythvideo).delete() - try: # An orphaned oldrecorded record may not exist - for oldrecorded in mythdb.searchOldRecorded(title=record[u'title'], subtitle=record[u'subtitle'] ): - delOldRecorded((channel_id, oldrecorded.starttime)).delete() - except Exception, e: - pass - statistics[u'Total_Miro_MythVideos']-=1 - if record[u'filename'][0] == '/': - try: - if simulation: - logger.info(u"Simulation: Remove video file symlink (%s)" % (record[u'filename'])) - else: - os.remove(record[u'filename']) - statistics[u'Miros_MythVideos_video_removed']+=1 - except OSError: - pass - elif record[u'host'] and storagegroups.has_key(u'mythvideo'): - try: - if simulation: - logger.info(u"Simulation: Remove video file (%s)" % (storagegroups[u'mythvideo']+record[u'filename'])) - else: - os.remove(storagegroups[u'mythvideo']+record[u'filename']) - except OSError: - pass - if record[u'screenshot']: # Remove any associated Screenshot - if record[u'screenshot'][0] == '/': - try: - if simulation: - logger.info(u"Simulation: Remove screenshot symlink (%s)" % (record[u'screenshot'])) - else: - os.remove(record[u'screenshot']) - except OSError: - pass - elif record[u'host'] and storagegroups.has_key(u'episodeimagedir'): - try: - if simulation: - logger.info(u"Simulation: Remove file (%s)" % (storagegroups[u'episodeimagedir']+record[u'screenshot'])) - else: - os.remove(storagegroups[u'episodeimagedir']+record[u'screenshot']) - except OSError: - pass - # Remove any unique cover art graphic files - if record[u'title'].lower() in channel_icon_override: - if record[u'coverfile'][0] == u'/': - try: - if simulation: - logger.info(u"Simulation: Remove item cover art file (%s)" % (record[u'coverfile'])) - else: - os.remove(record[u'coverfile']) - except OSError: - pass - elif record[u'host'] and storagegroups.has_key(u'posterdir'): - try: - if simulation: - logger.info(u"Simulation: Remove item cover art file (%s)" % (storagegroups[u'posterdir']+record[u'coverfile'])) - else: - os.remove(storagegroups[u'posterdir']+record[u'coverfile']) - except OSError: - pass + else: + if not os.path.isfile(vid_graphics_dirs[key_trans[field]]+record[u'filename']): + delete = True + else: + if not os.path.isfile(record[u'filename']): + delete = True + if delete: # Only delete video files if they are symlinks + if simulation: + logger.info(u"Simulation: DELETE videometadata for intid = %s" % (record[u'intid'],)) + logger.info(u"Simulation: DELETE oldrecorded for title(%s), subtitle(%s)" % (record[u'intid'],record[u'title'], record[u'subtitle'])) + else: + Video(id=record[u'intid'], db=mythvideo).delete() + try: # An orphaned oldrecorded record may not exist + for oldrecorded in mythdb.searchOldRecorded(title=record[u'title'], subtitle=record[u'subtitle'] ): + delOldRecorded((channel_id, oldrecorded.starttime)).delete() + except Exception, e: + pass + statistics[u'Total_Miro_MythVideos']-=1 + if record[u'filename'][0] == '/': + try: + if simulation: + logger.info(u"Simulation: Remove video file symlink (%s)" % (record[u'filename'])) + else: + os.remove(record[u'filename']) + statistics[u'Miros_MythVideos_video_removed']+=1 + except OSError: + pass + elif record[u'host'] and storagegroups.has_key(u'mythvideo'): + try: + if simulation: + logger.info(u"Simulation: Remove video file (%s)" % (storagegroups[u'mythvideo']+record[u'filename'])) + else: + os.remove(storagegroups[u'mythvideo']+record[u'filename']) + except OSError: + pass + if record[u'screenshot']: # Remove any associated Screenshot + if record[u'screenshot'][0] == '/': + try: + if simulation: + logger.info(u"Simulation: Remove screenshot symlink (%s)" % (record[u'screenshot'])) + else: + os.remove(record[u'screenshot']) + except OSError: + pass + elif record[u'host'] and storagegroups.has_key(u'episodeimagedir'): + try: + if simulation: + logger.info(u"Simulation: Remove file (%s)" % (storagegroups[u'episodeimagedir']+record[u'screenshot'])) + else: + os.remove(storagegroups[u'episodeimagedir']+record[u'screenshot']) + except OSError: + pass + # Remove any unique cover art graphic files + if record[u'title'].lower() in channel_icon_override: + if record[u'coverfile'][0] == u'/': + try: + if simulation: + logger.info(u"Simulation: Remove item cover art file (%s)" % (record[u'coverfile'])) + else: + os.remove(record[u'coverfile']) + except OSError: + pass + elif record[u'host'] and storagegroups.has_key(u'posterdir'): + try: + if simulation: + logger.info(u"Simulation: Remove item cover art file (%s)" % (storagegroups[u'posterdir']+record[u'coverfile'])) + else: + os.remove(storagegroups[u'posterdir']+record[u'coverfile']) + except OSError: + pass if not items: # There may not be any new items to add to MythVideo return True # Reread Miro Mythvideo videometadata records # Remove the matching videometadata record from array of items - items_copy = [] + items_copy = list(items) + records = list(mythvideo.searchVideos(category=u'Miro', custom=(('inetref=%s','99999999'),))) for item in items: - items_copy.append(item) - records = mythvideo.searchVideos(category=u'Miro', custom=(('inetref=%s','99999999'),)) - if records: - for record in records: - for item in items: - if item[u'channelTitle'] == record[u'title'] and item[u'title'] == record[u'subtitle']: - try: - items_copy.remove(item) - except ValueError: - logger.info(u"Video (%s - %s) was found multiple times in list of (watched and/or saved) items from Miro - skipping" % (item[u'channelTitle'], item[u'title'])) - pass - break + if item in records: + try: + items_copy.remove(item) + except ValueError: + logger.info(u"Video (%s - %s) was found multiple times in list of (watched and/or saved) items from Miro - skipping" % (item[u'channelTitle'], item[u'title'])) + pass + break for item in items: # Remove any items that are for a Channel that does not get MythVideo records if filter(is_not_punct_char, item[u'channelTitle'].lower()) in channel_watch_only: @@ -2014,13 +1957,13 @@ intid = mythvideo.getVideo(exactfile=videometadata[u'filename']) if intid == None: try: - intid = Video(db=mythvideo).create(videometadata).intid + videometadata.create() except MythError, e: logger.critical(u"Adding Miro video to MythVideo (%s - %s) failed for (%s)." % (item[u'channelTitle'], item[u'title'], e.args[0])) sys.exit(1) if not item.has_key(u'copied'): try: - OldRecorded().create(oldrecorded) + oldrecorded.create() except MythError, e: logger.critical(u"Failed writing the oldrecorded record for(%s)" % (e.args[0])) sys.exit(1)