More nosql
This commit is contained in:
1 parent
63743dd2b6
commit
99252074be
82 files changed
+643
-715
No files matched your search
@@ -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)
|
||||
});
|
||||
|
||||
|
||||
Whitespace-only changes.
@@ -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) \
|
||||
|
||||
Reference in new issue
Block a user