aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormorpheus65535 <[email protected]>2020-10-05 21:53:23 -0400
committerGitHub <[email protected]>2020-10-05 21:53:23 -0400
commit99318bbde1f7a1410aba7112cb14d4450a509352 (patch)
tree56ada2ed89bf8033011e0eacb973940e8ba57970
parentc323cd851895aaf4e2730927a962e2213cf98970 (diff)
parent27d078b719bf74d667ec5897d6fa00a6098a424e (diff)
downloadbazarr-99318bbde1f7a1410aba7112cb14d4450a509352.tar.gz
bazarr-99318bbde1f7a1410aba7112cb14d4450a509352.zip
Merge pull request #1139 from vitiko98/tusubtitulo
Adding TuSubtitulo provider
-rw-r--r--README.md1
-rw-r--r--libs/subliminal_patch/providers/tusubtitulo.py252
-rw-r--r--views/settingsproviders.html12
3 files changed, 265 insertions, 0 deletions
diff --git a/README.md b/README.md
index 336497efe..afaad0d29 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,7 @@ If you need something that is not already part of Bazarr, feel free to create a
* Supersubtitles
* Titlovi
* Titrari.ro
+* TuSubtitulo
* TVSubtitles
* Wizdom
* XSubs
diff --git a/libs/subliminal_patch/providers/tusubtitulo.py b/libs/subliminal_patch/providers/tusubtitulo.py
new file mode 100644
index 000000000..e78884324
--- /dev/null
+++ b/libs/subliminal_patch/providers/tusubtitulo.py
@@ -0,0 +1,252 @@
+# -*- coding: utf-8 -*-
+import logging
+from urllib import parse
+import re
+from bs4 import BeautifulSoup as bso
+
+from requests import Session
+from subzero.language import Language
+
+from subliminal import Episode
+from subliminal.exceptions import ServiceUnavailable
+from subliminal_patch.subtitle import Subtitle
+from subliminal.subtitle import fix_line_ending
+from subliminal_patch.providers import Provider
+
+logger = logging.getLogger(__name__)
+
+
+BASE = "https://www.tusubtitulo.com/series.php?/"
+
+
+class TuSubtituloSubtitle(Subtitle):
+ provider_name = "tusubtitulo"
+
+ def __init__(self, language, filename, download_link, page_link, matches):
+ super(TuSubtituloSubtitle, self).__init__(
+ language, hearing_impaired=False, page_link=page_link
+ )
+ self.download_link = download_link
+ self.page_link = page_link
+ self.language = language
+ self.release_info = filename
+ self.filename = filename
+ self.found_matches = matches
+
+ @property
+ def id(self):
+ return self.download_link
+
+ def get_matches(self, video):
+ if video.resolution and video.resolution.lower() in self.release_info.lower():
+ self.found_matches.add("resolution")
+
+ if video.source and video.source.lower() in self.release_info.lower():
+ self.found_matches.add("source")
+
+ if video.video_codec:
+ if video.video_codec == "H.264" and "x264" in self.release_info.lower():
+ self.found_matches.add("video_codec")
+ elif video.video_codec == "H.265" and "x265" in self.release_info.lower():
+ self.found_matches.add("video_codec")
+ elif video.video_codec.lower() in self.release_info.lower():
+ self.found_matches.add("video_codec")
+
+ if video.audio_codec:
+ if video.audio_codec.lower().replace(" ", ".") in self.release_info.lower():
+ self.found_matches.add("audio_codec")
+ return self.found_matches
+
+
+class TuSubtituloProvider(Provider):
+ """TuSubtitulo.com Provider"""
+
+ BASE = "https://www.tusubtitulo.com/series.php?/"
+ languages = {Language.fromalpha2(l) for l in ["es"]}
+ language_list = list(languages)
+ logger.debug(languages)
+ video_types = (Episode,)
+
+ def initialize(self):
+ self.session = Session()
+ self.session.headers = {
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36",
+ "referer": "https://www.tusubtitulo.com",
+ }
+
+ def terminate(self):
+ self.session.close()
+
+ def index_titles(self):
+ r = self.session.get(BASE)
+ r.raise_for_status()
+ soup = bso(r.content, "html.parser")
+ titles = []
+ for a in soup.find_all("a"):
+ href_url = a.get("href")
+ if "show" in href_url:
+ titles.append({"title": a.text, "url": href_url})
+ return titles
+
+ def is_season_available(self, seasons, season):
+ for i in seasons:
+ if i == season:
+ return True
+
+ def title_available(self, item):
+ try:
+ title_content = item[2].find_all("a")[0]
+ episode_number = re.search(
+ r".*\d+x(0+)?(\d+) - .*?", title_content.text
+ ).group(2)
+ episode_id = title_content.get("href").split("/")[4]
+ return {
+ "episode_number": episode_number,
+ "episode_id": episode_id,
+ "episode_url": title_content.get("href"),
+ }
+ except IndexError:
+ return
+
+ def source_separator(self, item):
+ try:
+ text = item[3].text.replace("\n", "")
+ if "Vers" in text:
+ source = text.replace("VersiĆ³n ", "")
+ if not source:
+ source = "Unknown"
+ return source
+ except IndexError:
+ return
+
+ def get_episodes(self, show_id, season):
+ logger.debug("https://www.tusubtitulo.com/show/{}/{}".format(show_id, season))
+ r2 = self.session.get(
+ "https://www.tusubtitulo.com/show/{}/{}".format(show_id, season),
+ )
+ r2.raise_for_status()
+ sopa = bso(r2.content, "lxml")
+ tables = sopa.find_all("tr")
+ seasons = [i.text for i in tables[1].find_all("a")]
+ if not self.is_season_available(seasons, season):
+ logger.debug("Season not found")
+ return
+ season_subs = []
+ episodes = []
+
+ for tr in range(len(tables)):
+ data = tables[tr].find_all("td")
+ title = self.title_available(data)
+ if title:
+ episodes.append(title)
+ source_var = self.source_separator(data)
+ if source_var:
+ inc = 1
+ while True:
+ try:
+ content = tables[tr + inc].find_all("td")
+ language = content[4].text
+ completed = content[5]
+ url = content[6].find_all("a")[0].get("href")
+ sub_id = parse.parse_qs(parse.urlparse(url).query)["id"][0]
+ lang_id = parse.parse_qs(parse.urlparse(url).query)["lang"][0]
+ version_ = parse.parse_qs(parse.urlparse(url).query)["version"][
+ 0
+ ]
+ download_url = (
+ "https://www.tusubtitulo.com/updated/{}/{}/{}".format(
+ lang_id, sub_id, version_
+ )
+ )
+ if "esp" in language.lower():
+ season_subs.append(
+ {
+ "episode_id": sub_id,
+ "metadata": source_var,
+ "download_url": download_url,
+ }
+ )
+ inc += 1
+ except IndexError:
+ break
+
+ final_list = []
+ for i in episodes:
+ for t in season_subs:
+ if i["episode_id"] == t["episode_id"]:
+ final_list.append(
+ {
+ "episode_number": i["episode_number"],
+ "episode_url": i["episode_url"],
+ "metadata": t["metadata"],
+ "download_url": t["download_url"],
+ }
+ )
+ return final_list
+
+ def search(self, title, season, episode):
+ titles = self.index_titles()
+ found_tv_show = None
+ for i in titles:
+ if title.lower() == i["title"].lower():
+ found_tv_show = i
+ break
+ if not found_tv_show:
+ logger.debug("Show not found")
+ return
+ tv_show_id = found_tv_show["url"].split("/")[2].replace(" ", "")
+ results = self.get_episodes(tv_show_id, season)
+ episode_list = []
+ if results:
+ for i in results:
+ if i["episode_number"] == episode:
+ episode_list.append(i)
+ if episode_list:
+ return episode_list
+ logger.debug("Episode not found")
+
+ def query(self, languages, video):
+ language = self.language_list[0]
+ query = "{} {} {}".format(video.series, video.season, video.episode)
+ logger.debug("Searching subtitles: {}".format(query))
+ results = self.search(video.series, str(video.season), str(video.episode))
+
+ if results:
+ subtitles = []
+ for i in results:
+ matches = set()
+ # self.search only returns results for the specific episode
+ matches.add("title")
+ matches.add("series")
+ matches.add("season")
+ matches.add("episode")
+ matches.add("year")
+ subtitles.append(
+ TuSubtituloSubtitle(
+ language,
+ i["metadata"],
+ i["download_url"],
+ i["episode_url"],
+ matches,
+ )
+ )
+ return subtitles
+ else:
+ logger.debug("No subtitles found")
+ return []
+
+ def list_subtitles(self, video, languages):
+ return self.query(languages, video)
+
+ def _check_response(self, response):
+ if response.status_code != 200:
+ raise ServiceUnavailable("Bad status code: " + str(response.status_code))
+
+ def download_subtitle(self, subtitle):
+ logger.info("Downloading subtitle %r", subtitle)
+ response = self.session.get(
+ subtitle.download_link, headers={"Referer": subtitle.page_link}, timeout=10
+ )
+ response.raise_for_status()
+ self._check_response(response)
+ subtitle.content = fix_line_ending(response.content)
diff --git a/views/settingsproviders.html b/views/settingsproviders.html
index 727ca6f66..d7946c7f2 100644
--- a/views/settingsproviders.html
+++ b/views/settingsproviders.html
@@ -591,6 +591,18 @@
<div class="row">
<div class="col-sm-3 text-right">
+ <b>Tusubtitulo.com</b>
+ </div>
+ <div class="form-group col-sm-8">
+ <label class="custom-control custom-checkbox">
+ <input type="checkbox" class="custom-control-input provider" id="tusubtitulo">
+ <span class="custom-control-label">Spanish subtitles provider.</span>
+ </label>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-sm-3 text-right">
<b>TVSubtitles</b>
</div>
<div class="form-group col-sm-1">