More nosql
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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):
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class Search(Plugin):
|
||||
}"""}
|
||||
})
|
||||
|
||||
addEvent('app.load2', self.addSingleSearches)
|
||||
addEvent('app.load', self.addSingleSearches)
|
||||
|
||||
def search(self, q = '', types = None, **kwargs):
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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)
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
from .main import MovieLibraryPlugin
|
||||
|
||||
|
||||
def start():
|
||||
return MovieLibraryPlugin()
|
||||
|
||||
config = []
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 []
|
||||
}
|
||||
|
||||
|
||||
@@ -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 :)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 ''
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -324,4 +324,4 @@ Profile.Type = new Class({
|
||||
return this.el;
|
||||
}
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
16
couchpotato/core/plugins/quality/index.py
Normal file
16
couchpotato/core/plugins/quality/index.py
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 []
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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'])
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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'), []):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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 '')
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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'])]),
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
@@ -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)})
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class SceneAccess(TorrentProvider):
|
||||
)
|
||||
|
||||
arguments = tryUrlencode({
|
||||
'search': movie['library']['identifier'],
|
||||
'search': movie['identifier'],
|
||||
'method': 1,
|
||||
})
|
||||
url = "%s&%s" % (url, arguments)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
})
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user