Cleanup
This commit is contained in:
@@ -14,20 +14,47 @@ log = CPLog(__name__)
|
||||
class ShowBase(MediaBase):
|
||||
|
||||
_type = 'show'
|
||||
query_condenser = QueryCondenser()
|
||||
|
||||
def __init__(self):
|
||||
super(ShowBase, self).__init__()
|
||||
|
||||
addApiView('show.add', self.addView, docs = {
|
||||
'desc': 'Add new movie to the wanted list',
|
||||
'desc': 'Add new show to the wanted list',
|
||||
'params': {
|
||||
'identifier': {'desc': 'IMDB id of the movie your want to add.'},
|
||||
'profile_id': {'desc': 'ID of quality profile you want the add the movie in. If empty will use the default profile.'},
|
||||
'title': {'desc': 'Movie title to use for searches. Has to be one of the titles returned by movie.search.'},
|
||||
'identifier': {'desc': 'IMDB id of the show your want to add.'},
|
||||
'profile_id': {'desc': 'ID of quality profile you want the add the show in. If empty will use the default profile.'},
|
||||
'category_id': {'desc': 'ID of category you want the add the show in.'},
|
||||
'title': {'desc': 'Title of the show to use for search and renaming'},
|
||||
}
|
||||
})
|
||||
|
||||
addEvent('show.add', self.add)
|
||||
addEvent('show.update_info', self.add)
|
||||
|
||||
addEvent('media.search_query', self.query)
|
||||
|
||||
def query(self, library, first = True, condense = True, **kwargs):
|
||||
if library is list or library.get('type') != 'show':
|
||||
return
|
||||
|
||||
titles = [title['title'] for title in library['titles']]
|
||||
|
||||
if condense:
|
||||
# Use QueryCondenser to build a list of optimal search titles
|
||||
condensed_titles = self.query_condenser.distinct(titles)
|
||||
|
||||
if condensed_titles:
|
||||
# Use condensed titles if we got a valid result
|
||||
titles = condensed_titles
|
||||
else:
|
||||
# Fallback to simplifying titles
|
||||
titles = [simplify(title) for title in titles]
|
||||
|
||||
if first:
|
||||
return titles[0] if titles else None
|
||||
|
||||
return titles
|
||||
|
||||
def addView(self, **kwargs):
|
||||
add_dict = self.add(params = kwargs)
|
||||
@@ -37,204 +64,35 @@ class ShowBase(MediaBase):
|
||||
'show': add_dict,
|
||||
}
|
||||
|
||||
def add(self, params = {}, force_readd = True, search_after = True, update_library = False, status_id = None):
|
||||
"""
|
||||
params
|
||||
{'category_id': u'-1',
|
||||
'identifier': u'tt1519931',
|
||||
'profile_id': u'12',
|
||||
'thetvdb_id': u'158661',
|
||||
'title': u'Haven'}
|
||||
"""
|
||||
log.debug("show.add")
|
||||
def add(self, params = {}, force_readd = True, search_after = True, update_library = False, status = None):
|
||||
|
||||
# Add show parent to db first; need to update library so maps will be in place (if any)
|
||||
parent = self.addToDatabase(params = params, update_library = True, type = 'show')
|
||||
db = get_db()
|
||||
|
||||
# TODO: add by airdate
|
||||
# Add Show
|
||||
show = {
|
||||
'identifiers': {
|
||||
'imdb': 'tt1234',
|
||||
'thetvdb': 123,
|
||||
'tmdb': 123,
|
||||
'rage': 123
|
||||
},
|
||||
'status': 'active',
|
||||
'title': title,
|
||||
'description': description,
|
||||
'profile_id': profile_id,
|
||||
'category_id': category_id,
|
||||
'primary_provider': 'thetvdb',
|
||||
'absolute_nr': True,
|
||||
'info': {}
|
||||
}
|
||||
|
||||
# Add by Season/Episode numbers
|
||||
self.addBySeasonEpisode(parent,
|
||||
params = params,
|
||||
force_readd = force_readd,
|
||||
search_after = search_after,
|
||||
update_library = update_library,
|
||||
status_id = status_id
|
||||
)
|
||||
show_info = fireEvent('show.info', show.get('identifiers'))
|
||||
|
||||
def addBySeasonEpisode(self, parent, params = {}, force_readd = True, search_after = True, update_library = False, status_id = None):
|
||||
identifier = params.get('id')
|
||||
# 'tvdb' will always be the master for our purpose. All mapped data can be mapped
|
||||
# to another source for downloading, but it will always be remapped back to tvdb numbering
|
||||
# when renamed so media can be used in media players that use tvdb for info provider
|
||||
#
|
||||
# This currently means the episode must actually exist in tvdb in order to be found but
|
||||
# the numbering can be different
|
||||
# Add Seasons
|
||||
for season_info in show_info.get('seasons', []):
|
||||
|
||||
#master = 'tvdb'
|
||||
#destination = 'scene'
|
||||
#destination = 'anidb'
|
||||
#destination = 'rage'
|
||||
#destination = 'trakt'
|
||||
# TODO: auto mode. if anime exists use it. if scene exists use it else use tvdb
|
||||
season = fireEvent('show.season.add', show.get('_id'), season_info)
|
||||
|
||||
# XXX: We should abort adding show, etc if either tvdb or xem is down or we will have incorrent mappings
|
||||
# I think if tvdb gets error we wont have anydata anyway, but we must make sure XEM returns!!!!
|
||||
for episode_info in season_info.get('seasons', []):
|
||||
|
||||
# Only the master should return results here; all other info providers should just return False
|
||||
# since we are just interested in the structure at this point.
|
||||
seasons = fireEvent('season.info', merge = True, identifier = identifier)
|
||||
if seasons is not None:
|
||||
for season in seasons:
|
||||
# Make sure we are only dealing with 'tvdb' responses at this point
|
||||
if season.get('primary_provider', None) != 'thetvdb':
|
||||
continue
|
||||
season_id = season.get('id', None)
|
||||
if season_id is None: continue
|
||||
|
||||
season_params = {'season_identifier': season_id}
|
||||
# Calling all info providers; merge your info now for individual season
|
||||
single_season = fireEvent('season.info', merge = True, identifier = identifier, params = season_params)
|
||||
single_season['category_id'] = params.get('category_id')
|
||||
single_season['profile_id'] = params.get('profile_id')
|
||||
single_season['title'] = single_season.get('original_title', None)
|
||||
single_season['identifier'] = season_id
|
||||
single_season['parent_identifier'] = identifier
|
||||
log.info("Adding Season %s" % season_id)
|
||||
s = self.addToDatabase(params = single_season, type = "season")
|
||||
|
||||
episode_params = {'season_identifier': season_id}
|
||||
episodes = fireEvent('episode.info', merge = True, identifier = identifier, params = episode_params)
|
||||
if episodes is not None:
|
||||
for episode in episodes:
|
||||
# Make sure we are only dealing with 'tvdb' responses at this point
|
||||
if episode.get('primary_provider', None) != 'thetvdb':
|
||||
continue
|
||||
episode_id = episode.get('id', None)
|
||||
if episode_id is None: continue
|
||||
try:
|
||||
episode_number = int(episode.get('episodenumber', None))
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
try:
|
||||
absolute_number = int(episode.get('absolute_number', None))
|
||||
except (ValueError, TypeError):
|
||||
absolute_number = None
|
||||
|
||||
episode_params = {'season_identifier': season_id,
|
||||
'episode_identifier': episode_id,
|
||||
'episode': episode_number}
|
||||
if absolute_number:
|
||||
episode_params['absolute'] = absolute_number
|
||||
# Calling all info providers; merge your info now for individual episode
|
||||
single_episode = fireEvent('episode.info', merge = True, identifier = identifier, params = episode_params)
|
||||
single_episode['category_id'] = params.get('category_id')
|
||||
single_episode['profile_id'] = params.get('profile_id')
|
||||
single_episode['title'] = single_episode.get('original_title', None)
|
||||
single_episode['identifier'] = episode_id
|
||||
single_episode['parent_identifier'] = single_season['identifier']
|
||||
log.info("Adding [%sx%s] %s - %s" % (season_id,
|
||||
episode_number,
|
||||
params['title'],
|
||||
single_episode.get('original_title', '')))
|
||||
e = self.addToDatabase(params = single_episode, type = "episode")
|
||||
|
||||
# Start searching now that all the media has been added
|
||||
if search_after:
|
||||
onComplete = self.createOnComplete(parent['id'])
|
||||
onComplete()
|
||||
|
||||
return parent
|
||||
|
||||
def addToDatabase(self, params = {}, type = "show", force_readd = True, search_after = False, update_library = False, status_id = None):
|
||||
log.debug("show.addToDatabase")
|
||||
|
||||
if not params.get('identifier'):
|
||||
msg = 'Can\'t add show without imdb identifier.'
|
||||
log.error(msg)
|
||||
fireEvent('notify.frontend', type = 'show.is_tvshow', message = msg)
|
||||
return False
|
||||
#else:
|
||||
#try:
|
||||
#is_show = fireEvent('movie.is_show', identifier = params.get('identifier'), single = True)
|
||||
#if not is_show:
|
||||
#msg = 'Can\'t add show, seems to be a TV show.'
|
||||
#log.error(msg)
|
||||
#fireEvent('notify.frontend', type = 'show.is_tvshow', message = msg)
|
||||
#return False
|
||||
#except:
|
||||
#pass
|
||||
|
||||
library = fireEvent('library.add.%s' % type, single = True, attrs = params, update_after = update_library)
|
||||
if not library:
|
||||
return False
|
||||
|
||||
# Status
|
||||
status_active, snatched_status, ignored_status, done_status, downloaded_status = \
|
||||
fireEvent('status.get', ['active', 'snatched', 'ignored', 'done', 'downloaded'], single = True)
|
||||
|
||||
default_profile = fireEvent('profile.default', single = True)
|
||||
cat_id = params.get('category_id', None)
|
||||
|
||||
db = get_session()
|
||||
m = db.query(Media).filter_by(library_id = library.get('id')).first()
|
||||
added = True
|
||||
do_search = False
|
||||
if not m:
|
||||
m = Media(
|
||||
type = type,
|
||||
library_id = library.get('id'),
|
||||
profile_id = params.get('profile_id', default_profile.get('id')),
|
||||
status_id = status_id if status_id else status_active.get('id'),
|
||||
category_id = tryInt(cat_id) if cat_id is not None and tryInt(cat_id) > 0 else None,
|
||||
)
|
||||
db.add(m)
|
||||
db.commit()
|
||||
|
||||
onComplete = None
|
||||
if search_after:
|
||||
onComplete = self.createOnComplete(m.id)
|
||||
|
||||
fireEventAsync('library.update.%s' % type, params.get('identifier'), default_title = params.get('title', ''), on_complete = onComplete)
|
||||
search_after = False
|
||||
elif force_readd:
|
||||
|
||||
# Clean snatched history
|
||||
for release in m.releases:
|
||||
if release.status_id in [downloaded_status.get('id'), snatched_status.get('id'), done_status.get('id')]:
|
||||
if params.get('ignore_previous', False):
|
||||
release.status_id = ignored_status.get('id')
|
||||
else:
|
||||
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 None
|
||||
else:
|
||||
log.debug('Show already exists, not updating: %s', params)
|
||||
added = False
|
||||
|
||||
if force_readd:
|
||||
m.status_id = status_id if status_id else status_active.get('id')
|
||||
m.last_edit = int(time.time())
|
||||
do_search = True
|
||||
|
||||
db.commit()
|
||||
|
||||
# Remove releases
|
||||
available_status = fireEvent('status.get', 'available', single = True)
|
||||
for rel in m.releases:
|
||||
if rel.status_id is available_status.get('id'):
|
||||
db.delete(rel)
|
||||
db.commit()
|
||||
|
||||
show_dict = m.to_dict(self.default_dict)
|
||||
|
||||
if do_search and search_after:
|
||||
onComplete = self.createOnComplete(m.id)
|
||||
onComplete()
|
||||
|
||||
if added:
|
||||
fireEvent('notify.frontend', type = 'show.added', data = show_dict, message = 'Successfully added "%s" to your wanted list.' % params.get('title', ''))
|
||||
|
||||
db.expire_all()
|
||||
return show_dict
|
||||
fireEvent('show.episode.add', season.get('_id'), episode_info)
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
from couchpotato.core.event import addEvent, fireEvent
|
||||
from couchpotato.core.helpers.encoding import toUnicode
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.helpers.variable import tryInt
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
autload = 'Episode'
|
||||
|
||||
class Episode(Plugin):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('media.search_query', self.query)
|
||||
addEvent('media.identifier', self.identifier)
|
||||
|
||||
addEvent('show.episode.add', self.add)
|
||||
addEvent('show.episode.update_info', self.update)
|
||||
|
||||
def query(self, library, first = True, condense = True, include_identifier = True, **kwargs):
|
||||
if library is list or library.get('type') != 'episode':
|
||||
return
|
||||
|
||||
# Get the titles of the season
|
||||
if not library.get('related_libraries', {}).get('season', []):
|
||||
log.warning('Invalid library, unable to determine title.')
|
||||
return
|
||||
|
||||
titles = fireEvent(
|
||||
'media.search_query',
|
||||
library['related_libraries']['season'][0],
|
||||
first=False,
|
||||
include_identifier=include_identifier,
|
||||
condense=condense,
|
||||
|
||||
single=True
|
||||
)
|
||||
|
||||
identifier = fireEvent('media.identifier', library, single = True)
|
||||
|
||||
# Add episode identifier to titles
|
||||
if include_identifier and identifier.get('episode'):
|
||||
titles = [title + ('E%02d' % identifier['episode']) for title in titles]
|
||||
|
||||
|
||||
if first:
|
||||
return titles[0] if titles else None
|
||||
|
||||
return titles
|
||||
|
||||
|
||||
def identifier(self, library):
|
||||
if library.get('type') != 'episode':
|
||||
return
|
||||
|
||||
identifier = {
|
||||
'season': None,
|
||||
'episode': None
|
||||
}
|
||||
|
||||
scene_map = library['info'].get('map_episode', {}).get('scene')
|
||||
|
||||
if scene_map:
|
||||
# Use scene mappings if they are available
|
||||
identifier['season'] = scene_map.get('season')
|
||||
identifier['episode'] = scene_map.get('episode')
|
||||
else:
|
||||
# Fallback to normal season/episode numbers
|
||||
identifier['season'] = library.get('season_number')
|
||||
identifier['episode'] = library.get('episode_number')
|
||||
|
||||
|
||||
# Cast identifiers to integers
|
||||
# TODO this will need changing to support identifiers with trailing 'a', 'b' characters
|
||||
identifier['season'] = tryInt(identifier['season'], None)
|
||||
identifier['episode'] = tryInt(identifier['episode'], None)
|
||||
|
||||
return identifier
|
||||
|
||||
def add(self, parent_id, update_after = True):
|
||||
|
||||
# Add Season
|
||||
season = {
|
||||
'nr': 1,
|
||||
'identifiers': {
|
||||
'imdb': 'tt1234',
|
||||
'thetvdb': 123,
|
||||
'tmdb': 123,
|
||||
'rage': 123
|
||||
},
|
||||
'parent': '_id',
|
||||
'info': {}, # Returned dict by providers
|
||||
}
|
||||
|
||||
episode_exists = True or False
|
||||
|
||||
if episode_exists:
|
||||
pass #update existing
|
||||
else:
|
||||
pass # Add Episode
|
||||
|
||||
|
||||
# Update library info
|
||||
if update_after is not False:
|
||||
handle = fireEventAsync if update_after is 'async' else fireEvent
|
||||
handle('show.episode.update_info', season.get('_id'), default_title = toUnicode(attrs.get('title', '')))
|
||||
|
||||
return season
|
||||
|
||||
def update_info(self, media_id = None, default_title = '', force = False):
|
||||
|
||||
if self.shuttingDown():
|
||||
return
|
||||
|
||||
# Get new info
|
||||
fireEvent('episode.info', merge = True)
|
||||
|
||||
# Update/create media
|
||||
|
||||
|
||||
# Get images
|
||||
|
||||
|
||||
return info
|
||||
@@ -1,173 +0,0 @@
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from couchpotato import get_db
|
||||
from couchpotato.core.event import addEvent, fireEvent
|
||||
from couchpotato.core.helpers.encoding import toUnicode
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.media._base.library.base import LibraryBase
|
||||
from couchpotato.core.helpers.variable import tryInt
|
||||
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
autload = 'EpisodeLibraryPlugin'
|
||||
|
||||
|
||||
class EpisodeLibraryPlugin(LibraryBase):
|
||||
|
||||
default_dict = {'titles': {}, 'files':{}}
|
||||
|
||||
def __init__(self):
|
||||
addEvent('library.query', self.query)
|
||||
addEvent('library.identifier', self.identifier)
|
||||
addEvent('library.update.episode', self.update)
|
||||
|
||||
def query(self, library, first = True, condense = True, include_identifier = True, **kwargs):
|
||||
if library is list or library.get('type') != 'episode':
|
||||
return
|
||||
|
||||
# Get the titles of the season
|
||||
if not library.get('related_libraries', {}).get('season', []):
|
||||
log.warning('Invalid library, unable to determine title.')
|
||||
return
|
||||
|
||||
titles = fireEvent(
|
||||
'library.query',
|
||||
library['related_libraries']['season'][0],
|
||||
first=False,
|
||||
include_identifier=include_identifier,
|
||||
condense=condense,
|
||||
|
||||
single=True
|
||||
)
|
||||
|
||||
identifier = fireEvent('library.identifier', library, single = True)
|
||||
|
||||
# Add episode identifier to titles
|
||||
if include_identifier and identifier.get('episode'):
|
||||
titles = [title + ('E%02d' % identifier['episode']) for title in titles]
|
||||
|
||||
|
||||
if first:
|
||||
return titles[0] if titles else None
|
||||
|
||||
return titles
|
||||
|
||||
|
||||
def identifier(self, library):
|
||||
if library.get('type') != 'episode':
|
||||
return
|
||||
|
||||
identifier = {
|
||||
'season': None,
|
||||
'episode': None
|
||||
}
|
||||
|
||||
scene_map = library['info'].get('map_episode', {}).get('scene')
|
||||
|
||||
if scene_map:
|
||||
# Use scene mappings if they are available
|
||||
identifier['season'] = scene_map.get('season')
|
||||
identifier['episode'] = scene_map.get('episode')
|
||||
else:
|
||||
# Fallback to normal season/episode numbers
|
||||
identifier['season'] = library.get('season_number')
|
||||
identifier['episode'] = library.get('episode_number')
|
||||
|
||||
|
||||
# Cast identifiers to integers
|
||||
# TODO this will need changing to support identifiers with trailing 'a', 'b' characters
|
||||
identifier['season'] = tryInt(identifier['season'], None)
|
||||
identifier['episode'] = tryInt(identifier['episode'], None)
|
||||
|
||||
return identifier
|
||||
|
||||
def update(self, media_id = None, identifier = None, default_title = '', force = False):
|
||||
|
||||
if self.shuttingDown():
|
||||
return
|
||||
|
||||
db = get_db()
|
||||
|
||||
if media_id:
|
||||
media = db.get('id', media_id)
|
||||
else:
|
||||
media = db.get('media', identifier, with_doc = True)['doc']
|
||||
|
||||
do_update = True
|
||||
|
||||
if media.get('status') == 'done' and not force:
|
||||
do_update = False
|
||||
|
||||
episode_params = {
|
||||
'season_identifier': media.get('parent'),
|
||||
'episode_identifier': media.get('identifier'),
|
||||
'episode': media.get('episode_number'),
|
||||
'absolute': media.get('episode_number'),
|
||||
}
|
||||
info = fireEvent('episode.info', merge = True, params = episode_params)
|
||||
|
||||
# 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
|
||||
if do_update:
|
||||
episode = {
|
||||
'plot': toUnicode(info.get('plot', '')),
|
||||
'tagline': toUnicode(info.get('tagline', '')),
|
||||
'year': info.get('year', 0),
|
||||
'status_id': 'done',
|
||||
'season_number': tryInt(info.get('seasonnumber', None)),
|
||||
'episode_number': tryInt(info.get('episodenumber', None)),
|
||||
'absolute_number': tryInt(info.get('absolute_number', None)),
|
||||
'last_updated': tryInt(info.get('lastupdated', time.time())),
|
||||
}
|
||||
|
||||
titles = info.get('titles', [])
|
||||
log.debug('Adding titles: %s', titles)
|
||||
counter = 0
|
||||
for title in titles:
|
||||
if not title:
|
||||
continue
|
||||
title = toUnicode(title)
|
||||
t = LibraryTitle(
|
||||
title = title,
|
||||
simple_title = self.simplifyTitle(title),
|
||||
default = (len(default_title) == 0 and counter == 0) or len(titles) == 1 or title.lower() == toUnicode(default_title.lower()) or (toUnicode(default_title) == u'' and toUnicode(titles[0]) == title)
|
||||
)
|
||||
library.titles.append(t)
|
||||
counter += 1
|
||||
|
||||
media.update(episode)
|
||||
db.update(media)
|
||||
|
||||
# Files
|
||||
images = info.get('images', [])
|
||||
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)
|
||||
if file_path:
|
||||
file_obj = fireEvent('file.add', path = file_path, type_tuple = ('image', image_type), single = True)
|
||||
try:
|
||||
file_obj = db.query(File).filter_by(id = file_obj.get('id')).one()
|
||||
library.files.append(file_obj)
|
||||
db.commit()
|
||||
|
||||
break
|
||||
except:
|
||||
log.debug('Failed to attach to library: %s', traceback.format_exc())
|
||||
|
||||
library_dict = library.to_dict(self.default_dict)
|
||||
db.expire_all()
|
||||
return library_dict
|
||||
@@ -1,158 +0,0 @@
|
||||
import traceback
|
||||
|
||||
from couchpotato import get_session
|
||||
from couchpotato.core.event import addEvent, fireEvent
|
||||
from couchpotato.core.helpers.encoding import toUnicode
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.media._base.library.base import LibraryBase
|
||||
from couchpotato.core.helpers.variable import tryInt
|
||||
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
autload = 'SeasonLibraryPlugin'
|
||||
|
||||
|
||||
class SeasonLibraryPlugin(LibraryBase):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('library.query', self.query)
|
||||
addEvent('library.identifier', self.identifier)
|
||||
addEvent('library.update.season', self.update)
|
||||
|
||||
def query(self, library, first = True, condense = True, include_identifier = True, **kwargs):
|
||||
if library is list or library.get('type') != 'season':
|
||||
return
|
||||
|
||||
# Get the titles of the show
|
||||
if not library.get('related_libraries', {}).get('show', []):
|
||||
log.warning('Invalid library, unable to determine title.')
|
||||
return
|
||||
|
||||
titles = fireEvent(
|
||||
'library.query',
|
||||
library['related_libraries']['show'][0],
|
||||
first=False,
|
||||
condense=condense,
|
||||
|
||||
single=True
|
||||
)
|
||||
|
||||
# Add season map_names if they exist
|
||||
if 'map_names' in library['info']:
|
||||
season_names = library['info']['map_names'].get(str(library['season_number']), {})
|
||||
|
||||
# Add titles from all locations
|
||||
# TODO only add name maps from a specific location
|
||||
for location, names in season_names.items():
|
||||
titles += [name for name in names if name and name not in titles]
|
||||
|
||||
|
||||
identifier = fireEvent('library.identifier', library, single = True)
|
||||
|
||||
# Add season identifier to titles
|
||||
if include_identifier and identifier.get('season') is not None:
|
||||
titles = [title + (' S%02d' % identifier['season']) for title in titles]
|
||||
|
||||
|
||||
if first:
|
||||
return titles[0] if titles else None
|
||||
|
||||
return titles
|
||||
|
||||
def identifier(self, library):
|
||||
if library.get('type') != 'season':
|
||||
return
|
||||
|
||||
return {
|
||||
'season': tryInt(library['season_number'], None)
|
||||
}
|
||||
|
||||
def update(self, identifier, default_title = '', force = False):
|
||||
|
||||
if self.shuttingDown():
|
||||
return
|
||||
|
||||
db = get_session()
|
||||
library = db.query(SeasonLibrary).filter_by(identifier = identifier).first()
|
||||
done_status = fireEvent('status.get', 'done', single = True)
|
||||
|
||||
if library:
|
||||
library_dict = library.to_dict(self.default_dict)
|
||||
|
||||
do_update = True
|
||||
|
||||
parent_identifier = None
|
||||
if library.parent is not None:
|
||||
parent_identifier = library.parent.identifier
|
||||
|
||||
if library.status_id == done_status.get('id') and not force:
|
||||
do_update = False
|
||||
|
||||
season_params = {'season_identifier': identifier}
|
||||
info = fireEvent('season.info', merge = True, identifier = parent_identifier, params = season_params)
|
||||
|
||||
# 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
|
||||
if do_update:
|
||||
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.season_number = tryInt(info.get('seasonnumber', None))
|
||||
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
|
||||
for title in titles:
|
||||
if not title:
|
||||
continue
|
||||
title = toUnicode(title)
|
||||
t = LibraryTitle(
|
||||
title = title,
|
||||
simple_title = self.simplifyTitle(title),
|
||||
# XXX: default was None; so added a quick hack since we don't really need titiles for seasons anyway
|
||||
#default = (len(default_title) == 0 and counter == 0) or len(titles) == 1 or title.lower() == toUnicode(default_title.lower()) or (toUnicode(default_title) == u'' and toUnicode(titles[0]) == title)
|
||||
default = True,
|
||||
)
|
||||
library.titles.append(t)
|
||||
counter += 1
|
||||
|
||||
db.commit()
|
||||
|
||||
# Files
|
||||
images = info.get('images', [])
|
||||
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)
|
||||
if file_path:
|
||||
file_obj = fireEvent('file.add', path = file_path, type_tuple = ('image', image_type), single = True)
|
||||
try:
|
||||
file_obj = db.query(File).filter_by(id = file_obj.get('id')).one()
|
||||
library.files.append(file_obj)
|
||||
db.commit()
|
||||
break
|
||||
except:
|
||||
log.debug('Failed to attach to library: %s', traceback.format_exc())
|
||||
|
||||
library_dict = library.to_dict(self.default_dict)
|
||||
db.expire_all()
|
||||
return library_dict
|
||||
@@ -1,196 +0,0 @@
|
||||
from string import ascii_letters
|
||||
import time
|
||||
import traceback
|
||||
|
||||
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.base import LibraryBase
|
||||
from qcond.helpers import simplify
|
||||
from qcond import QueryCondenser
|
||||
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
autload = 'SeasonLibraryPlugin'
|
||||
|
||||
|
||||
class ShowLibraryPlugin(LibraryBase):
|
||||
|
||||
default_dict = {'titles': {}, 'files':{}}
|
||||
|
||||
def __init__(self):
|
||||
self.query_condenser = QueryCondenser()
|
||||
|
||||
addEvent('library.query', self.query)
|
||||
addEvent('library.add.show', self.add)
|
||||
addEvent('library.update.show', self.update)
|
||||
addEvent('library.update.show_release_date', self.updateReleaseDate)
|
||||
|
||||
def query(self, library, first = True, condense = True, **kwargs):
|
||||
if library is list or library.get('type') != 'show':
|
||||
return
|
||||
|
||||
titles = [title['title'] for title in library['titles']]
|
||||
|
||||
if condense:
|
||||
# Use QueryCondenser to build a list of optimal search titles
|
||||
condensed_titles = self.query_condenser.distinct(titles)
|
||||
|
||||
if condensed_titles:
|
||||
# Use condensed titles if we got a valid result
|
||||
titles = condensed_titles
|
||||
else:
|
||||
# Fallback to simplifying titles
|
||||
titles = [simplify(title) for title in titles]
|
||||
|
||||
if first:
|
||||
return titles[0] if titles else None
|
||||
|
||||
return titles
|
||||
|
||||
def add(self, attrs = {}, update_after = True):
|
||||
type = attrs.get('type', 'show')
|
||||
primary_provider = attrs.get('primary_provider', 'thetvdb')
|
||||
|
||||
db = get_session()
|
||||
|
||||
l = db.query(ShowLibrary).filter_by(type = type, identifier = attrs.get('identifier')).first()
|
||||
if not l:
|
||||
status = fireEvent('status.get', 'needs_update', single = True)
|
||||
l = ShowLibrary(
|
||||
type = type,
|
||||
primary_provider = primary_provider,
|
||||
year = attrs.get('year'),
|
||||
identifier = attrs.get('identifier'),
|
||||
plot = toUnicode(attrs.get('plot')),
|
||||
tagline = toUnicode(attrs.get('tagline')),
|
||||
status_id = status.get('id'),
|
||||
info = {},
|
||||
parent = None,
|
||||
)
|
||||
|
||||
title = LibraryTitle(
|
||||
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.show', identifier = l.identifier, default_title = toUnicode(attrs.get('title', '')))
|
||||
|
||||
library_dict = l.to_dict(self.default_dict)
|
||||
db.expire_all()
|
||||
return library_dict
|
||||
|
||||
def update(self, identifier, default_title = '', force = False):
|
||||
|
||||
if self.shuttingDown():
|
||||
return
|
||||
|
||||
db = get_session()
|
||||
library = db.query(ShowLibrary).filter_by(identifier = identifier).first()
|
||||
done_status = fireEvent('status.get', 'done', single = True)
|
||||
|
||||
if library:
|
||||
library_dict = library.to_dict(self.default_dict)
|
||||
|
||||
do_update = True
|
||||
|
||||
info = fireEvent('show.info', merge = True, 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 show info to work with: %s', identifier)
|
||||
return False
|
||||
|
||||
# Main info
|
||||
if do_update:
|
||||
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.show_status = toUnicode(info.get('status', '').lower())
|
||||
library.airs_time = info.get('airs_time', None)
|
||||
|
||||
# Bits
|
||||
days_of_week_map = {
|
||||
u'Monday': 1,
|
||||
u'Tuesday': 2,
|
||||
u'Wednesday': 4,
|
||||
u'Thursday': 8,
|
||||
u'Friday': 16,
|
||||
u'Saturday': 32,
|
||||
u'Sunday': 64,
|
||||
u'Daily': 127,
|
||||
}
|
||||
try:
|
||||
library.airs_dayofweek = days_of_week_map.get(info.get('airs_dayofweek'))
|
||||
except:
|
||||
library.airs_dayofweek = 0
|
||||
|
||||
try:
|
||||
library.last_updated = int(info.get('lastupdated'))
|
||||
except:
|
||||
library.last_updated = int(time.time())
|
||||
|
||||
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
|
||||
for title in titles:
|
||||
if not title:
|
||||
continue
|
||||
title = toUnicode(title)
|
||||
t = LibraryTitle(
|
||||
title = title,
|
||||
simple_title = self.simplifyTitle(title),
|
||||
default = (len(default_title) == 0 and counter == 0) or len(titles) == 1 or title.lower() == toUnicode(default_title.lower()) or (toUnicode(default_title) == u'' and toUnicode(titles[0]) == title)
|
||||
)
|
||||
library.titles.append(t)
|
||||
counter += 1
|
||||
|
||||
db.commit()
|
||||
|
||||
# Files
|
||||
images = info.get('images', [])
|
||||
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)
|
||||
if file_path:
|
||||
file_obj = fireEvent('file.add', path = file_path, type_tuple = ('image', image_type), single = True)
|
||||
try:
|
||||
file_obj = db.query(File).filter_by(id = file_obj.get('id')).one()
|
||||
library.files.append(file_obj)
|
||||
db.commit()
|
||||
|
||||
break
|
||||
except:
|
||||
log.debug('Failed to attach to library: %s', traceback.format_exc())
|
||||
|
||||
library_dict = library.to_dict(self.default_dict)
|
||||
|
||||
db.expire_all()
|
||||
return library_dict
|
||||
@@ -96,7 +96,7 @@ class Episode(Base):
|
||||
log.info2('Wrong: releases with identifier ranges are not supported yet')
|
||||
return False
|
||||
|
||||
required = fireEvent('library.identifier', media['library'], single = True)
|
||||
required = fireEvent('media.identifier', media['library'], single = True)
|
||||
|
||||
# TODO - Support air by date episodes
|
||||
# TODO - Support episode parts
|
||||
@@ -121,7 +121,7 @@ class Season(Base):
|
||||
log.info2('Wrong: releases with identifier ranges are not supported yet')
|
||||
return False
|
||||
|
||||
required = fireEvent('library.identifier', media['library'], single = True)
|
||||
required = fireEvent('media.identifier', media['library'], single = True)
|
||||
|
||||
if identifier != required:
|
||||
log.info2('Wrong: required identifier (%s) does not match release identifier (%s)', (required, identifier))
|
||||
|
||||
@@ -21,7 +21,7 @@ class Season(SeasonProvider, Base):
|
||||
|
||||
def buildUrl(self, media, quality):
|
||||
query = tryUrlencode({
|
||||
'q': fireEvent('library.query', media, single = True),
|
||||
'q': fireEvent('media.search_query', media, single = True),
|
||||
'm': 'n',
|
||||
'max': 400,
|
||||
'adv_age': Env.setting('retention', 'nzb'),
|
||||
@@ -38,7 +38,7 @@ class Episode(EpisodeProvider, Base):
|
||||
|
||||
def buildUrl(self, media, quality):
|
||||
query = tryUrlencode({
|
||||
'q': fireEvent('library.query', media, single = True),
|
||||
'q': fireEvent('media.search_query', media, single = True),
|
||||
'm': 'n',
|
||||
'max': 400,
|
||||
'adv_age': Env.setting('retention', 'nzb'),
|
||||
|
||||
@@ -19,8 +19,8 @@ class Newznab(MultiProvider):
|
||||
class Season(SeasonProvider, Base):
|
||||
|
||||
def buildUrl(self, media, api_key):
|
||||
search_title = fireEvent('library.query', media, include_identifier = False, single = True)
|
||||
identifier = fireEvent('library.identifier', media, single = True)
|
||||
search_title = fireEvent('media.search_query', media, include_identifier = False, single = True)
|
||||
identifier = fireEvent('media.identifier', media, single = True)
|
||||
|
||||
query = tryUrlencode({
|
||||
't': 'tvsearch',
|
||||
@@ -35,8 +35,8 @@ class Season(SeasonProvider, Base):
|
||||
class Episode(EpisodeProvider, Base):
|
||||
|
||||
def buildUrl(self, media, api_key):
|
||||
search_title = fireEvent('library.query', media, include_identifier = False, single = True)
|
||||
identifier = fireEvent('library.identifier', media, single = True)
|
||||
search_title = fireEvent('media.search_query', media, include_identifier = False, single = True)
|
||||
identifier = fireEvent('media.identifier', media, single = True)
|
||||
|
||||
query = tryUrlencode({
|
||||
't': 'tvsearch',
|
||||
|
||||
@@ -21,7 +21,7 @@ class Season(SeasonProvider, Base):
|
||||
def buildUrl(self, media):
|
||||
|
||||
q = tryUrlencode({
|
||||
'q': fireEvent('library.query', media, single = True),
|
||||
'q': fireEvent('media.search_query', media, single = True),
|
||||
})
|
||||
|
||||
query = tryUrlencode({
|
||||
@@ -39,7 +39,7 @@ class Episode(EpisodeProvider, Base):
|
||||
def buildUrl(self, media):
|
||||
|
||||
q = tryUrlencode({
|
||||
'q': fireEvent('library.query', media, single = True),
|
||||
'q': fireEvent('media.search_query', media, single = True),
|
||||
})
|
||||
|
||||
query = tryUrlencode({
|
||||
|
||||
@@ -21,7 +21,7 @@ class Season(SeasonProvider, Base):
|
||||
|
||||
def buildUrl(self, media, quality):
|
||||
query = tryUrlencode({
|
||||
'q': fireEvent('library.query', media, single = True),
|
||||
'q': fireEvent('media.search_query', media, single = True),
|
||||
'age': Env.setting('retention', 'nzb'),
|
||||
'sort': 'agedesc',
|
||||
'minsize': quality.get('size_min'),
|
||||
@@ -38,7 +38,7 @@ class Episode(EpisodeProvider, Base):
|
||||
|
||||
def buildUrl(self, media, quality):
|
||||
query = tryUrlencode({
|
||||
'q': fireEvent('library.query', media, single = True),
|
||||
'q': fireEvent('media.search_query', media, single = True),
|
||||
'age': Env.setting('retention', 'nzb'),
|
||||
'sort': 'agedesc',
|
||||
'minsize': quality.get('size_min'),
|
||||
|
||||
@@ -20,7 +20,7 @@ class Season(SeasonProvider, Base):
|
||||
|
||||
def buildUrl(self, media):
|
||||
query = tryUrlencode({
|
||||
'search': fireEvent('library.query', media, single = True),
|
||||
'search': fireEvent('media.search_query', media, single = True),
|
||||
'cat': 12 # Season cat
|
||||
})
|
||||
return query
|
||||
@@ -30,7 +30,7 @@ class Episode(EpisodeProvider, Base):
|
||||
|
||||
def buildUrl(self, media):
|
||||
query = tryUrlencode({
|
||||
'search': fireEvent('library.query', media, single = True),
|
||||
'search': fireEvent('media.search_query', media, single = True),
|
||||
'cat': 10 # Episode cat
|
||||
})
|
||||
return query
|
||||
|
||||
@@ -20,7 +20,7 @@ class Season(SeasonProvider, Base):
|
||||
# For season bundles, bitsoup currently only has one category
|
||||
def buildUrl(self, media, quality):
|
||||
query = tryUrlencode({
|
||||
'search': fireEvent('library.query', media, single = True),
|
||||
'search': fireEvent('media.search_query', media, single = True),
|
||||
'cat': 45 # TV-Packs Category
|
||||
})
|
||||
return query
|
||||
@@ -35,7 +35,7 @@ class Episode(EpisodeProvider, Base):
|
||||
|
||||
def buildUrl(self, media, quality):
|
||||
query = tryUrlencode({
|
||||
'search': fireEvent('library.query', media, single = True),
|
||||
'search': fireEvent('media.search_query', media, single = True),
|
||||
'cat': self.getCatId(quality['identifier'])[0],
|
||||
})
|
||||
return query
|
||||
|
||||
@@ -18,10 +18,10 @@ class PublicHD(MultiProvider):
|
||||
class Season(SeasonProvider, Base):
|
||||
|
||||
def buildUrl(self, media):
|
||||
return fireEvent('library.query', media, single = True)
|
||||
return fireEvent('media.search_query', media, single = True)
|
||||
|
||||
|
||||
class Episode(EpisodeProvider, Base):
|
||||
|
||||
def buildUrl(self, media):
|
||||
return fireEvent('library.query', media, single = True)
|
||||
return fireEvent('media.search_query', media, single = True)
|
||||
|
||||
@@ -30,7 +30,7 @@ class Season(SeasonProvider, Base):
|
||||
)
|
||||
|
||||
arguments = tryUrlencode({
|
||||
'search': fireEvent('library.query', media, single = True),
|
||||
'search': fireEvent('media.search_query', media, single = True),
|
||||
'method': 3,
|
||||
})
|
||||
query = "%s&%s" % (url, arguments)
|
||||
@@ -52,7 +52,7 @@ class Episode(EpisodeProvider, Base):
|
||||
)
|
||||
|
||||
arguments = tryUrlencode({
|
||||
'search': fireEvent('library.query', media, single = True),
|
||||
'search': fireEvent('media.search_query', media, single = True),
|
||||
'method': 3,
|
||||
})
|
||||
query = "%s&%s" % (url, arguments)
|
||||
|
||||
@@ -25,7 +25,7 @@ class Season(SeasonProvider, Base):
|
||||
|
||||
def buildUrl(self, media, page, cats):
|
||||
return (
|
||||
tryUrlencode('"%s"' % fireEvent('library.query', media, single = True)),
|
||||
tryUrlencode('"%s"' % fireEvent('media.search_query', media, single = True)),
|
||||
page,
|
||||
','.join(str(x) for x in cats)
|
||||
)
|
||||
@@ -40,7 +40,7 @@ class Episode(EpisodeProvider, Base):
|
||||
|
||||
def buildUrl(self, media, page, cats):
|
||||
return (
|
||||
tryUrlencode('"%s"' % fireEvent('library.query', media, single = True)),
|
||||
tryUrlencode('"%s"' % fireEvent('media.search_query', media, single = True)),
|
||||
page,
|
||||
','.join(str(x) for x in cats)
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ class Season(SeasonProvider, Base):
|
||||
([14], ['hdtv_sd', 'hdtv_720p', 'webdl_720p', 'webdl_1080p']),
|
||||
]
|
||||
def buildUrl(self, media):
|
||||
return fireEvent('library.query', media, single = True)
|
||||
return fireEvent('media.search_query', media, single = True)
|
||||
|
||||
|
||||
class Episode(EpisodeProvider, Base):
|
||||
@@ -30,5 +30,5 @@ class Episode(EpisodeProvider, Base):
|
||||
([2], [24], [26], ['hdtv_sd'])
|
||||
]
|
||||
def buildUrl(self, media):
|
||||
return fireEvent('library.query', media, single = True)
|
||||
return fireEvent('media.search_query', media, single = True)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class Season(SeasonProvider, Base):
|
||||
|
||||
def buildUrl(self, media, quality):
|
||||
return (
|
||||
tryUrlencode(fireEvent('library.query', media, single = True)),
|
||||
tryUrlencode(fireEvent('media.search_query', media, single = True)),
|
||||
self.getCatId(quality['identifier'])[0]
|
||||
)
|
||||
|
||||
@@ -37,6 +37,6 @@ class Episode(EpisodeProvider, Base):
|
||||
|
||||
def buildUrl(self, media, quality):
|
||||
return (
|
||||
tryUrlencode(fireEvent('library.query', media, single = True)),
|
||||
tryUrlencode(fireEvent('media.search_query', media, single = True)),
|
||||
self.getCatId(quality['identifier'])[0]
|
||||
)
|
||||
|
||||
@@ -22,7 +22,7 @@ class Season(SeasonProvider, Base):
|
||||
arguments = tryUrlencode({
|
||||
'user': host['name'],
|
||||
'passkey': host['pass_key'],
|
||||
'search': fireEvent('library.query', media, single = True)
|
||||
'search': fireEvent('media.search_query', media, single = True)
|
||||
})
|
||||
return '%s?%s' % (host['host'], arguments)
|
||||
|
||||
@@ -33,6 +33,6 @@ class Episode(EpisodeProvider, Base):
|
||||
arguments = tryUrlencode({
|
||||
'user': host['name'],
|
||||
'passkey': host['pass_key'],
|
||||
'search': fireEvent('library.query', media, single = True)
|
||||
'search': fireEvent('media.search_query', media, single = True)
|
||||
})
|
||||
return '%s?%s' % (host['host'], arguments)
|
||||
|
||||
@@ -29,7 +29,7 @@ class Season(SeasonProvider, Base):
|
||||
cat_backup_id = 980
|
||||
|
||||
def buildUrl(self, media, quality):
|
||||
query = (tryUrlencode(fireEvent('library.query', media, single = True)),
|
||||
query = (tryUrlencode(fireEvent('media.search_query', media, single = True)),
|
||||
self.getCatId(quality['identifier'])[0],
|
||||
self.getSceneOnly())
|
||||
return query
|
||||
@@ -46,7 +46,7 @@ class Episode(EpisodeProvider, Base):
|
||||
cat_backup_id = 620
|
||||
|
||||
def buildUrl(self, media, quality):
|
||||
query = (tryUrlencode(fireEvent('library.query', media, single = True)),
|
||||
query = (tryUrlencode(fireEvent('media.search_query', media, single = True)),
|
||||
self.getCatId(quality['identifier'])[0],
|
||||
self.getSceneOnly())
|
||||
return query
|
||||
|
||||
@@ -5,7 +5,6 @@ from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.media._base.searcher.base import SearcherBase
|
||||
from couchpotato.core.media._base.searcher.main import SearchSetupError
|
||||
from couchpotato.core.media.show import ShowTypeBase
|
||||
from couchpotato.core.media.show._base import ShowBase
|
||||
from qcond import QueryCondenser
|
||||
|
||||
log = CPLog(__name__)
|
||||
@@ -61,7 +60,7 @@ class ShowSearcher(SearcherBase, ShowTypeBase):
|
||||
found_releases = []
|
||||
too_early_to_search = []
|
||||
|
||||
default_title = fireEvent('library.query', media['library'], condense = False, single=True)
|
||||
default_title = fireEvent('media.search_query', media['library'], condense = False, single=True)
|
||||
if not default_title:
|
||||
log.error('No proper info found for episode, removing it from library to cause it from having more issues.')
|
||||
#fireEvent('episode.delete', episode['id'], single = True)
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
from couchpotato.core.event import addEvent, fireEvent
|
||||
from couchpotato.core.logger import CPLog
|
||||
from couchpotato.core.helpers.variable import tryInt
|
||||
from couchpotato.core.plugins.base import Plugin
|
||||
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
autload = 'Season'
|
||||
|
||||
|
||||
class Season(Plugin):
|
||||
|
||||
def __init__(self):
|
||||
addEvent('media.search_query', self.query)
|
||||
addEvent('media.identifier', self.identifier)
|
||||
|
||||
addEvent('show.season.add', self.update)
|
||||
addEvent('show.season.update_info', self.update)
|
||||
|
||||
def query(self, library, first = True, condense = True, include_identifier = True, **kwargs):
|
||||
if library is list or library.get('type') != 'season':
|
||||
return
|
||||
|
||||
# Get the titles of the show
|
||||
if not library.get('related_libraries', {}).get('show', []):
|
||||
log.warning('Invalid library, unable to determine title.')
|
||||
return
|
||||
|
||||
titles = fireEvent(
|
||||
'media._search_query',
|
||||
library['related_libraries']['show'][0],
|
||||
first=False,
|
||||
condense=condense,
|
||||
|
||||
single=True
|
||||
)
|
||||
|
||||
# Add season map_names if they exist
|
||||
if 'map_names' in library['info']:
|
||||
season_names = library['info']['map_names'].get(str(library['season_number']), {})
|
||||
|
||||
# Add titles from all locations
|
||||
# TODO only add name maps from a specific location
|
||||
for location, names in season_names.items():
|
||||
titles += [name for name in names if name and name not in titles]
|
||||
|
||||
|
||||
identifier = fireEvent('media.identifier', library, single = True)
|
||||
|
||||
# Add season identifier to titles
|
||||
if include_identifier and identifier.get('season') is not None:
|
||||
titles = [title + (' S%02d' % identifier['season']) for title in titles]
|
||||
|
||||
|
||||
if first:
|
||||
return titles[0] if titles else None
|
||||
|
||||
return titles
|
||||
|
||||
def identifier(self, library):
|
||||
if library.get('type') != 'season':
|
||||
return
|
||||
|
||||
return {
|
||||
'season': tryInt(library['season_number'], None)
|
||||
}
|
||||
|
||||
def add(self, parent_id, update_after = True):
|
||||
|
||||
# Add Season
|
||||
season = {
|
||||
'nr': 1,
|
||||
'identifiers': {
|
||||
'imdb': 'tt1234',
|
||||
'thetvdb': 123,
|
||||
'tmdb': 123,
|
||||
'rage': 123
|
||||
},
|
||||
'parent': '_id',
|
||||
'info': {}, # Returned dict by providers
|
||||
}
|
||||
|
||||
# Check if season already exists
|
||||
season_exists = True or False
|
||||
|
||||
if season_exists:
|
||||
pass #update existing
|
||||
else:
|
||||
|
||||
db.insert(season)
|
||||
|
||||
|
||||
# Update library info
|
||||
if update_after is not False:
|
||||
handle = fireEventAsync if update_after is 'async' else fireEvent
|
||||
handle('show.season.update_info', episode.get('_id'))
|
||||
|
||||
return season
|
||||
|
||||
def update_info(self, media_id = None, default_title = '', force = False):
|
||||
|
||||
if self.shuttingDown():
|
||||
return
|
||||
|
||||
# Get new info
|
||||
fireEvent('season.info', merge = True)
|
||||
|
||||
# Update/create media
|
||||
|
||||
# Get images
|
||||
|
||||
|
||||
return info
|
||||
Reference in New Issue
Block a user