diff options
author | morpheus65535 <[email protected]> | 2021-06-16 13:45:54 -0400 |
---|---|---|
committer | morpheus65535 <[email protected]> | 2021-06-16 13:45:54 -0400 |
commit | ee41b78f4e4fe015ce915d1721b880b6d2d4d40f (patch) | |
tree | 7534a4e85d4b6b245f9bdd0540f06b91257ae801 | |
parent | 26e978b14b2289fa189a789f6f2c03570c55eb08 (diff) | |
download | bazarr-ee41b78f4e4fe015ce915d1721b880b6d2d4d40f.tar.gz bazarr-ee41b78f4e4fe015ce915d1721b880b6d2d4d40f.zip |
Upgraded calls to Sonarr API in order to use the new v3 API when available.
-rw-r--r-- | bazarr/config.py | 6 | ||||
-rw-r--r-- | bazarr/filesystem.py | 25 | ||||
-rw-r--r-- | bazarr/get_episodes.py | 81 | ||||
-rw-r--r-- | bazarr/get_rootfolder.py | 15 | ||||
-rw-r--r-- | bazarr/get_series.py | 16 | ||||
-rw-r--r-- | bazarr/main.py | 10 | ||||
-rw-r--r-- | bazarr/utils.py | 17 |
7 files changed, 137 insertions, 33 deletions
diff --git a/bazarr/config.py b/bazarr/config.py index 2ebae7e32..e076ea3b8 100644 --- a/bazarr/config.py +++ b/bazarr/config.py @@ -290,6 +290,7 @@ def get_settings(): return result + def save_settings(settings_items): from database import database @@ -479,6 +480,7 @@ def url_sonarr(): return f"{protocol_sonarr}://{settings.sonarr.ip}{port}{settings.sonarr.base_url}" + def url_sonarr_short(): if settings.sonarr.getboolean('ssl'): protocol_sonarr = "https" @@ -492,6 +494,7 @@ def url_sonarr_short(): return f"{protocol_sonarr}://{settings.sonarr.ip}{port}" + def url_radarr(): if settings.radarr.getboolean('ssl'): protocol_radarr = "https" @@ -512,6 +515,7 @@ def url_radarr(): return f"{protocol_radarr}://{settings.radarr.ip}{port}{settings.radarr.base_url}" + def url_radarr_short(): if settings.radarr.getboolean('ssl'): protocol_radarr = "https" @@ -525,6 +529,7 @@ def url_radarr_short(): return f"{protocol_radarr}://{settings.radarr.ip}{port}" + def get_array_from(property): if property: if '[' in property: @@ -536,6 +541,7 @@ def get_array_from(property): else: return [] + def configure_captcha_func(): # set anti-captcha provider and key if settings.general.anti_captcha_provider == 'anti-captcha' and settings.anticaptcha.anti_captcha_key != "": diff --git a/bazarr/filesystem.py b/bazarr/filesystem.py index ab7494334..47e09c8cb 100644 --- a/bazarr/filesystem.py +++ b/bazarr/filesystem.py @@ -6,6 +6,7 @@ import logging import string from config import settings, url_sonarr, url_radarr +from utils import get_sonarr_version, get_radarr_version headers = {"User-Agent": os.environ["SZ_USER_AGENT"]} @@ -45,11 +46,17 @@ def browse_bazarr_filesystem(path='#'): def browse_sonarr_filesystem(path='#'): + sonarr_version = get_sonarr_version() if path == '#': path = '' - url_sonarr_api_filesystem = url_sonarr() + "/api/filesystem?path=" + path + \ - "&allowFoldersWithoutTrailingSlashes=true&includeFiles=false&apikey=" + \ - settings.sonarr.apikey + if sonarr_version.startswith('2'): + url_sonarr_api_filesystem = url_sonarr() + "/api/filesystem?path=" + path + \ + "&allowFoldersWithoutTrailingSlashes=true&includeFiles=false&apikey=" + \ + settings.sonarr.apikey + else: + url_sonarr_api_filesystem = url_sonarr() + "/api/v3/filesystem?path=" + path + \ + "&allowFoldersWithoutTrailingSlashes=true&includeFiles=false&apikey=" + \ + settings.sonarr.apikey try: r = requests.get(url_sonarr_api_filesystem, timeout=60, verify=False, headers=headers) r.raise_for_status() @@ -70,12 +77,18 @@ def browse_sonarr_filesystem(path='#'): def browse_radarr_filesystem(path='#'): + radarr_version = get_radarr_version() if path == '#': path = '' - url_radarr_api_filesystem = url_radarr() + "/api/filesystem?path=" + path + \ - "&allowFoldersWithoutTrailingSlashes=true&includeFiles=false&apikey=" + \ - settings.radarr.apikey + if radarr_version.startswith('0'): + url_radarr_api_filesystem = url_radarr() + "/api/filesystem?path=" + path + \ + "&allowFoldersWithoutTrailingSlashes=true&includeFiles=false&apikey=" + \ + settings.radarr.apikey + else: + url_radarr_api_filesystem = url_radarr() + "/api/v3/filesystem?path=" + path + \ + "&allowFoldersWithoutTrailingSlashes=true&includeFiles=false&apikey=" + \ + settings.radarr.apikey try: r = requests.get(url_radarr_api_filesystem, timeout=60, verify=False, headers=headers) r.raise_for_status() diff --git a/bazarr/get_episodes.py b/bazarr/get_episodes.py index 009d07d33..4c1332882 100644 --- a/bazarr/get_episodes.py +++ b/bazarr/get_episodes.py @@ -12,6 +12,7 @@ from helper import path_mappings from list_subtitles import store_subtitles, series_full_scan_subtitles from get_subtitle import episode_download_subtitles from event_handler import event_stream, show_progress, hide_progress +from utils import get_sonarr_version headers = {"User-Agent": os.environ["SZ_USER_AGENT"]} @@ -24,6 +25,7 @@ def update_all_episodes(): def sync_episodes(series_id=None, send_event=True): logging.debug('BAZARR Starting episodes sync from Sonarr.') apikey_sonarr = settings.sonarr.apikey + sonarr_version = get_sonarr_version() # Get current episodes id in DB current_episodes_db = TableEpisodes.select(TableEpisodes.sonarrEpisodeId, @@ -40,7 +42,8 @@ def sync_episodes(series_id=None, send_event=True): altered_episodes = [] # Get sonarrId for each series from database - seriesIdList = get_series_from_sonarr_api(series_id=series_id, url=url_sonarr(), apikey_sonarr=apikey_sonarr) + seriesIdList = get_series_from_sonarr_api(series_id=series_id, url=url_sonarr(), apikey_sonarr=apikey_sonarr, + sonarr_version=sonarr_version) series_count = len(seriesIdList) for i, seriesId in enumerate(seriesIdList, 1): @@ -54,10 +57,21 @@ def sync_episodes(series_id=None, send_event=True): # Get episodes data for a series from Sonarr episodes = get_episodes_from_sonarr_api(url=url_sonarr(), apikey_sonarr=apikey_sonarr, - series_id=seriesId['sonarrSeriesId']) + series_id=seriesId['sonarrSeriesId'], + sonarr_version=sonarr_version) if not episodes: continue else: + # For Sonarr v3, we need to update episodes to integrate the episodeFile API endpoint results + if sonarr_version.startswith('3'): + episodeFiles = get_episodesFiles_from_sonarr_api(url=url_sonarr(), apikey_sonarr=apikey_sonarr, + series_id=seriesId['sonarrSeriesId']) + for episode in episodes: + if episode['hasFile']: + item = [x for x in episodeFiles if x['id'] == episode['episodeFileId']] + if item: + episode['episodeFile'] = item[0] + for episode in episodes: sleep() if 'hasFile' in episode: @@ -67,7 +81,7 @@ def sync_episodes(series_id=None, send_event=True): # Add episodes in sonarr to current episode list current_episodes_sonarr.append(episode['id']) - # Parse episdoe data + # Parse episode data if episode['id'] in current_episodes_db_list: episodes_to_update.append(episodeParser(episode)) else: @@ -150,10 +164,13 @@ def sync_episodes(series_id=None, send_event=True): def sync_one_episode(episode_id): logging.debug('BAZARR syncing this specific episode from Sonarr: {}'.format(episode_id)) + url = url_sonarr() + apikey_sonarr = settings.sonarr.apikey + sonarr_version = get_sonarr_version() # Check if there's a row in database for this episode ID try: - existing_episode = TableEpisodes.select(TableEpisodes.path)\ + existing_episode = TableEpisodes.select(TableEpisodes.path, TableEpisodes.episode_file_id)\ .where(TableEpisodes.sonarrEpisodeId == episode_id)\ .dicts()\ .get() @@ -163,11 +180,19 @@ def sync_one_episode(episode_id): try: # Get episode data from sonarr api episode = None - episode_data = get_episodes_from_sonarr_api(url=url_sonarr(), apikey_sonarr=settings.sonarr.apikey, - episode_id=episode_id) + episode_data = get_episodes_from_sonarr_api(url=url, apikey_sonarr=apikey_sonarr, + episode_id=episode_id, sonarr_version=sonarr_version) if not episode_data: return + else: + # For Sonarr v3, we need to update episodes to integrate the episodeFile API endpoint results + if sonarr_version.startswith('3'): + episodeFile = get_episodesFiles_from_sonarr_api(url=url, apikey_sonarr=apikey_sonarr, + episode_file_id=existing_episode['episode_file_id']) + if episode_data['hasFile']: + episode_data['episodeFile'] = episodeFile + episode = episodeParser(episode_data) except Exception: logging.debug('BAZARR cannot get episode returned by SignalR feed from Sonarr API.') @@ -311,11 +336,13 @@ def episodeParser(episode): 'file_size': episode['episodeFile']['size']} -def get_series_from_sonarr_api(series_id, url, apikey_sonarr): +def get_series_from_sonarr_api(series_id, url, apikey_sonarr, sonarr_version): if series_id: - url_sonarr_api_series = url + "/api/series/{0}?apikey={1}".format(series_id, apikey_sonarr) + url_sonarr_api_series = url + "/api/{0}series/{1}?apikey={2}".format( + '' if sonarr_version.startswith('2') else 'v3/', series_id, apikey_sonarr) else: - url_sonarr_api_series = url + "/api/series?apikey={}".format(apikey_sonarr) + url_sonarr_api_series = url + "/api/{0}series?apikey={1}".format( + '' if sonarr_version.startswith('2') else 'v3/', apikey_sonarr) try: r = requests.get(url_sonarr_api_series, timeout=60, verify=False, headers=headers) r.raise_for_status() @@ -345,11 +372,13 @@ def get_series_from_sonarr_api(series_id, url, apikey_sonarr): return series_list -def get_episodes_from_sonarr_api(url, apikey_sonarr, series_id=None, episode_id=None): +def get_episodes_from_sonarr_api(url, apikey_sonarr, sonarr_version, series_id=None, episode_id=None): if series_id: - url_sonarr_api_episode = url + "/api/episode?seriesId={}&apikey=".format(series_id) + apikey_sonarr + url_sonarr_api_episode = url + "/api/{0}episode?seriesId={1}&apikey={2}".format( + '' if sonarr_version.startswith('2') else 'v3/', series_id, apikey_sonarr) elif episode_id: - url_sonarr_api_episode = url + "/api/episode/{}?apikey=".format(episode_id) + apikey_sonarr + url_sonarr_api_episode = url + "/api/{0}episode/{1}?apikey={2}".format( + '' if sonarr_version.startswith('2') else 'v3/', episode_id, apikey_sonarr) else: return @@ -370,3 +399,31 @@ def get_episodes_from_sonarr_api(url, apikey_sonarr, series_id=None, episode_id= return else: return r.json() + + +def get_episodesFiles_from_sonarr_api(url, apikey_sonarr, series_id=None, episode_file_id=None): + if series_id: + url_sonarr_api_episodeFiles = url + "/api/v3/episodeFile?seriesId={0}&apikey={1}".format(series_id, + apikey_sonarr) + elif episode_file_id: + url_sonarr_api_episodeFiles = url + "/api/v3/episodeFile/{0}?apikey={1}".format(episode_file_id, apikey_sonarr) + else: + return + + try: + r = requests.get(url_sonarr_api_episodeFiles, timeout=60, verify=False, headers=headers) + r.raise_for_status() + except requests.exceptions.HTTPError: + logging.exception("BAZARR Error trying to get episodeFiles from Sonarr. Http error.") + return + except requests.exceptions.ConnectionError: + logging.exception("BAZARR Error trying to get episodeFiles from Sonarr. Connection Error.") + return + except requests.exceptions.Timeout: + logging.exception("BAZARR Error trying to get episodeFiles from Sonarr. Timeout Error.") + return + except requests.exceptions.RequestException: + logging.exception("BAZARR Error trying to get episodeFiles from Sonarr.") + return + else: + return r.json() diff --git a/bazarr/get_rootfolder.py b/bazarr/get_rootfolder.py index c74b5c632..e8529e954 100644 --- a/bazarr/get_rootfolder.py +++ b/bazarr/get_rootfolder.py @@ -7,7 +7,7 @@ import logging from config import settings, url_sonarr, url_radarr from helper import path_mappings from database import TableShowsRootfolder, TableMoviesRootfolder, TableShows, TableMovies -from utils import get_radarr_version +from utils import get_sonarr_version, get_radarr_version headers = {"User-Agent": os.environ["SZ_USER_AGENT"]} @@ -15,9 +15,13 @@ headers = {"User-Agent": os.environ["SZ_USER_AGENT"]} def get_sonarr_rootfolder(): apikey_sonarr = settings.sonarr.apikey sonarr_rootfolder = [] + sonarr_version = get_sonarr_version() # Get root folder data from Sonarr - url_sonarr_api_rootfolder = url_sonarr() + "/api/rootfolder?apikey=" + apikey_sonarr + if sonarr_version.startswith('2'): + url_sonarr_api_rootfolder = url_sonarr() + "/api/rootfolder?apikey=" + apikey_sonarr + else: + url_sonarr_api_rootfolder = url_sonarr() + "/api/v3/rootfolder?apikey=" + apikey_sonarr try: rootfolder = requests.get(url_sonarr_api_rootfolder, timeout=60, verify=False, headers=headers) @@ -58,14 +62,17 @@ def check_sonarr_rootfolder(): get_sonarr_rootfolder() rootfolder = TableShowsRootfolder.select(TableShowsRootfolder.id, TableShowsRootfolder.path).dicts() for item in rootfolder: - if not os.path.isdir(path_mappings.path_replace(item['path'])): + root_path = item['path'] + if not root_path.endswith(os.path.sep): + root_path += os.path.sep + if not os.path.isdir(path_mappings.path_replace(root_path)): TableShowsRootfolder.update({TableShowsRootfolder.accessible: 0, TableShowsRootfolder.error: 'This Sonarr root directory does not seems to ' 'be accessible by Bazarr. Please check path ' 'mapping.'})\ .where(TableShowsRootfolder.id == item['id'])\ .execute() - elif not os.access(path_mappings.path_replace(item['path']), os.W_OK): + elif not os.access(path_mappings.path_replace(root_path), os.W_OK): TableShowsRootfolder.update({TableShowsRootfolder.accessible: 0, TableShowsRootfolder.error: 'Bazarr cannot write to this directory.'}) \ .where(TableShowsRootfolder.id == item['id']) \ diff --git a/bazarr/get_series.py b/bazarr/get_series.py index 42a5d6972..1ef7b90f1 100644 --- a/bazarr/get_series.py +++ b/bazarr/get_series.py @@ -38,7 +38,8 @@ def update_series(send_event=True): tagsDict = get_tags() # Get shows data from Sonarr - series = get_series_from_sonarr_api(url=url_sonarr(), apikey_sonarr=apikey_sonarr) + series = get_series_from_sonarr_api(url=url_sonarr(), apikey_sonarr=apikey_sonarr, + sonarr_version=sonarr_version) if not series: return else: @@ -172,7 +173,7 @@ def update_one_series(series_id, action): series = None series_data = get_series_from_sonarr_api(url=url_sonarr(), apikey_sonarr=settings.sonarr.apikey, - sonarr_series_id=int(series_id)) + sonarr_series_id=int(series_id), sonarr_version=get_sonarr_version()) if not series_data: return @@ -252,7 +253,10 @@ def get_tags(): tagsDict = [] # Get tags data from Sonarr - url_sonarr_api_series = url_sonarr() + "/api/tag?apikey=" + apikey_sonarr + if get_sonarr_version().startswith('2'): + url_sonarr_api_series = url_sonarr() + "/api/tag?apikey=" + apikey_sonarr + else: + url_sonarr_api_series = url_sonarr() + "/api/v3/tag?apikey=" + apikey_sonarr try: tagsDict = requests.get(url_sonarr_api_series, timeout=60, verify=False, headers=headers) @@ -328,9 +332,9 @@ def seriesParser(show, action, sonarr_version, tags_dict, serie_default_profile, 'profileId': serie_default_profile} -def get_series_from_sonarr_api(url, apikey_sonarr, sonarr_series_id=None): - url_sonarr_api_series = url + "/api/series" + ("/{}".format(sonarr_series_id) if sonarr_series_id else "") + \ - "?apikey=" + apikey_sonarr +def get_series_from_sonarr_api(url, apikey_sonarr, sonarr_version, sonarr_series_id=None): + url_sonarr_api_series = url + "/api/{0}series/{1}?apikey={2}".format( + '' if sonarr_version.startswith('2') else 'v3/', sonarr_series_id if sonarr_series_id else "", apikey_sonarr) try: r = requests.get(url_sonarr_api_series, timeout=60, verify=False, headers=headers) r.raise_for_status() diff --git a/bazarr/main.py b/bazarr/main.py index 62d2b18eb..71632d97e 100644 --- a/bazarr/main.py +++ b/bazarr/main.py @@ -43,7 +43,7 @@ from signalr_client import sonarr_signalr_client, radarr_signalr_client from check_update import apply_update, check_if_new_update, check_releases from server import app, webserver from functools import wraps -from utils import check_credentials, get_radarr_version +from utils import check_credentials, get_sonarr_version, get_radarr_version # Install downloaded update if bazarr_version != '': @@ -131,7 +131,13 @@ def series_images(url): url = url.strip("/") apikey = settings.sonarr.apikey baseUrl = settings.sonarr.base_url - url_image = (url_sonarr() + '/api/' + url.lstrip(baseUrl) + '?apikey=' + apikey).replace('poster-250', 'poster-500') + sonarr_version = get_sonarr_version() + if sonarr_version.startswith('2'): + url_image = (url_sonarr() + '/api/' + url.lstrip(baseUrl) + '?apikey=' + + apikey).replace('poster-250', 'poster-500') + else: + url_image = (url_sonarr() + '/api/v3/' + url.lstrip(baseUrl) + '?apikey=' + + apikey).replace('poster-250', 'poster-500') try: req = requests.get(url_image, stream=True, timeout=15, verify=False, headers=headers) except: diff --git a/bazarr/utils.py b/bazarr/utils.py index 4674d5c79..88e55ed84 100644 --- a/bazarr/utils.py +++ b/bazarr/utils.py @@ -241,7 +241,12 @@ def get_sonarr_version(): if settings.general.getboolean('use_sonarr'): try: sv = url_sonarr() + "/api/system/status?apikey=" + settings.sonarr.apikey - sonarr_version = requests.get(sv, timeout=60, verify=False, headers=headers).json()['version'] + sonarr_json = requests.get(sv, timeout=60, verify=False, headers=headers).json() + if 'version' in sonarr_json: + sonarr_version = sonarr_json['version'] + else: + sv = url_sonarr() + "/api/v3/system/status?apikey=" + settings.sonarr.apikey + sonarr_version = requests.get(sv, timeout=60, verify=False, headers=headers).json()['version'] except Exception: logging.debug('BAZARR cannot get Sonarr version') sonarr_version = 'unknown' @@ -252,7 +257,10 @@ def get_sonarr_platform(): sonarr_platform = '' if settings.general.getboolean('use_sonarr'): try: - sv = url_sonarr() + "/api/system/status?apikey=" + settings.sonarr.apikey + if get_sonarr_version().startswith('2'): + sv = url_sonarr() + "/api/system/status?apikey=" + settings.sonarr.apikey + else: + sv = url_sonarr() + "/api/v3/system/status?apikey=" + settings.sonarr.apikey response = requests.get(sv, timeout=60, verify=False, headers=headers).json() if response['isLinux'] or response['isOsx']: sonarr_platform = 'posix' @@ -265,7 +273,10 @@ def get_sonarr_platform(): def notify_sonarr(sonarr_series_id): try: - url = url_sonarr() + "/api/command?apikey=" + settings.sonarr.apikey + if get_sonarr_version().startswith('2'): + url = url_sonarr() + "/api/command?apikey=" + settings.sonarr.apikey + else: + url = url_sonarr() + "/api/v3/command?apikey=" + settings.sonarr.apikey data = { 'name': 'RescanSeries', 'seriesId': int(sonarr_series_id) |