diff --git a/couchpotato/core/_base/_core/main.py b/couchpotato/core/_base/_core/main.py index 22b5a91b..02e21f2d 100644 --- a/couchpotato/core/_base/_core/main.py +++ b/couchpotato/core/_base/_core/main.py @@ -42,11 +42,11 @@ class Core(Plugin): addEvent('app.shutdown', self.shutdown) addEvent('app.restart', self.restart) - addEvent('app.load2', self.launchBrowser, priority = 1) + addEvent('app.load', self.launchBrowser, priority = 1) addEvent('app.base_url', self.createBaseUrl) addEvent('app.api_url', self.createApiUrl) addEvent('app.version', self.version) - addEvent('app.load2', self.checkDataDir) + addEvent('app.load', self.checkDataDir) addEvent('setting.save.core.password', self.md5Password) addEvent('setting.save.core.api_key', self.checkApikey) diff --git a/couchpotato/core/_base/clientscript/main.py b/couchpotato/core/_base/clientscript/main.py index 1c9d82a6..248d2bc5 100644 --- a/couchpotato/core/_base/clientscript/main.py +++ b/couchpotato/core/_base/clientscript/main.py @@ -74,7 +74,7 @@ class ClientScript(Plugin): addEvent('clientscript.get_scripts', self.getScripts) if not Env.get('dev'): - addEvent('app.load2', self.minify) + addEvent('app.load', self.minify) self.addCore() diff --git a/couchpotato/core/_base/desktop/main.py b/couchpotato/core/_base/desktop/main.py index 21499159..c3beff17 100644 --- a/couchpotato/core/_base/desktop/main.py +++ b/couchpotato/core/_base/desktop/main.py @@ -25,7 +25,7 @@ if Env.get('desktop'): # Events to desktop addEvent('app.after_shutdown', desktop.afterShutdown) - addEvent('app.load2', desktop.onAppLoad, priority = 110) + addEvent('app.load', desktop.onAppLoad, priority = 110) def onClose(self, event): return fireEvent('app.shutdown', single = True) diff --git a/couchpotato/core/_base/updater/main.py b/couchpotato/core/_base/updater/main.py index aad4eee2..ef595ad7 100644 --- a/couchpotato/core/_base/updater/main.py +++ b/couchpotato/core/_base/updater/main.py @@ -33,8 +33,8 @@ class Updater(Plugin): else: self.updater = SourceUpdater() - addEvent('app.load2', self.logVersion, priority = 10000) - addEvent('app.load2', self.setCrons) + addEvent('app.load', self.logVersion, priority = 10000) + addEvent('app.load', self.setCrons) addEvent('updater.info', self.info) addApiView('updater.info', self.info, docs = { diff --git a/couchpotato/core/downloaders/rtorrent/main.py b/couchpotato/core/downloaders/rtorrent/main.py index 23b7a25c..27177756 100755 --- a/couchpotato/core/downloaders/rtorrent/main.py +++ b/couchpotato/core/downloaders/rtorrent/main.py @@ -23,7 +23,7 @@ class rTorrent(Downloader): def __init__(self): super(rTorrent, self).__init__() - addEvent('app.load2', self.migrate) + addEvent('app.load', self.migrate) def migrate(self): diff --git a/couchpotato/core/helpers/variable.py b/couchpotato/core/helpers/variable.py index 47810a66..fc910dff 100644 --- a/couchpotato/core/helpers/variable.py +++ b/couchpotato/core/helpers/variable.py @@ -216,26 +216,24 @@ def toIterable(value): return [value] -def getTitle(library_dict): +def getTitle(media_dict): try: try: - return library_dict['titles'][0]['title'] + return media_dict['title'] except: try: - for title in library_dict.titles: - if title.default: - return title.title + return media_dict['titles'][0] except: try: - return library_dict['info']['titles'][0] + return media_dict['info']['titles'][0] except: - log.error('Could not get title for %s', library_dict.identifier) + log.error('Could not get title for %s', media_dict.get('identifier')) return None - log.error('Could not get title for %s', library_dict['identifier']) + log.error('Could not get title for %s', media_dict['identifier']) return None except: - log.error('Could not get title for library item: %s', library_dict) + log.error('Could not get title for library item: %s', media_dict) return None diff --git a/couchpotato/core/media/__init__.py b/couchpotato/core/media/__init__.py index db87aa75..c7ae732a 100644 --- a/couchpotato/core/media/__init__.py +++ b/couchpotato/core/media/__init__.py @@ -1,8 +1,7 @@ import traceback -from couchpotato import get_session, get_db, CPLog -from couchpotato.core.event import addEvent, fireEventAsync, fireEvent +from couchpotato import get_db, CPLog +from couchpotato.core.event import addEvent, fireEvent, fireEventAsync from couchpotato.core.plugins.base import Plugin -from couchpotato.core.settings.model import Media log = CPLog(__name__) @@ -34,11 +33,9 @@ class MediaBase(Plugin): media = db.get('id', media_id) event_name = '%s.searcher.single' % media.get('type') - fireEvent(event_name, media, on_complete = self.createNotifyFront(media_id)) + fireEventAsync(event_name, media, on_complete = self.createNotifyFront(media_id)) except: log.error('Failed creating onComplete: %s', traceback.format_exc()) - finally: - pass #db.close() return onComplete @@ -53,7 +50,5 @@ class MediaBase(Plugin): fireEvent('notify.frontend', type = event_name, data = media) except: log.error('Failed creating onComplete: %s', traceback.format_exc()) - finally: - pass #db.close() return notifyFront diff --git a/couchpotato/core/media/_base/library/__init__.py b/couchpotato/core/media/_base/library/__init__.py deleted file mode 100644 index 553eff5a..00000000 --- a/couchpotato/core/media/_base/library/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -from couchpotato.core.event import addEvent -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/_base/media/index.py b/couchpotato/core/media/_base/media/index.py index e930dd3c..97b16066 100644 --- a/couchpotato/core/media/_base/media/index.py +++ b/couchpotato/core/media/_base/media/index.py @@ -14,9 +14,14 @@ class MediaIMDBIndex(HashIndex): return int(key.strip('t')) def make_key_value(self, data): - if data.get('type') == 'media' and data.get('identifier'): + if data.get('_t') == 'media' and data.get('identifier'): return int(data['identifier'].strip('t')), None + def run_to_dict(self, db, media_id, dict = None): + if not dict: dict = {} + + return db.get('id', media_id) + def run_with_status(self, db, status = []): status = list(status if isinstance(status, (list, tuple)) else [status]) @@ -29,15 +34,15 @@ class MediaIMDBIndex(HashIndex): class MediaStatusIndex(TreeBasedIndex): def __init__(self, *args, **kwargs): - kwargs['key_format'] = '16s' + kwargs['key_format'] = '32s' super(MediaStatusIndex, self).__init__(*args, **kwargs) def make_key(self, key): - return md5(key).digest() + return md5(key).hexdigest() def make_key_value(self, data): - if data.get('type') == 'media' and data.get('status'): - return md5(data.get('status')).digest(), None + if data.get('_t') == 'media' and data.get('status'): + return md5(data.get('status')).hexdigest(), None class TitleIndex(MultiTreeBasedIndex): @@ -52,7 +57,7 @@ from itertools import izip""" def make_key_value(self, data): - if data.get('type') == 'title' and len(data.get('title', '')) > 0: + if data.get('_t') == 'title' and len(data.get('title', '')) > 0: out = set() title = data.get('title').lower() @@ -80,5 +85,5 @@ class YearIndex(TreeBasedIndex): return key def make_key_value(self, data): - if data.get('type') == 'media' and data.get('year') is not None: + if data.get('_t') == 'media' and data.get('year') is not None: return data['year'], None diff --git a/couchpotato/core/media/_base/media/main.py b/couchpotato/core/media/_base/media/main.py index 2b56ac79..b4b0cc18 100644 --- a/couchpotato/core/media/_base/media/main.py +++ b/couchpotato/core/media/_base/media/main.py @@ -1,16 +1,14 @@ import traceback +import time from couchpotato import get_session, tryInt, get_db from couchpotato.api import addApiView from couchpotato.core.event import fireEvent, fireEventAsync, addEvent -from couchpotato.core.helpers.encoding import toUnicode from couchpotato.core.helpers.variable import mergeDicts, splitString, getImdb, getTitle from couchpotato.core.logger import CPLog from couchpotato.core.media import MediaBase from .index import MediaIMDBIndex, TitleIndex, MediaStatusIndex, YearIndex from couchpotato.core.settings.model import Library, LibraryTitle, Release, \ Media -from sqlalchemy.orm import joinedload_all -from sqlalchemy.sql.expression import or_, asc, not_, desc from string import ascii_lowercase log = CPLog(__name__) @@ -63,10 +61,10 @@ class MediaPlugin(MediaBase): addEvent('database.setup', self.databaseSetup) - addEvent('app.load2', self.addSingleRefreshView) - addEvent('app.load2', self.addSingleListView) - addEvent('app.load2', self.addSingleCharView) - addEvent('app.load2', self.addSingleDeleteView) + addEvent('app.load', self.addSingleRefreshView) + addEvent('app.load', self.addSingleListView) + addEvent('app.load', self.addSingleCharView) + addEvent('app.load', self.addSingleDeleteView) addEvent('media.get', self.get) addEvent('media.list', self.list) @@ -126,7 +124,7 @@ class MediaPlugin(MediaBase): try: media = get_db().get('id', media_id) - default_title = getTitle(media_id) + default_title = getTitle(media) event = 'library.update.%s' % media.get('type') def handler(): @@ -157,7 +155,7 @@ class MediaPlugin(MediaBase): results = None if m: - results = db.run('media', 'to_dict', m, self.default_dict) + results = db.run('media', 'to_dict', m['_id']) return results @@ -172,7 +170,9 @@ class MediaPlugin(MediaBase): def list(self, types = None, status = None, release_status = None, limit_offset = None, starts_with = None, search = None, order = None): - db = get_session() + db = get_db() + + start = time.time() # Make a list from string if status and not isinstance(status, (list, tuple)): @@ -182,120 +182,128 @@ class MediaPlugin(MediaBase): if types and not isinstance(types, (list, tuple)): types = [types] - # query movie ids - q = db.query(Media) \ - .with_entities(Media.id) \ - .group_by(Media.id) + # query media ids + all_media_ids = set([x['_id'] for x in db.all('media')]) + media_ids = all_media_ids + filter_by = {} # Filter on movie status if status and len(status) > 0: - statuses = fireEvent('status.get', status, single = len(status) > 1) - statuses = [s.get('id') for s in statuses] - - q = q.filter(Media.status_id.in_(statuses)) + filter_by['media_status'] = set() + for media_status in db.run('media', 'with_status', status): + filter_by['media_status'].add(media_status.get('_id')) # Filter on release status if release_status and len(release_status) > 0: - q = q.join(Media.releases) + filter_by['release_status'] = set() + for release_status in db.run('release', 'with_status', release_status): + filter_by['release_status'].add(release_status.get('media_id')) - statuses = fireEvent('status.get', release_status, single = len(release_status) > 1) - statuses = [s.get('id') for s in statuses] - - q = q.filter(Release.status_id.in_(statuses)) + # Filter by combining ids + for x in filter_by: + media_ids = media_ids & filter_by[x] # Filter on type - if types and len(types) > 0: - try: q = q.filter(Media.type.in_(types)) - except: pass + # if types and len(types) > 0: + # try: q = q.filter(Media.type.in_(types)) + # except: pass # Only join when searching / ordering - if starts_with or search or order != 'release_order': - q = q.join(Media.library, Library.titles) \ - .filter(LibraryTitle.default == True) + # if starts_with or search or order != 'release_order': + # q = q.join(Media.library, Library.titles) \ + # .filter(LibraryTitle.default == True) # Add search filters - filter_or = [] - if starts_with: - starts_with = toUnicode(starts_with.lower()) - if starts_with in ascii_lowercase: - filter_or.append(LibraryTitle.simple_title.startswith(starts_with)) - else: - ignore = [] - for letter in ascii_lowercase: - ignore.append(LibraryTitle.simple_title.startswith(toUnicode(letter))) - filter_or.append(not_(or_(*ignore))) + # filter_or = [] + # if starts_with: + # starts_with = toUnicode(starts_with.lower()) + # if starts_with in ascii_lowercase: + # filter_or.append(LibraryTitle.simple_title.startswith(starts_with)) + # else: + # ignore = [] + # for letter in ascii_lowercase: + # ignore.append(LibraryTitle.simple_title.startswith(toUnicode(letter))) + # filter_or.append(not_(or_(*ignore))) if search: - filter_or.append(LibraryTitle.simple_title.like('%%' + search + '%%')) + search_ids = db.get_many('media_title', search) + for search_id in search_ids: + print search_id - if len(filter_or) > 0: - q = q.filter(or_(*filter_or)) + #if len(filter_or) > 0: + # pass #q = q.filter(or_(*filter_or)) - total_count = q.count() + total_count = len(media_ids) if total_count == 0: return 0, [] - if order == 'release_order': - q = q.order_by(desc(Release.last_edit)) - else: - q = q.order_by(asc(LibraryTitle.simple_title)) + # if order == 'release_order': + # q = q.order_by(desc(Release.last_edit)) + # else: + # q = q.order_by(asc(LibraryTitle.simple_title)) - if limit_offset: - splt = splitString(limit_offset) if isinstance(limit_offset, (str, unicode)) else limit_offset - limit = splt[0] - offset = 0 if len(splt) is 1 else splt[1] - q = q.limit(limit).offset(offset) + # if limit_offset: + # splt = splitString(limit_offset) if isinstance(limit_offset, (str, unicode)) else limit_offset + # limit = splt[0] + # offset = 0 if len(splt) is 1 else splt[1] + # q = q.limit(limit).offset(offset) # Get all media_ids in sorted order - media_ids = [m.id for m in q.all()] + # media_ids = [m.id for m in q.all()] # List release statuses - releases = db.query(Release) \ - .filter(Release.movie_id.in_(media_ids)) \ - .all() + # releases = db.query(Release) \ + # .filter(Release.movie_id.in_(media_ids)) \ + # .all() - release_statuses = dict((m, set()) for m in media_ids) - releases_count = dict((m, 0) for m in media_ids) - for release in releases: - release_statuses[release.movie_id].add('%d,%d' % (release.status_id, release.quality_id)) - releases_count[release.movie_id] += 1 + # release_statuses = dict((m, set()) for m in media_ids) + # releases_count = dict((m, 0) for m in media_ids) + # for release in releases: + # release_statuses[release.movie_id].add('%d,%d' % (release.status_id, release.quality_id)) + # releases_count[release.movie_id] += 1 # Get main movie data - q2 = db.query(Media) \ - .options(joinedload_all('library.titles')) \ - .options(joinedload_all('library.files')) \ - .options(joinedload_all('status')) \ - .options(joinedload_all('files')) + # q2 = db.query(Media) \ + # .options(joinedload_all('library.titles')) \ + # .options(joinedload_all('library.files')) \ + # .options(joinedload_all('status')) \ + # .options(joinedload_all('files')) - q2 = q2.filter(Media.id.in_(media_ids)) + # q2 = q2.filter(Media.id.in_(media_ids)) - results = q2.all() + # results = q2.all() # Create dict by movie id - movie_dict = {} - for movie in results: - movie_dict[movie.id] = movie + # medias = {} + # for media in media_ids: + # movie_dict[movie.id] = movie # List movies based on media_ids order - movies = [] + medias = [] for media_id in media_ids: - releases = [] - for r in release_statuses.get(media_id): - x = splitString(r) - releases.append({'status_id': x[0], 'quality_id': x[1]}) - - # Merge releases with movie dict - movies.append(mergeDicts(movie_dict[media_id].to_dict({ + media = db.run('media', 'to_dict', media_id, { 'library': {'titles': {}, 'files': {}}, 'files': {}, - }), { - 'releases': releases, - 'releases_count': releases_count.get(media_id), - })) + }) - pass #db.close() - return total_count, movies + media['releases'] = [] + for r in db.get_many('release', media_id, with_doc = True): + media['releases'].append(r) + + # Merge releases with movie dict + medias.append(media) + # medias.append(mergeDicts(movie_dict[media_id].to_dict({ + # 'library': {'titles': {}, 'files': {}}, + # 'files': {}, + # }), { + # 'releases': releases, + # 'releases_count': releases_count.get(media_id), + # })) + + print time.time() - start + + return total_count, medias def listView(self, **kwargs): @@ -424,19 +432,18 @@ class MediaPlugin(MediaBase): db.commit() deleted = True else: - done_status = fireEvent('status.get', 'done', single = True) total_releases = len(media.releases) total_deleted = 0 new_movie_status = None for release in media.releases: if delete_from in ['wanted', 'snatched', 'late']: - if release.status_id != done_status.get('id'): + if release.get('status') != 'done': db.delete(release) total_deleted += 1 new_movie_status = 'done' elif delete_from == 'manage': - if release.status_id == done_status.get('id'): + if release.get('status') == 'done': db.delete(release) total_deleted += 1 new_movie_status = 'active' @@ -447,9 +454,8 @@ class MediaPlugin(MediaBase): db.commit() deleted = True elif new_movie_status: - new_status = fireEvent('status.get', new_movie_status, single = True) media.profile_id = None - media.status_id = new_status.get('id') + media['status'] = new_status db.commit() else: fireEvent('media.restatus', media.id, single = True) @@ -458,9 +464,6 @@ class MediaPlugin(MediaBase): fireEvent('notify.frontend', type = 'movie.deleted', data = media.to_dict()) except: log.error('Failed deleting media: %s', traceback.format_exc()) - db.rollback() - finally: - pass #db.close() return True @@ -483,8 +486,6 @@ class MediaPlugin(MediaBase): def restatus(self, media_id): - active_status, done_status = fireEvent('status.get', ['active', 'done'], single = True) - try: db = get_session() @@ -494,17 +495,17 @@ class MediaPlugin(MediaBase): return False log.debug('Changing status for %s', m.library.titles[0].title) - if not m.profile: - m.status_id = done_status.get('id') + if not m['profile_id']: + m['status'] = 'done' else: move_to_wanted = True for t in m.profile.types: for release in m.releases: - if t.quality.identifier is release.quality.identifier and (release.status_id is done_status.get('id') and t.finish): + if t.quality.identifier is release.quality.identifier and (release.get('status') == 'done' and t.finish): move_to_wanted = False - m.status_id = active_status.get('id') if move_to_wanted else done_status.get('id') + m['status'] = 'active' if move_to_wanted else 'done' db.commit() diff --git a/couchpotato/core/media/_base/search/main.py b/couchpotato/core/media/_base/search/main.py index 6f0f5172..81897b5f 100644 --- a/couchpotato/core/media/_base/search/main.py +++ b/couchpotato/core/media/_base/search/main.py @@ -25,7 +25,7 @@ class Search(Plugin): }"""} }) - addEvent('app.load2', self.addSingleSearches) + addEvent('app.load', self.addSingleSearches) def search(self, q = '', types = None, **kwargs): diff --git a/couchpotato/core/media/_base/searcher/base.py b/couchpotato/core/media/_base/searcher/base.py index 60799bf0..5322d850 100644 --- a/couchpotato/core/media/_base/searcher/base.py +++ b/couchpotato/core/media/_base/searcher/base.py @@ -28,7 +28,7 @@ class SearcherBase(Plugin): fireEvent('schedule.cron', '%s.searcher.all' % _type, self.searchAll, day = self.conf('cron_day'), hour = self.conf('cron_hour'), minute = self.conf('cron_minute')) - addEvent('app.load2', setCrons) + addEvent('app.load', setCrons) addEvent('setting.save.%s_searcher.cron_day.after' % _type, setCrons) addEvent('setting.save.%s_searcher.cron_hour.after' % _type, setCrons) addEvent('setting.save.%s_searcher.cron_minute.after' % _type, setCrons) diff --git a/couchpotato/core/media/_base/searcher/main.py b/couchpotato/core/media/_base/searcher/main.py index e7209b60..8c0eaa0f 100644 --- a/couchpotato/core/media/_base/searcher/main.py +++ b/couchpotato/core/media/_base/searcher/main.py @@ -48,7 +48,7 @@ class Searcher(SearcherBase): results = [] for search_protocol in protocols: - protocol_results = fireEvent('provider.search.%s.%s' % (search_protocol, media['type']), media, quality, merge = True) + protocol_results = fireEvent('provider.search.%s.%s' % (search_protocol, media.get('type')), media, quality, merge = True) if protocol_results: results += protocol_results diff --git a/couchpotato/core/media/movie/_base/main.py b/couchpotato/core/media/movie/_base/main.py index 306766c4..f35d4a8b 100644 --- a/couchpotato/core/media/movie/_base/main.py +++ b/couchpotato/core/media/movie/_base/main.py @@ -1,13 +1,13 @@ import traceback -from couchpotato import get_session, get_db +from couchpotato import get_db from couchpotato.api import addApiView from couchpotato.core.event import fireEvent, fireEventAsync, addEvent from couchpotato.core.helpers.encoding import toUnicode from couchpotato.core.helpers.variable import splitString, tryInt, getTitle from couchpotato.core.logger import CPLog from couchpotato.core.media.movie import MovieTypeBase -from couchpotato.core.settings.model import Media import time +import six log = CPLog(__name__) @@ -42,8 +42,10 @@ class MovieBase(MovieTypeBase): }) addEvent('movie.add', self.add) + addEvent('movie.update_info', self.updateInfo) + addEvent('movie.update_release_dates', self.updateReleaseDate) - def add(self, params = None, force_readd = True, search_after = True, update_library = False, status_id = None): + def add(self, params = None, force_readd = True, search_after = True, update_library = False, status = None): if not params: params = {} if not params.get('identifier'): @@ -62,27 +64,55 @@ class MovieBase(MovieTypeBase): except: pass - # library = fireEvent('library.add.movie', single = True, attrs = params, update_after = update_library) info = fireEvent('movie.info', merge = True, extended = False, identifier = params.get('identifier')) + # Set default title + default_title = toUnicode(info.get('title')) + titles = info.get('titles', []) + counter = 0 + def_title = None + for title in titles: + if (len(default_title) == 0 and counter == 0) or len(titles) == 1 or title.lower() == toUnicode(default_title.lower()) or (toUnicode(default_title) == six.u('') and toUnicode(titles[0]) == title): + def_title = toUnicode(title) + break + counter += 1 + + if not def_title: + def_title = toUnicode(titles[0]) + + # Default profile and category default_profile = fireEvent('profile.default', single = True) cat_id = params.get('category_id') try: db = get_db() + media = { + '_t': 'media', + 'type': 'movie', + 'title': def_title, + 'identifier': params.get('identifier'), + 'status': status if status else 'active', + 'profile_id': params.get('profile_id', default_profile.get('_id')), + 'category_id': tryInt(cat_id) if cat_id is not None and tryInt(cat_id) > 0 else None, + } + new = False try: - m = db.get('movie', params.get('identifier'), with_doc = True)['doc'] + m = db.get('media', params.get('identifier'), with_doc = True)['doc'] except: new = True - m = db.insert({ - 'type': 'movie', - 'identifier': params.get('identifier'), - 'status': status_id if status_id else 'active', - 'profile_id': params.get('profile_id', default_profile.get('id')), - 'category_id': tryInt(cat_id) if cat_id is not None and tryInt(cat_id) > 0 else None, - }) + m = db.insert(media) + + # Update dict to be usable + m.update(media) + + # Update movie info + try: del info['in_wanted'] + except: pass + try: del info['in_library'] + except: pass + m['info'] = info added = True do_search = False @@ -92,7 +122,7 @@ class MovieBase(MovieTypeBase): if search_after: onComplete = self.createOnComplete(m['_id']) - # fireEventAsync('library.update.movie', params.get('identifier'), default_title = params.get('title', ''), on_complete = onComplete) + fireEventAsync('movie.update_info', m['_id'], default_title = params.get('title', ''), on_complete = onComplete) search_after = False elif force_readd: @@ -106,24 +136,24 @@ class MovieBase(MovieTypeBase): fireEvent('release.delete', release['_id'], single = True) m['profile_id'] = params.get('profile_id', default_profile.get('id')) - m['category_id'] = tryInt(cat_id) if cat_id is not None and tryInt(cat_id) > 0 else (m['category_id'] or None) + m['category_id'] = tryInt(cat_id) if cat_id is not None and tryInt(cat_id) > 0 else (m.get('category_id') or None) else: log.debug('Movie already exists, not updating: %s', params) added = False if force_readd: - m['status'] = status_id if status_id else 'active' m['last_edit'] = int(time.time()) do_search = True - db.update(m) + if added: + db.update(m) # Remove releases for rel in db.run('release', 'for_media', m['_id']): if rel['status'] is 'available': db.delete(rel) - movie_dict = db.run('movie', 'to_dict', m['_id']) + movie_dict = db.run('media', 'to_dict', m['_id']) if do_search and search_after: onComplete = self.createOnComplete(m['_id']) @@ -137,7 +167,7 @@ class MovieBase(MovieTypeBase): if title: message = 'Successfully added "%s" to your wanted list.' % title else: - message = 'Succesfully added to your wanted list.' + message = 'Successfully added to your wanted list.' fireEvent('notify.frontend', type = 'movie.added', data = movie_dict, message = message) return movie_dict @@ -161,7 +191,7 @@ class MovieBase(MovieTypeBase): for media_id in ids: try: - m = db.get('media', media_id) + m = db.get('id', media_id) m['profile_id'] = kwargs.get('profile_id') cat_id = kwargs.get('category_id') @@ -197,3 +227,128 @@ class MovieBase(MovieTypeBase): return { 'success': False, } + + def updateInfo(self, media_id = None, identifier = None, default_title = None, extended = False): + """ + Update movie information inside media['doc']['info'] + + @param media_id: document id + @param default_title: default title, if empty, use first one or existing one + @param extended: update with extended info (parses more info, actors, images from some info providers) + @return: dict, with media + """ + + if self.shuttingDown(): + return + + try: + db = get_db() + + if media_id: + media = db.get('id', media_id) + else: + media = db.get('media', identifier, with_doc = True)['doc'] + + info = fireEvent('movie.info', merge = True, extended = extended, identifier = media.get('identifier')) + + # 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', media.get('identifier')) + return False + + # Update basic info + media['info'] = info + + titles = info.get('titles', []) + log.debug('Adding titles: %s', titles) + counter = 0 + + def_title = None + for title in titles: + if (len(default_title) == 0 and counter == 0) or len(titles) == 1 or title.lower() == toUnicode(default_title.lower()) or (toUnicode(default_title) == six.u('') and toUnicode(titles[0]) == title): + def_title = toUnicode(title) + break + counter += 1 + + if not def_title: + def_title = toUnicode(titles[0]) + + media = { + 'title': def_title, + } + + # Files + images = info.get('images', []) + media['files'] = media.get('filed', []) + for image_type in ['poster']: + for image in images.get(image_type, []): + if not isinstance(image, (str, unicode)): + continue + + file_path = fireEvent('file.download', url = image, single = True) + media['files'].append({ + 'type': 'image_%s' % image_type, + 'path': file_path + }) + + db.update(media) + + return media + except: + log.error('Failed update media: %s', traceback.format_exc()) + + return {} + + def updateReleaseDate(self, media_id): + """ + Update releasedate (eta) info only + + @param media_id: document id + @return: dict, with dates dvd, theater, bluray, expires + """ + + try: + db = get_db() + + media = db.get('id', media_id) + + if not media.get('info'): + info_dict = self.updateInfo(media_id) + dates = info_dict.get('info', {}).get('release_date') + else: + dates = media.get('info').get('release_date') + + if dates and (dates.get('expires', 0) < time.time() or dates.get('expires', 0) > time.time() + (604800 * 4)) or not dates: + dates = fireEvent('movie.info.release_date', identifier = media['identifier'], merge = True) + media['info'].update({'release_date': dates}) + db.update(media) + + return dates + except: + log.error('Failed updating release dates: %s', traceback.format_exc()) + + return {} + + def simplifyTitle(self, title): + """ + Removes all special chars from a title so it's easier to make sortable + @param title: media title + @return: string, simplified title + """ + + title = toUnicode(title) + + nr_prefix = '' if title[0] in ascii_letters else '#' + title = simplifyString(title) + + for prefix in ['the ']: + if prefix == title[:len(prefix)]: + title = title[len(prefix):] + break + + return nr_prefix + title diff --git a/couchpotato/core/media/movie/_base/static/movie.actions.js b/couchpotato/core/media/movie/_base/static/movie.actions.js index 66c84c68..c5186935 100644 --- a/couchpotato/core/media/movie/_base/static/movie.actions.js +++ b/couchpotato/core/media/movie/_base/static/movie.actions.js @@ -191,11 +191,9 @@ MA.Release = new Class({ self.releases.each(function(release){ - var status = Status.get(release.status_id), - quality = Quality.getProfile(release.quality_id) || {}, + var quality = Quality.getProfile(release.quality_id) || {}, info = release.info, provider = self.get(release, 'provider') + (release.info['provider_extra'] ? self.get(release, 'provider_extra') : ''); - release.status = status; var release_name = self.get(release, 'name'); if(release.files && release.files.length > 0){ @@ -215,7 +213,7 @@ MA.Release = new Class({ 'id': 'release_'+release.id }).adopt( new Element('span.name', {'text': release_name, 'title': release_name}), - new Element('span.status', {'text': status.identifier, 'class': 'release_status '+status.identifier}), + new Element('span.status', {'text': status.identifier, 'class': 'release_status '+release.status}), new Element('span.quality', {'text': quality.get('label') || 'n/a'}), new Element('span.size', {'text': release.info['size'] ? Math.floor(self.get(release, 'size')) : 'n/a'}), new Element('span.age', {'text': self.get(release, 'age')}), @@ -257,22 +255,20 @@ MA.Release = new Class({ if(notification.data.id != release.id) return; var q = self.movie.quality.getElement('.q_id' + release.quality_id), - status = Status.get(release.status_id), - new_status = Status.get(notification.data.status_id); + new_status = notification.data.status; - release.status_id = new_status.id - release.el.set('class', 'item ' + new_status.identifier); + release.el.set('class', 'item ' + new_status); var status_el = release.el.getElement('.release_status'); - status_el.set('class', 'release_status ' + new_status.identifier); + status_el.set('class', 'release_status ' + new_status); status_el.set('text', new_status.identifier); - if(!q && (new_status.identifier == 'snatched' || new_status.identifier == 'seeding' || new_status.identifier == 'done')) + if(!q && (new_status == 'snatched' || new_status == 'seeding' || new_status == 'done')) var q = self.addQuality(release.quality_id); - if(new_status && q && !q.hasClass(new_status.identifier)) { - q.removeClass(status.identifier).addClass(new_status.identifier); - q.set('title', q.get('title').replace(status.label, new_status.label)); + if(q && !q.hasClass(new_status)) { + q.removeClass(release.status).addClass(new_status); + q.set('title', q.get('title').replace(status, new_status)); } } @@ -344,12 +340,10 @@ MA.Release = new Class({ self.movie.data.releases.each(function(release){ if(has_available && has_snatched) return; - var status = Status.get(release.status_id); - - if(['snatched', 'downloaded', 'seeding'].contains(status.identifier)) + if(['snatched', 'downloaded', 'seeding'].contains(release.status)) has_snatched = true; - if(['available'].contains(status.identifier)) + if(['available'].contains(release.status)) has_available = true; }); @@ -726,10 +720,10 @@ MA.Readd = new Class({ create: function(){ var self = this; - var movie_done = Status.get(self.movie.data.status_id).identifier == 'done'; + var movie_done = self.movie.data.status == 'done'; if(!movie_done) var snatched = self.movie.data.releases.filter(function(release){ - return release.status && (release.status.identifier == 'snatched' || release.status.identifier == 'downloaded' || release.status.identifier == 'done'); + return release.status && (release.status == 'snatched' || release.status == 'downloaded' || release.status == 'done'); }).length; if(movie_done || snatched && snatched > 0) @@ -924,4 +918,4 @@ MA.Files = new Class({ self.movie.slide('in', self.options_container); }, -}); \ No newline at end of file +}); diff --git a/couchpotato/core/media/movie/_base/static/movie.js b/couchpotato/core/media/movie/_base/static/movie.js index 3ca1912c..bd290dcd 100644 --- a/couchpotato/core/media/movie/_base/static/movie.js +++ b/couchpotato/core/media/movie/_base/static/movie.js @@ -59,7 +59,7 @@ var Movie = new Class({ if(!self.data.releases) self.data.releases = []; - self.data.releases.push({'quality_id': data.quality_id, 'status_id': data.status_id}); + self.data.releases.push({'quality_id': data.quality_id, 'status': data.status}); self.updateReleases(); } } @@ -146,8 +146,7 @@ var Movie = new Class({ create: function(){ var self = this; - var s = Status.get(self.get('status_id')); - self.el.addClass('status_'+s.identifier); + self.el.addClass('status_'+self.get('status')); self.el.adopt( self.select_checkbox = new Element('input[type=checkbox].inlay', { @@ -157,7 +156,7 @@ var Movie = new Class({ } } }), - self.thumbnail = File.Select.single('poster', self.data.library.files), + self.thumbnail = File.Select.single('poster', self.data.files || []), self.data_container = new Element('div.data.inlay.light').adopt( self.info_container = new Element('div.info').adopt( new Element('div.title').adopt( @@ -165,11 +164,11 @@ var Movie = new Class({ 'text': self.getTitle() || 'n/a' }), self.year = new Element('div.year', { - 'text': self.data.library.year || 'n/a' + 'text': self.data.info.year || 'n/a' }) ), self.description = new Element('div.description', { - 'text': self.data.library.plot + 'text': self.data.info.plot }), self.quality = new Element('div.quality', { 'events': { @@ -221,14 +220,14 @@ var Movie = new Class({ self.data.releases.each(function(release){ var q = self.quality.getElement('.q_id'+ release.quality_id), - status = Status.get(release.status_id); + status = release.status; - if(!q && (status.identifier == 'snatched' || status.identifier == 'seeding' || status.identifier == 'done')) + if(!q && (status == 'snatched' || status == 'seeding' || status == 'done')) var q = self.addQuality(release.quality_id) - if (status && q && !q.hasClass(status.identifier)){ - q.addClass(status.identifier); - q.set('title', (q.get('title') ? q.get('title') : '') + ' status: '+ status.label) + if (q && !q.hasClass(status)){ + q.addClass(status); + q.set('title', (q.get('title') ? q.get('title') : '') + ' status: '+ status) } }); @@ -249,16 +248,10 @@ var Movie = new Class({ getTitle: function(){ var self = this; - var titles = self.data.library.titles; - - var title = titles.filter(function(title){ - return title['default'] - }).pop() - - if(title) - return self.getUnprefixedTitle(title.title) - else if(titles.length > 0) - return self.getUnprefixedTitle(titles[0].title) + if(self.data.title) + return self.getUnprefixedTitle(self.data.title) + else if(self.data.info.titles.length > 0) + return self.getUnprefixedTitle(self.data.info.titles[0]) return 'Unknown movie' }, @@ -313,7 +306,7 @@ var Movie = new Class({ }, get: function(attr){ - return this.data[attr] || this.data.library[attr] + return this.data[attr] || this.data.info[attr] }, select: function(bool){ diff --git a/couchpotato/core/media/movie/_base/static/search.js b/couchpotato/core/media/movie/_base/static/search.js index e04167f0..61842149 100644 --- a/couchpotato/core/media/movie/_base/static/search.js +++ b/couchpotato/core/media/movie/_base/static/search.js @@ -197,8 +197,8 @@ Block.Search.MovieItem = new Class({ profiles.each(function(profile){ new Element('option', { - 'value': profile.id ? profile.id : profile.data.id, - 'text': profile.label ? profile.label : profile.data.label + 'value': profile.get('_id'), + 'text': profile.get('label') }).inject(self.profile_select) }); diff --git a/couchpotato/core/media/movie/library/__init__.py b/couchpotato/core/media/movie/library/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/couchpotato/core/media/movie/library/movie/__init__.py b/couchpotato/core/media/movie/library/movie/__init__.py deleted file mode 100644 index 98ed54c0..00000000 --- a/couchpotato/core/media/movie/library/movie/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .main import MovieLibraryPlugin - - -def start(): - return MovieLibraryPlugin() - -config = [] diff --git a/couchpotato/core/media/movie/library/movie/main.py b/couchpotato/core/media/movie/library/movie/main.py deleted file mode 100644 index 663c6d04..00000000 --- a/couchpotato/core/media/movie/library/movie/main.py +++ /dev/null @@ -1,193 +0,0 @@ -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.media._base.library import LibraryBase -from couchpotato.core.settings.model import Library, LibraryTitle, File -from string import ascii_letters -import time -import traceback -import six - -log = CPLog(__name__) - - -class MovieLibraryPlugin(LibraryBase): - - default_dict = {'titles': {}, 'files': {}} - - def __init__(self): - addEvent('library.add.movie', self.add) - addEvent('library.update.movie', self.update) - addEvent('library.update.movie.release_date', self.updateReleaseDate) - - def add(self, attrs = None, update_after = True): - if not attrs: attrs = {} - - primary_provider = attrs.get('primary_provider', 'imdb') - - try: - db = get_session() - - l = db.query(Library).filter_by(identifier = attrs.get('identifier')).first() - if not l: - status = fireEvent('status.get', 'needs_update', single = True) - l = Library( - year = attrs.get('year'), - identifier = attrs.get('identifier'), - plot = toUnicode(attrs.get('plot')), - tagline = toUnicode(attrs.get('tagline')), - status_id = status.get('id'), - info = {} - ) - - title = LibraryTitle( - title = toUnicode(attrs.get('title')), - simple_title = self.simplifyTitle(attrs.get('title')), - ) - - l.titles.append(title) - - db.add(l) - db.commit() - - # Update library info - if update_after is not False: - handle = fireEventAsync if update_after is 'async' else fireEvent - handle('library.update.movie', identifier = l.identifier, default_title = toUnicode(attrs.get('title', ''))) - - library_dict = l.to_dict(self.default_dict) - return library_dict - except: - log.error('Failed adding media: %s', traceback.format_exc()) - db.rollback() - finally: - pass #db.close() - - return {} - - def update(self, identifier, default_title = '', extended = False): - - if self.shuttingDown(): - return - - try: - db = get_session() - - library = db.query(Library).filter_by(identifier = identifier).first() - done_status = fireEvent('status.get', 'done', single = True) - - info = fireEvent('movie.info', merge = True, extended = extended, identifier = identifier) - - # 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 - - # Main info - library.plot = toUnicode(info.get('plot', '')) - library.tagline = toUnicode(info.get('tagline', '')) - library.year = info.get('year', 0) - library.status_id = done_status.get('id') - library.info.update(info) - db.commit() - - # Titles - [db.delete(title) for title in library.titles] - db.commit() - - titles = info.get('titles', []) - log.debug('Adding titles: %s', titles) - counter = 0 - - def_title = None - for title in titles: - if (len(default_title) == 0 and counter == 0) or len(titles) == 1 or title.lower() == toUnicode(default_title.lower()) or (toUnicode(default_title) == six.u('') and toUnicode(titles[0]) == title): - def_title = toUnicode(title) - break - counter += 1 - - if not def_title: - def_title = toUnicode(titles[0]) - - for title in titles: - if not title: - continue - title = toUnicode(title) - t = LibraryTitle( - title = title, - simple_title = self.simplifyTitle(title), - default = title == def_title - ) - library.titles.append(t) - - db.commit() - - # Files - images = info.get('images', []) - library['files'] = [] - for image_type in ['poster']: - for image in images.get(image_type, []): - if not isinstance(image, (str, unicode)): - continue - - file_path = fireEvent('file.download', url = image, single = True) - - # TODO: save in movie doc - library['files'].append({ - 'type': 'image_%s' % image_type, - 'path': file_path - }) - - library_dict = library.to_dict(self.default_dict) - return library_dict - except: - log.error('Failed update media: %s', traceback.format_exc()) - - return {} - - def updateReleaseDate(self, identifier): - - try: - db = get_session() - library = db.query(Library).filter_by(identifier = identifier).first() - - if not library.info: - library_dict = self.update(identifier) - dates = library_dict.get('info', {}).get('release_date') - else: - dates = library.info.get('release_date') - - if dates and (dates.get('expires', 0) < time.time() or dates.get('expires', 0) > time.time() + (604800 * 4)) or not dates: - dates = fireEvent('movie.release_date', identifier = identifier, merge = True) - library.info.update({'release_date': dates}) - db.commit() - - return dates - except: - log.error('Failed updating release dates: %s', traceback.format_exc()) - db.rollback() - finally: - pass #db.close() - - return {} - - - def simplifyTitle(self, title): - - title = toUnicode(title) - - nr_prefix = '' if title[0] in ascii_letters else '#' - title = simplifyString(title) - - for prefix in ['the ']: - if prefix == title[:len(prefix)]: - title = title[len(prefix):] - break - - return nr_prefix + title diff --git a/couchpotato/core/media/movie/searcher/main.py b/couchpotato/core/media/movie/searcher/main.py index b4665deb..fdff2fd9 100644 --- a/couchpotato/core/media/movie/searcher/main.py +++ b/couchpotato/core/media/movie/searcher/main.py @@ -1,4 +1,4 @@ -from couchpotato import get_session, get_db +from couchpotato import get_db from couchpotato.api import addApiView from couchpotato.core.event import addEvent, fireEvent, fireEventAsync from couchpotato.core.helpers.encoding import simplifyString @@ -6,7 +6,6 @@ from couchpotato.core.helpers.variable import getTitle, possibleTitles, getImdb from couchpotato.core.logger import CPLog from couchpotato.core.media._base.searcher.base import SearcherBase from couchpotato.core.media.movie import MovieTypeBase -from couchpotato.core.settings.model import Media, Release from couchpotato.environment import Env from datetime import date import random @@ -51,7 +50,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase): }) if self.conf('run_on_launch'): - addEvent('app.load2', self.searchAll) + addEvent('app.load', self.searchAll) def searchAllView(self, **kwargs): @@ -94,7 +93,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['identifier'], traceback.format_exc())) - fireEvent('library.update.movie', movie['identifier']) + fireEvent('movie.update_info', movie['_id']) except: log.error('Search failed for %s: %s', (movie['identifier'], traceback.format_exc())) @@ -111,10 +110,6 @@ class MovieSearcher(SearcherBase, MovieTypeBase): def single(self, movie, search_protocols = None, manual = False): - # movies don't contain 'type' yet, so just set to default here - if 'type' not in movie: - movie['type'] = 'movie' - # Find out search type try: if not search_protocols: @@ -127,7 +122,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase): return pre_releases = fireEvent('quality.pre_releases', single = True) - release_dates = fireEvent('library.update.movie.release_date', identifier = movie['library']['identifier'], merge = True) + release_dates = fireEvent('movie.update_release_date', media_id = movie['_id'], merge = True) found_releases = [] too_early_to_search = [] @@ -142,39 +137,50 @@ class MovieSearcher(SearcherBase, MovieTypeBase): db = get_db() + profile = db.get('id', movie['profile_id']) + quality_order = fireEvent('quality.order', single = True) + media_releases = db.get_many('release', movie['_id']) + ret = False - for quality_type in movie['profile']['types']: - if not self.conf('always_search') and not self.couldBeReleased(quality_type['quality']['identifier'] in pre_releases, release_dates, movie['year']): - too_early_to_search.append(quality_type['quality']['identifier']) + for q_identifier in profile.get('qualities'): + index = profile['qualities'].index(q_identifier) + quality_custom = { + 'quality': q_identifier, + 'finish': profile['finish'][index], + 'wait_for': profile['wait_for'][index] + } + + if not self.conf('always_search') and not self.couldBeReleased(q_identifier in pre_releases, release_dates, movie['info']['year']): + too_early_to_search.append(q_identifier) continue has_better_quality = 0 # See if better quality is available - for release in movie['releases']: - if release['quality']['order'] <= quality_type['quality']['order'] and release['status'] not in ['available', 'ignored', 'failed']: + for release in media_releases: + if quality_order.index(release['quality']) <= quality_order.index(q_identifier) and release['status'] not in ['available', 'ignored', 'failed']: has_better_quality += 1 # Don't search for quality lower then already available. if has_better_quality is 0: - log.info('Search for %s in %s', (default_title, quality_type['quality']['label'])) - quality = fireEvent('quality.single', identifier = quality_type['quality']['identifier'], single = True) + quality = fireEvent('quality.single', identifier = q_identifier, single = True) + log.info('Search for %s in %s', (default_title, quality['label'])) results = fireEvent('searcher.search', search_protocols, movie, quality, single = True) or [] if len(results) == 0: - log.debug('Nothing found for %s in %s', (default_title, quality_type['quality']['label'])) + log.debug('Nothing found for %s in %s', (default_title, quality['label'])) # Check if movie isn't deleted while searching if not fireEvent('media.get', movie.get('_id'), single = True): break # Add them to this movie releases list - found_releases += fireEvent('release.create_from_search', results, movie, quality_type, single = True) + found_releases += fireEvent('release.create_from_search', results, movie, quality, single = True) # Try find a valid result and download it - if fireEvent('release.try_download_result', results, movie, quality_type, manual, single = True): + if fireEvent('release.try_download_result', results, movie, quality_custom, manual, single = True): ret = True # Remove releases that aren't found anymore @@ -183,7 +189,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase): fireEvent('release.delete', release.get('_id'), single = True) else: - log.info('Better quality (%s) already available or snatched for %s', (quality_type['quality']['label'], default_title)) + log.info('Better quality (%s) already available or snatched for %s', (quality['label'], default_title)) fireEvent('media.restatus', movie['_id']) break @@ -219,7 +225,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase): preferred_quality = fireEvent('quality.single', identifier = quality['identifier'], single = True) # Contains lower quality string - if fireEvent('searcher.contains_other_quality', nzb, movie_year = media['library']['year'], preferred_quality = preferred_quality, single = True): + if fireEvent('searcher.contains_other_quality', nzb, movie_year = media['info']['year'], preferred_quality = preferred_quality, single = True): log.info2('Wrong: %s, looking for %s', (nzb['name'], quality['label'])) return False @@ -249,23 +255,23 @@ class MovieSearcher(SearcherBase, MovieTypeBase): return True # Check if nzb contains imdb link - if getImdb(nzb.get('description', '')) == media['library']['identifier']: + if getImdb(nzb.get('description', '')) == media['identifier']: return True - for raw_title in media['library']['titles']: - for movie_title in possibleTitles(raw_title['title']): + for raw_title in media['info']['titles']: + for movie_title in possibleTitles(raw_title): movie_words = re.split('\W+', simplifyString(movie_title)) if fireEvent('searcher.correct_name', nzb['name'], movie_title, single = True): # if no IMDB link, at least check year range 1 - if len(movie_words) > 2 and fireEvent('searcher.correct_year', nzb['name'], media['library']['year'], 1, single = True): + if len(movie_words) > 2 and fireEvent('searcher.correct_year', nzb['name'], media['info']['year'], 1, single = True): return True # if no IMDB link, at least check year - if len(movie_words) <= 2 and fireEvent('searcher.correct_year', nzb['name'], media['library']['year'], 0, single = True): + if len(movie_words) <= 2 and fireEvent('searcher.correct_year', nzb['name'], media['info']['year'], 0, single = True): return True - log.info("Wrong: %s, undetermined naming. Looking for '%s (%s)'", (nzb['name'], media_title, media['library']['year'])) + log.info("Wrong: %s, undetermined naming. Looking for '%s (%s)'", (nzb['name'], media_title, media['info']['year'])) return False def couldBeReleased(self, is_pre_release, dates, year = None): @@ -337,7 +343,7 @@ class MovieSearcher(SearcherBase, MovieTypeBase): def getSearchTitle(self, media): if media['type'] == 'movie': - return getTitle(media['library']) + return getTitle(media) class SearchSetupError(Exception): pass diff --git a/couchpotato/core/media/movie/suggestion/main.py b/couchpotato/core/media/movie/suggestion/main.py index eaccbe64..55cf7062 100644 --- a/couchpotato/core/media/movie/suggestion/main.py +++ b/couchpotato/core/media/movie/suggestion/main.py @@ -89,8 +89,6 @@ class Suggestion(Plugin): # Get new results and add them if len(new_suggestions) - 1 < limit: - active_status, done_status = fireEvent('status.get', ['active', 'done'], single = True) - db = get_session() active_movies = db.query(Media) \ .join(Library) \ diff --git a/couchpotato/core/notifications/core/index.py b/couchpotato/core/notifications/core/index.py index e51124d6..a6fb13d4 100644 --- a/couchpotato/core/notifications/core/index.py +++ b/couchpotato/core/notifications/core/index.py @@ -15,7 +15,7 @@ import time""" return key def make_key_value(self, data): - if data.get('type') == 'notification': + if data.get('_t') == 'notification': added = data.get('added', time.time()) data['added'] = added @@ -35,7 +35,7 @@ import time""" return key def make_key_value(self, data): - if data.get('type') == 'notification' and not data.get('read'): + if data.get('_t') == 'notification' and not data.get('read'): added = data.get('added', time.time()) data['added'] = added diff --git a/couchpotato/core/notifications/core/main.py b/couchpotato/core/notifications/core/main.py index 2eb5a302..5610ef28 100644 --- a/couchpotato/core/notifications/core/main.py +++ b/couchpotato/core/notifications/core/main.py @@ -57,8 +57,8 @@ class CoreNotifier(Notification): fireEvent('schedule.interval', 'core.check_messages', self.checkMessages, hours = 12, single = True) fireEvent('schedule.interval', 'core.clean_messages', self.cleanMessages, seconds = 15, single = True) - addEvent('app.load2', self.clean) - addEvent('app.load2', self.checkMessages) + addEvent('app.load', self.clean) + addEvent('app.load', self.checkMessages) addEvent('database.setup', self.databaseSetup) @@ -161,7 +161,7 @@ class CoreNotifier(Notification): data['notification_type'] = listener if listener else 'unknown' n = { - 'type': 'notification', + '_t': 'notification', 'time': int(time.time()), 'message': toUnicode(message), 'data': data diff --git a/couchpotato/core/notifications/growl/main.py b/couchpotato/core/notifications/growl/main.py index 68d73cb1..a3927ed2 100644 --- a/couchpotato/core/notifications/growl/main.py +++ b/couchpotato/core/notifications/growl/main.py @@ -16,7 +16,7 @@ class Growl(Notification): super(Growl, self).__init__() if self.isEnabled(): - addEvent('app.load2', self.register) + addEvent('app.load', self.register) def register(self): if self.registered: return diff --git a/couchpotato/core/notifications/pushover/main.py b/couchpotato/core/notifications/pushover/main.py index ba954a54..b90c2118 100644 --- a/couchpotato/core/notifications/pushover/main.py +++ b/couchpotato/core/notifications/pushover/main.py @@ -23,16 +23,16 @@ class Pushover(Notification): 'priority': self.conf('priority'), } - if data and data.get('library'): + if data and data.get('identifier'): api_data.update({ - 'url': toUnicode('http://www.imdb.com/title/%s/' % data['library']['identifier']), - 'url_title': toUnicode('%s on IMDb' % getTitle(data['library'])), + 'url': toUnicode('http://www.imdb.com/title/%s/' % data['identifier']), + 'url_title': toUnicode('%s on IMDb' % getTitle(data)), }) http_handler.request('POST', - "/1/messages.json", - headers = {'Content-type': 'application/x-www-form-urlencoded'}, - body = tryUrlencode(api_data) + "/1/messages.json", + headers = {'Content-type': 'application/x-www-form-urlencoded'}, + body = tryUrlencode(api_data) ) response = http_handler.getresponse() diff --git a/couchpotato/core/notifications/trakt/main.py b/couchpotato/core/notifications/trakt/main.py index c759c6db..55eee425 100644 --- a/couchpotato/core/notifications/trakt/main.py +++ b/couchpotato/core/notifications/trakt/main.py @@ -1,3 +1,4 @@ +from couchpotato.core.helpers.variable import getTitle from couchpotato.core.logger import CPLog from couchpotato.core.notifications.base import Notification @@ -21,9 +22,9 @@ class Trakt(Notification): 'username': self.conf('automation_username'), 'password' : self.conf('automation_password'), 'movies': [{ - 'imdb_id': data['library']['identifier'], - 'title': data['library']['titles'][0]['title'], - 'year': data['library']['year'] + 'imdb_id': data['identifier'], + 'title': getTitle(data), + 'year': data['info']['year'] }] if data else [] } diff --git a/couchpotato/core/notifications/xbmc/main.py b/couchpotato/core/notifications/xbmc/main.py index bfda85e1..31a776c5 100755 --- a/couchpotato/core/notifications/xbmc/main.py +++ b/couchpotato/core/notifications/xbmc/main.py @@ -1,4 +1,4 @@ -from couchpotato.core.helpers.variable import splitString +from couchpotato.core.helpers.variable import splitString, getTitle from couchpotato.core.logger import CPLog from couchpotato.core.notifications.base import Notification import base64 @@ -131,7 +131,7 @@ class XBMC(Notification): server = 'http://%s/xbmcCmds/' % host # Notification(title, message [, timeout , image]) - cmd = "xbmcHttp?command=ExecBuiltIn(Notification(%s,%s,'',%s))" % (urllib.quote(data['title']), urllib.quote(data['message']), urllib.quote(self.getNotificationImage('medium'))) + cmd = "xbmcHttp?command=ExecBuiltIn(Notification(%s,%s,'',%s))" % (urllib.quote(getTitle(data)), urllib.quote(data['message']), urllib.quote(self.getNotificationImage('medium'))) server += cmd # I have no idea what to set to, just tried text/plain and seems to be working :) diff --git a/couchpotato/core/plugins/automation/main.py b/couchpotato/core/plugins/automation/main.py index 44d7673f..2edcd3be 100644 --- a/couchpotato/core/plugins/automation/main.py +++ b/couchpotato/core/plugins/automation/main.py @@ -10,10 +10,10 @@ class Automation(Plugin): def __init__(self): - addEvent('app.load2', self.setCrons) + addEvent('app.load', self.setCrons) if not Env.get('dev'): - addEvent('app.load2', self.addMovies) + addEvent('app.load', self.addMovies) addEvent('setting.save.automation.hour.after', self.setCrons) diff --git a/couchpotato/core/plugins/base.py b/couchpotato/core/plugins/base.py index 0625535e..5a805361 100644 --- a/couchpotato/core/plugins/base.py +++ b/couchpotato/core/plugins/base.py @@ -291,7 +291,7 @@ class Plugin(object): def cpTag(self, media): if Env.setting('enabled', 'renamer'): - return '.cp(' + media['library'].get('identifier') + ')' if media['library'].get('identifier') else '' + return '.cp(' + media.get('identifier') + ')' if media.get('identifier') else '' return '' diff --git a/couchpotato/core/plugins/category/index.py b/couchpotato/core/plugins/category/index.py index fa579dd9..1eb3651e 100644 --- a/couchpotato/core/plugins/category/index.py +++ b/couchpotato/core/plugins/category/index.py @@ -5,12 +5,12 @@ from CodernityDB.tree_index import TreeBasedIndex class CategoryIndex(TreeBasedIndex): def __init__(self, *args, **kwargs): - kwargs['key_format'] = '16s' + kwargs['key_format'] = '32s' super(CategoryIndex, self).__init__(*args, **kwargs) def make_key(self, key): - return md5(key).digest() + return md5(key).hexdigest() def make_key_value(self, data): - if data.get('type') == 'category': - return md5(data['media_id']).digest(), None + if data.get('_t') == 'category': + return md5(data['media_id']).hexdigest(), None diff --git a/couchpotato/core/plugins/custom/main.py b/couchpotato/core/plugins/custom/main.py index 42400994..a15c915c 100644 --- a/couchpotato/core/plugins/custom/main.py +++ b/couchpotato/core/plugins/custom/main.py @@ -10,7 +10,7 @@ log = CPLog(__name__) class Custom(Plugin): def __init__(self): - addEvent('app.load2', self.createStructure) + addEvent('app.load', self.createStructure) def createStructure(self): diff --git a/couchpotato/core/plugins/dashboard/main.py b/couchpotato/core/plugins/dashboard/main.py index bc14f4b5..10c1c61b 100644 --- a/couchpotato/core/plugins/dashboard/main.py +++ b/couchpotato/core/plugins/dashboard/main.py @@ -49,7 +49,6 @@ class Dashboard(Plugin): limit = tryInt(splt[0]) # Get all active movies - active_status, ignored_status = fireEvent('status.get', ['active', 'ignored'], single = True) q = db.query(Media) \ .join(Library) \ .outerjoin(Media.releases) \ diff --git a/couchpotato/core/plugins/file/main.py b/couchpotato/core/plugins/file/main.py index c24d0d58..37aa7282 100644 --- a/couchpotato/core/plugins/file/main.py +++ b/couchpotato/core/plugins/file/main.py @@ -5,8 +5,7 @@ from couchpotato.core.helpers.encoding import toUnicode from couchpotato.core.helpers.variable import md5, getExt from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin -from couchpotato.core.plugins.scanner.main import Scanner -from couchpotato.core.settings.model import FileType, File +from couchpotato.core.settings.model import File from couchpotato.environment import Env from tornado.web import StaticFileHandler import os.path diff --git a/couchpotato/core/plugins/manage/main.py b/couchpotato/core/plugins/manage/main.py index 47081692..86d00557 100644 --- a/couchpotato/core/plugins/manage/main.py +++ b/couchpotato/core/plugins/manage/main.py @@ -47,7 +47,7 @@ class Manage(Plugin): }) if not Env.get('dev') and self.conf('startup_scan'): - addEvent('app.load2', self.updateLibraryQuick) + addEvent('app.load', self.updateLibraryQuick) def getProgress(self, **kwargs): return { @@ -120,7 +120,7 @@ class Manage(Plugin): total_movies, done_movies = fireEvent('media.list', types = 'movie', status = 'done', single = True) for done_movie in done_movies: - if done_movie['library']['identifier'] not in added_identifiers: + if done_movie['identifier'] not in added_identifiers: fireEvent('media.delete', media_id = done_movie['id'], delete_from = 'all') else: @@ -184,13 +184,13 @@ class Manage(Plugin): 'to_go': total_found, }) - if group['library'] and group['library'].get('identifier'): - identifier = group['library'].get('identifier') + if group['media'] and group['media'].get('identifier'): + identifier = group['media'].get('identifier') added_identifiers.append(identifier) # Add it to release and update the info fireEvent('release.add', group = group) - fireEvent('library.update.movie', identifier = identifier, on_complete = self.createAfterUpdate(folder, identifier)) + fireEvent('movie.update_info', identifier = identifier, on_complete = self.createAfterUpdate(folder, identifier)) else: self.updateProgress(folder) @@ -207,7 +207,7 @@ class Manage(Plugin): total = self.in_progress[folder]['total'] movie_dict = fireEvent('media.get', identifier, single = True) - fireEvent('notify.frontend', type = 'movie.added', data = movie_dict, message = None if total > 5 else 'Added "%s" to manage.' % getTitle(movie_dict['library'])) + fireEvent('notify.frontend', type = 'movie.added', data = movie_dict, message = None if total > 5 else 'Added "%s" to manage.' % getTitle(movie_dict)) return afterUpdate @@ -237,7 +237,7 @@ class Manage(Plugin): if groups: for group in groups.values(): - if group['library'] and group['library'].get('identifier'): + if group.get('info'): fireEvent('release.add', group = group) def getDiskSpace(self): diff --git a/couchpotato/core/plugins/nosql/index.py b/couchpotato/core/plugins/nosql/index.py index e6b0389e..f88738fb 100644 --- a/couchpotato/core/plugins/nosql/index.py +++ b/couchpotato/core/plugins/nosql/index.py @@ -12,6 +12,6 @@ class NameIndex(TreeBasedIndex): return key def make_key_value(self, data): - if data.get('type') == 'media' and data.get('title') is not None: + if data.get('_t') == 'media' and data.get('title') is not None: return data.get('title'), None diff --git a/couchpotato/core/plugins/nosql/main.py b/couchpotato/core/plugins/nosql/main.py index 511c8f1b..b5243d9f 100644 --- a/couchpotato/core/plugins/nosql/main.py +++ b/couchpotato/core/plugins/nosql/main.py @@ -2,7 +2,6 @@ import time from couchpotato import CPLog, get_db from couchpotato.core.event import addEvent from couchpotato.core.plugins.base import Plugin -from .index import ReleaseIndex, NameIndex log = CPLog(__name__) @@ -13,7 +12,7 @@ class NoSQL(Plugin): def __init__(self): - pass #addEvent('app.load2', self.test) + pass #addEvent('app.load', self.test) def test(self): @@ -31,7 +30,8 @@ class NoSQL(Plugin): for id in range(10): media = db.insert({ - 'type': 'media', + '_t': 'media', + 'type': 'movie', 'tmdb': id, 'imdb': 'tt%s' % id, 'last_edit': 0, diff --git a/couchpotato/core/plugins/profile/index.py b/couchpotato/core/plugins/profile/index.py index 2457699b..dbba1632 100644 --- a/couchpotato/core/plugins/profile/index.py +++ b/couchpotato/core/plugins/profile/index.py @@ -1,16 +1,15 @@ -from CodernityDB.hash_index import HashIndex -from hashlib import md5 +from CodernityDB.tree_index import TreeBasedIndex -class ProfileIndex(HashIndex): +class ProfileIndex(TreeBasedIndex): def __init__(self, *args, **kwargs): - kwargs['key_format'] = '16s' + kwargs['key_format'] = 'i' super(ProfileIndex, self).__init__(*args, **kwargs) def make_key(self, key): - return md5(key).digest() + return key def make_key_value(self, data): - if data.get('type') == 'profile' and data.get('identifier'): - return md5(data.get('identifier')).digest(), None + if data.get('_t') == 'profile': + return data.get('order', 99), None diff --git a/couchpotato/core/plugins/profile/main.py b/couchpotato/core/plugins/profile/main.py index 8939f414..8f04fe3b 100644 --- a/couchpotato/core/plugins/profile/main.py +++ b/couchpotato/core/plugins/profile/main.py @@ -1,13 +1,12 @@ import traceback from couchpotato import get_session, get_db from couchpotato.api import addApiView -from couchpotato.core.event import addEvent, fireEvent +from couchpotato.core.event import addEvent from couchpotato.core.helpers.encoding import toUnicode from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin from .index import ProfileIndex -from couchpotato.core.settings.model import Profile, ProfileType, Media -from sqlalchemy.orm import joinedload_all +from couchpotato.core.settings.model import Profile, ProfileType log = CPLog(__name__) @@ -34,7 +33,7 @@ class ProfilePlugin(Plugin): addEvent('database.setup', self.databaseSetup) addEvent('app.initialize', self.fill, priority = 90) - addEvent('app.load2', self.forceDefaults) + addEvent('app.load', self.forceDefaults) def databaseSetup(self): @@ -46,7 +45,6 @@ class ProfilePlugin(Plugin): log.debug('Index already exists') db.edit_index(ProfileIndex(db.path, 'profile')) - def forceDefaults(self): # Get all active movies without profile @@ -57,7 +55,7 @@ class ProfilePlugin(Plugin): profile_ids = [x.get('_id') for x in self.all()] for media in medias: - if media['profile_id'] not in profile_ids: + if media.get('profile_id') not in profile_ids: default_profile = self.default() media['profile_id'] = default_profile.get('id') db.update(media) @@ -76,7 +74,7 @@ class ProfilePlugin(Plugin): db = get_db() profiles = db.all('profile', with_doc = True) - return list(profiles) + return [x['doc'] for x in profiles] def save(self, **kwargs): @@ -127,7 +125,7 @@ class ProfilePlugin(Plugin): def default(self): db = get_db() - return db.get_many('profile', limit = 1, with_doc = True)[0] + return list(db.all('profile', limit = 1, with_doc = True))[0]['doc'] def saveOrder(self, **kwargs): @@ -213,8 +211,7 @@ class ProfilePlugin(Plugin): log.info('Creating default profile: %s', profile.get('label')) pro = { - 'type': 'profile', - 'identifier': profile.get('label').lower(), + '_t': 'profile', 'label': toUnicode(profile.get('label')), 'order': order, 'qualities': profile.get('qualities'), @@ -229,9 +226,6 @@ class ProfilePlugin(Plugin): db.insert(pro) order += 1 - for x in db.all('profile', with_doc = True): - log.info(x) - return True except: log.error('Failed: %s', traceback.format_exc()) diff --git a/couchpotato/core/plugins/profile/static/profile.js b/couchpotato/core/plugins/profile/static/profile.js index a93ca1bc..bb0504b2 100644 --- a/couchpotato/core/plugins/profile/static/profile.js +++ b/couchpotato/core/plugins/profile/static/profile.js @@ -324,4 +324,4 @@ Profile.Type = new Class({ return this.el; } -}) \ No newline at end of file +}) diff --git a/couchpotato/core/plugins/quality/index.py b/couchpotato/core/plugins/quality/index.py new file mode 100644 index 00000000..cf2d5c77 --- /dev/null +++ b/couchpotato/core/plugins/quality/index.py @@ -0,0 +1,16 @@ +from CodernityDB.hash_index import HashIndex +from hashlib import md5 + + +class QualityIndex(HashIndex): + + def __init__(self, *args, **kwargs): + kwargs['key_format'] = '32s' + super(QualityIndex, self).__init__(*args, **kwargs) + + def make_key(self, key): + return md5(key).hexdigest() + + def make_key_value(self, data): + if data.get('_t') == 'quality' and data.get('identifier'): + return md5(data.get('identifier')).hexdigest(), None diff --git a/couchpotato/core/plugins/quality/main.py b/couchpotato/core/plugins/quality/main.py index e5070093..e75eb465 100644 --- a/couchpotato/core/plugins/quality/main.py +++ b/couchpotato/core/plugins/quality/main.py @@ -1,15 +1,14 @@ import traceback -from couchpotato import get_session +from couchpotato import get_session, get_db from couchpotato.api import addApiView from couchpotato.core.event import addEvent from couchpotato.core.helpers.encoding import toUnicode, ss from couchpotato.core.helpers.variable import mergeDicts, getExt from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin -from couchpotato.core.settings.model import Quality, Profile, ProfileType -from sqlalchemy.sql.expression import or_ +from couchpotato.core.plugins.quality.index import QualityIndex +from couchpotato.core.settings.model import Quality import re -import time log = CPLog(__name__) @@ -39,6 +38,7 @@ class QualityPlugin(Plugin): addEvent('quality.single', self.single) addEvent('quality.guess', self.guess) addEvent('quality.pre_releases', self.preReleases) + addEvent('quality.order', self.getOrder) addApiView('quality.size.save', self.saveSize) addApiView('quality.list', self.allView, docs = { @@ -50,9 +50,31 @@ class QualityPlugin(Plugin): }) addEvent('app.initialize', self.fill, priority = 10) + addEvent('database.setup', self.databaseSetup) addEvent('app.test', self.doTest) + self.addOrder() + + def addOrder(self): + self.order = [] + for q in self.qualities: + self.order.append(q.get('identifier')) + + def getOrder(self): + return self.order + + def databaseSetup(self): + + db = get_db() + + # Quality index + try: + db.add_index(QualityIndex(db.path, 'quality')) + except: + log.debug('Index already exists') + db.edit_index(QualityIndex(db.path, 'quality')) + def preReleases(self): return self.pre_releases @@ -68,30 +90,29 @@ class QualityPlugin(Plugin): if self.cached_qualities: return self.cached_qualities - db = get_session() + db = get_db() - qualities = db.query(Quality).all() + qualities = db.all('quality', with_doc = True) temp = [] for quality in qualities: - q = mergeDicts(self.getQuality(quality.identifier), quality.to_dict()) + quality = quality['doc'] + q = mergeDicts(self.getQuality(quality.get('identifier')), quality) temp.append(q) self.cached_qualities = temp - pass #db.close() return temp def single(self, identifier = ''): - db = get_session() + db = get_db() quality_dict = {} - quality = db.query(Quality).filter(or_(Quality.identifier == identifier, Quality.id == identifier)).first() + quality = db.get('quality', identifier, with_doc = True)['doc'] if quality: - quality_dict = dict(self.getQuality(quality.identifier), **quality.to_dict()) + quality_dict = mergeDicts(self.getQuality(quality['identifier']), quality) - pass #db.close() return quality_dict def getQuality(self, identifier): @@ -128,60 +149,35 @@ class QualityPlugin(Plugin): def fill(self): try: - db = get_session() + db = get_db() order = 0 for q in self.qualities: - # Create quality - qual = db.query(Quality).filter_by(identifier = q.get('identifier')).first() + db.insert({ + '_t': 'quality', + 'order': order, + 'identifier': q.get('identifier'), + 'size_min': q.get('size')[0], + 'size_max': q.get('size')[1] + }) - if not qual: - log.info('Creating quality: %s', q.get('label')) - qual = Quality() - qual.order = order - qual.identifier = q.get('identifier') - qual.label = toUnicode(q.get('label')) - qual.size_min, qual.size_max = q.get('size') - - db.add(qual) - - # Create single quality profile - prof = db.query(Profile).filter( - Profile.core == True - ).filter( - Profile.types.any(quality = qual) - ).all() - - if not prof: - log.info('Creating profile: %s', q.get('label')) - prof = Profile( - core = True, - label = toUnicode(qual.label), - order = order - ) - db.add(prof) - - profile_type = ProfileType( - quality = qual, - profile = prof, - finish = True, - order = 0 - ) - prof.types.append(profile_type) + log.info('Creating profile: %s', q.get('label')) + db.insert({ + '_t': 'profile', + 'order': order + 20, # Make sure it goes behind other profiles + 'core': True, + 'qualities': [q.get('identifier')], + 'label': toUnicode(q.get('label')), + 'finish': [True], + 'wait_for': [0], + }) order += 1 - db.commit() - - time.sleep(0.3) # Wait a moment - return True except: log.error('Failed: %s', traceback.format_exc()) - db.rollback() - finally: - pass #db.close() return False diff --git a/couchpotato/core/plugins/release/index.py b/couchpotato/core/plugins/release/index.py index 3db2cba5..c68edf1c 100644 --- a/couchpotato/core/plugins/release/index.py +++ b/couchpotato/core/plugins/release/index.py @@ -5,15 +5,15 @@ from CodernityDB.tree_index import TreeBasedIndex class ReleaseIndex(TreeBasedIndex): def __init__(self, *args, **kwargs): - kwargs['key_format'] = '16s' + kwargs['key_format'] = '32s' super(ReleaseIndex, self).__init__(*args, **kwargs) def make_key(self, key): - return md5(key).digest() + return md5(key).hexdigest() def make_key_value(self, data): - if data.get('type') == 'release' and data.get('media_id'): - return md5(data['media_id']).digest(), {'media_id': data.get('media_id')} + if data.get('_t') == 'release' and data.get('media_id'): + return md5(data['media_id']).hexdigest(), {'media_id': data.get('media_id')} def run_for_media(self, db, media_id): for release in db.get_many('release', media_id, with_doc = True): @@ -31,12 +31,26 @@ class ReleaseIndex(TreeBasedIndex): class ReleaseStatusIndex(TreeBasedIndex): def __init__(self, *args, **kwargs): - kwargs['key_format'] = '16s' + kwargs['key_format'] = '32s' super(ReleaseStatusIndex, self).__init__(*args, **kwargs) def make_key(self, key): - return md5(key).digest() + return md5(key).hexdigest() def make_key_value(self, data): - if data.get('type') == 'release' and data.get('status'): - return md5(data.get('status')).digest(), None + if data.get('_t') == 'release' and data.get('status'): + return md5(data.get('status')).hexdigest(), None + + +class ReleaseIDIndex(TreeBasedIndex): + + def __init__(self, *args, **kwargs): + kwargs['key_format'] = '32s' + super(ReleaseIDIndex, self).__init__(*args, **kwargs) + + def make_key(self, key): + return md5(key).hexdigest() + + def make_key_value(self, data): + if data.get('_t') == 'release' and data.get('identifier'): + return md5(data.get('identifier')).hexdigest(), None diff --git a/couchpotato/core/plugins/release/main.py b/couchpotato/core/plugins/release/main.py index 8faf6a5d..7cb634bd 100644 --- a/couchpotato/core/plugins/release/main.py +++ b/couchpotato/core/plugins/release/main.py @@ -5,7 +5,7 @@ from couchpotato.core.helpers.encoding import ss, toUnicode from couchpotato.core.helpers.variable import getTitle from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin -from .index import ReleaseIndex, ReleaseStatusIndex +from .index import ReleaseIndex, ReleaseStatusIndex, ReleaseIDIndex from couchpotato.core.plugins.scanner.main import Scanner from couchpotato.core.settings.model import Release as Relea, Media, \ ReleaseInfo @@ -61,7 +61,7 @@ class Release(Plugin): addEvent('database.setup', self.databaseSetup) # Clean releases that didn't have activity in the last week - addEvent('app.load2', self.cleanDone) + addEvent('app.load', self.cleanDone) fireEvent('schedule.interval', 'movie.clean_releases', self.cleanDone, hours = 4) def databaseSetup(self): @@ -82,6 +82,13 @@ class Release(Plugin): log.debug('Index already exists') db.edit_index(ReleaseStatusIndex(db.path, 'release_status')) + # Release identifier index + try: + db.add_index(ReleaseIDIndex(db.path, 'release_identifier')) + except: + log.debug('Index already exists') + db.edit_index(ReleaseIDIndex(db.path, 'release_identifier')) + def cleanDone(self): log.debug('Removing releases from dashboard') @@ -112,7 +119,7 @@ class Release(Plugin): try: db = get_session() - identifier = '%s.%s.%s' % (group['library']['identifier'], group['meta_data'].get('audio', 'unknown'), group['meta_data']['quality']['identifier']) + identifier = '%s.%s.%s' % (group['identifier'], group['meta_data'].get('audio', 'unknown'), group['meta_data']['quality']['identifier']) # Add movie media = db.query(Media).filter_by(library_id = group['library'].get('id')).first() @@ -120,7 +127,7 @@ class Release(Plugin): media = Media( library_id = group['library'].get('id'), profile_id = 0, - status_id = done_status.get('id') + status = 'done' ) db.add(media) db.commit() @@ -129,7 +136,7 @@ class Release(Plugin): rel = db.query(Relea).filter( or_( Relea.identifier == identifier, - and_(Relea.identifier.startswith(group['library']['identifier']), Relea.status_id == snatched_status.get('id')) + and_(Relea.identifier.startswith(group['identifier']), Relea.status == 'snatched') ) ).first() if not rel: @@ -137,7 +144,7 @@ class Release(Plugin): identifier = identifier, movie = media, quality_id = group['meta_data']['quality'].get('id'), - status_id = done_status.get('id') + status = 'done' ) db.add(rel) db.commit() @@ -246,11 +253,6 @@ class Release(Plugin): # Get matching provider provider = fireEvent('provider.belongs_to', item['url'], provider = item.get('provider'), single = True) - # Backwards compatibility code - if not item.get('protocol'): - item['protocol'] = item['type'] - item['type'] = 'movie' - if item.get('protocol') != 'torrent_magnet': item['download'] = provider.loginDownload if provider.urls.get('login') else provider.download @@ -271,11 +273,6 @@ class Release(Plugin): def download(self, data, media, manual = False): - # Backwards compatibility code - if not data.get('protocol'): - data['protocol'] = data['type'] - data['type'] = 'movie' - # Test to see if any downloaders are enabled for this type downloader_enabled = fireEvent('download.enabled', manual, data, single = True) if not downloader_enabled: @@ -303,8 +300,6 @@ class Release(Plugin): return False log.debug('Downloader result: %s', download_result) - snatched_status, done_status, downloaded_status, active_status = fireEvent('status.get', ['snatched', 'done', 'downloaded', 'active'], single = True) - try: db = get_session() rls = db.query(Relea).filter_by(identifier = md5(data['url'])).first() @@ -324,7 +319,7 @@ class Release(Plugin): rls.info.append(rls_info) db.commit() - log_movie = '%s (%s) in %s' % (getTitle(media['library']), media['library']['year'], rls.quality.label) + log_movie = '%s (%s) in %s' % (getTitle(media), media['info']['year'], rls.quality.label) snatch_message = 'Snatched "%s": %s' % (data.get('name'), log_movie) log.info(snatch_message) fireEvent('%s.snatched' % data['type'], message = snatch_message, data = rls.to_dict()) @@ -335,7 +330,7 @@ class Release(Plugin): # If renamer isn't used, mark media done if finished or release downloaded else: - if media['status_id'] == active_status.get('id'): + if media['status'] == 'active': finished = next((True for profile_type in media['profile']['types'] if profile_type['quality_id'] == rls.quality.id and profile_type['finish']), False) if finished: @@ -346,7 +341,7 @@ class Release(Plugin): # Mark media done mdia = db.query(Media).filter_by(id = media['id']).first() - mdia.status_id = done_status.get('id') + mdia.status = 'done' mdia.last_edit = int(time.time()) db.commit() @@ -364,15 +359,14 @@ class Release(Plugin): return True - def tryDownloadResult(self, results, media, quality_type, manual = False): - ignored_status, failed_status = fireEvent('status.get', ['ignored', 'failed'], single = True) + def tryDownloadResult(self, results, media, quality_custom, manual = False): for rel in results: - if not quality_type.get('finish', False) and quality_type.get('wait_for', 0) > 0 and rel.get('age') <= quality_type.get('wait_for', 0): - log.info('Ignored, waiting %s days: %s', (quality_type.get('wait_for'), rel['name'])) + if not quality_custom.get('finish', False) and quality_custom.get('wait_for', 0) > 0 and rel.get('age') <= quality_custom.get('wait_for', 0): + log.info('Ignored, waiting %s days: %s', (quality_custom.get('wait_for'), rel['name'])) continue - if rel['status_id'] in [ignored_status.get('id'), failed_status.get('id')]: + if rel['status'] in ['ignored', 'failed']: log.info('Ignored: %s', rel['name']) continue @@ -388,12 +382,10 @@ class Release(Plugin): return False - def createFromSearch(self, search_results, media, quality_type): - - available_status = fireEvent('status.get', ['available'], single = True) + def createFromSearch(self, search_results, media, quality): try: - db = get_session() + db = get_db() found_releases = [] @@ -402,45 +394,40 @@ class Release(Plugin): rel_identifier = md5(rel['url']) found_releases.append(rel_identifier) - rls = db.query(Relea).filter_by(identifier = rel_identifier).first() - if not rls: - rls = Relea( - identifier = rel_identifier, - movie_id = media.get('id'), - #media_id = media.get('id'), - quality_id = quality_type.get('quality_id'), - status_id = available_status.get('id') - ) - db.add(rls) - else: - [db.delete(old_info) for old_info in rls.info] - rls.last_edit = int(time.time()) + release = { + '_t': 'release', + 'identifier': rel_identifier, + 'media_id': media.get('_id'), + 'quality': quality.get('identifier'), + 'status': 'available', + 'last_edit': int(time.time()), + 'info': {} + } - db.commit() + try: + rls = db.get('release_identifier', rel_identifier, with_doc = True)['doc'] + except: + rls = db.insert(release) + rls.update(release) + # Update info, but filter out functions for info in rel: try: if not isinstance(rel[info], (str, unicode, int, long, float)): continue - rls_info = ReleaseInfo( - identifier = info, - value = toUnicode(rel[info]) - ) - rls.info.append(rls_info) + rls['info'][info] = toUnicode(rel[info]) except InterfaceError: log.debug('Couldn\'t add %s to ReleaseInfo: %s', (info, traceback.format_exc())) - db.commit() + db.update(rls) - rel['status_id'] = rls.status_id + # Update release in search_results + rel['status'] = rls.get('status') return found_releases except: log.error('Failed: %s', traceback.format_exc()) - db.rollback() - finally: - pass #db.close() return [] diff --git a/couchpotato/core/plugins/renamer/main.py b/couchpotato/core/plugins/renamer/main.py index d00eee6b..0e06a751 100755 --- a/couchpotato/core/plugins/renamer/main.py +++ b/couchpotato/core/plugins/renamer/main.py @@ -45,7 +45,7 @@ class Renamer(Plugin): addEvent('renamer.scan', self.scan) addEvent('renamer.check_snatched', self.checkSnatched) - addEvent('app.load2', self.scan) + addEvent('app.load', self.scan) addEvent('app.load', self.setCrons) # Enable / disable interval @@ -222,23 +222,20 @@ class Renamer(Plugin): remove_files = [] remove_releases = [] - movie_title = getTitle(group['library']) + movie_title = getTitle(group) # Add _UNKNOWN_ if no library item is connected - if not group['library'] or not movie_title: + if not group.get('info') or not movie_title: self.tagRelease(group = group, tag = 'unknown') continue # Rename the files using the library data else: - group['library'] = fireEvent('library.update.movie', identifier = group['library']['identifier'], single = True) - if not group['library']: + group['media'] = fireEvent('movie.update_info', identifier = group['media']['identifier'], single = True) + if not group['media']: log.error('Could not rename, no library item to work with: %s', group_identifier) continue - library = group['library'] - library_ent = db.query(Library).filter_by(identifier = group['library']['identifier']).first() - - movie_title = getTitle(library) + movie_title = getTitle(group['media']) # Overwrite destination when set in category destination = to_folder @@ -419,19 +416,19 @@ class Renamer(Plugin): # Add it to the wanted list before we continue if len(library_ent.movies) == 0: profile = db.query(Profile).filter_by(core = True, label = group['meta_data']['quality']['label']).first() - fireEvent('movie.add', params = {'identifier': group['library']['identifier'], 'profile_id': profile.id}, search_after = False) + fireEvent('movie.add', params = {'identifier': group['identifier'], 'profile_id': profile.id}, search_after = False) db.expire_all() - library_ent = db.query(Library).filter_by(identifier = group['library']['identifier']).first() + library_ent = db.query(Library).filter_by(identifier = group['identifier']).first() for movie in library_ent.movies: # Mark movie "done" once it's found the quality with the finish check try: - if movie.status_id == active_status.get('id') and movie.profile: + if movie.get('status') == 'active' and movie.get('profile_id'): for profile_type in movie.profile.types: if profile_type.quality_id == group['meta_data']['quality']['id'] and profile_type.finish: - movie.status_id = done_status.get('id') - movie.last_edit = int(time.time()) + movie['status'] = 'done' + movie['last_edit'] = int(time.time()) db.commit() except Exception as e: log.error('Failed marking movie finished: %s %s', (e, traceback.format_exc())) @@ -441,7 +438,7 @@ class Renamer(Plugin): for release in movie.releases: # When a release already exists - if release.status_id is done_status.get('id'): + if release.get('status') == 'done': # This is where CP removes older, lesser quality releases if release.quality.order > group['meta_data']['quality']['order']: @@ -470,7 +467,7 @@ class Renamer(Plugin): break - elif release.status_id in [snatched_status.get('id'), seeding_status.get('id')]: + elif release.get('status') in ['snatched', 'seeding']: if release_download and release_download.get('rls_id'): if release_download['rls_id'] == release.id: if release_download['status'] == 'completed': @@ -917,7 +914,7 @@ Remove it if you want it to be renamed (again, or at least let it try again) found_release = True break else: - if release_download['name'] == nzbname or rel['info']['name'] in release_download['name'] or getImdb(release_download['name']) == movie_dict['library']['identifier']: + if release_download['name'] == nzbname or rel['info']['name'] in release_download['name'] or getImdb(release_download['name']) == movie_dict['identifier']: log.debug('Found release by release name or imdb ID: %s', release_download['name']) found_release = True break @@ -951,7 +948,7 @@ Remove it if you want it to be renamed (again, or at least let it try again) elif release_download['status'] == 'seeding': #If linking setting is enabled, process release - if self.conf('file_action') != 'move' and not rel.status_id == 'seeding' and self.statusInfoComplete(release_download): + if self.conf('file_action') != 'move' and not rel.get('status') == 'seeding' and self.statusInfoComplete(release_download): log.info('Download of %s completed! It is now being processed while leaving the original files alone for seeding. Current ratio: %s.', (release_download['name'], release_download['seed_ratio'])) # Remove the downloading tag diff --git a/couchpotato/core/plugins/scanner/main.py b/couchpotato/core/plugins/scanner/main.py index 7e8fb9bb..f9ccea78 100644 --- a/couchpotato/core/plugins/scanner/main.py +++ b/couchpotato/core/plugins/scanner/main.py @@ -5,7 +5,7 @@ from couchpotato.core.helpers.variable import getExt, getImdb, tryInt, \ splitString from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin -from couchpotato.core.settings.model import File, Media +from couchpotato.core.settings.model import File from enzyme.exceptions import NoParserError, ParseError from guessit import guess_movie_info from subliminal.videos import Video @@ -417,13 +417,11 @@ class Scanner(Plugin): del group['unsorted_files'] # Determine movie - group['library'] = self.determineMovie(group, release_download = release_download) - if not group['library']: - log.error('Unable to determine movie: %s', group['identifiers']) + group['media'] = self.determineMedia(group, release_download = release_download) + if not group['media']: + log.error('Unable to determine media: %s', group['identifiers']) else: - movie = db.query(Media).filter_by(library_id = group['library']['id']).first() - group['movie_id'] = None if not movie else movie.id - db.expire_all() + group['identifier'] = group['media']['identifier'] processed_movies[identifier] = group @@ -554,7 +552,7 @@ class Scanner(Plugin): return detected_languages - def determineMovie(self, group, release_download = None): + def determineMedia(self, group, release_download = None): # Get imdb id from downloader imdb_id = release_download and release_download.get('imdb_id') diff --git a/couchpotato/core/plugins/score/main.py b/couchpotato/core/plugins/score/main.py index 30e7baca..e6fef253 100644 --- a/couchpotato/core/plugins/score/main.py +++ b/couchpotato/core/plugins/score/main.py @@ -24,11 +24,11 @@ class Score(Plugin): try: preferred_words = removeDuplicate(preferred_words + splitString(movie['category']['preferred'].lower())) except: pass - score = nameScore(toUnicode(nzb['name']), movie['library']['year'], preferred_words) + score = nameScore(toUnicode(nzb['name']), movie['info']['year'], preferred_words) - for movie_title in movie['library']['titles']: - score += nameRatioScore(toUnicode(nzb['name']), toUnicode(movie_title['title'])) - score += namePositionScore(toUnicode(nzb['name']), toUnicode(movie_title['title'])) + for movie_title in movie['info']['titles']: + score += nameRatioScore(toUnicode(nzb['name']), toUnicode(movie_title)) + score += namePositionScore(toUnicode(nzb['name']), toUnicode(movie_title)) score += sizeScore(nzb['size']) @@ -44,7 +44,7 @@ class Score(Plugin): score += providerScore(nzb['provider']) # Duplicates in name - score += duplicateScore(nzb['name'], getTitle(movie['library'])) + score += duplicateScore(nzb['name'], getTitle(movie)) # Merge global and category ignored_words = splitString(Env.setting('ignored_words', section = 'searcher').lower()) @@ -52,7 +52,7 @@ class Score(Plugin): except: pass # Partial ignored words - score += partialIgnoredScore(nzb['name'], getTitle(movie['library']), ignored_words) + score += partialIgnoredScore(nzb['name'], getTitle(movie), ignored_words) # Ignore single downloads from multipart score += halfMultipartScore(nzb['name']) diff --git a/couchpotato/core/plugins/subtitle/main.py b/couchpotato/core/plugins/subtitle/main.py index b8d9a06b..a3b1d13c 100644 --- a/couchpotato/core/plugins/subtitle/main.py +++ b/couchpotato/core/plugins/subtitle/main.py @@ -25,14 +25,13 @@ class Subtitle(Plugin): db = get_session() library = db.query(Library).all() - done_status = fireEvent('status.get', 'done', single = True) for movie in library.movies: for release in movie.releases: # get releases and their movie files - if release.status_id is done_status.get('id'): + if release.get('status') == 'done': files = [] for file in release.files.filter(FileType.status.has(identifier = 'movie')).all(): diff --git a/couchpotato/core/plugins/trailer/main.py b/couchpotato/core/plugins/trailer/main.py index ba040058..36084066 100644 --- a/couchpotato/core/plugins/trailer/main.py +++ b/couchpotato/core/plugins/trailer/main.py @@ -18,7 +18,7 @@ class Trailer(Plugin): trailers = fireEvent('trailer.search', group = group, merge = True) if not trailers or trailers == []: - log.info('No trailers found for: %s', getTitle(group['library'])) + log.info('No trailers found for: %s', getTitle(group)) return False for trailer in trailers.get(self.conf('quality'), []): diff --git a/couchpotato/core/providers/base.py b/couchpotato/core/providers/base.py index 93e0900f..c772be47 100644 --- a/couchpotato/core/providers/base.py +++ b/couchpotato/core/providers/base.py @@ -199,7 +199,7 @@ class YarrProvider(Provider): self._search(movie, quality, results) # Search possible titles else: - for title in possibleTitles(getTitle(movie['library'])): + for title in possibleTitles(getTitle(movie)): self._searchOnTitle(title, movie, quality, results) return results diff --git a/couchpotato/core/providers/info/_modifier/main.py b/couchpotato/core/providers/info/_modifier/main.py index cefecb74..09d19258 100644 --- a/couchpotato/core/providers/info/_modifier/main.py +++ b/couchpotato/core/providers/info/_modifier/main.py @@ -1,9 +1,9 @@ -from couchpotato import get_session -from couchpotato.core.event import addEvent, fireEvent +from CodernityDB.database import RecordNotFound +from couchpotato import get_db +from couchpotato.core.event import addEvent from couchpotato.core.helpers.variable import mergeDicts, randomString from couchpotato.core.logger import CPLog from couchpotato.core.plugins.base import Plugin -from couchpotato.core.settings.model import Library import copy import traceback @@ -86,25 +86,26 @@ class MovieResultModifier(Plugin): } # Add release info from current library - db = get_session() + db = get_db() try: - l = db.query(Library).filter_by(identifier = imdb).first() - if l: - # Statuses - active_status, done_status = fireEvent('status.get', ['active', 'done'], single = True) + media = None + try: + media = db.get('media', imdb, with_doc = True)['doc'] + except RecordNotFound: + pass - for movie in l.movies: - if movie.status_id == active_status['id']: - temp['in_wanted'] = fireEvent('media.get', movie.id, single = True) + if media: - for release in movie.releases: - if release.status_id == done_status['id']: - temp['in_library'] = fireEvent('media.get', movie.id, single = True) + if media.get('status') == 'active': + temp['in_wanted'] = media + + for release in db.get_many('release', media.get('_id'), with_doc = True): + if release.get('status') == 'done': + temp['in_library'] = media except: log.error('Tried getting more info on searched movies: %s', traceback.format_exc()) - pass #db.close() return temp def checkLibrary(self, result): diff --git a/couchpotato/core/providers/info/couchpotatoapi/main.py b/couchpotato/core/providers/info/couchpotatoapi/main.py index 848cbf05..a07eb135 100644 --- a/couchpotato/core/providers/info/couchpotatoapi/main.py +++ b/couchpotato/core/providers/info/couchpotatoapi/main.py @@ -26,9 +26,11 @@ class CouchPotatoApi(MovieProvider): def __init__(self): addEvent('movie.info', self.getInfo, priority = 1) + addEvent('movie.info.release_date', self.getReleaseDate) + addEvent('info.search', self.search, priority = 1) addEvent('movie.search', self.search, priority = 1) - addEvent('movie.release_date', self.getReleaseDate) + addEvent('movie.suggest', self.getSuggestions) addEvent('movie.is_movie', self.isMovie) diff --git a/couchpotato/core/providers/info/themoviedb/main.py b/couchpotato/core/providers/info/themoviedb/main.py index d301db2b..1b706b52 100644 --- a/couchpotato/core/providers/info/themoviedb/main.py +++ b/couchpotato/core/providers/info/themoviedb/main.py @@ -12,8 +12,6 @@ log = CPLog(__name__) class TheMovieDb(MovieProvider): def __init__(self): - #addEvent('info.search', self.search, priority = 2) - #addEvent('movie.search', self.search, priority = 2) addEvent('movie.info', self.getInfo, priority = 2) addEvent('movie.info_by_tmdb', self.getInfo) diff --git a/couchpotato/core/providers/metadata/base.py b/couchpotato/core/providers/metadata/base.py index 3f336be4..0d8f08ef 100644 --- a/couchpotato/core/providers/metadata/base.py +++ b/couchpotato/core/providers/metadata/base.py @@ -25,8 +25,7 @@ class MetaDataBase(Plugin): # Update library to get latest info try: - updated_library = fireEvent('library.update.movie', group['library']['identifier'], extended = True, single = True) - group['library'] = mergeDicts(group['library'], updated_library) + group['media'] = fireEvent('movie.update_info', group['media']['identifier'], extended = True, single = True) except: log.error('Failed to update movie, before creating metadata: %s', traceback.format_exc()) @@ -34,7 +33,7 @@ class MetaDataBase(Plugin): meta_name = os.path.basename(root_name) root = os.path.dirname(root_name) - movie_info = group['library'].get('info') + movie_info = group['media'].get('info') for file_type in ['nfo', 'thumbnail', 'fanart']: try: @@ -96,13 +95,13 @@ class MetaDataBase(Plugin): break # See if it is in current files - for cur_file in data['library'].get('files', []): + for cur_file in data.get('files', []): if cur_file.get('type_id') is file_type.get('id') and os.path.isfile(cur_file.get('path')): return cur_file.get('path') # Download using existing info try: - images = data['library']['info']['images'][wanted_file_type] + images = data['info']['images'][wanted_file_type] file_path = fireEvent('file.download', url = images[0], single = True) return file_path except: diff --git a/couchpotato/core/providers/metadata/xbmc/main.py b/couchpotato/core/providers/metadata/xbmc/main.py index 267b2822..90cab8f3 100644 --- a/couchpotato/core/providers/metadata/xbmc/main.py +++ b/couchpotato/core/providers/metadata/xbmc/main.py @@ -30,21 +30,21 @@ class XBMC(MetaDataBase): # return imdb url only if self.conf('meta_url_only'): - return 'http://www.imdb.com/title/%s/' % toUnicode(data['library']['identifier']) + return 'http://www.imdb.com/title/%s/' % toUnicode(data['identifier']) nfoxml = Element('movie') # Title try: el = SubElement(nfoxml, 'title') - el.text = toUnicode(getTitle(data['library'])) + el.text = toUnicode(getTitle(data)) except: pass # IMDB id try: el = SubElement(nfoxml, 'id') - el.text = toUnicode(data['library']['identifier']) + el.text = toUnicode(data['identifier']) except: pass diff --git a/couchpotato/core/providers/nzb/binsearch/main.py b/couchpotato/core/providers/nzb/binsearch/main.py index c54dd435..60007d5a 100644 --- a/couchpotato/core/providers/nzb/binsearch/main.py +++ b/couchpotato/core/providers/nzb/binsearch/main.py @@ -23,7 +23,7 @@ class BinSearch(NZBProvider): def _search(self, movie, quality, results): arguments = tryUrlencode({ - 'q': movie['library']['identifier'], + 'q': movie['identifier'], 'm': 'n', 'max': 400, 'adv_age': Env.setting('retention', 'nzb'), diff --git a/couchpotato/core/providers/nzb/newznab/main.py b/couchpotato/core/providers/nzb/newznab/main.py index deadaa1c..c6830b79 100644 --- a/couchpotato/core/providers/nzb/newznab/main.py +++ b/couchpotato/core/providers/nzb/newznab/main.py @@ -43,7 +43,7 @@ class Newznab(NZBProvider, RSS): def _searchOnHost(self, host, movie, quality, results): arguments = tryUrlencode({ - 'imdbid': movie['library']['identifier'].replace('tt', ''), + 'imdbid': movie['identifier'].replace('tt', ''), 'apikey': host['api_key'], 'extended': 1 }) + ('&%s' % host['custom_tag'] if host.get('custom_tag') else '') diff --git a/couchpotato/core/providers/nzb/nzbclub/main.py b/couchpotato/core/providers/nzb/nzbclub/main.py index 778cdbcd..5d027a5a 100644 --- a/couchpotato/core/providers/nzb/nzbclub/main.py +++ b/couchpotato/core/providers/nzb/nzbclub/main.py @@ -20,7 +20,7 @@ class NZBClub(NZBProvider, RSS): def _searchOnTitle(self, title, movie, quality, results): - q = '"%s %s"' % (title, movie['library']['year']) + q = '"%s %s"' % (title, movie['info']['year']) params = tryUrlencode({ 'q': q, diff --git a/couchpotato/core/providers/nzb/nzbindex/main.py b/couchpotato/core/providers/nzb/nzbindex/main.py index a143c199..d29d94ff 100644 --- a/couchpotato/core/providers/nzb/nzbindex/main.py +++ b/couchpotato/core/providers/nzb/nzbindex/main.py @@ -23,7 +23,7 @@ class NzbIndex(NZBProvider, RSS): def _searchOnTitle(self, title, movie, quality, results): - q = '"%s %s" | "%s (%s)"' % (title, movie['library']['year'], title, movie['library']['year']) + q = '"%s %s" | "%s (%s)"' % (title, movie['info']['year'], title, movie['info']['year']) arguments = tryUrlencode({ 'q': q, 'age': Env.setting('retention', 'nzb'), diff --git a/couchpotato/core/providers/nzb/omgwtfnzbs/main.py b/couchpotato/core/providers/nzb/omgwtfnzbs/main.py index 93925752..73254632 100644 --- a/couchpotato/core/providers/nzb/omgwtfnzbs/main.py +++ b/couchpotato/core/providers/nzb/omgwtfnzbs/main.py @@ -37,7 +37,7 @@ class OMGWTFNZBs(NZBProvider, RSS): def _searchOnTitle(self, title, movie, quality, results): - q = '%s %s' % (title, movie['library']['year']) + q = '%s %s' % (title, movie['info']['year']) params = tryUrlencode({ 'search': q, 'catid': ','.join([str(x) for x in self.getCatId(quality['identifier'])]), diff --git a/couchpotato/core/providers/torrent/awesomehd/main.py b/couchpotato/core/providers/torrent/awesomehd/main.py index ca6a30df..cc26030c 100644 --- a/couchpotato/core/providers/torrent/awesomehd/main.py +++ b/couchpotato/core/providers/torrent/awesomehd/main.py @@ -20,7 +20,7 @@ class AwesomeHD(TorrentProvider): def _search(self, movie, quality, results): - data = self.getHTMLData(self.urls['search'] % (self.conf('passkey'), movie['library']['identifier'], self.conf('only_internal'))) + data = self.getHTMLData(self.urls['search'] % (self.conf('passkey'), movie['identifier'], self.conf('only_internal'))) if data: try: diff --git a/couchpotato/core/providers/torrent/bithdtv/main.py b/couchpotato/core/providers/torrent/bithdtv/main.py index 90117de4..259de6bc 100644 --- a/couchpotato/core/providers/torrent/bithdtv/main.py +++ b/couchpotato/core/providers/torrent/bithdtv/main.py @@ -26,7 +26,7 @@ class BiTHDTV(TorrentProvider): def _searchOnTitle(self, title, movie, quality, results): arguments = tryUrlencode({ - 'search': '%s %s' % (title.replace(':', ''), movie['library']['year']), + 'search': '%s %s' % (title.replace(':', ''), movie['info']['year']), 'cat': self.cat_id_movies }) diff --git a/couchpotato/core/providers/torrent/bitsoup/main.py b/couchpotato/core/providers/torrent/bitsoup/main.py index a709c5c1..c4035635 100644 --- a/couchpotato/core/providers/torrent/bitsoup/main.py +++ b/couchpotato/core/providers/torrent/bitsoup/main.py @@ -22,7 +22,7 @@ class Bitsoup(TorrentProvider): def _searchOnTitle(self, title, movie, quality, results): - q = '"%s" %s' % (simplifyString(title), movie['library']['year']) + q = '"%s" %s' % (simplifyString(title), movie['info']['year']) arguments = tryUrlencode({ 'search': q, }) diff --git a/couchpotato/core/providers/torrent/hdbits/main.py b/couchpotato/core/providers/torrent/hdbits/main.py index ce17bbac..461745b9 100644 --- a/couchpotato/core/providers/torrent/hdbits/main.py +++ b/couchpotato/core/providers/torrent/hdbits/main.py @@ -43,7 +43,7 @@ class HDBits(TorrentProvider): def _search(self, movie, quality, results): - match = re.match(r'tt(\d{7})', movie['library']['identifier']) + match = re.match(r'tt(\d{7})', movie['identifier']) data = self._post_query(imdb = {'id': match.group(1)}) diff --git a/couchpotato/core/providers/torrent/ilovetorrents/main.py b/couchpotato/core/providers/torrent/ilovetorrents/main.py index 6d56ea48..74bf0c40 100644 --- a/couchpotato/core/providers/torrent/ilovetorrents/main.py +++ b/couchpotato/core/providers/torrent/ilovetorrents/main.py @@ -38,7 +38,7 @@ class ILoveTorrents(TorrentProvider): while page < total_pages: - movieTitle = tryUrlencode('"%s" %s' % (title, movie['library']['year'])) + movieTitle = tryUrlencode('"%s" %s' % (title, movie['info']['year'])) search_url = self.urls['search'] % (movieTitle, page, cats[0]) page += 1 diff --git a/couchpotato/core/providers/torrent/iptorrents/main.py b/couchpotato/core/providers/torrent/iptorrents/main.py index 35ce25c0..b4e038ca 100644 --- a/couchpotato/core/providers/torrent/iptorrents/main.py +++ b/couchpotato/core/providers/torrent/iptorrents/main.py @@ -36,7 +36,7 @@ class IPTorrents(TorrentProvider): current_page = 1 while current_page <= pages and not self.shuttingDown(): - url = self.urls['search'] % (self.getCatId(quality['identifier'])[0], freeleech, tryUrlencode('%s %s' % (title.replace(':', ''), movie['library']['year'])), current_page) + url = self.urls['search'] % (self.getCatId(quality['identifier'])[0], freeleech, tryUrlencode('%s %s' % (title.replace(':', ''), movie['info']['year'])), current_page) data = self.getHTMLData(url) if data: diff --git a/couchpotato/core/providers/torrent/kickasstorrents/main.py b/couchpotato/core/providers/torrent/kickasstorrents/main.py index f96e9812..8752348e 100644 --- a/couchpotato/core/providers/torrent/kickasstorrents/main.py +++ b/couchpotato/core/providers/torrent/kickasstorrents/main.py @@ -36,7 +36,7 @@ class KickAssTorrents(TorrentMagnetProvider): def _search(self, movie, quality, results): - data = self.getHTMLData(self.urls['search'] % (self.getDomain(), 'm', movie['library']['identifier'].replace('tt', ''))) + data = self.getHTMLData(self.urls['search'] % (self.getDomain(), 'm', movie['identifier'].replace('tt', ''))) if data: diff --git a/couchpotato/core/providers/torrent/passthepopcorn/main.py b/couchpotato/core/providers/torrent/passthepopcorn/main.py index 66cad33c..21bfa72e 100644 --- a/couchpotato/core/providers/torrent/passthepopcorn/main.py +++ b/couchpotato/core/providers/torrent/passthepopcorn/main.py @@ -56,13 +56,13 @@ class PassThePopcorn(TorrentProvider): def _search(self, movie, quality, results): - movie_title = getTitle(movie['library']) + movie_title = getTitle(movie) quality_id = quality['identifier'] params = mergeDicts(self.quality_search_params[quality_id].copy(), { 'order_by': 'relevance', 'order_way': 'descending', - 'searchstr': movie['library']['identifier'] + 'searchstr': movie['identifier'] }) url = '%s?json=noredirect&%s' % (self.urls['torrent'], tryUrlencode(params)) diff --git a/couchpotato/core/providers/torrent/publichd/main.py b/couchpotato/core/providers/torrent/publichd/main.py index b7c32fba..b200b1fd 100644 --- a/couchpotato/core/providers/torrent/publichd/main.py +++ b/couchpotato/core/providers/torrent/publichd/main.py @@ -30,7 +30,7 @@ class PublicHD(TorrentMagnetProvider): params = tryUrlencode({ 'page':'torrents', - 'search': '%s %s' % (title, movie['library']['year']), + 'search': '%s %s' % (title, movie['info']['year']), 'active': 1, }) diff --git a/couchpotato/core/providers/torrent/sceneaccess/main.py b/couchpotato/core/providers/torrent/sceneaccess/main.py index a43c49bb..dcf0b351 100644 --- a/couchpotato/core/providers/torrent/sceneaccess/main.py +++ b/couchpotato/core/providers/torrent/sceneaccess/main.py @@ -39,7 +39,7 @@ class SceneAccess(TorrentProvider): ) arguments = tryUrlencode({ - 'search': movie['library']['identifier'], + 'search': movie['identifier'], 'method': 1, }) url = "%s&%s" % (url, arguments) diff --git a/couchpotato/core/providers/torrent/thepiratebay/main.py b/couchpotato/core/providers/torrent/thepiratebay/main.py index f8b77787..8ccefeb1 100644 --- a/couchpotato/core/providers/torrent/thepiratebay/main.py +++ b/couchpotato/core/providers/torrent/thepiratebay/main.py @@ -50,7 +50,7 @@ class ThePirateBay(TorrentMagnetProvider): while page < total_pages: - search_url = self.urls['search'] % (self.getDomain(), tryUrlencode('"%s" %s' % (title, movie['library']['year'])), page, ','.join(str(x) for x in cats)) + search_url = self.urls['search'] % (self.getDomain(), tryUrlencode('"%s" %s' % (title, movie['info']['year'])), page, ','.join(str(x) for x in cats)) page += 1 data = self.getHTMLData(search_url) diff --git a/couchpotato/core/providers/torrent/torrentbytes/main.py b/couchpotato/core/providers/torrent/torrentbytes/main.py index 91939e78..109e50f7 100644 --- a/couchpotato/core/providers/torrent/torrentbytes/main.py +++ b/couchpotato/core/providers/torrent/torrentbytes/main.py @@ -34,7 +34,7 @@ class TorrentBytes(TorrentProvider): def _searchOnTitle(self, title, movie, quality, results): - url = self.urls['search'] % (tryUrlencode('%s %s' % (title.replace(':', ''), movie['library']['year'])), self.getCatId(quality['identifier'])[0]) + url = self.urls['search'] % (tryUrlencode('%s %s' % (title.replace(':', ''), movie['info']['year'])), self.getCatId(quality['identifier'])[0]) data = self.getHTMLData(url) if data: diff --git a/couchpotato/core/providers/torrent/torrentday/main.py b/couchpotato/core/providers/torrent/torrentday/main.py index 6d343234..83177a22 100644 --- a/couchpotato/core/providers/torrent/torrentday/main.py +++ b/couchpotato/core/providers/torrent/torrentday/main.py @@ -27,7 +27,7 @@ class TorrentDay(TorrentProvider): def _searchOnTitle(self, title, movie, quality, results): - q = '"%s %s"' % (title, movie['library']['year']) + q = '"%s %s"' % (title, movie['info']['year']) data = { '/browse.php?': None, diff --git a/couchpotato/core/providers/torrent/torrentleech/main.py b/couchpotato/core/providers/torrent/torrentleech/main.py index ea6158df..80c426f8 100644 --- a/couchpotato/core/providers/torrent/torrentleech/main.py +++ b/couchpotato/core/providers/torrent/torrentleech/main.py @@ -35,7 +35,7 @@ class TorrentLeech(TorrentProvider): def _searchOnTitle(self, title, movie, quality, results): - url = self.urls['search'] % (tryUrlencode('%s %s' % (title.replace(':', ''), movie['library']['year'])), self.getCatId(quality['identifier'])[0]) + url = self.urls['search'] % (tryUrlencode('%s %s' % (title.replace(':', ''), movie['info']['year'])), self.getCatId(quality['identifier'])[0]) data = self.getHTMLData(url) if data: diff --git a/couchpotato/core/providers/torrent/torrentpotato/main.py b/couchpotato/core/providers/torrent/torrentpotato/main.py index eaaf8d2c..a58fd61c 100644 --- a/couchpotato/core/providers/torrent/torrentpotato/main.py +++ b/couchpotato/core/providers/torrent/torrentpotato/main.py @@ -35,7 +35,7 @@ class TorrentPotato(TorrentProvider): arguments = tryUrlencode({ 'user': host['name'], 'passkey': host['pass_key'], - 'imdbid': movie['library']['identifier'] + 'imdbid': movie['identifier'] }) url = '%s?%s' % (host['host'], arguments) diff --git a/couchpotato/core/providers/torrent/torrentshack/main.py b/couchpotato/core/providers/torrent/torrentshack/main.py index f0cd5997..6c6dc3b8 100644 --- a/couchpotato/core/providers/torrent/torrentshack/main.py +++ b/couchpotato/core/providers/torrent/torrentshack/main.py @@ -34,7 +34,7 @@ class TorrentShack(TorrentProvider): scene_only = '1' if self.conf('scene_only') else '' - url = self.urls['search'] % (tryUrlencode('%s %s' % (title.replace(':', ''), movie['library']['year'])), scene_only, self.getCatId(quality['identifier'])[0]) + url = self.urls['search'] % (tryUrlencode('%s %s' % (title.replace(':', ''), movie['info']['year'])), scene_only, self.getCatId(quality['identifier'])[0]) data = self.getHTMLData(url) if data: diff --git a/couchpotato/core/providers/torrent/yify/main.py b/couchpotato/core/providers/torrent/yify/main.py index 6deaf7bb..00d67eb0 100644 --- a/couchpotato/core/providers/torrent/yify/main.py +++ b/couchpotato/core/providers/torrent/yify/main.py @@ -33,7 +33,7 @@ class Yify(TorrentMagnetProvider): def _search(self, movie, quality, results): - search_url = self.urls['search'] % (self.getDomain(), movie['library']['identifier'], quality['identifier']) + search_url = self.urls['search'] % (self.getDomain(), movie['identifier'], quality['identifier']) data = self.getJsonData(search_url) diff --git a/couchpotato/core/providers/trailer/hdtrailers/main.py b/couchpotato/core/providers/trailer/hdtrailers/main.py index cba7609f..6af83ac7 100644 --- a/couchpotato/core/providers/trailer/hdtrailers/main.py +++ b/couchpotato/core/providers/trailer/hdtrailers/main.py @@ -20,11 +20,11 @@ class HDTrailers(TrailerProvider): def search(self, group): - movie_name = getTitle(group['library']) + movie_name = getTitle(group) url = self.urls['api'] % self.movieUrlName(movie_name) try: - data = self.getCache('hdtrailers.%s' % group['library']['identifier'], url, show_error = False) + data = self.getCache('hdtrailers.%s' % group['identifier'], url, show_error = False) except HTTPError: log.debug('No page found for: %s', movie_name) data = None @@ -50,11 +50,11 @@ class HDTrailers(TrailerProvider): def findViaAlternative(self, group): results = {'480p':[], '720p':[], '1080p':[]} - movie_name = getTitle(group['library']) + movie_name = getTitle(group) url = "%s?%s" % (self.urls['backup'], tryUrlencode({'s':movie_name})) try: - data = self.getCache('hdtrailers.alt.%s' % group['library']['identifier'], url, show_error = False) + data = self.getCache('hdtrailers.alt.%s' % group['identifier'], url, show_error = False) except HTTPError: log.debug('No alternative page found for: %s', movie_name) data = None diff --git a/couchpotato/core/settings/__init__.py b/couchpotato/core/settings/__init__.py index bbbc9381..fcea04f5 100644 --- a/couchpotato/core/settings/__init__.py +++ b/couchpotato/core/settings/__init__.py @@ -5,7 +5,6 @@ from couchpotato.core.event import addEvent, fireEvent from couchpotato.core.helpers.encoding import toUnicode from couchpotato.core.helpers.variable import mergeDicts, tryInt, tryFloat from couchpotato.core.settings.index import PropertyIndex -from couchpotato.core.settings.model import Properties import ConfigParser @@ -247,7 +246,7 @@ class Settings(object): db.update(p['doc']) except: db.insert({ - 'type': 'property', + '_t': 'property', 'identifier': identifier, 'value': toUnicode(value), }) diff --git a/couchpotato/core/settings/index.py b/couchpotato/core/settings/index.py index 45d366eb..68ec52d8 100644 --- a/couchpotato/core/settings/index.py +++ b/couchpotato/core/settings/index.py @@ -5,12 +5,12 @@ from hashlib import md5 class PropertyIndex(HashIndex): def __init__(self, *args, **kwargs): - kwargs['key_format'] = '16s' + kwargs['key_format'] = '32s' super(PropertyIndex, self).__init__(*args, **kwargs) def make_key(self, key): - return md5(key).digest() + return md5(key).hexdigest() def make_key_value(self, data): - if data.get('type') == 'property': - return md5(data['identifier']).digest(), None + if data.get('_t') == 'property': + return md5(data['identifier']).hexdigest(), None diff --git a/couchpotato/runner.py b/couchpotato/runner.py index 744d425b..b2ea606b 100644 --- a/couchpotato/runner.py +++ b/couchpotato/runner.py @@ -223,9 +223,9 @@ def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, En loader.run() # Fill database with needed stuff + fireEvent('database.setup') if not db_exists: fireEvent('app.initialize', in_order = True) - fireEvent('database.setup') # Go go go! from tornado.ioloop import IOLoop @@ -234,7 +234,7 @@ def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, En # Some logging and fire load event try: log.info('Starting server on port %(port)s', config) except: pass - fireEventAsync('app.load2') + fireEventAsync('app.load') if config['ssl_cert'] and config['ssl_key']: server = HTTPServer(application, no_keep_alive = True, ssl_options = { diff --git a/couchpotato/templates/index.html b/couchpotato/templates/index.html index af257454..b4328001 100644 --- a/couchpotato/templates/index.html +++ b/couchpotato/templates/index.html @@ -69,8 +69,6 @@ 'qualities': {{ json_encode(fireEvent('quality.all', single = True)) }} }); - Status.setup({{ json_encode(fireEvent('status.all', single = True)) }}); - CategoryList.setup({{ json_encode(fireEvent('category.all', single = True)) }}); App.setup({