summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormorpheus65535 <[email protected]>2021-06-16 13:45:54 -0400
committermorpheus65535 <[email protected]>2021-06-16 13:45:54 -0400
commitee41b78f4e4fe015ce915d1721b880b6d2d4d40f (patch)
tree7534a4e85d4b6b245f9bdd0540f06b91257ae801
parent26e978b14b2289fa189a789f6f2c03570c55eb08 (diff)
downloadbazarr-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.py6
-rw-r--r--bazarr/filesystem.py25
-rw-r--r--bazarr/get_episodes.py81
-rw-r--r--bazarr/get_rootfolder.py15
-rw-r--r--bazarr/get_series.py16
-rw-r--r--bazarr/main.py10
-rw-r--r--bazarr/utils.py17
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)