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): class ShowBase(MediaBase):
_type = 'show' _type = 'show'
query_condenser = QueryCondenser()
def __init__(self): def __init__(self):
super(ShowBase, self).__init__() super(ShowBase, self).__init__()
addApiView('show.add', self.addView, docs = { addApiView('show.add', self.addView, docs = {
'desc': 'Add new movie to the wanted list', 'desc': 'Add new show to the wanted list',
'params': { 'params': {
'identifier': {'desc': 'IMDB id of the movie your want to add.'}, 'identifier': {'desc': 'IMDB id of the show 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.'}, 'profile_id': {'desc': 'ID of quality profile you want the add the show 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.'}, '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.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): def addView(self, **kwargs):
add_dict = self.add(params = kwargs) add_dict = self.add(params = kwargs)
@ -37,204 +64,35 @@ class ShowBase(MediaBase):
'show': add_dict, 'show': add_dict,
} }
def add(self, params = {}, force_readd = True, search_after = True, update_library = False, status_id = None): def add(self, params = {}, force_readd = True, search_after = True, update_library = False, status = None):
"""
params db = get_db()
{'category_id': u'-1',
'identifier': u'tt1519931', # Add Show
'profile_id': u'12', show = {
'thetvdb_id': u'158661', 'identifiers': {
'title': u'Haven'} 'imdb': 'tt1234',
""" 'thetvdb': 123,
log.debug("show.add") 'tmdb': 123,
'rage': 123
# 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') 'status': 'active',
'title': title,
# TODO: add by airdate 'description': description,
'profile_id': profile_id,
# Add by Season/Episode numbers 'category_id': category_id,
self.addBySeasonEpisode(parent, 'primary_provider': 'thetvdb',
params = params, 'absolute_nr': True,
force_readd = force_readd, 'info': {}
search_after = search_after, }
update_library = update_library,
status_id = status_id show_info = fireEvent('show.info', show.get('identifiers'))
)
# Add Seasons
def addBySeasonEpisode(self, parent, params = {}, force_readd = True, search_after = True, update_library = False, status_id = None): for season_info in show_info.get('seasons', []):
identifier = params.get('id')
# 'tvdb' will always be the master for our purpose. All mapped data can be mapped season = fireEvent('show.season.add', show.get('_id'), season_info)
# 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 for episode_info in season_info.get('seasons', []):
#
# This currently means the episode must actually exist in tvdb in order to be found but fireEvent('show.episode.add', season.get('_id'), episode_info)
# 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

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') log.info2('Wrong: releases with identifier ranges are not supported yet')
return False 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 air by date episodes
# TODO - Support episode parts # TODO - Support episode parts
@ -121,7 +121,7 @@ class Season(Base):
log.info2('Wrong: releases with identifier ranges are not supported yet') log.info2('Wrong: releases with identifier ranges are not supported yet')
return False return False
required = fireEvent('library.identifier', media['library'], single = True) required = fireEvent('media.identifier', media['library'], single = True)
if identifier != required: if identifier != required:
log.info2('Wrong: required identifier (%s) does not match release identifier (%s)', (required, identifier)) 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): def buildUrl(self, media, quality):
query = tryUrlencode({ query = tryUrlencode({
'q': fireEvent('library.query', media, single = True), 'q': fireEvent('media.search_query', media, single = True),
'm': 'n', 'm': 'n',
'max': 400, 'max': 400,
'adv_age': Env.setting('retention', 'nzb'), 'adv_age': Env.setting('retention', 'nzb'),
@ -38,7 +38,7 @@ class Episode(EpisodeProvider, Base):
def buildUrl(self, media, quality): def buildUrl(self, media, quality):
query = tryUrlencode({ query = tryUrlencode({
'q': fireEvent('library.query', media, single = True), 'q': fireEvent('media.search_query', media, single = True),
'm': 'n', 'm': 'n',
'max': 400, 'max': 400,
'adv_age': Env.setting('retention', 'nzb'), '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): class Season(SeasonProvider, Base):
def buildUrl(self, media, api_key): def buildUrl(self, media, api_key):
search_title = fireEvent('library.query', media, include_identifier = False, single = True) search_title = fireEvent('media.search_query', media, include_identifier = False, single = True)
identifier = fireEvent('library.identifier', media, single = True) identifier = fireEvent('media.identifier', media, single = True)
query = tryUrlencode({ query = tryUrlencode({
't': 'tvsearch', 't': 'tvsearch',
@ -35,8 +35,8 @@ class Season(SeasonProvider, Base):
class Episode(EpisodeProvider, Base): class Episode(EpisodeProvider, Base):
def buildUrl(self, media, api_key): def buildUrl(self, media, api_key):
search_title = fireEvent('library.query', media, include_identifier = False, single = True) search_title = fireEvent('media.search_query', media, include_identifier = False, single = True)
identifier = fireEvent('library.identifier', media, single = True) identifier = fireEvent('media.identifier', media, single = True)
query = tryUrlencode({ query = tryUrlencode({
't': 'tvsearch', 't': 'tvsearch',

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

@ -21,7 +21,7 @@ class Season(SeasonProvider, Base):
def buildUrl(self, media): def buildUrl(self, media):
q = tryUrlencode({ q = tryUrlencode({
'q': fireEvent('library.query', media, single = True), 'q': fireEvent('media.search_query', media, single = True),
}) })
query = tryUrlencode({ query = tryUrlencode({
@ -39,7 +39,7 @@ class Episode(EpisodeProvider, Base):
def buildUrl(self, media): def buildUrl(self, media):
q = tryUrlencode({ q = tryUrlencode({
'q': fireEvent('library.query', media, single = True), 'q': fireEvent('media.search_query', media, single = True),
}) })
query = tryUrlencode({ query = tryUrlencode({

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

@ -21,7 +21,7 @@ class Season(SeasonProvider, Base):
def buildUrl(self, media, quality): def buildUrl(self, media, quality):
query = tryUrlencode({ query = tryUrlencode({
'q': fireEvent('library.query', media, single = True), 'q': fireEvent('media.search_query', media, single = True),
'age': Env.setting('retention', 'nzb'), 'age': Env.setting('retention', 'nzb'),
'sort': 'agedesc', 'sort': 'agedesc',
'minsize': quality.get('size_min'), 'minsize': quality.get('size_min'),
@ -38,7 +38,7 @@ class Episode(EpisodeProvider, Base):
def buildUrl(self, media, quality): def buildUrl(self, media, quality):
query = tryUrlencode({ query = tryUrlencode({
'q': fireEvent('library.query', media, single = True), 'q': fireEvent('media.search_query', media, single = True),
'age': Env.setting('retention', 'nzb'), 'age': Env.setting('retention', 'nzb'),
'sort': 'agedesc', 'sort': 'agedesc',
'minsize': quality.get('size_min'), '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): def buildUrl(self, media):
query = tryUrlencode({ query = tryUrlencode({
'search': fireEvent('library.query', media, single = True), 'search': fireEvent('media.search_query', media, single = True),
'cat': 12 # Season cat 'cat': 12 # Season cat
}) })
return query return query
@ -30,7 +30,7 @@ class Episode(EpisodeProvider, Base):
def buildUrl(self, media): def buildUrl(self, media):
query = tryUrlencode({ query = tryUrlencode({
'search': fireEvent('library.query', media, single = True), 'search': fireEvent('media.search_query', media, single = True),
'cat': 10 # Episode cat 'cat': 10 # Episode cat
}) })
return query 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 # For season bundles, bitsoup currently only has one category
def buildUrl(self, media, quality): def buildUrl(self, media, quality):
query = tryUrlencode({ query = tryUrlencode({
'search': fireEvent('library.query', media, single = True), 'search': fireEvent('media.search_query', media, single = True),
'cat': 45 # TV-Packs Category 'cat': 45 # TV-Packs Category
}) })
return query return query
@ -35,7 +35,7 @@ class Episode(EpisodeProvider, Base):
def buildUrl(self, media, quality): def buildUrl(self, media, quality):
query = tryUrlencode({ query = tryUrlencode({
'search': fireEvent('library.query', media, single = True), 'search': fireEvent('media.search_query', media, single = True),
'cat': self.getCatId(quality['identifier'])[0], 'cat': self.getCatId(quality['identifier'])[0],
}) })
return query return query

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

@ -18,10 +18,10 @@ class PublicHD(MultiProvider):
class Season(SeasonProvider, Base): class Season(SeasonProvider, Base):
def buildUrl(self, media): def buildUrl(self, media):
return fireEvent('library.query', media, single = True) return fireEvent('media.search_query', media, single = True)
class Episode(EpisodeProvider, Base): class Episode(EpisodeProvider, Base):
def buildUrl(self, media): 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({ arguments = tryUrlencode({
'search': fireEvent('library.query', media, single = True), 'search': fireEvent('media.search_query', media, single = True),
'method': 3, 'method': 3,
}) })
query = "%s&%s" % (url, arguments) query = "%s&%s" % (url, arguments)
@ -52,7 +52,7 @@ class Episode(EpisodeProvider, Base):
) )
arguments = tryUrlencode({ arguments = tryUrlencode({
'search': fireEvent('library.query', media, single = True), 'search': fireEvent('media.search_query', media, single = True),
'method': 3, 'method': 3,
}) })
query = "%s&%s" % (url, arguments) 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): def buildUrl(self, media, page, cats):
return ( return (
tryUrlencode('"%s"' % fireEvent('library.query', media, single = True)), tryUrlencode('"%s"' % fireEvent('media.search_query', media, single = True)),
page, page,
','.join(str(x) for x in cats) ','.join(str(x) for x in cats)
) )
@ -40,7 +40,7 @@ class Episode(EpisodeProvider, Base):
def buildUrl(self, media, page, cats): def buildUrl(self, media, page, cats):
return ( return (
tryUrlencode('"%s"' % fireEvent('library.query', media, single = True)), tryUrlencode('"%s"' % fireEvent('media.search_query', media, single = True)),
page, page,
','.join(str(x) for x in cats) ','.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']), ([14], ['hdtv_sd', 'hdtv_720p', 'webdl_720p', 'webdl_1080p']),
] ]
def buildUrl(self, media): def buildUrl(self, media):
return fireEvent('library.query', media, single = True) return fireEvent('media.search_query', media, single = True)
class Episode(EpisodeProvider, Base): class Episode(EpisodeProvider, Base):
@ -30,5 +30,5 @@ class Episode(EpisodeProvider, Base):
([2], [24], [26], ['hdtv_sd']) ([2], [24], [26], ['hdtv_sd'])
] ]
def buildUrl(self, media): 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): def buildUrl(self, media, quality):
return ( return (
tryUrlencode(fireEvent('library.query', media, single = True)), tryUrlencode(fireEvent('media.search_query', media, single = True)),
self.getCatId(quality['identifier'])[0] self.getCatId(quality['identifier'])[0]
) )
@ -37,6 +37,6 @@ class Episode(EpisodeProvider, Base):
def buildUrl(self, media, quality): def buildUrl(self, media, quality):
return ( return (
tryUrlencode(fireEvent('library.query', media, single = True)), tryUrlencode(fireEvent('media.search_query', media, single = True)),
self.getCatId(quality['identifier'])[0] self.getCatId(quality['identifier'])[0]
) )

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

@ -22,7 +22,7 @@ class Season(SeasonProvider, Base):
arguments = tryUrlencode({ arguments = tryUrlencode({
'user': host['name'], 'user': host['name'],
'passkey': host['pass_key'], '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) return '%s?%s' % (host['host'], arguments)
@ -33,6 +33,6 @@ class Episode(EpisodeProvider, Base):
arguments = tryUrlencode({ arguments = tryUrlencode({
'user': host['name'], 'user': host['name'],
'passkey': host['pass_key'], '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) 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 cat_backup_id = 980
def buildUrl(self, media, quality): 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.getCatId(quality['identifier'])[0],
self.getSceneOnly()) self.getSceneOnly())
return query return query
@ -46,7 +46,7 @@ class Episode(EpisodeProvider, Base):
cat_backup_id = 620 cat_backup_id = 620
def buildUrl(self, media, quality): 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.getCatId(quality['identifier'])[0],
self.getSceneOnly()) self.getSceneOnly())
return query 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.base import SearcherBase
from couchpotato.core.media._base.searcher.main import SearchSetupError from couchpotato.core.media._base.searcher.main import SearchSetupError
from couchpotato.core.media.show import ShowTypeBase from couchpotato.core.media.show import ShowTypeBase
from couchpotato.core.media.show._base import ShowBase
from qcond import QueryCondenser from qcond import QueryCondenser
log = CPLog(__name__) log = CPLog(__name__)
@ -61,7 +60,7 @@ class ShowSearcher(SearcherBase, ShowTypeBase):
found_releases = [] found_releases = []
too_early_to_search = [] 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: if not default_title:
log.error('No proper info found for episode, removing it from library to cause it from having more issues.') 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) #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