|
|
|
@ -95,25 +95,25 @@ def get_profile_id(pvr, profile):
|
|
|
|
|
if not profile_id or not profile_id > 0:
|
|
|
|
|
log.error("Aborting due to failure to retrieve Profile ID for: %s", profile)
|
|
|
|
|
exit()
|
|
|
|
|
log.info("Retrieved Profile ID for %s: %d", profile, profile_id)
|
|
|
|
|
log.info("Retrieved Profile ID for \'%s\': %d", profile, profile_id)
|
|
|
|
|
return profile_id
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_profile_tags(pvr):
|
|
|
|
|
profile_tags = pvr.get_tags()
|
|
|
|
|
if profile_tags is None:
|
|
|
|
|
log.error("Aborting due to failure to retrieve Tag ID's")
|
|
|
|
|
log.error("Aborting due to failure to retrieve Tag IDs")
|
|
|
|
|
exit()
|
|
|
|
|
log.info("Retrieved %d Tag ID's", len(profile_tags))
|
|
|
|
|
log.info("Retrieved Sonarr Tag IDs: %d", len(profile_tags))
|
|
|
|
|
return profile_tags
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_objects(pvr, pvr_type, notifications):
|
|
|
|
|
objects_list = pvr.get_objects()
|
|
|
|
|
if not objects_list:
|
|
|
|
|
log.error("Aborting due to failure to retrieve %s shows list", pvr_type)
|
|
|
|
|
log.error("Aborting due to failure to retrieve shows list from %s", pvr_type)
|
|
|
|
|
if notifications:
|
|
|
|
|
callback_notify({'event': 'error', 'reason': 'Failure to retrieve %s shows list' % pvr_type})
|
|
|
|
|
callback_notify({'event': 'error', 'reason': 'Failure to retrieve shows list from %s' % pvr_type})
|
|
|
|
|
exit()
|
|
|
|
|
objects_type = 'movies' if pvr_type.lower() == 'radarr' else 'shows'
|
|
|
|
|
log.info("Retrieved %s %s list, %s found: %d", pvr_type, objects_type, objects_type, len(objects_list))
|
|
|
|
@ -125,9 +125,18 @@ def get_objects(pvr, pvr_type, notifications):
|
|
|
|
|
############################################################
|
|
|
|
|
|
|
|
|
|
@app.command(help='Add a single show to Sonarr.', context_settings=dict(max_content_width=100))
|
|
|
|
|
@click.option('--show-id', '-id', help='Trakt Show ID.', required=True)
|
|
|
|
|
@click.option('--folder', '-f', default=None, help='Add show with this root folder to Sonarr.')
|
|
|
|
|
@click.option('--no-search', is_flag=True, help='Disable search when adding show to Sonarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--show-id', '-id',
|
|
|
|
|
help='Trakt Show ID.',
|
|
|
|
|
required=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--folder', '-f',
|
|
|
|
|
default=None,
|
|
|
|
|
help='Add show with this root folder to Sonarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--no-search',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Disable search when adding show to Sonarr.')
|
|
|
|
|
def show(show_id, folder=None, no_search=False):
|
|
|
|
|
from media.sonarr import Sonarr
|
|
|
|
|
from media.trakt import Trakt
|
|
|
|
@ -153,8 +162,8 @@ def show(show_id, folder=None, no_search=False):
|
|
|
|
|
log.error("Aborting due to failure to retrieve Trakt show")
|
|
|
|
|
return None
|
|
|
|
|
else:
|
|
|
|
|
log.info("Retrieved Trakt show information for %s: \'%s (%d)\'", show_id, trakt_show['title'],
|
|
|
|
|
trakt_show['year'])
|
|
|
|
|
log.info("Retrieved Trakt show information for \'%s\': \'%s (%s)\'", show_id, trakt_show['title'],
|
|
|
|
|
str(trakt_show['year']) if trakt_show['year'] else '????')
|
|
|
|
|
|
|
|
|
|
# determine which tags to use when adding this series
|
|
|
|
|
use_tags = sonarr_helper.series_tag_id_from_network(profile_tags, cfg.sonarr.tags, trakt_show['network'])
|
|
|
|
@ -162,36 +171,72 @@ def show(show_id, folder=None, no_search=False):
|
|
|
|
|
# add show to sonarr
|
|
|
|
|
if sonarr.add_series(trakt_show['ids']['tvdb'], trakt_show['title'], trakt_show['ids']['slug'], profile_id,
|
|
|
|
|
cfg.sonarr.root_folder, use_tags, not no_search):
|
|
|
|
|
log.info("ADDED \'%s (%d)\' with tags: %s", trakt_show['title'], trakt_show['year'],
|
|
|
|
|
log.info("ADDED: \'%s (%s)\' with Sonarr Tags: %s", trakt_show['title'],
|
|
|
|
|
str(trakt_show['year']) if trakt_show['year'] else '????',
|
|
|
|
|
sonarr_helper.readable_tag_from_ids(profile_tags, use_tags))
|
|
|
|
|
else:
|
|
|
|
|
log.error("FAILED adding \'%s (%d)\' with tags: %s", trakt_show['title'], trakt_show['year'],
|
|
|
|
|
log.error("FAILED ADDING: \'%s (%s)\' with Sonarr Tags: %s", trakt_show['title'],
|
|
|
|
|
str(trakt_show['year']) if trakt_show['year'] else '????',
|
|
|
|
|
sonarr_helper.readable_tag_from_ids(profile_tags, use_tags))
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.command(help='Add multiple shows to Sonarr.', context_settings=dict(max_content_width=100))
|
|
|
|
|
@click.option('--list-type', '-t',
|
|
|
|
|
help='Trakt list to process. For example, anticipated, trending, popular, person, watched, played, '
|
|
|
|
|
'recommended, watchlist or any URL to a list', required=True)
|
|
|
|
|
@click.option('--add-limit', '-l', default=0, help='Limit number of shows added to Sonarr.')
|
|
|
|
|
@click.option('--add-delay', '-d', default=2.5, help='Seconds between each add request to Sonarr.', show_default=True)
|
|
|
|
|
@click.option('--sort', '-s', default='votes', type=click.Choice(['rating', 'release', 'votes']),
|
|
|
|
|
help='Sort list to process.', show_default=True)
|
|
|
|
|
@click.option('--genre', '-g', default=None, help='Only add shows from this genre to Sonarr. '
|
|
|
|
|
'Use \'ignore\' to add shows from any genre, '
|
|
|
|
|
'including ones with no genre specified.')
|
|
|
|
|
@click.option('--folder', '-f', default=None, help='Add shows with this root folder to Sonarr.')
|
|
|
|
|
@click.option('--actor', '-a', default=None, help='Only add movies from this actor to Radarr.')
|
|
|
|
|
@click.option('--no-search', is_flag=True, help='Disable search when adding shows to Sonarr.')
|
|
|
|
|
@click.option('--notifications', is_flag=True, help='Send notifications.')
|
|
|
|
|
@click.option('--authenticate-user',
|
|
|
|
|
help='Specify which user to authenticate with to retrieve Trakt lists. '
|
|
|
|
|
'Default: first user in the config')
|
|
|
|
|
@click.option('--ignore-blacklist', is_flag=True, help='Ignores the blacklist when running the command.')
|
|
|
|
|
@click.option('--remove-rejected-from-recommended', is_flag=True,
|
|
|
|
|
help='Removes rejected/existing shows from recommended.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--list-type', '-t',
|
|
|
|
|
help='Trakt list to process. '
|
|
|
|
|
'For example, \'anticipated\', \'trending\', \'popular\', \'person\', \'watched\', \'played\', '
|
|
|
|
|
'\'recommended\', \'watchlist\', or any URL to a list',
|
|
|
|
|
required=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--add-limit', '-l',
|
|
|
|
|
default=0,
|
|
|
|
|
help='Limit number of shows added to Sonarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--add-delay', '-d',
|
|
|
|
|
default=2.5,
|
|
|
|
|
help='Seconds between each add request to Sonarr.',
|
|
|
|
|
show_default=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--sort', '-s',
|
|
|
|
|
default='votes',
|
|
|
|
|
type=click.Choice(['rating', 'release', 'votes']),
|
|
|
|
|
help='Sort list to process.',
|
|
|
|
|
show_default=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--genre', '-g',
|
|
|
|
|
default=None,
|
|
|
|
|
help='Only add shows from this genre to Sonarr. '
|
|
|
|
|
'Use \'ignore\' to add shows from any genre, including ones with no genre specified.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--folder', '-f',
|
|
|
|
|
default=None,
|
|
|
|
|
help='Add shows with this root folder to Sonarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--actor', '-a',
|
|
|
|
|
default=None,
|
|
|
|
|
help='Only add movies from this actor to Radarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--no-search',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Disable search when adding shows to Sonarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--notifications',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Send notifications.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--authenticate-user',
|
|
|
|
|
help='Specify which user to authenticate with to retrieve Trakt lists. '
|
|
|
|
|
'Defaults to first user in the config')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--ignore-blacklist',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Ignores the blacklist when running the command.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--remove-rejected-from-recommended',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Removes rejected/existing shows from recommended.')
|
|
|
|
|
def shows(list_type, add_limit=0, add_delay=2.5, sort='votes', genre=None, folder=None, actor=None, no_search=False,
|
|
|
|
|
notifications=False, authenticate_user=None, ignore_blacklist=False, remove_rejected_from_recommended=False):
|
|
|
|
|
from media.sonarr import Sonarr
|
|
|
|
@ -227,33 +272,41 @@ def shows(list_type, add_limit=0, add_delay=2.5, sort='votes', genre=None, folde
|
|
|
|
|
|
|
|
|
|
# get trakt series list
|
|
|
|
|
if list_type.lower() == 'anticipated':
|
|
|
|
|
trakt_objects_list = trakt.get_anticipated_shows(genres=genre if 'ignore' not in genre.lower() else None,
|
|
|
|
|
trakt_objects_list = trakt.get_anticipated_shows(genres=genre if genre and
|
|
|
|
|
'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.shows.allowed_languages)
|
|
|
|
|
elif list_type.lower() == 'trending':
|
|
|
|
|
trakt_objects_list = trakt.get_trending_shows(genres=genre if 'ignore' not in genre.lower() else None,
|
|
|
|
|
trakt_objects_list = trakt.get_trending_shows(genres=genre if genre and
|
|
|
|
|
'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.shows.allowed_languages)
|
|
|
|
|
elif list_type.lower() == 'popular':
|
|
|
|
|
trakt_objects_list = trakt.get_popular_shows(genres=genre if 'ignore' not in genre.lower() else None,
|
|
|
|
|
trakt_objects_list = trakt.get_popular_shows(genres=genre if genre and
|
|
|
|
|
'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.shows.allowed_languages)
|
|
|
|
|
elif list_type.lower() == 'person':
|
|
|
|
|
if not actor:
|
|
|
|
|
log.error("You must specify an actor with the --actor / -a parameter when using the person list type!")
|
|
|
|
|
log.error("You must specify an actor with the \'--actor\' / \'-a\' parameter when using the \'person\'" +
|
|
|
|
|
" list type!")
|
|
|
|
|
return None
|
|
|
|
|
trakt_objects_list = trakt.get_person_shows(person=actor,
|
|
|
|
|
genres=genre if 'ignore' not in genre.lower() else None,
|
|
|
|
|
genres=genre if genre and
|
|
|
|
|
'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.shows.allowed_languages)
|
|
|
|
|
elif list_type.lower() == 'recommended':
|
|
|
|
|
trakt_objects_list = trakt.get_recommended_shows(authenticate_user,
|
|
|
|
|
genres=genre if 'ignore' not in genre else None,
|
|
|
|
|
genres=genre if genre
|
|
|
|
|
and 'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.shows.allowed_languages)
|
|
|
|
|
elif list_type.lower().startswith('played'):
|
|
|
|
|
most_type = misc_helper.substring_after(list_type.lower(), "_")
|
|
|
|
|
trakt_objects_list = trakt.get_most_played_shows(genres=genre if 'ignore' not in genre.lower() else None,
|
|
|
|
|
trakt_objects_list = trakt.get_most_played_shows(genres=genre if genre
|
|
|
|
|
and 'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.shows.allowed_languages,
|
|
|
|
|
most_type=most_type if most_type else None)
|
|
|
|
|
elif list_type.lower().startswith('watched'):
|
|
|
|
|
most_type = misc_helper.substring_after(list_type.lower(), "_")
|
|
|
|
|
trakt_objects_list = trakt.get_most_watched_shows(genres=genre if 'ignore' not in genre.lower() else None,
|
|
|
|
|
trakt_objects_list = trakt.get_most_watched_shows(genres=genre if genre
|
|
|
|
|
and 'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.shows.allowed_languages,
|
|
|
|
|
most_type=most_type if most_type else None)
|
|
|
|
|
elif list_type.lower() == 'watchlist':
|
|
|
|
@ -262,14 +315,14 @@ def shows(list_type, add_limit=0, add_delay=2.5, sort='votes', genre=None, folde
|
|
|
|
|
trakt_objects_list = trakt.get_user_list_shows(list_type, authenticate_user)
|
|
|
|
|
|
|
|
|
|
if not trakt_objects_list:
|
|
|
|
|
log.error("Aborting due to failure to retrieve Trakt %s shows list", list_type)
|
|
|
|
|
log.error("Aborting due to failure to retrieve Trakt \'%s\' shows list", list_type.capitalize())
|
|
|
|
|
if notifications:
|
|
|
|
|
callback_notify(
|
|
|
|
|
{'event': 'abort', 'type': 'shows', 'list_type': list_type,
|
|
|
|
|
'reason': 'Failure to retrieve Trakt %s shows list' % list_type})
|
|
|
|
|
'reason': 'Failure to retrieve Trakt %s shows list' % list_type.capitalize()})
|
|
|
|
|
return None
|
|
|
|
|
else:
|
|
|
|
|
log.info("Retrieved Trakt %s shows list, shows found: %d", list_type, len(trakt_objects_list))
|
|
|
|
|
log.info("Retrieved Trakt \'%s\' shows list, shows found: %d", list_type.capitalize(), len(trakt_objects_list))
|
|
|
|
|
|
|
|
|
|
# set remove_rejected_recommended to False if this is not the recommended list
|
|
|
|
|
if list_type.lower() != 'recommended':
|
|
|
|
@ -284,7 +337,7 @@ def shows(list_type, add_limit=0, add_delay=2.5, sort='votes', genre=None, folde
|
|
|
|
|
if notifications:
|
|
|
|
|
callback_notify({'event': 'abort', 'type': 'shows', 'list_type': list_type,
|
|
|
|
|
'reason': 'Failure to remove existing Sonarr shows from retrieved Trakt %s shows list'
|
|
|
|
|
% list_type})
|
|
|
|
|
% list_type.capitalize()})
|
|
|
|
|
return None
|
|
|
|
|
else:
|
|
|
|
|
log.info("Removed existing Sonarr shows from Trakt shows list, shows left to process: %d",
|
|
|
|
@ -293,13 +346,13 @@ def shows(list_type, add_limit=0, add_delay=2.5, sort='votes', genre=None, folde
|
|
|
|
|
# sort filtered series list
|
|
|
|
|
if sort == 'release':
|
|
|
|
|
sorted_series_list = misc_helper.sorted_list(processed_series_list, 'show', 'first_aired')
|
|
|
|
|
log.info("Sorted shows list to process by release date")
|
|
|
|
|
log.info("Sorted shows list to process by recent 'release' date")
|
|
|
|
|
elif sort == 'rating':
|
|
|
|
|
sorted_series_list = misc_helper.sorted_list(processed_series_list, 'show', 'rating')
|
|
|
|
|
log.info("Sorted shows list to process by highest rating")
|
|
|
|
|
log.info("Sorted shows list to process by highest 'rating'")
|
|
|
|
|
else:
|
|
|
|
|
sorted_series_list = misc_helper.sorted_list(processed_series_list, 'show', 'votes')
|
|
|
|
|
log.info("Sorted shows list to process by highest votes")
|
|
|
|
|
log.info("Sorted shows list to process by highest 'votes'")
|
|
|
|
|
|
|
|
|
|
# loop series_list
|
|
|
|
|
log.info("Processing list now...")
|
|
|
|
@ -308,17 +361,21 @@ def shows(list_type, add_limit=0, add_delay=2.5, sort='votes', genre=None, folde
|
|
|
|
|
try:
|
|
|
|
|
# check if genre matches genre supplied via argument
|
|
|
|
|
if genre and not misc_helper.allowed_genres(genre, 'show', series):
|
|
|
|
|
log.debug("Skipping: %s because it was not from %s genre(s)", series['show']['title'], genre.lower())
|
|
|
|
|
log.debug("Skipping: \'%s\' because it was not from genre: %s", series['show']['title'],
|
|
|
|
|
genre.title())
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# check if series passes out blacklist criteria inspection
|
|
|
|
|
if not trakt_helper.is_show_blacklisted(series, cfg.filters.shows, ignore_blacklist,
|
|
|
|
|
callback_remove_recommended
|
|
|
|
|
if remove_rejected_from_recommended else None):
|
|
|
|
|
log.info("Adding: %s | Genres: %s | Network: %s | Country: %s", series['show']['title'],
|
|
|
|
|
(', '.join(series['show']['genres'])) if series['show']['genres'] else 'N/A',
|
|
|
|
|
series['show']['network'],
|
|
|
|
|
(series['show']['country'] or 'N/A').upper())
|
|
|
|
|
log.info("Adding: %s (%s) | Country: %s | Language: %s | Genre: %s | Network: %s",
|
|
|
|
|
series['show']['title'],
|
|
|
|
|
str(series['show']['year']) if series['show']['year'] else '????',
|
|
|
|
|
(series['show']['country'] or 'N/A').upper(),
|
|
|
|
|
(series['show']['language'] or 'N/A').upper(),
|
|
|
|
|
(', '.join(series['show']['genres'])).title() if series['show']['genres'] else 'N/A',
|
|
|
|
|
series['show']['network'])
|
|
|
|
|
|
|
|
|
|
# determine which tags to use when adding this series
|
|
|
|
|
use_tags = sonarr_helper.series_tag_id_from_network(profile_tags, cfg.sonarr.tags,
|
|
|
|
@ -327,14 +384,15 @@ def shows(list_type, add_limit=0, add_delay=2.5, sort='votes', genre=None, folde
|
|
|
|
|
if sonarr.add_series(series['show']['ids']['tvdb'], series['show']['title'],
|
|
|
|
|
series['show']['ids']['slug'], profile_id, cfg.sonarr.root_folder, use_tags,
|
|
|
|
|
not no_search):
|
|
|
|
|
log.info("ADDED \'%s (%d)\' with tags: %s", series['show']['title'], series['show']['year'],
|
|
|
|
|
log.info("ADDED: \'%s (%s)\' with tags: %s", series['show']['title'],
|
|
|
|
|
str(series['show']['year']) if series['show']['year'] else '????',
|
|
|
|
|
sonarr_helper.readable_tag_from_ids(profile_tags, use_tags))
|
|
|
|
|
if notifications:
|
|
|
|
|
callback_notify({'event': 'add_show', 'list_type': list_type, 'show': series['show']})
|
|
|
|
|
added_shows += 1
|
|
|
|
|
else:
|
|
|
|
|
log.error("FAILED adding \'%s (%d)\' with tags: %s", series['show']['title'],
|
|
|
|
|
series['show']['year'],
|
|
|
|
|
log.error("FAILED ADDING: \'%s (%s)\' with tags: %s", series['show']['title'],
|
|
|
|
|
str(series['show']['year']) if series['show']['year'] else '????',
|
|
|
|
|
sonarr_helper.readable_tag_from_ids(profile_tags, use_tags))
|
|
|
|
|
|
|
|
|
|
# stop adding shows, if added_shows >= add_limit
|
|
|
|
@ -345,13 +403,13 @@ def shows(list_type, add_limit=0, add_delay=2.5, sort='votes', genre=None, folde
|
|
|
|
|
time.sleep(add_delay)
|
|
|
|
|
|
|
|
|
|
except Exception:
|
|
|
|
|
log.exception("Exception while processing show %s: ", series['show']['title'])
|
|
|
|
|
log.exception("Exception while processing show \'%s\': ", series['show']['title'])
|
|
|
|
|
|
|
|
|
|
log.info("Added %d new show(s) to Sonarr", added_shows)
|
|
|
|
|
|
|
|
|
|
# send notification
|
|
|
|
|
if notifications and (cfg.notifications.verbose or added_shows > 0):
|
|
|
|
|
notify.send(message="Added %d shows from Trakt's %s list" % (added_shows, list_type))
|
|
|
|
|
notify.send(message="Added %d shows from Trakt's \'%s\' list" % (added_shows, list_type))
|
|
|
|
|
|
|
|
|
|
return added_shows
|
|
|
|
|
|
|
|
|
@ -361,12 +419,23 @@ def shows(list_type, add_limit=0, add_delay=2.5, sort='votes', genre=None, folde
|
|
|
|
|
############################################################
|
|
|
|
|
|
|
|
|
|
@app.command(help='Add a single movie to Radarr.', context_settings=dict(max_content_width=100))
|
|
|
|
|
@click.option('--movie-id', '-id', help='Trakt Movie ID.', required=True)
|
|
|
|
|
@click.option('--folder', '-f', default=None, help='Add movie with this root folder to Radarr.')
|
|
|
|
|
@click.option('--minimum-availability', '-ma', default='released',
|
|
|
|
|
type=click.Choice(['announced', 'in_cinemas', 'released', 'predb']),
|
|
|
|
|
help='Add movies with this minimum availability to Radarr.', show_default=True)
|
|
|
|
|
@click.option('--no-search', is_flag=True, help='Disable search when adding movie to Radarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--movie-id', '-id',
|
|
|
|
|
help='Trakt Movie ID.',
|
|
|
|
|
required=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--folder', '-f',
|
|
|
|
|
default=None,
|
|
|
|
|
help='Add movie with this root folder to Radarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--minimum-availability', '-ma',
|
|
|
|
|
default='released',
|
|
|
|
|
type=click.Choice(['announced', 'in_cinemas', 'released', 'predb']),
|
|
|
|
|
help='Add movies with this minimum availability to Radarr.', show_default=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--no-search',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Disable search when adding movie to Radarr.')
|
|
|
|
|
def movie(movie_id, folder=None, minimum_availability='released', no_search=False):
|
|
|
|
|
from media.radarr import Radarr
|
|
|
|
|
from media.trakt import Trakt
|
|
|
|
@ -397,46 +466,87 @@ def movie(movie_id, folder=None, minimum_availability='released', no_search=Fals
|
|
|
|
|
log.error("Aborting due to failure to retrieve Trakt movie")
|
|
|
|
|
return None
|
|
|
|
|
else:
|
|
|
|
|
log.info("Retrieved Trakt movie information for %s: \'%s (%d)\'", movie_id, trakt_movie['title'],
|
|
|
|
|
trakt_movie['year'])
|
|
|
|
|
log.info("Retrieved Trakt movie information for \'%s\': \'%s (%s)\'", movie_id, trakt_movie['title'],
|
|
|
|
|
str(trakt_movie['year']) if trakt_movie['year'] else '????')
|
|
|
|
|
|
|
|
|
|
# add movie to radarr
|
|
|
|
|
if radarr.add_movie(trakt_movie['ids']['tmdb'], trakt_movie['title'], trakt_movie['year'],
|
|
|
|
|
trakt_movie['ids']['slug'], profile_id, cfg.radarr.root_folder,
|
|
|
|
|
cfg.radarr.minimum_availability, not no_search):
|
|
|
|
|
log.info("ADDED \'%s (%d)\'", trakt_movie['title'], trakt_movie['year'])
|
|
|
|
|
log.info("ADDED \'%s (%s)\'", trakt_movie['title'],
|
|
|
|
|
str(trakt_movie['year']) if trakt_movie['year'] else '????')
|
|
|
|
|
else:
|
|
|
|
|
log.error("FAILED adding \'%s (%d)\'", trakt_movie['title'], trakt_movie['year'])
|
|
|
|
|
log.error("FAILED adding \'%s (%s)\'", trakt_movie['title'],
|
|
|
|
|
str(trakt_movie['year']) if trakt_movie['year'] else '????')
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.command(help='Add multiple movies to Radarr.', context_settings=dict(max_content_width=100))
|
|
|
|
|
@click.option('--list-type', '-t',
|
|
|
|
|
help='Trakt list to process. For example, anticipated, trending, popular, boxoffice, person, watched, '
|
|
|
|
|
'recommended, played, watchlist or any URL to a list', required=True)
|
|
|
|
|
@click.option('--add-limit', '-l', default=0, help='Limit number of movies added to Radarr.')
|
|
|
|
|
@click.option('--add-delay', '-d', default=2.5, help='Seconds between each add request to Radarr.', show_default=True)
|
|
|
|
|
@click.option('--sort', '-s', default='votes', type=click.Choice(['rating', 'release', 'votes']),
|
|
|
|
|
help='Sort list to process.', show_default=True)
|
|
|
|
|
@click.option('--rating', '-r', default=None, type=int,
|
|
|
|
|
help='Set a minimum rating threshold (according to Rotten Tomatoes)')
|
|
|
|
|
@click.option('--genre', '-g', default=None, help='Only add movies from this genre to Radarr.'
|
|
|
|
|
'Use \'ignore\' to add movies from any genre, '
|
|
|
|
|
'including ones with no genre specified.')
|
|
|
|
|
@click.option('--folder', '-f', default=None, help='Add movies with this root folder to Radarr.')
|
|
|
|
|
@click.option('--minimum-availability', '-ma', default='released',
|
|
|
|
|
type=click.Choice(['announced', 'in_cinemas', 'released', 'predb']),
|
|
|
|
|
help='Add movies with this minimum availability to Radarr.', show_default=True)
|
|
|
|
|
@click.option('--actor', '-a', default=None, help='Only add movies from this actor to Radarr.')
|
|
|
|
|
@click.option('--no-search', is_flag=True, help='Disable search when adding movies to Radarr.')
|
|
|
|
|
@click.option('--notifications', is_flag=True, help='Send notifications.')
|
|
|
|
|
@click.option('--authenticate-user',
|
|
|
|
|
help='Specify which user to authenticate with to retrieve Trakt lists. '
|
|
|
|
|
'Default: first user in the config.')
|
|
|
|
|
@click.option('--ignore-blacklist', is_flag=True, help='Ignores the blacklist when running the command.')
|
|
|
|
|
@click.option('--remove-rejected-from-recommended', is_flag=True,
|
|
|
|
|
help='Removes rejected/existing movies from recommended.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--list-type', '-t',
|
|
|
|
|
help='Trakt list to process. '
|
|
|
|
|
'For example, \'anticipated\', \'trending\', \'popular\', \'person\', \'watched\', \'played\', '
|
|
|
|
|
'\'recommended\', \'watchlist\', or any URL to a list',
|
|
|
|
|
required=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--add-limit', '-l',
|
|
|
|
|
default=0,
|
|
|
|
|
help='Limit number of movies added to Radarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--add-delay', '-d',
|
|
|
|
|
default=2.5,
|
|
|
|
|
help='Seconds between each add request to Radarr.',
|
|
|
|
|
show_default=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--sort', '-s',
|
|
|
|
|
default='votes',
|
|
|
|
|
type=click.Choice(['rating', 'release', 'votes']),
|
|
|
|
|
help='Sort list to process.', show_default=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--rating', '-r',
|
|
|
|
|
default=None,
|
|
|
|
|
type=int,
|
|
|
|
|
help='Set a minimum Rotten Tomatoes score.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--genre', '-g',
|
|
|
|
|
default=None,
|
|
|
|
|
help='Only add movies from this genre to Radarr. '
|
|
|
|
|
'Use \'ignore\' to add movies from any genre, including ones with no genre specified.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--folder', '-f',
|
|
|
|
|
default=None,
|
|
|
|
|
help='Add movies with this root folder to Radarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--minimum-availability', '-ma',
|
|
|
|
|
default='released',
|
|
|
|
|
type=click.Choice(['announced', 'in_cinemas', 'released', 'predb']),
|
|
|
|
|
help='Add movies with this minimum availability to Radarr.',
|
|
|
|
|
show_default=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--actor', '-a',
|
|
|
|
|
default=None,
|
|
|
|
|
help='Only add movies from this actor to Radarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--no-search',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Disable search when adding movies to Radarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--notifications',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Send notifications.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--authenticate-user',
|
|
|
|
|
help='Specify which user to authenticate with to retrieve Trakt lists. '
|
|
|
|
|
'Default: first user in the config.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--ignore-blacklist',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Ignores the blacklist when running the command.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--remove-rejected-from-recommended',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Removes rejected/existing movies from recommended.')
|
|
|
|
|
def movies(list_type, add_limit=0, add_delay=2.5, sort='votes', rating=None, genre=None, folder=None,
|
|
|
|
|
minimum_availability='released', actor=None, no_search=False, notifications=False, authenticate_user=None,
|
|
|
|
|
ignore_blacklist=False, remove_rejected_from_recommended=False):
|
|
|
|
@ -479,36 +589,44 @@ def movies(list_type, add_limit=0, add_delay=2.5, sort='votes', rating=None, gen
|
|
|
|
|
|
|
|
|
|
# get trakt movies list
|
|
|
|
|
if list_type.lower() == 'anticipated':
|
|
|
|
|
trakt_objects_list = trakt.get_anticipated_movies(genres=genre if 'ignore' not in genre else None,
|
|
|
|
|
trakt_objects_list = trakt.get_anticipated_movies(genres=genre if genre
|
|
|
|
|
and 'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.movies.allowed_languages)
|
|
|
|
|
elif list_type.lower() == 'trending':
|
|
|
|
|
trakt_objects_list = trakt.get_trending_movies(genres=genre if 'ignore' not in genre else None,
|
|
|
|
|
trakt_objects_list = trakt.get_trending_movies(genres=genre if genre
|
|
|
|
|
and 'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.movies.allowed_languages)
|
|
|
|
|
elif list_type.lower() == 'popular':
|
|
|
|
|
trakt_objects_list = trakt.get_popular_movies(genres=genre if 'ignore' not in genre else None,
|
|
|
|
|
trakt_objects_list = trakt.get_popular_movies(genres=genre if genre
|
|
|
|
|
and 'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.movies.allowed_languages)
|
|
|
|
|
elif list_type.lower() == 'boxoffice':
|
|
|
|
|
trakt_objects_list = trakt.get_boxoffice_movies()
|
|
|
|
|
elif list_type.lower() == 'person':
|
|
|
|
|
if not actor:
|
|
|
|
|
log.error("You must specify an actor with the --actor / -a parameter when using the person list type!")
|
|
|
|
|
log.error("You must specify an actor with the \'--actor\' / \'-a\' parameter when using the \'person\'" +
|
|
|
|
|
" list type!")
|
|
|
|
|
return None
|
|
|
|
|
trakt_objects_list = trakt.get_person_movies(person=actor,
|
|
|
|
|
genres=genre if 'ignore' not in genre.lower() else None,
|
|
|
|
|
genres=genre if genre
|
|
|
|
|
and 'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.movies.allowed_languages)
|
|
|
|
|
|
|
|
|
|
elif list_type.lower() == 'recommended':
|
|
|
|
|
trakt_objects_list = trakt.get_recommended_movies(authenticate_user,
|
|
|
|
|
genres=genre if 'ignore' not in genre.lower() else None,
|
|
|
|
|
genres=genre if genre
|
|
|
|
|
and 'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.movies.allowed_languages)
|
|
|
|
|
elif list_type.lower().startswith('played'):
|
|
|
|
|
most_type = misc_helper.substring_after(list_type.lower(), "_")
|
|
|
|
|
trakt_objects_list = trakt.get_most_played_movies(genres=genre if 'ignore' not in genre.lower() else None,
|
|
|
|
|
trakt_objects_list = trakt.get_most_played_movies(genres=genre if genre
|
|
|
|
|
and 'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.movies.allowed_languages,
|
|
|
|
|
most_type=most_type if most_type else None)
|
|
|
|
|
elif list_type.lower().startswith('watched'):
|
|
|
|
|
most_type = misc_helper.substring_after(list_type.lower(), "_")
|
|
|
|
|
trakt_objects_list = trakt.get_most_watched_movies(genres=genre if 'ignore' not in genre.lower() else None,
|
|
|
|
|
trakt_objects_list = trakt.get_most_watched_movies(genres=genre if genre
|
|
|
|
|
and 'ignore' not in genre.lower() else None,
|
|
|
|
|
languages=cfg.filters.movies.allowed_languages,
|
|
|
|
|
most_type=most_type if most_type else None)
|
|
|
|
|
elif list_type.lower() == 'watchlist':
|
|
|
|
@ -517,14 +635,15 @@ def movies(list_type, add_limit=0, add_delay=2.5, sort='votes', rating=None, gen
|
|
|
|
|
trakt_objects_list = trakt.get_user_list_movies(list_type, authenticate_user)
|
|
|
|
|
|
|
|
|
|
if not trakt_objects_list:
|
|
|
|
|
log.error("Aborting due to failure to retrieve Trakt %s movies list", list_type)
|
|
|
|
|
log.error("Aborting due to failure to retrieve Trakt \'%s\' movies list", list_type.capitalize())
|
|
|
|
|
if notifications:
|
|
|
|
|
callback_notify(
|
|
|
|
|
{'event': 'abort', 'type': 'movies', 'list_type': list_type,
|
|
|
|
|
'reason': 'Failure to retrieve Trakt %s movies list' % list_type})
|
|
|
|
|
'reason': 'Failure to retrieve Trakt \'%s\' movies list' % list_type.capitalize()})
|
|
|
|
|
return None
|
|
|
|
|
else:
|
|
|
|
|
log.info("Retrieved Trakt %s movies list, movies found: %d", list_type, len(trakt_objects_list))
|
|
|
|
|
log.info("Retrieved Trakt \'%s\' movies list, movies found: %d", list_type.capitalize(),
|
|
|
|
|
len(trakt_objects_list))
|
|
|
|
|
|
|
|
|
|
# set remove_rejected_recommended to False if this is not the recommended list
|
|
|
|
|
if list_type.lower() != 'recommended':
|
|
|
|
@ -539,7 +658,7 @@ def movies(list_type, add_limit=0, add_delay=2.5, sort='votes', rating=None, gen
|
|
|
|
|
if notifications:
|
|
|
|
|
callback_notify({'event': 'abort', 'type': 'movies', 'list_type': list_type,
|
|
|
|
|
'reason': 'Failure to remove existing Radarr movies from retrieved '
|
|
|
|
|
'Trakt %s movies list' % list_type})
|
|
|
|
|
'Trakt %s movies list' % list_type.capitalize()})
|
|
|
|
|
return None
|
|
|
|
|
else:
|
|
|
|
|
log.info("Removed existing Radarr movies from Trakt movies list, movies left to process: %d",
|
|
|
|
@ -548,13 +667,13 @@ def movies(list_type, add_limit=0, add_delay=2.5, sort='votes', rating=None, gen
|
|
|
|
|
# sort filtered movie list
|
|
|
|
|
if sort == 'release':
|
|
|
|
|
sorted_movies_list = misc_helper.sorted_list(processed_movies_list, 'movie', 'released')
|
|
|
|
|
log.info("Sorted movies list to process by release date")
|
|
|
|
|
log.info("Sorted movies list to process by recent 'release' date")
|
|
|
|
|
elif sort == 'rating':
|
|
|
|
|
sorted_movies_list = misc_helper.sorted_list(processed_movies_list, 'movie', 'rating')
|
|
|
|
|
log.info("Sorted movies list to process by highest rating")
|
|
|
|
|
log.info("Sorted movies list to process by highest 'rating'")
|
|
|
|
|
else:
|
|
|
|
|
sorted_movies_list = misc_helper.sorted_list(processed_movies_list, 'movie', 'votes')
|
|
|
|
|
log.info("Sorted movies list to process by highest votes")
|
|
|
|
|
log.info("Sorted movies list to process by highest 'votes'")
|
|
|
|
|
|
|
|
|
|
# display specified RT score
|
|
|
|
|
if rating is not None and 'omdb' in cfg and 'api_key' in cfg['omdb'] and cfg['omdb']['api_key']:
|
|
|
|
@ -567,8 +686,8 @@ def movies(list_type, add_limit=0, add_delay=2.5, sort='votes', rating=None, gen
|
|
|
|
|
try:
|
|
|
|
|
# check if genre matches genre supplied via argument
|
|
|
|
|
if genre and not misc_helper.allowed_genres(genre, 'movie', sorted_movie):
|
|
|
|
|
log.debug("Skipping: %s because it was not from %s genre(s)", sorted_movie['movie']['title'],
|
|
|
|
|
genre.lower())
|
|
|
|
|
log.debug("Skipping: \'%s\' because it was not from genre: %s", sorted_movie['movie']['title'],
|
|
|
|
|
genre.title())
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# check if movie passes out blacklist criteria inspection
|
|
|
|
@ -580,28 +699,35 @@ def movies(list_type, add_limit=0, add_delay=2.5, sort='votes', rating=None, gen
|
|
|
|
|
if rating is not None and 'omdb' in cfg and 'api_key' in cfg['omdb'] and cfg['omdb']['api_key']:
|
|
|
|
|
movie_rating = rating_helper.get_rating(cfg['omdb']['api_key'], sorted_movie)
|
|
|
|
|
if movie_rating == -1:
|
|
|
|
|
log.info("SKIPPED \'%s (%d)\'", sorted_movie['movie']['title'], sorted_movie['movie']['year'])
|
|
|
|
|
log.info("SKIPPED: \'%s (%s)\'", sorted_movie['movie']['title'],
|
|
|
|
|
str(sorted_movie['movie']['year']) if sorted_movie['movie']['year'] else '????')
|
|
|
|
|
continue
|
|
|
|
|
if (rating is None or movie_rating is None) or movie_rating >= rating:
|
|
|
|
|
log.info("Adding: \'%s (%d)\' | Genres: %s | Country: %s", sorted_movie['movie']['title'],
|
|
|
|
|
sorted_movie['movie']['year'],
|
|
|
|
|
(', '.join(sorted_movie['movie']['genres']) if sorted_movie['movie']['genres'] else 'N/A'),
|
|
|
|
|
(sorted_movie['movie']['country'] or 'N/A').upper())
|
|
|
|
|
log.info("Adding: \'%s (%s)\' | Country: %s | Language: %s | Genre: %s ",
|
|
|
|
|
sorted_movie['movie']['title'],
|
|
|
|
|
str(sorted_movie['movie']['year']) if sorted_movie['movie']['year'] else '????',
|
|
|
|
|
(sorted_movie['movie']['country'] or 'N/A').upper(),
|
|
|
|
|
(sorted_movie['movie']['language'] or 'N/A').upper(),
|
|
|
|
|
(', '.join(sorted_movie['movie']['genres'])).title()
|
|
|
|
|
if sorted_movie['movie']['genres'] else 'N/A')
|
|
|
|
|
# add movie to radarr
|
|
|
|
|
if radarr.add_movie(sorted_movie['movie']['ids']['tmdb'], sorted_movie['movie']['title'],
|
|
|
|
|
sorted_movie['movie']['year'], sorted_movie['movie']['ids']['slug'], profile_id,
|
|
|
|
|
str(sorted_movie['movie']['year']) if sorted_movie['movie']['year'] else '????',
|
|
|
|
|
sorted_movie['movie']['ids']['slug'], profile_id,
|
|
|
|
|
cfg.radarr.root_folder, cfg.radarr.minimum_availability, not no_search):
|
|
|
|
|
log.info("ADDED \'%s (%d)\'", sorted_movie['movie']['title'], sorted_movie['movie']['year'])
|
|
|
|
|
log.info("ADDED: \'%s (%s)\'", sorted_movie['movie']['title'],
|
|
|
|
|
str(sorted_movie['movie']['year']) if sorted_movie['movie']['year'] else '????')
|
|
|
|
|
if notifications:
|
|
|
|
|
callback_notify({'event': 'add_movie', 'list_type': list_type,
|
|
|
|
|
'movie': sorted_movie['movie']})
|
|
|
|
|
added_movies += 1
|
|
|
|
|
else:
|
|
|
|
|
log.error("FAILED adding \'%s (%d)\'", sorted_movie['movie']['title'],
|
|
|
|
|
sorted_movie['movie']['year'])
|
|
|
|
|
log.error("FAILED ADDING: \'%s (%s)\'", sorted_movie['movie']['title'],
|
|
|
|
|
str(sorted_movie['movie']['year']) if sorted_movie['movie']['year'] else '????')
|
|
|
|
|
else:
|
|
|
|
|
log.debug("Minimum Rotten Tomatoes score of %d%% was not met.", rating)
|
|
|
|
|
log.info("SKIPPED \'%s (%d)\'", sorted_movie['movie']['title'], sorted_movie['movie']['year'])
|
|
|
|
|
log.info("SKIPPED: \'%s (%s)\'", sorted_movie['movie']['title'],
|
|
|
|
|
str(sorted_movie['movie']['year']) if sorted_movie['movie']['year'] else '????')
|
|
|
|
|
# stop adding movies, if added_movies >= add_limit
|
|
|
|
|
if add_limit and added_movies >= add_limit:
|
|
|
|
|
break
|
|
|
|
@ -610,13 +736,13 @@ def movies(list_type, add_limit=0, add_delay=2.5, sort='votes', rating=None, gen
|
|
|
|
|
time.sleep(add_delay)
|
|
|
|
|
|
|
|
|
|
except Exception:
|
|
|
|
|
log.exception("Exception while processing movie %s: ", sorted_movie['movie']['title'])
|
|
|
|
|
log.exception("Exception while processing movie \'%s\': ", sorted_movie['movie']['title'])
|
|
|
|
|
|
|
|
|
|
log.info("Added %d new movie(s) to Radarr", added_movies)
|
|
|
|
|
|
|
|
|
|
# send notification
|
|
|
|
|
if notifications and (cfg.notifications.verbose or added_movies > 0):
|
|
|
|
|
notify.send(message="Added %d movies from Trakt's %s list" % (added_movies, list_type))
|
|
|
|
|
notify.send(message="Added %d movie(s) from Trakt's \'%s\' list" % (added_movies, list_type.capitalize()))
|
|
|
|
|
|
|
|
|
|
return added_movies
|
|
|
|
|
|
|
|
|
@ -636,12 +762,13 @@ def callback_remove_recommended(media_type, media_info):
|
|
|
|
|
media_info)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
media_name = '\'%s (%d)\'' % (media_info[media_type]['title'], media_info[media_type]['year'])
|
|
|
|
|
media_name = '\'%s (%s)\'' % (media_info[media_type]['title'],
|
|
|
|
|
str(media_info[media_type]['year']) if media_info[media_type]['year'] else '????')
|
|
|
|
|
|
|
|
|
|
if trakt.remove_recommended_item(media_type, media_info[media_type]['ids']['trakt']):
|
|
|
|
|
log.info("Removed rejected recommended %s: %s", media_type, media_name)
|
|
|
|
|
log.info("Removed rejected recommended %s: \'%s\'", media_type, media_name)
|
|
|
|
|
else:
|
|
|
|
|
log.info("FAILED removing rejected recommended %s: %s", media_type, media_name)
|
|
|
|
|
log.info("FAILED removing rejected recommended %s: \'%s\'", media_type, media_name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def callback_notify(data):
|
|
|
|
@ -651,15 +778,20 @@ def callback_notify(data):
|
|
|
|
|
if data['event'] == 'add_movie':
|
|
|
|
|
if cfg.notifications.verbose:
|
|
|
|
|
notify.send(
|
|
|
|
|
message="Added %s movie: \'%s (%d)\'" % (data['list_type'], data['movie']['title'], data['movie']['year']))
|
|
|
|
|
message="Added \'%s\' movie: \'%s (%s)\'" % (data['list_type'].capitalize(), data['movie']['title'],
|
|
|
|
|
str(data['movie']['year'])
|
|
|
|
|
if data['movie']['year'] else '????'))
|
|
|
|
|
return
|
|
|
|
|
elif data['event'] == 'add_show':
|
|
|
|
|
if cfg.notifications.verbose:
|
|
|
|
|
notify.send(
|
|
|
|
|
message="Added %s show: \'%s (%d)\'" % (data['list_type'], data['show']['title'], data['show']['year']))
|
|
|
|
|
message="Added \'%s\' show: \'%s (%s)\'" % (data['list_type'].capitalize(), data['show']['title'],
|
|
|
|
|
str(data['movie']['year'])
|
|
|
|
|
if data['movie']['year'] else '????'))
|
|
|
|
|
return
|
|
|
|
|
elif data['event'] == 'abort':
|
|
|
|
|
notify.send(message="Aborted adding Trakt %s %s due to: %s" % (data['list_type'], data['type'], data['reason']))
|
|
|
|
|
notify.send(message="Aborted adding Trakt \'%s\' %s due to: %s" % (data['list_type'].capitalize(), data['type'],
|
|
|
|
|
data['reason']))
|
|
|
|
|
return
|
|
|
|
|
elif data['event'] == 'error':
|
|
|
|
|
notify.send(message="Error: %s" % data['reason'])
|
|
|
|
@ -697,10 +829,10 @@ def automatic_shows(add_delay=2.5, sort='votes', no_search=False, notifications=
|
|
|
|
|
limit = value
|
|
|
|
|
|
|
|
|
|
if limit <= 0:
|
|
|
|
|
log.info("Skipped Trakt's %s shows list", list_type)
|
|
|
|
|
log.info("Skipped Trakt's \'%s\' shows list", list_type.capitalize())
|
|
|
|
|
continue
|
|
|
|
|
else:
|
|
|
|
|
log.info("Adding %d shows from Trakt's %s list", limit, list_type)
|
|
|
|
|
log.info("Adding %d show(s) from Trakt's \'%s\' list", limit, list_type.capitalize())
|
|
|
|
|
|
|
|
|
|
local_ignore_blacklist = ignore_blacklist
|
|
|
|
|
|
|
|
|
@ -714,10 +846,11 @@ def automatic_shows(add_delay=2.5, sort='votes', no_search=False, notifications=
|
|
|
|
|
elif list_type.lower() == 'watchlist':
|
|
|
|
|
for authenticate_user, limit in value.items():
|
|
|
|
|
if limit <= 0:
|
|
|
|
|
log.info("Skipped Trakt's %s for %s", list_type, authenticate_user)
|
|
|
|
|
log.info("Skipped Trakt user \'%s\''s \'%s\'", authenticate_user, list_type.capitalize)
|
|
|
|
|
continue
|
|
|
|
|
else:
|
|
|
|
|
log.info("Adding %d shows from the %s from %s", limit, list_type, authenticate_user)
|
|
|
|
|
log.info("Adding %d show(s) from Trakt user \'%s\''s \'%s\'", limit, authenticate_user,
|
|
|
|
|
list_type.capitalize)
|
|
|
|
|
|
|
|
|
|
local_ignore_blacklist = ignore_blacklist
|
|
|
|
|
|
|
|
|
@ -750,7 +883,7 @@ def automatic_shows(add_delay=2.5, sort='votes', no_search=False, notifications=
|
|
|
|
|
ignore_blacklist=local_ignore_blacklist)
|
|
|
|
|
|
|
|
|
|
if added_shows is None:
|
|
|
|
|
log.error("Failed adding shows from Trakt's %s list", list_type)
|
|
|
|
|
log.error("Failed adding shows from Trakt's \'%s\' list", list_type)
|
|
|
|
|
time.sleep(10)
|
|
|
|
|
continue
|
|
|
|
|
total_shows_added += added_shows
|
|
|
|
@ -758,10 +891,10 @@ def automatic_shows(add_delay=2.5, sort='votes', no_search=False, notifications=
|
|
|
|
|
# sleep
|
|
|
|
|
time.sleep(10)
|
|
|
|
|
|
|
|
|
|
log.info("Finished, added %d shows total to Sonarr!", total_shows_added)
|
|
|
|
|
log.info("Finished, added %d show(s) total to Sonarr!", total_shows_added)
|
|
|
|
|
# send notification
|
|
|
|
|
if notifications and (cfg.notifications.verbose or total_shows_added > 0):
|
|
|
|
|
notify.send(message="Added %d shows total to Sonarr!" % total_shows_added)
|
|
|
|
|
notify.send(message="Added %d show(s) total to Sonarr!" % total_shows_added)
|
|
|
|
|
|
|
|
|
|
except Exception:
|
|
|
|
|
log.exception("Exception while automatically adding shows: ")
|
|
|
|
@ -792,10 +925,10 @@ def automatic_movies(add_delay=2.5, sort='votes', no_search=False, notifications
|
|
|
|
|
limit = value
|
|
|
|
|
|
|
|
|
|
if limit <= 0:
|
|
|
|
|
log.info("Skipped Trakt's %s movies list", list_type)
|
|
|
|
|
log.info("Skipped Trakt's \'%s\' movies list", list_type.capitalize())
|
|
|
|
|
continue
|
|
|
|
|
else:
|
|
|
|
|
log.info("Adding %d movies from Trakt's %s list", limit, list_type)
|
|
|
|
|
log.info("Adding %d movie(s) from Trakt's \'%s\' list", limit, list_type.capitalize())
|
|
|
|
|
|
|
|
|
|
local_ignore_blacklist = ignore_blacklist
|
|
|
|
|
|
|
|
|
@ -810,10 +943,11 @@ def automatic_movies(add_delay=2.5, sort='votes', no_search=False, notifications
|
|
|
|
|
elif list_type.lower() == 'watchlist':
|
|
|
|
|
for authenticate_user, limit in value.items():
|
|
|
|
|
if limit <= 0:
|
|
|
|
|
log.info("Skipped Trakt's %s for %s", list_type, authenticate_user)
|
|
|
|
|
log.info("Skipped Trakt user \'%s\''s \'%s\'", authenticate_user, list_type.capitalize)
|
|
|
|
|
continue
|
|
|
|
|
else:
|
|
|
|
|
log.info("Adding %d movies from the %s from %s", limit, list_type, authenticate_user)
|
|
|
|
|
log.info("Adding %d movie(s) from Trakt user \'%s\''s \'%s\'", limit,
|
|
|
|
|
authenticate_user, list_type.capitalize())
|
|
|
|
|
|
|
|
|
|
local_ignore_blacklist = ignore_blacklist
|
|
|
|
|
|
|
|
|
@ -846,7 +980,7 @@ def automatic_movies(add_delay=2.5, sort='votes', no_search=False, notifications
|
|
|
|
|
ignore_blacklist=local_ignore_blacklist, rating=rating_limit)
|
|
|
|
|
|
|
|
|
|
if added_movies is None:
|
|
|
|
|
log.error("Failed adding movies from Trakt's %s list", list_type)
|
|
|
|
|
log.error("Failed adding movies from Trakt's \'%s\' list", list_type.capitalize())
|
|
|
|
|
time.sleep(10)
|
|
|
|
|
continue
|
|
|
|
|
total_movies_added += added_movies
|
|
|
|
@ -854,10 +988,10 @@ def automatic_movies(add_delay=2.5, sort='votes', no_search=False, notifications
|
|
|
|
|
# sleep
|
|
|
|
|
time.sleep(10)
|
|
|
|
|
|
|
|
|
|
log.info("Finished, added %d movies total to Radarr!", total_movies_added)
|
|
|
|
|
log.info("Finished, added %d movie(s) total to Radarr!", total_movies_added)
|
|
|
|
|
# send notification
|
|
|
|
|
if notifications and (cfg.notifications.verbose or total_movies_added > 0):
|
|
|
|
|
notify.send(message="Added %d movies total to Radarr!" % total_movies_added)
|
|
|
|
|
notify.send(message="Added %d movie(s) total to Radarr!" % total_movies_added)
|
|
|
|
|
|
|
|
|
|
except Exception:
|
|
|
|
|
log.exception("Exception while automatically adding movies: ")
|
|
|
|
@ -865,14 +999,33 @@ def automatic_movies(add_delay=2.5, sort='votes', no_search=False, notifications
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@app.command(help='Run Traktarr in automatic mode.')
|
|
|
|
|
@click.option('--add-delay', '-d', default=2.5, help='Seconds between each add request to Sonarr / Radarr.',
|
|
|
|
|
show_default=True)
|
|
|
|
|
@click.option('--sort', '-s', default='votes', type=click.Choice(['votes', 'rating', 'release']),
|
|
|
|
|
help='Sort list to process.', show_default=True)
|
|
|
|
|
@click.option('--no-search', is_flag=True, help='Disable search when adding to Sonarr / Radarr.')
|
|
|
|
|
@click.option('--run-now', is_flag=True, help="Do a first run immediately without waiting.")
|
|
|
|
|
@click.option('--no-notifications', is_flag=True, help="Disable notifications.")
|
|
|
|
|
@click.option('--ignore-blacklist', is_flag=True, help='Ignores the blacklist when running the command.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--add-delay', '-d',
|
|
|
|
|
default=2.5,
|
|
|
|
|
help='Seconds between each add request to Sonarr / Radarr.',
|
|
|
|
|
show_default=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--sort', '-s',
|
|
|
|
|
default='votes',
|
|
|
|
|
type=click.Choice(['votes', 'rating', 'release']),
|
|
|
|
|
help='Sort list to process.',
|
|
|
|
|
show_default=True)
|
|
|
|
|
@click.option(
|
|
|
|
|
'--no-search',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Disable search when adding to Sonarr / Radarr.')
|
|
|
|
|
@click.option(
|
|
|
|
|
'--run-now',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help="Do a first run immediately without waiting.")
|
|
|
|
|
@click.option(
|
|
|
|
|
'--no-notifications',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help="Disable notifications.")
|
|
|
|
|
@click.option(
|
|
|
|
|
'--ignore-blacklist',
|
|
|
|
|
is_flag=True,
|
|
|
|
|
help='Ignores the blacklist when running the command.')
|
|
|
|
|
def run(add_delay=2.5, sort='votes', no_search=False, run_now=False, no_notifications=False, ignore_blacklist=False):
|
|
|
|
|
log.info("Automatic mode is now running.")
|
|
|
|
|
|
|
|
|
|