def on_nfo_loaded(self, nfo, result): # optionally include 'watched' tag to XML content if (addon.getSettingBool('movies.export.watched')): nfo.add_tag('watched', replace=True) # optionally include 'userrating' tag to XML content if (addon.getSettingBool('movies.export.userrating')): nfo.add_tag('userrating', replace=True)
def on_process_finished(self, result): # optionally clean library if (addon.getSettingBool('movies.import.autoclean') and result.nb_modified > 0): try: self.log.info('automatically cleaning the library...') exec_jsonrpc('VideoLibrary.Clean') except JSONRPCError as e: # just log the error self.log.warning('error cleaning the library: %s' % str(e)) # if we do not save the resume point, then we will not notify the user if (not self.save_resume_point): return # if everything is fine, save the run datetime as the new import resume point if (not result.script_errors and not result.errors): try: self.log.debug('saving last_import to data file \'%s\'' % self.LAST_IMPORT_FILE) # save this_run datetime to last_import.tmp save_data(self.LAST_IMPORT_FILE, timestamp_to_str(self.this_run)) except FileError as e: self.log.warning( 'error saving last_import datetime to data file \'%s\': %s' % (e.path, e)) self.log.warning( ' => next import will probably process the same videos again!' ) result.warnings.append('cannot save import resume point') else: self.log.debug( 'NOT saving last_import to data file \'%s\', as there were some errors' % self.LAST_IMPORT_FILE)
def run(self): result = self.process() # result is a TaskResult object # build result to have proper title and lines result.build(self.task_family) # allow post-process actions self.on_process_finished(result) # log and optionally notify user self.notify_result( result, notify_user=addon.getSettingBool('movies.auto.notify'))
def on_nfo_load_failed(self, nfo, result): # fallback to MovieNFOBuildHandler, in order to regenerate the file completely # first check if correct setting is activated if (nfo and nfo.family == 'load' and addon.getSettingBool('movies.export.rebuild')): self.log.warning(' => rebuilding nfo file: \'%s\'' % nfo.nfo_path) return MovieNFOBuildHandler(self, nfo.video_type, nfo.video_id) else: self.log.warning(' => no fallback NFO handler => skipping video') return None
def load_script(self): script_path = xbmc.translatePath( addon.getSetting('movies.general.script.path')) if (not addon.getSettingBool('movies.general.script') or not script_path): self.log.debug('not applying any script on nfo') return None else: self.log.debug('loading script: %s' % script_path) return FileScriptHandler(script_path, log_prefix=self.__class__.__name__)
def process(self): # collect entries we should process try: self.populate_entries() except TaskError as e: self.log.error(e) self.log.error('error populating entries => aborting task') return TaskResult('aborted', 'cannot populate entries, see logs') # early exit if nothing to process if (len(self.items) == 0): return TaskResult('complete') # instantiate a TaskResult object result = TaskResult() # optionally load the script we will apply on all entries # we load the file now, in order to bypass it later if errors are encountered if (not self.ignore_script): try: self.script = self.load_script() except ScriptError as e: self.log.notice(e) self.log.notice( ' => ignoring script error => resuming task without script' ) self.script = None result.script_errors = True for video_id in self.items: # collect the nb of processed items in result result.nb_items += 1 # instantiate a nfo handler; we use a loop here, as the derived class can implement some fallback strategy if a handler fails (see on_nfo_load_failed()) default_nfo = True # at first, we want the default NFOHandler while (True): try: if (default_nfo): nfo = None # needed in case nfo cannot be instantiated nfo = self.get_nfo_handler(video_id) nfo.make_xml() self.on_nfo_loaded(nfo, result) break except NFOHandlerError as e: default_nfo = False # we will not use the default anymore self.log.warning(e) # try to fall back to another nfo handler try: nfo = self.on_nfo_load_failed(nfo, result) except Exception as e: self.log.warning( 'error instantiating the fallback NFO handler') self.log.warning(e) self.log.warning( ' => will not try further more => skipping this video' ) nfo = None break if (not nfo): result.add_error( nfo, e ) # a dummy error will be added, as nfo == None raises an exception break if (not nfo): # skip this video if there is no valid NFOHandler continue # we need to track if the script was successful, in order to decide whether we can save or not script_success = True # apply script to nfo content if (self.script and not self.ignore_script): if (not self.apply_script(nfo)): result.script_errors = True # not tracked in result.errors script_success = False # save nfo, and trigger event if content was actually modified if (not script_success): if (addon.getSettingBool( 'movies.general.script.ignore_script_errors')): self.log.warning( ' => script error => ignoring and trying to save the NFO anyway [berserker mode]' ) else: self.log.warning(' => script error => NOT saving the NFO') try: modified = nfo.save() if (modified): self.log.info('saved nfo: \'%s\'' % nfo.nfo_path) if (self.on_nfo_saved(nfo, result) and self.refresh_nfo(nfo, result)): result.modified.append( nfo.nfo_path ) # add to modified only if saved and refreshed else: self.log.debug( 'not saving to \'%s\': contents are identical' % nfo.nfo_path) except NFOHandlerError as e: self.log.error(e) result.add_error(nfo, e) result.status = 'complete' return result