From 11fcfa82027340da8008098fed33191724d72ed9 Mon Sep 17 00:00:00 2001 From: Jason Mehring Date: Tue, 20 Aug 2013 01:54:47 -0400 Subject: [PATCH 1/5] Moved library and refactored to its now location. Modified anything firing libray.add/update/_release date to now fire library.add.movie... Conflicts: couchpotato/core/loader.py couchpotato/core/media/show/_base/main.py couchpotato/core/media/show/library/season/main.py --- couchpotato/core/loader.py | 38 ++++++++++------ .../core/media/_base/library/__init__.py | 14 ++++++ couchpotato/core/media/movie/_base/main.py | 6 +-- .../core/media/movie/library/__init__.py | 0 .../media/movie/library/movie/__init__.py | 6 +++ .../movie/library/movie}/main.py | 45 ++++++++++--------- couchpotato/core/media/movie/searcher/main.py | 4 +- couchpotato/core/plugins/library/__init__.py | 6 --- couchpotato/core/plugins/manage/main.py | 2 +- couchpotato/core/plugins/renamer/main.py | 2 +- couchpotato/core/plugins/scanner/main.py | 2 +- couchpotato/core/providers/metadata/base.py | 2 +- 12 files changed, 77 insertions(+), 50 deletions(-) create mode 100644 couchpotato/core/media/_base/library/__init__.py create mode 100644 couchpotato/core/media/movie/library/__init__.py create mode 100644 couchpotato/core/media/movie/library/movie/__init__.py rename couchpotato/core/{plugins/library => media/movie/library/movie}/main.py (80%) delete mode 100644 couchpotato/core/plugins/library/__init__.py diff --git a/couchpotato/core/loader.py b/couchpotato/core/loader.py index d9e7d787..7d92bfc6 100644 --- a/couchpotato/core/loader.py +++ b/couchpotato/core/loader.py @@ -10,9 +10,19 @@ class Loader(object): plugins = {} providers = {} - modules = {} + def addPath(self, root, base_path, priority, recursive=False): + for filename in os.listdir(os.path.join(root, *base_path)): + path = os.path.join(os.path.join(root, *base_path), filename) + if os.path.isdir(path) and filename[:2] != '__': + if not u'__init__.py' in os.listdir(path): + return + new_base_path = ''.join(s + '.' for s in base_path) + filename + self.paths[new_base_path.replace('.', '_')] = (priority, new_base_path, path) + if recursive: + self.addPath(root, base_path + [filename], priority, recursive=True) + def preload(self, root = ''): core = os.path.join(root, 'couchpotato', 'core') @@ -25,19 +35,14 @@ class Loader(object): } # Add providers to loader - provider_dir = os.path.join(root, 'couchpotato', 'core', 'providers') - for provider in os.listdir(provider_dir): - path = os.path.join(provider_dir, provider) - if os.path.isdir(path) and provider[:2] != '__' and '__init__.py' in os.listdir(path): - self.paths[provider + '_provider'] = (25, 'couchpotato.core.providers.' + provider, path) - + self.addPath(root, ['couchpotato', 'core', 'providers'], 25, recursive=False) + # Add media to loader - media_dir = os.path.join(root, 'couchpotato', 'core', 'media') - for media in os.listdir(media_dir): - path = os.path.join(media_dir, media) - if os.path.isdir(path) and media[:2] != '__' and '__init__.py' in os.listdir(path): - self.paths[media + '_media'] = (25, 'couchpotato.core.media.' + media, path) - + self.addPath(root, ['couchpotato', 'core', 'media'], 25, recursive=False) + + # Add Libraries to loader + self.addPath(root, ['couchpotato', 'core', 'media', 'movie'], 1, recursive=False) + self.addPath(root, ['couchpotato', 'core', 'media', 'show'], 1, recursive=False) for plugin_type, plugin_tuple in self.paths.iteritems(): priority, module, dir_name = plugin_tuple @@ -111,7 +116,12 @@ class Loader(object): def loadPlugins(self, module, name): try: - module.start() + klass = module.start() + klass.registerPlugin() + + if klass and getattr(klass, 'auto_register_static'): + klass.registerStatic(module.__file__) + return True except Exception, e: log.error('Failed loading plugin "%s": %s', (module.__file__, traceback.format_exc())) diff --git a/couchpotato/core/media/_base/library/__init__.py b/couchpotato/core/media/_base/library/__init__.py new file mode 100644 index 00000000..588a42d7 --- /dev/null +++ b/couchpotato/core/media/_base/library/__init__.py @@ -0,0 +1,14 @@ +from couchpotato.core.event import addEvent +from couchpotato.core.logger import CPLog +from couchpotato.core.plugins.base import Plugin + + +class LibraryBase(Plugin): + + _type = None + + def initType(self): + addEvent('library.types', self.getType) + + def getType(self): + return self._type diff --git a/couchpotato/core/media/movie/_base/main.py b/couchpotato/core/media/movie/_base/main.py index 448e9985..bf2a867e 100644 --- a/couchpotato/core/media/movie/_base/main.py +++ b/couchpotato/core/media/movie/_base/main.py @@ -319,7 +319,7 @@ class MovieBase(MovieTypeBase): if title.default: default_title = title.title fireEvent('notify.frontend', type = 'movie.busy.%s' % x, data = True) - fireEventAsync('library.update', identifier = movie.library.identifier, default_title = default_title, force = True, on_complete = self.createOnComplete(x)) + fireEventAsync('library.update.movie', identifier = movie.library.identifier, default_title = default_title, force = True, on_complete = self.createOnComplete(x)) db.expire_all() return { @@ -364,7 +364,7 @@ class MovieBase(MovieTypeBase): pass - library = fireEvent('library.add', single = True, attrs = params, update_after = update_library) + library = fireEvent('library.add.movie', single = True, attrs = params, update_after = update_library) # Status status_active, snatched_status, ignored_status, done_status, downloaded_status = \ @@ -391,7 +391,7 @@ class MovieBase(MovieTypeBase): if search_after: onComplete = self.createOnComplete(m.id) - fireEventAsync('library.update', params.get('identifier'), default_title = params.get('title', ''), on_complete = onComplete) + fireEventAsync('library.update.movie', params.get('identifier'), default_title = params.get('title', ''), on_complete = onComplete) search_after = False elif force_readd: diff --git a/couchpotato/core/media/movie/library/__init__.py b/couchpotato/core/media/movie/library/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/couchpotato/core/media/movie/library/movie/__init__.py b/couchpotato/core/media/movie/library/movie/__init__.py new file mode 100644 index 00000000..03494a11 --- /dev/null +++ b/couchpotato/core/media/movie/library/movie/__init__.py @@ -0,0 +1,6 @@ +from .main import MovieLibraryPlugin + +def start(): + return MovieLibraryPlugin() + +config = [] diff --git a/couchpotato/core/plugins/library/main.py b/couchpotato/core/media/movie/library/movie/main.py similarity index 80% rename from couchpotato/core/plugins/library/main.py rename to couchpotato/core/media/movie/library/movie/main.py index 1842ed70..51091273 100644 --- a/couchpotato/core/plugins/library/main.py +++ b/couchpotato/core/media/movie/library/movie/main.py @@ -2,8 +2,8 @@ from couchpotato import get_session from couchpotato.core.event import addEvent, fireEventAsync, fireEvent from couchpotato.core.helpers.encoding import toUnicode, simplifyString from couchpotato.core.logger import CPLog -from couchpotato.core.plugins.base import Plugin from couchpotato.core.settings.model import Library, LibraryTitle, File +from couchpotato.core.media._base.library import LibraryBase from string import ascii_letters import time import traceback @@ -11,29 +11,35 @@ import traceback log = CPLog(__name__) -class LibraryPlugin(Plugin): +class MovieLibraryPlugin(LibraryBase): default_dict = {'titles': {}, 'files':{}} def __init__(self): - addEvent('library.add', self.add) - addEvent('library.update', self.update) - addEvent('library.update_release_date', self.updateReleaseDate) + addEvent('library.add.movie', self.add) + addEvent('library.update.movie', self.update) + addEvent('library.update.movie_release_date', self.updateReleaseDate) def add(self, attrs = {}, update_after = True): - + # movies don't yet contain these, so lets make sure to set defaults + type = attrs.get('type', 'movie') + primary_provider = attrs.get('primary_provider', 'imdb') + db = get_session() - - l = db.query(Library).filter_by(identifier = attrs.get('identifier')).first() + + l = db.query(Library).filter_by(type = type, identifier = attrs.get('identifier')).first() if not l: status = fireEvent('status.get', 'needs_update', single = True) l = Library( + type = type, + primary_provider = primary_provider, year = attrs.get('year'), identifier = attrs.get('identifier'), plot = toUnicode(attrs.get('plot')), tagline = toUnicode(attrs.get('tagline')), status_id = status.get('id'), info = {}, + parent = None, ) title = LibraryTitle( @@ -49,7 +55,7 @@ class LibraryPlugin(Plugin): # Update library info if update_after is not False: handle = fireEventAsync if update_after is 'async' else fireEvent - handle('library.update', identifier = l.identifier, default_title = toUnicode(attrs.get('title', ''))) + handle('library.update.movie', identifier = l.identifier, default_title = toUnicode(attrs.get('title', ''))) library_dict = l.to_dict(self.default_dict) @@ -70,20 +76,17 @@ class LibraryPlugin(Plugin): do_update = True - if library.status_id == done_status.get('id') and not force: - do_update = False - else: - info = fireEvent('movie.info', merge = True, identifier = identifier) + info = fireEvent('movie.info', merge = True, identifier = identifier) - # Don't need those here - try: del info['in_wanted'] - except: pass - try: del info['in_library'] - except: pass + # Don't need those here + try: del info['in_wanted'] + except: pass + try: del info['in_library'] + except: pass - if not info or len(info) == 0: - log.error('Could not update, no movie info to work with: %s', identifier) - return False + if not info or len(info) == 0: + log.error('Could not update, no movie info to work with: %s', identifier) + return False # Main info if do_update: diff --git a/couchpotato/core/media/movie/searcher/main.py b/couchpotato/core/media/movie/searcher/main.py index 8fb4acf1..7ea09d86 100644 --- a/couchpotato/core/media/movie/searcher/main.py +++ b/couchpotato/core/media/movie/searcher/main.py @@ -100,7 +100,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase): self.single(movie_dict, search_protocols) except IndexError: log.error('Forcing library update for %s, if you see this often, please report: %s', (movie_dict['library']['identifier'], traceback.format_exc())) - fireEvent('library.update', movie_dict['library']['identifier'], force = True) + fireEvent('library.update.movie', movie_dict['library']['identifier'], force = True) except: log.error('Search failed for %s: %s', (movie_dict['library']['identifier'], traceback.format_exc())) @@ -133,7 +133,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase): db = get_session() pre_releases = fireEvent('quality.pre_releases', single = True) - release_dates = fireEvent('library.update_release_date', identifier = movie['library']['identifier'], merge = True) + release_dates = fireEvent('library.update.movie_release_date', identifier = movie['library']['identifier'], merge = True) available_status, ignored_status, failed_status = fireEvent('status.get', ['available', 'ignored', 'failed'], single = True) found_releases = [] diff --git a/couchpotato/core/plugins/library/__init__.py b/couchpotato/core/plugins/library/__init__.py deleted file mode 100644 index f5970329..00000000 --- a/couchpotato/core/plugins/library/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from .main import LibraryPlugin - -def start(): - return LibraryPlugin() - -config = [] diff --git a/couchpotato/core/plugins/manage/main.py b/couchpotato/core/plugins/manage/main.py index 63584636..516cb882 100644 --- a/couchpotato/core/plugins/manage/main.py +++ b/couchpotato/core/plugins/manage/main.py @@ -182,7 +182,7 @@ class Manage(Plugin): # Add it to release and update the info fireEvent('release.add', group = group) - fireEventAsync('library.update', identifier = identifier, on_complete = self.createAfterUpdate(folder, identifier)) + fireEventAsync('library.update.movie', identifier = identifier, on_complete = self.createAfterUpdate(folder, identifier)) else: self.in_progress[folder]['to_go'] = self.in_progress[folder]['to_go'] - 1 diff --git a/couchpotato/core/plugins/renamer/main.py b/couchpotato/core/plugins/renamer/main.py index 53d13fd0..36acc254 100644 --- a/couchpotato/core/plugins/renamer/main.py +++ b/couchpotato/core/plugins/renamer/main.py @@ -161,7 +161,7 @@ class Renamer(Plugin): continue # Rename the files using the library data else: - group['library'] = fireEvent('library.update', identifier = group['library']['identifier'], single = True) + group['library'] = fireEvent('library.update.movie', identifier = group['library']['identifier'], single = True) if not group['library']: log.error('Could not rename, no library item to work with: %s', group_identifier) continue diff --git a/couchpotato/core/plugins/scanner/main.py b/couchpotato/core/plugins/scanner/main.py index 9407636f..73f22914 100644 --- a/couchpotato/core/plugins/scanner/main.py +++ b/couchpotato/core/plugins/scanner/main.py @@ -620,7 +620,7 @@ class Scanner(Plugin): log.debug('Identifier to short to use for search: %s', identifier) if imdb_id: - return fireEvent('library.add', attrs = { + return fireEvent('library.add.movie', attrs = { 'identifier': imdb_id }, update_after = False, single = True) diff --git a/couchpotato/core/providers/metadata/base.py b/couchpotato/core/providers/metadata/base.py index d7de8988..d2393ddc 100644 --- a/couchpotato/core/providers/metadata/base.py +++ b/couchpotato/core/providers/metadata/base.py @@ -24,7 +24,7 @@ class MetaDataBase(Plugin): # Update library to get latest info try: - updated_library = fireEvent('library.update', group['library']['identifier'], force = True, single = True) + updated_library = fireEvent('library.update.movie', group['library']['identifier'], force = True, single = True) group['library'] = mergeDicts(group['library'], updated_library) except: log.error('Failed to update movie, before creating metadata: %s', traceback.format_exc()) From 7dd3b0ed15406a260214628ecba4cc6993389d94 Mon Sep 17 00:00:00 2001 From: Jason Mehring Date: Fri, 23 Aug 2013 15:32:47 -0400 Subject: [PATCH 2/5] fix loader error messages for modules that are selected recursively but are not really modules --- couchpotato/core/loader.py | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/couchpotato/core/loader.py b/couchpotato/core/loader.py index 7d92bfc6..8846cf2c 100644 --- a/couchpotato/core/loader.py +++ b/couchpotato/core/loader.py @@ -21,10 +21,9 @@ class Loader(object): new_base_path = ''.join(s + '.' for s in base_path) + filename self.paths[new_base_path.replace('.', '_')] = (priority, new_base_path, path) if recursive: - self.addPath(root, base_path + [filename], priority, recursive=True) - - def preload(self, root = ''): + self.addPath(root, base_path + [filename], priority, recursive = True) + def preload(self, root = ''): core = os.path.join(root, 'couchpotato', 'core') self.paths = { @@ -35,14 +34,14 @@ class Loader(object): } # Add providers to loader - self.addPath(root, ['couchpotato', 'core', 'providers'], 25, recursive=False) - + self.addPath(root, ['couchpotato', 'core', 'providers'], 25, recursive = False) + # Add media to loader - self.addPath(root, ['couchpotato', 'core', 'media'], 25, recursive=False) - + self.addPath(root, ['couchpotato', 'core', 'media'], 25, recursive = False) + # Add Libraries to loader - self.addPath(root, ['couchpotato', 'core', 'media', 'movie'], 1, recursive=False) - self.addPath(root, ['couchpotato', 'core', 'media', 'show'], 1, recursive=False) + self.addPath(root, ['couchpotato', 'core', 'media', 'movie'], 1, recursive = False) + self.addPath(root, ['couchpotato', 'core', 'media', 'show'], 1, recursive = False) for plugin_type, plugin_tuple in self.paths.iteritems(): priority, module, dir_name = plugin_tuple @@ -58,7 +57,10 @@ class Loader(object): if plugin.get('name')[:2] == '__': continue - m = getattr(self.loadModule(module_name), plugin.get('name')) + m = self.loadModule(module_name) + if m is None: + continue + m = getattr(m, plugin.get('name')) log.info('Loading %s: %s', (plugin['type'], plugin['name'])) @@ -101,6 +103,9 @@ class Loader(object): self.addModule(priority, plugin_type, module_name, name) def loadSettings(self, module, name, save = True): + if not hasattr(module, 'config'): + log.warning('Skip loading settings for plugin %s as it has no config section' % module.__file__) + return False try: for section in module.config: fireEvent('settings.options', section['name'], section) @@ -115,6 +120,9 @@ class Loader(object): return False def loadPlugins(self, module, name): + if not hasattr(module, 'start'): + log.warning('Skip startup for plugin %s as it has no start section' % module.__file__) + return False try: klass = module.start() klass.registerPlugin() @@ -146,5 +154,8 @@ class Loader(object): for sub in splitted[1:-1]: m = getattr(m, sub) return m + except ImportError: + log.warning("Skip loading module plugin '%s' as it seems not to be a module." % name) + return None except: raise From f1948ffb6a915de988b8d0669ebcf8797d9df98e Mon Sep 17 00:00:00 2001 From: Ruud Date: Sat, 24 Aug 2013 20:12:59 +0200 Subject: [PATCH 3/5] Just load media recursively --- couchpotato/core/loader.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/couchpotato/core/loader.py b/couchpotato/core/loader.py index 8846cf2c..c6c5c7cf 100644 --- a/couchpotato/core/loader.py +++ b/couchpotato/core/loader.py @@ -37,11 +37,7 @@ class Loader(object): self.addPath(root, ['couchpotato', 'core', 'providers'], 25, recursive = False) # Add media to loader - self.addPath(root, ['couchpotato', 'core', 'media'], 25, recursive = False) - - # Add Libraries to loader - self.addPath(root, ['couchpotato', 'core', 'media', 'movie'], 1, recursive = False) - self.addPath(root, ['couchpotato', 'core', 'media', 'show'], 1, recursive = False) + self.addPath(root, ['couchpotato', 'core', 'media'], 25, recursive = True) for plugin_type, plugin_tuple in self.paths.iteritems(): priority, module, dir_name = plugin_tuple @@ -124,13 +120,7 @@ class Loader(object): log.warning('Skip startup for plugin %s as it has no start section' % module.__file__) return False try: - klass = module.start() - klass.registerPlugin() - - if klass and getattr(klass, 'auto_register_static'): - klass.registerStatic(module.__file__) - - return True + module.start() except Exception, e: log.error('Failed loading plugin "%s": %s', (module.__file__, traceback.format_exc())) return False From 54a37b577de38012908434b212324b80f8ad1c26 Mon Sep 17 00:00:00 2001 From: Ruud Date: Sat, 24 Aug 2013 19:14:09 +0200 Subject: [PATCH 4/5] Import cleanup Conflicts: couchpotato/core/providers/torrent/sceneaccess/main.py --- couchpotato/core/loader.py | 19 +++++++++++-------- .../core/media/_base/library/__init__.py | 1 - 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/couchpotato/core/loader.py b/couchpotato/core/loader.py index c6c5c7cf..a45a2c04 100644 --- a/couchpotato/core/loader.py +++ b/couchpotato/core/loader.py @@ -6,20 +6,20 @@ import traceback log = CPLog(__name__) -class Loader(object): +class Loader(object): plugins = {} providers = {} modules = {} - def addPath(self, root, base_path, priority, recursive=False): + def addPath(self, root, base_path, priority, recursive = False): for filename in os.listdir(os.path.join(root, *base_path)): path = os.path.join(os.path.join(root, *base_path), filename) if os.path.isdir(path) and filename[:2] != '__': if not u'__init__.py' in os.listdir(path): return - new_base_path = ''.join(s + '.' for s in base_path) + filename - self.paths[new_base_path.replace('.', '_')] = (priority, new_base_path, path) + new_base_path = ''.join(s + '.' for s in base_path) + filename + self.paths[new_base_path.replace('.', '_')] = (priority, new_base_path, path) if recursive: self.addPath(root, base_path + [filename], priority, recursive = True) @@ -94,14 +94,16 @@ class Loader(object): for cur_file in glob.glob(os.path.join(dir_name, '*')): name = os.path.basename(cur_file) - if os.path.isdir(os.path.join(dir_name, name)): + if os.path.isdir(os.path.join(dir_name, name)) and name != 'static': module_name = '%s.%s' % (module, name) self.addModule(priority, plugin_type, module_name, name) def loadSettings(self, module, name, save = True): + if not hasattr(module, 'config'): - log.warning('Skip loading settings for plugin %s as it has no config section' % module.__file__) + log.debug('Skip loading settings for plugin %s as it has no config section' % module.__file__) return False + try: for section in module.config: fireEvent('settings.options', section['name'], section) @@ -116,8 +118,9 @@ class Loader(object): return False def loadPlugins(self, module, name): + if not hasattr(module, 'start'): - log.warning('Skip startup for plugin %s as it has no start section' % module.__file__) + log.debug('Skip startup for plugin %s as it has no start section' % module.__file__) return False try: module.start() @@ -145,7 +148,7 @@ class Loader(object): m = getattr(m, sub) return m except ImportError: - log.warning("Skip loading module plugin '%s' as it seems not to be a module." % name) + log.debug('Skip loading module plugin %s: %s', (name, traceback.format_exc())) return None except: raise diff --git a/couchpotato/core/media/_base/library/__init__.py b/couchpotato/core/media/_base/library/__init__.py index 588a42d7..553eff5a 100644 --- a/couchpotato/core/media/_base/library/__init__.py +++ b/couchpotato/core/media/_base/library/__init__.py @@ -1,5 +1,4 @@ from couchpotato.core.event import addEvent -from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin From 65896497fb84be32701e6ebf0806461192a3da87 Mon Sep 17 00:00:00 2001 From: Ruud Date: Sat, 24 Aug 2013 20:22:31 +0200 Subject: [PATCH 5/5] Return true for loader --- couchpotato/core/loader.py | 1 + 1 file changed, 1 insertion(+) diff --git a/couchpotato/core/loader.py b/couchpotato/core/loader.py index a45a2c04..ffb05cb4 100644 --- a/couchpotato/core/loader.py +++ b/couchpotato/core/loader.py @@ -124,6 +124,7 @@ class Loader(object): return False try: module.start() + return True except Exception, e: log.error('Failed loading plugin "%s": %s', (module.__file__, traceback.format_exc())) return False