Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added multilanguage Support - Sonarr API v3 Parameter #52

Merged
merged 3 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .vs/searcharr-languageProfile/v16/.suo
Binary file not shown.
Binary file added .vs/slnx.sqlite
Binary file not shown.
2 changes: 2 additions & 0 deletions lang/en-us.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ convo_not_found: I received your command, but I don't recognize the conversation
search_canceled: Search canceled!
no_root_folders: "Error adding {kind}: no root folders enabled for {app}! Please check your Searcharr configuration and try again."
no_quality_profiles: "Error adding {kind}: no quality profiles enabled for {app}! Please check your Searcharr configuration and try again."
no_language_profiles: "Error adding {kind}: no language profiles enabled for {app}! Please check your Searcharr configuration and try again."
all_seasons: All Seasons
first_season: First Season Only
latest_season: Latest Season Only
Expand All @@ -43,6 +44,7 @@ add_tag_button: "Add Tag: {tag}"
finished_tagging_button: Finished Tagging
monitor_button: Monitor {option}
add_quality_button: "Add Quality: {quality}"
select_language_button: "Select Language: {language}"
add_path_button: Add to {path}
add_button: Add {kind}!
already_added_button: Already Added!
Expand Down
103 changes: 103 additions & 0 deletions searcharr.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,35 @@ def __init__(self, token):
)
self.sonarr._quality_profiles = quality_profiles

language_profiles = []
if not isinstance(settings.sonarr_language_profile_id, list):
settings.sonarr_language_profile_id = [
settings.sonarr_language_profile_id
]
for i in settings.sonarr_language_profile_id:
logger.debug(
f"Looking up/validating Sonarr language profile id for [{i}]..."
)
foundProfile = self.sonarr.lookup_language_profile(i)
if not foundProfile:
logger.error(f"Sonarr language profile id/name [{i}] is invalid!")
else:
logger.debug(
f"Found Sonarr language profile for [{i}]: [{foundProfile}]"
)
language_profiles.append(foundProfile)
if not len(language_profiles):
logger.warning(
f"No valid Sonarr language profile(s) provided! Using all of the language profiles I found in Sonarr: {self.sonarr._language_profiles}"
)
else:
logger.debug(
f"Using the following Sonarr language profile(s): {[(x['id'], x['name']) for x in language_profiles]}"
)
self.sonarr._language_profiles = language_profiles



root_folders = []
if not hasattr(settings, "sonarr_series_paths"):
settings.sonarr_series_paths = []
Expand Down Expand Up @@ -1077,6 +1106,68 @@ def callback(self, update, context):
query.answer()
return

if not additional_data.get("l"):
language_profiles = (
self.sonarr._language_profiles
if convo["type"] == "series"
else self.radarr._language_profiles
)
if len(language_profiles) > 1:
# prepare response to prompt user to select language profile, and return
reply_message, reply_markup = self._prepare_response(
convo["type"],
r,
cid,
i,
len(convo["results"]),
add=True,
language_profiles=language_profiles,
)
try:
query.message.edit_media(
media=InputMediaPhoto(r["remotePoster"]),
reply_markup=reply_markup,
)
except BadRequest as e:
if str(e) in self._bad_request_poster_error_messages:
logger.error(
f"Error sending photo [{r['remotePoster']}]: BadRequest: {e}. Attempting to send with default poster..."
)
query.message.edit_media(
media=InputMediaPhoto(
"https://artworks.thetvdb.com/banners/images/missing/movie.jpg"
),
reply_markup=reply_markup,
)
else:
raise
query.bot.edit_message_caption(
chat_id=query.message.chat_id,
message_id=query.message.message_id,
caption=reply_message,
reply_markup=reply_markup,
)
query.answer()
return
elif len(language_profiles) == 1:
logger.debug(
f"Only one language profile enabled. Adding/Updating additional data for cid=[{cid}], key=[q], value=[{language_profiles[0]['id']}]..."
)
self._update_add_data(cid, "l", language_profiles[0]["id"])
else:
self._delete_conversation(cid)
query.message.reply_text(
self._xlate(
"no_language_profiles",
kind=self._xlate(convo["type"]),
app="Sonarr" if convo["type"] == "series" else "Radarr",
)
)
query.message.delete()
query.answer()
return


if (
convo["type"] == "series"
and settings.sonarr_season_monitor_prompt
Expand Down Expand Up @@ -1418,6 +1509,7 @@ def _prepare_response(
add=False,
paths=None,
quality_profiles=None,
language_profiles=None,
metadata_profiles=None,
monitor_options=None,
tags=None,
Expand Down Expand Up @@ -1503,6 +1595,17 @@ def _prepare_response(
)
],
)
elif language_profiles:
for l in language_profiles:
keyboard.append(
[
InlineKeyboardButton(
self._xlate("select_language_button", language=l["name"]),
callback_data=f"{cid}^^^{i}^^^add^^l={l['id']}",

)
],
)
elif metadata_profiles:
for m in metadata_profiles:
keyboard.append(
Expand Down
1 change: 1 addition & 0 deletions settings-sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
sonarr_url = "" # http://192.168.0.100:8989
sonarr_api_key = ""
sonarr_quality_profile_id = ["HD - 720p/1080p"] # can be name or id value - include multiple to allow the user to choose
sonarr_language_profile_id = ["English", "German"] # select languages, include multiple to allow the user to choose
sonarr_add_monitored = True
sonarr_search_on_add = True
sonarr_tag_with_username = True
Expand Down
16 changes: 15 additions & 1 deletion sonarr.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ def __init__(self, api_url, api_key, verbose=False):
)
self.api_url = api_url + "/api/{endpoint}?apikey=" + api_key
self._quality_profiles = self.get_all_quality_profiles()
self._language_profiles = self.get_all_language_profiles()
self._root_folders = self.get_root_folders()
self._all_series = {}
self.get_all_series()



def lookup_series(self, title=None, tvdb_id=None):
r = self._api_get(
"series/lookup", {"term": f"tvdb:{tvdb_id}" if tvdb_id else quote(title)}
Expand Down Expand Up @@ -100,6 +102,7 @@ def add_series(

path = additional_data["p"]
quality = int(additional_data["q"])
language = int(additional_data["l"])
monitor_options = int(additional_data.get("m", 0))
if monitor_options == 1:
# Monitor only the first season
Expand Down Expand Up @@ -130,6 +133,7 @@ def add_series(
"tvdbId": series_info["tvdbId"],
"title": series_info["title"],
"qualityProfileId": quality,
"languageProfileId": language,
"titleSlug": series_info["titleSlug"],
"images": series_info["images"],
"seasons": series_info["seasons"],
Expand Down Expand Up @@ -226,9 +230,19 @@ def lookup_quality_profile(self, v):
None,
)

def lookup_language_profile(self, v):
# Look up language profile from a profile name or id
return next(
(x for x in self._language_profiles if str(v) in [x["name"], str(x["id"])]),
None,
)

def get_all_quality_profiles(self):
return self._api_get("profile", {}) or None

def get_all_language_profiles(self):
return self._api_get("v3/languageprofile", {}) or None

def lookup_root_folder(self, v):
# Look up root folder from a path or id
return next(
Expand Down