diff --git a/trackma/engine.py b/trackma/engine.py index 16c8c20f..09428687 100644 --- a/trackma/engine.py +++ b/trackma/engine.py @@ -59,20 +59,21 @@ class Engine: name = 'Engine' - signals = {'show_added': None, - 'show_deleted': None, - 'episode_changed': None, - 'score_changed': None, - 'status_changed': None, - 'show_synced': None, - 'sync_complete': None, - 'queue_changed': None, - 'playing': None, - 'prompt_for_update': None, - 'prompt_for_add': None, - 'tracker_state': None, - 'episode_missing': None, - } + signals = { + 'show_added': None, + 'show_deleted': None, + 'episode_changed': None, + 'score_changed': None, + 'status_changed': None, + 'show_synced': None, + 'sync_complete': None, + 'queue_changed': None, + 'playing': None, + 'prompt_for_update': None, + 'prompt_for_add': None, + 'tracker_state': None, + 'episode_missing': None, + } def __init__(self, account=None, message_handler=None, accountnum=None): self.msg = messenger.Messenger(message_handler, self.name) @@ -101,8 +102,8 @@ def _load(self, account): utils.VERSION, account['username'], account['api'])) self.msg.info('Reading config files...') try: - self.config = utils.parse_config( - self.configfile, utils.config_defaults) + self.config = utils.parse_config(self.configfile, + utils.config_defaults) except IOError: raise utils.EngineFatal("Couldn't open config file.") @@ -112,18 +113,20 @@ def _load(self, account): self.msg.debug("Fixing string searchdir to list.") self.config['searchdir'] = [self.config['searchdir']] - self.searchdirs = [path for path in utils.expand_paths( - self.config['searchdir']) if self._searchdir_exists(path)] + self.searchdirs = [ + path for path in utils.expand_paths(self.config['searchdir']) + if self._searchdir_exists(path) + ] def _init_data_handler(self, mediatype=None): # Create data handler - self.data_handler = data.Data( - self.msg, self.config, self.account, mediatype) + self.data_handler = data.Data(self.msg, self.config, self.account, + mediatype) self.data_handler.connect_signal('show_synced', self._data_show_synced) - self.data_handler.connect_signal( - 'sync_complete', self._data_sync_complete) - self.data_handler.connect_signal( - 'queue_changed', self._data_queue_changed) + self.data_handler.connect_signal('sync_complete', + self._data_sync_complete) + self.data_handler.connect_signal('queue_changed', + self._data_queue_changed) # Record the API details (self.api_info, self.mediainfo) = self.data_handler.get_api_info() @@ -192,8 +195,9 @@ def _get_tracker_list(self, filter_num=None): source_list = [] for status in filter_num: if status is not self.mediainfo['statuses_finish']: - self.msg.debug("Scanning for " - "{}".format(self.mediainfo['statuses_dict'][status])) + self.msg.debug( + "Scanning for " + "{}".format(self.mediainfo['statuses_dict'][status])) source_list = source_list + self.filter_list(status) else: source_list = self.filter_list(filter_num) @@ -264,15 +268,16 @@ def start(self): else: fname = utils.to_data_path('anime-relations.txt') if self.config['redirections_time'] and ( - not utils.file_exists(fname) or - utils.file_older_than(fname, self.config['redirections_time'] * 86400)): + not utils.file_exists(fname) or utils.file_older_than( + fname, self.config['redirections_time'] * 86400)): self.msg.info("Syncing redirection file...") self.msg.debug("Syncing from: %s" % self.config['redirections_url']) utils.sync_file(fname, self.config['redirections_url']) if not utils.file_exists(fname): - self.msg.debug("Defaulting to repo provided redirections file.") + self.msg.debug( + "Defaulting to repo provided redirections file.") fname = utils.DATADIR + '/anime-relations/anime-relations.txt' self.msg.info("Parsing redirection file...") @@ -286,10 +291,12 @@ def start(self): # Determine parser library try: self.msg.debug(self.name, "Initializing parser...") - self.parser_class = get_parser_class(self.msg, self.config['title_parser']) + self.parser_class = get_parser_class(self.msg, + self.config['title_parser']) except ImportError as e: - self.msg.warn(self.name, "Couldn't import specified parser: {}; {}".format( - self.config['title_parser'], e)) + self.msg.warn( + self.name, "Couldn't import specified parser: {}; {}".format( + self.config['title_parser'], e)) # Rescan library if necessary if self.config['library_autoscan']: @@ -312,7 +319,8 @@ def start(self): # for later calls. try: self.msg.debug("Importing hook {}...".format(name)) - module = loader.find_module(name).load_module(name) + module = loader.find_spec(name).loader.load_module( + name) if hasattr(module, 'init'): module.init(self) self.hooks_available.append(module) @@ -327,18 +335,19 @@ def start(self): TrackerClass = self._get_tracker_class( self.config['tracker_type']) - self.tracker = TrackerClass(self.msg, - self._get_tracker_list(), - self.config, - self.searchdirs, - self.redirections, - ) + self.tracker = TrackerClass( + self.msg, + self._get_tracker_list(), + self.config, + self.searchdirs, + self.redirections, + ) self.tracker.connect_signal('detected', self._tracker_detected) self.tracker.connect_signal('removed', self._tracker_removed) self.tracker.connect_signal('playing', self._tracker_playing) self.tracker.connect_signal('update', self._tracker_update) - self.tracker.connect_signal( - 'unrecognised', self._tracker_unrecognised) + self.tracker.connect_signal('unrecognised', + self._tracker_unrecognised) self.tracker.connect_signal('state', self._tracker_state) except ImportError: self.msg.warn("Couldn't import specified tracker: {}".format( @@ -366,8 +375,7 @@ def unload(self): # If there are loaded hooks, unload them self.msg.info("Unloading user hooks...") for module in self.hooks_available.copy(): - self.msg.debug("Unloading hook {}...".format( - module.__name__)) + self.msg.debug("Unloading hook {}...".format(module.__name__)) try: if hasattr(module, 'destroy'): module.destroy(self) @@ -449,7 +457,8 @@ def get_show_info(self, showid=None, title=None, filename=None): show = utils.guess_show(show_title, tracker_list) if show: - return utils.redirect_show((show, ep), self.redirections, tracker_list) + return utils.redirect_show((show, ep), self.redirections, + tracker_list) else: raise utils.EngineError("Show not found.") else: @@ -467,7 +476,8 @@ def regex_list(self, regex): list of show dictionaries with all the matches. """ showlist = self.data_handler.get() - return list(v for k, v in showlist.items() if re.search(regex, v['title'], re.I)) + return list(v for k, v in showlist.items() + if re.search(regex, v['title'], re.I)) def regex_list_titles(self, pattern): # TODO : Temporal hack for the client autocomplete function @@ -498,7 +508,8 @@ def search(self, criteria, method=utils.SearchMethod.KW): and returns it as a list of show dictionaries. This is useful to add a show. """ - if method not in self.mediainfo.get('search_methods', [utils.SearchMethod.KW]): + if method not in self.mediainfo.get('search_methods', + [utils.SearchMethod.KW]): raise utils.EngineError( 'Search method not supported by API or mediatype.') @@ -561,25 +572,28 @@ def set_episode(self, showid, newep): self._emit_signal('episode_changed', show) # Change status if required - if self.config['auto_status_change'] and self.mediainfo.get('can_status'): + if self.config['auto_status_change'] and self.mediainfo.get( + 'can_status'): try: - if newep == show['total'] and self.mediainfo.get('statuses_finish'): - if ( - not self.config['auto_status_change_if_scored'] or - not self.mediainfo.get('can_score') or - show['my_score'] - ): + if newep == show['total'] and self.mediainfo.get( + 'statuses_finish'): + if (not self.config['auto_status_change_if_scored'] + or not self.mediainfo.get('can_score') + or show['my_score']): # Change to finished status - self.set_status( - show['id'], self._guess_new_finish(show)) + self.set_status(show['id'], + self._guess_new_finish(show)) else: - self.msg.warn("Updated episode but status won't be changed until a score is set.") + self.msg.warn( + "Updated episode but status won't be changed until a score is set." + ) elif newep == 1 and self.mediainfo.get('statuses_start'): # Change to start status self.set_status(show['id'], self._guess_new_start(show)) except utils.EngineError as e: # Only warn about engine errors since status change here is not critical - self.msg.warn('Updated episode but status wasn\'t changed: %s' % e) + self.msg.warn( + 'Updated episode but status wasn\'t changed: %s' % e) # Change dates if required if self.config['auto_date_change'] and self.mediainfo.get('can_date'): @@ -594,7 +608,8 @@ def set_episode(self, showid, newep): self.set_dates(show['id'], start_date, finish_date) except utils.EngineError as e: # Only warn about engine errors since date change here is not critical - self.msg.warn('Updated episode but dates weren\'t changed: %s' % e) + self.msg.warn( + 'Updated episode but dates weren\'t changed: %s' % e) # Update the tracker with the new information self._update_tracker() @@ -632,7 +647,8 @@ def set_score(self, showid, newscore): raise utils.EngineError('Operation not supported by API.') # Check for the correctness of the score - if (Decimal(str(newscore)) % Decimal(str(self.mediainfo['score_step']))) != 0: + if (Decimal(str(newscore)) % + Decimal(str(self.mediainfo['score_step']))) != 0: raise utils.EngineError('Invalid score.') # Convert to proper type @@ -658,20 +674,17 @@ def set_score(self, showid, newscore): self._emit_signal('score_changed', show) # Change status if required - if ( - show['total'] and - show['my_progress'] == show['total'] and - show['my_score'] and - self.mediainfo.get('can_status') and - self.config['auto_status_change'] and - self.config['auto_status_change_if_scored'] and - self.mediainfo.get('statuses_finish') - ): + if (show['total'] and show['my_progress'] == show['total'] + and show['my_score'] and self.mediainfo.get('can_status') + and self.config['auto_status_change'] + and self.config['auto_status_change_if_scored'] + and self.mediainfo.get('statuses_finish')): try: self.set_status(show['id'], self._guess_new_finish(show)) except utils.EngineError as e: # Only warn about engine errors since status change here is not critical - self.msg.warn('Updated episode but status wasn\'t changed: %s' % e) + self.msg.warn( + 'Updated episode but status wasn\'t changed: %s' % e) return show @@ -718,7 +731,8 @@ def set_tags(self, showid, newtags): and queues the list update for the next sync. """ # Check if operation is supported by the API - if 'can_tag' not in self.mediainfo or not self.mediainfo.get('can_tag'): + if 'can_tag' not in self.mediainfo or not self.mediainfo.get( + 'can_tag'): raise utils.EngineError('Operation not supported by API.') # Get the show and update it @@ -791,7 +805,8 @@ def scan_library(self, my_status=None, rescan=False): filename = self._get_show_name_from_full_path( searchdir, fullpath) (library, library_cache) = self._add_show_to_library( - library, library_cache, rescan, fullpath, filename, tracker_list) + library, library_cache, rescan, fullpath, filename, + tracker_list) self.msg.debug("Time: %s" % (time.time() - t)) self.data_handler.library_save(library) @@ -802,14 +817,15 @@ def remove_from_library(self, path, filename): library = self.data_handler.library_get() library_cache = self.data_handler.library_cache_get() tracker_list = self._get_tracker_list() - fullpath = path+"/"+filename + fullpath = path + "/" + filename # Only remove if the filename matches library entry if filename in library_cache and library_cache[filename]: (show_id, show_ep) = library_cache[filename] if show_id and show_id in library \ and show_ep and show_ep in library[show_id].keys(): if library[show_id][show_ep] == fullpath: - self.msg.debug("File removed from local library: %s" % fullpath) + self.msg.debug("File removed from local library: %s" % + fullpath) library_cache.pop(filename, None) library[show_id].pop(show_ep, None) @@ -819,11 +835,12 @@ def add_to_library(self, path, filename, rescan=False): library = self.data_handler.library_get() library_cache = self.data_handler.library_cache_get() tracker_list = self._get_tracker_list() - fullpath = path+"/"+filename - self._add_show_to_library( - library, library_cache, rescan, fullpath, filename, tracker_list) + fullpath = path + "/" + filename + self._add_show_to_library(library, library_cache, rescan, fullpath, + filename, tracker_list) - def _add_show_to_library(self, library, library_cache, rescan, fullpath, filename, tracker_list): + def _add_show_to_library(self, library, library_cache, rescan, fullpath, + filename, tracker_list): show_id = None if not rescan and filename in library_cache: # If the filename was already seen before @@ -838,7 +855,8 @@ def _add_show_to_library(self, library, library_cache, rescan, fullpath, filenam show_ep_start = show_ep_end = show_ep self.msg.debug("File in cache: {}".format(fullpath)) else: - self.msg.debug("File in cache but skipped: {}".format(fullpath)) + self.msg.debug( + "File in cache but skipped: {}".format(fullpath)) return library, library_cache else: # If the filename has not been seen, extract @@ -857,20 +875,21 @@ def _add_show_to_library(self, library, library_cache, rescan, fullpath, filenam if show_ep_start == show_ep_end: # TODO : Support redirections for episode ranges (show, show_ep) = utils.redirect_show( - (show, show_ep_start), self.redirections, tracker_list) + (show, show_ep_start), self.redirections, + tracker_list) show_ep_end = show_ep_start = show_ep self.msg.debug("Redirected to: {} - {}".format( show['title'], show_ep)) library_cache[filename] = (show['id'], show_ep) else: - library_cache[filename] = ( - show['id'], (show_ep_start, show_ep_end)) + library_cache[filename] = (show['id'], (show_ep_start, + show_ep_end)) show_id = show['id'] else: - self.msg.debug("Unable to match '{}', skipping: {}" - .format(show_title, fullpath)) + self.msg.debug("Unable to match '{}', skipping: {}".format( + show_title, fullpath)) library_cache[filename] = None else: self.msg.debug("Not recognized, skipping: {}".format(fullpath)) @@ -880,7 +899,7 @@ def _add_show_to_library(self, library, library_cache, rescan, fullpath, filenam if show_id: if show_id not in library: library[show_id] = {} - for show_ep in range(show_ep_start, show_ep_end+1): + for show_ep in range(show_ep_start, show_ep_end + 1): library[show_id][show_ep] = fullpath return library, library_cache @@ -918,7 +937,7 @@ def play_random(self): try: show = self.get_show_info(showid) except utils.EngineError: - continue # In library but not available + continue # In library but not available if show['my_progress'] + 1 in eps: newep.append(show) @@ -955,7 +974,7 @@ def play_episode(self, show, playep=0): raise utils.EngineError('Episode beyond limits.') self.msg.info("Getting '%s' episode '%s' from library..." % - (show['title'], playep)) + (show['title'], playep)) try: filename = self.get_episode_path(show, playep) @@ -968,7 +987,8 @@ def play_episode(self, show, playep=0): args = shlex.split(self.config['player']) if not args: - raise utils.EngineError('Player not set up, check your config.json') + raise utils.EngineError( + 'Player not set up, check your config.json') args[0] = shutil.which(args[0]) @@ -1011,7 +1031,8 @@ def filter_list(self, status_num): If you need a list with all the shows, use :func:`get_list`. """ showlist = self.data_handler.get() - return list(v for k, v in showlist.items() if v['my_status'] == status_num) + return list(v for k, v in showlist.items() + if v['my_status'] == status_num) def list_download(self): """Asks the data handler to download the remote list.""" @@ -1037,7 +1058,8 @@ def _get_show_name_from_full_path(self, searchdir, fullpath): def _searchdir_exists(self, path): """Variation of dir_exists that warns the user if the path doesn't exist.""" if not utils.dir_exists(path): - self.msg.warn("The specified media directory {} doesn't exist!".format(path)) + self.msg.warn( + "The specified media directory {} doesn't exist!".format(path)) return False return True @@ -1059,7 +1081,7 @@ def _guess_new_start(self, show): # Use following start status if we're already in a finish status new_index = self.mediainfo['statuses_finish'].index( show['my_status']) - new_status = self.mediainfo['statuses_start'][new_index+1] + new_status = self.mediainfo['statuses_start'][new_index + 1] except ValueError: new_status = self.mediainfo['statuses_start'][0] except IndexError: