mirror of https://github.com/morpheus65535/bazarr
Upgraded calls to Sonarr API in order to use the new v3 API when available.
This commit is contained in:
parent
26e978b14b
commit
ee41b78f4e
|
@ -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 != "":
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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']) \
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue