Browse Source

Cleanup

pull/3111/head
Ruud 11 years ago
parent
commit
cfc9f524a7
  1. 268
      couchpotato/core/media/show/_base/main.py
  2. 125
      couchpotato/core/media/show/episode.py
  3. 0
      couchpotato/core/media/show/library/__init__.py
  4. 173
      couchpotato/core/media/show/library/episode.py
  5. 158
      couchpotato/core/media/show/library/season.py
  6. 196
      couchpotato/core/media/show/library/show.py
  7. 4
      couchpotato/core/media/show/matcher.py
  8. 4
      couchpotato/core/media/show/providers/nzb/binsearch.py
  9. 8
      couchpotato/core/media/show/providers/nzb/newznab.py
  10. 4
      couchpotato/core/media/show/providers/nzb/nzbclub.py
  11. 4
      couchpotato/core/media/show/providers/nzb/nzbindex.py
  12. 4
      couchpotato/core/media/show/providers/torrent/bithdtv.py
  13. 4
      couchpotato/core/media/show/providers/torrent/bitsoup.py
  14. 4
      couchpotato/core/media/show/providers/torrent/publichd.py
  15. 4
      couchpotato/core/media/show/providers/torrent/sceneaccess.py
  16. 4
      couchpotato/core/media/show/providers/torrent/thepiratebay.py
  17. 4
      couchpotato/core/media/show/providers/torrent/torrentday.py
  18. 4
      couchpotato/core/media/show/providers/torrent/torrentleech.py
  19. 4
      couchpotato/core/media/show/providers/torrent/torrentpotato.py
  20. 4
      couchpotato/core/media/show/providers/torrent/torrentshack.py
  21. 3
      couchpotato/core/media/show/searcher.py
  22. 114
      couchpotato/core/media/show/season.py

268
couchpotato/core/media/show/_base/main.py

@ -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")
# 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')
# TODO: add by airdate
# 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
)
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
#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
# 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!!!!
# 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
def add(self, params = {}, force_readd = True, search_after = True, update_library = False, status = None):
db = get_db()
# 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': {}
}
show_info = fireEvent('show.info', show.get('identifiers'))
# Add Seasons
for season_info in show_info.get('seasons', []):
season = fireEvent('show.season.add', show.get('_id'), season_info)
for episode_info in season_info.get('seasons', []):
fireEvent('show.episode.add', season.get('_id'), episode_info)

125
couchpotato/core/media/show/episode.py

@ -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

0
couchpotato/core/media/show/library/__init__.py

173
couchpotato/core/media/show/library/episode.py

@ -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

158
couchpotato/core/media/show/library/season.py

@ -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

196
couchpotato/core/media/show/library/show.py

@ -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

4
couchpotato/core/media/show/matcher.py

@ -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))

4
couchpotato/core/media/show/providers/nzb/binsearch.py

@ -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'),

8
couchpotato/core/media/show/providers/nzb/newznab.py

@ -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',

4
couchpotato/core/media/show/providers/nzb/nzbclub.py

@ -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({

4
couchpotato/core/media/show/providers/nzb/nzbindex.py

@ -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'),

4
couchpotato/core/media/show/providers/torrent/bithdtv.py

@ -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

4
couchpotato/core/media/show/providers/torrent/bitsoup.py

@ -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

4
couchpotato/core/media/show/providers/torrent/publichd.py

@ -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)

4
couchpotato/core/media/show/providers/torrent/sceneaccess.py

@ -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)

4
couchpotato/core/media/show/providers/torrent/thepiratebay.py

@ -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)
)

4
couchpotato/core/media/show/providers/torrent/torrentday.py

@ -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)

4
couchpotato/core/media/show/providers/torrent/torrentleech.py

@ -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]
)

4
couchpotato/core/media/show/providers/torrent/torrentpotato.py

@ -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)

4
couchpotato/core/media/show/providers/torrent/torrentshack.py

@ -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

3
couchpotato/core/media/show/searcher.py

@ -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)

114
couchpotato/core/media/show/season.py

@ -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
Loading…
Cancel
Save