# coding=utf-8 from __future__ import absolute_import from json import JSONDecodeError import logging import os import urllib.parse from requests import Session from subliminal import Episode from subliminal import Movie from subliminal_patch.providers import Provider from subliminal_patch.providers.mixins import ProviderSubtitleArchiveMixin from subliminal_patch.providers.utils import get_archive_from_bytes from subliminal_patch.providers.utils import get_subtitle_from_archive from subliminal_patch.providers.utils import update_matches from subliminal_patch.subtitle import Subtitle from subzero.language import Language BASE_URL = "https://argenteam.net" API_URL = f"{BASE_URL}/api/v1" logger = logging.getLogger(__name__) class ArgenteamSubtitle(Subtitle): provider_name = "argenteam" hearing_impaired_verifiable = False def __init__(self, language, page_link, download_link, release_info, matches): super(ArgenteamSubtitle, self).__init__(language, page_link=page_link) self._found_matches = matches self.page_link = page_link self.download_link = download_link self.release_info = release_info @property def id(self): return self.download_link def get_matches(self, video): update_matches(self._found_matches, video, self.release_info) return self._found_matches class ArgenteamProvider(Provider, ProviderSubtitleArchiveMixin): provider_name = "argenteam" languages = {Language("spa", "MX")} video_types = (Episode, Movie) subtitle_class = ArgenteamSubtitle _default_lang = Language("spa", "MX") def __init__(self): self.session = Session() def initialize(self): self.session.headers.update( {"User-Agent": os.environ.get("SZ_USER_AGENT", "Sub-Zero/2")} ) def terminate(self): self.session.close() def query(self, video): is_episode = isinstance(video, Episode) imdb_id = video.series_imdb_id if is_episode else video.imdb_id if not imdb_id: logger.debug("%s doesn't have IMDB ID. Can't search") return [] if is_episode: argenteam_ids = self._search_ids( imdb_id, season=video.season, episode=video.episode ) else: argenteam_ids = self._search_ids(imdb_id) if not argenteam_ids: logger.debug("No IDs found") return [] return self._parse_subtitles(argenteam_ids, is_episode) def _parse_subtitles(self, ids, is_episode=True): movie_kind = "episode" if is_episode else "movie" subtitles = [] for aid in ids: response = self.session.get( f"{API_URL}/{movie_kind}", params={"id": aid}, timeout=10 ) response.raise_for_status() try: content = response.json() except JSONDecodeError: continue if not content or not content.get("releases"): continue for r in content["releases"]: for s in r["subtitles"]: page_link = f"{BASE_URL}/{movie_kind}/{aid}" release_info = self._combine_release_info(r, s) logger.debug("Got release info: %s", release_info) download_link = s["uri"].replace("http://", "https://") # Already matched within query if is_episode: matches = {"series", "title", "season", "episode", "imdb_id", "year"} else: matches = {"title", "year", "imdb_id"} subtitles.append( ArgenteamSubtitle( self._default_lang, page_link, download_link, release_info, matches, ) ) return subtitles def list_subtitles(self, video, languages): return self.query(video) def download_subtitle(self, subtitle): r = self.session.get(subtitle.download_link, timeout=10) r.raise_for_status() archive = get_archive_from_bytes(r.content) subtitle.content = get_subtitle_from_archive(archive) def _search_ids(self, identifier, **kwargs): """ :param identifier: imdb_id or title (without year) """ identifier = identifier.lstrip("tt") query = identifier if kwargs.get("season") and kwargs.get("episode"): query = f"{identifier} S{kwargs['season']:02}E{kwargs['episode']:02}" logger.debug("Searching ID for %s", query) r = self.session.get(f"{API_URL}/search", params={"q": query}, timeout=10) r.raise_for_status() try: results = r.json() except JSONDecodeError: return [] if not results.get("results"): return [] match_ids = [result["id"] for result in results["results"]] logger.debug("Found matching IDs: %s", match_ids) return match_ids def _combine_release_info(self, release_dict, subtitle_dict): releases = [ urllib.parse.unquote(subtitle_dict.get("uri", "Unknown").split("/")[-1]) ] combine = [ release_dict.get(key) for key in ("source", "codec", "tags") if release_dict.get(key) ] if combine: r_info = ".".join(combine) if release_dict.get("team"): r_info += f"-{release_dict['team']}" releases.append(r_info) return "\n".join(releases)