From 0887c50d5c0c0fca1940f78ca0aa4ae8d2f92906 Mon Sep 17 00:00:00 2001 From: Luca <l.dimarino@gmail.com> Date: Wed, 15 May 2013 15:36:20 +0200 Subject: [PATCH] Add ITASA Service to Subliminal (Only Italian Subtitles) --- gui/slick/images/subtitles/itasa.png | Bin 0 -> 1150 bytes lib/subliminal/core.py | 2 +- lib/subliminal/services/itasa.py | 177 +++++++++++++++++++++++++++ 3 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 gui/slick/images/subtitles/itasa.png create mode 100644 lib/subliminal/services/itasa.py diff --git a/gui/slick/images/subtitles/itasa.png b/gui/slick/images/subtitles/itasa.png new file mode 100644 index 0000000000000000000000000000000000000000..908a52adae06ff1de52837cdd35b7942a7ec43ce GIT binary patch literal 1150 zcmZQzU}Ruq5D);-3Je)63=Con3=A3!3=9Gc3=9ek5OD?&U;z=R`2YX^3^4rn?{DTe z_Yc@#+>}0R-z1HjJ31v^?VX@<@9diB<<D<y^#A+kCo4=XI{o9zOVNw#;}`B|<N3C& znf3qnR<0krdn8`%>6Ll9vqRw1_7;v`r<eO~`S#(V9J=0L-{13}S?<1bR~y^k0~2MQ z-`Zc>`r+AWqwk-dN`lP&`u4W+(~FDZPA;@Na(u4I+3z18OCg(adw*%~zHZjP=T^Gz z`S$*<B1rDfudkdRpB}e(dw-YPm)DoI|NZ;R@aOk;_J=2Ximq;nUGneWUq+C+uWzqw z9G$}Z_0k&G-G6?5<^kb{#~bQT%#?h2a<=T_>)T?M+&xs*_2^_<<;SN-t^WP}&HVEE zvZ(hDce{Y}KR(q^e`dbq%Wv;)s{a1|R`A9a-z}$R@qc=Js;TbR_qReI^*=s6l>77R zE7#xO-`PR-g2dk5SsMh>e{+k=?#Cy}x<T%He7vad+&rGIZ*DJ*0?GaObYK4I>6(@= zug@BR^!)ktnd|GT)5hQ5U)KQ1fz;ewuXX+FtK$|wKiyTlx=irx<0C1vL1z8>_FUrL zPM1ADKi!xA{{E`g?;mdk-``sv`RnU*agbTRzC4!t{r$DbgIzX<{{H&R_5SwE)SD}L zzJ7mqQ4gg5#p$f+Z?AP1fz-agJu~Iw{iTt=KHrxI*$Knn-<~ymb3S*{-#_2k-(Ie6 zd9+>i_TS&1x&Hq8$oFuo{DU9wFY5jJd{^oH&F<0<w<qTQ`SDs9rWZtieYVx>%j4zY ze}8}F`f$Cr>BS-IBOvkLU+>F5+RXX&&-bU2Aokm{u?xRGT^scM<xY2yJP7~$^PT<c z)78O$f4&t0sr&YHY2@p}x|jd`{mJ_0$4k){yZAr+`gmR+6y9%6*dO@$_MqM8+s(CK zA56^q{(N=FmwVkse}BFf0htBDe}6m|e}7E(@}F;a6+vcvIBmcG>)pmWklfF=d!61L z)x7@m<=TMXpDybC{&?Qt_veeczuq0T0m;MgkH?d9e?00f0`Y&n-Rbt}xbodUU$1L` z_`g3Kwfb@;e8uPUj(fjePoDGh#mZ1n*n;F>7-a9y$K54=KA$%L#lg>KGgH2vH$U;` z!+!gJe}A%r)cyPOl@sJA5E~o*_wP6JpO1%a{{4C@1d{*z^{VEtC!M9go=wjF^Xa(x zzrR1(K;kg`!=8cR0Y3x7;pYqt{l6I)=GZeZZ2r%{pkB|wkoKQ}A@@H6gYSO^hO_$_ Y7~X>LeFlbqj~N*L*E2Bu|Ifex04ZzgqW}N^ literal 0 HcmV?d00001 diff --git a/lib/subliminal/core.py b/lib/subliminal/core.py index 1b8c840d1..80c7f024f 100644 --- a/lib/subliminal/core.py +++ b/lib/subliminal/core.py @@ -32,7 +32,7 @@ __all__ = ['SERVICES', 'LANGUAGE_INDEX', 'SERVICE_INDEX', 'SERVICE_CONFIDENCE', 'create_list_tasks', 'create_download_tasks', 'consume_task', 'matching_confidence', 'key_subtitles', 'group_by_video'] logger = logging.getLogger("subliminal") -SERVICES = ['opensubtitles', 'bierdopje', 'subswiki', 'subtitulos', 'thesubdb', 'addic7ed', 'tvsubtitles'] +SERVICES = ['opensubtitles', 'bierdopje', 'subswiki', 'subtitulos', 'thesubdb', 'addic7ed', 'tvsubtitles', 'itasa'] LANGUAGE_INDEX, SERVICE_INDEX, SERVICE_CONFIDENCE, MATCHING_CONFIDENCE = range(4) diff --git a/lib/subliminal/services/itasa.py b/lib/subliminal/services/itasa.py new file mode 100644 index 000000000..880537d27 --- /dev/null +++ b/lib/subliminal/services/itasa.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# Copyright 2012 Mr_Orange <mr_orange@hotmail.it> +# +# This file is part of subliminal. +# +# subliminal is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# subliminal is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with subliminal. If not, see <http://www.gnu.org/licenses/>. +from . import ServiceBase +from ..cache import cachedmethod +from ..language import language_set, Language +from ..subtitles import get_subtitle_path, ResultSubtitle +from ..utils import get_keywords +from ..videos import Episode +from bs4 import BeautifulSoup +import logging +import re +import requests + +from sickbeard.common import Quality + +logger = logging.getLogger("subliminal") + + +class Itasa(ServiceBase): + server_url = 'http://www.italiansubs.net/' + site_url = 'http://www.italiansubs.net/' + api_based = False + languages = language_set(['it']) + videos = [Episode] + require_video = False + required_features = ['permissive'] + quality_dict = {Quality.SDTV : '', + Quality.SDDVD : 'dvdrip', + Quality.RAWHDTV : '1080i', + Quality.HDTV : '720p', + Quality.FULLHDTV : '720p', + Quality.HDWEBDL : 'web-dl', + Quality.FULLHDWEBDL : 'web-dl', + Quality.HDBLURAY : 'bluray', + Quality.FULLHDBLURAY : 'bluray' + } + + def init(self): + + super(Itasa, self).init() + username = 'sickbeard' + password = 'subliminal' + login_pattern = '<input type="hidden" name="return" value="([^\n\r\t ]+?)" /><input type="hidden" name="([^\n\r\t ]+?)" value="([^\n\r\t ]+?)" />' + + response = requests.get(self.server_url + 'index.php') + if response.status_code != 200: + raise ServiceError('Initiate failed') + + match = re.search(login_pattern, response.content, re.IGNORECASE | re.DOTALL) + if not match: + raise ServiceError('Can not find unique id parameter on page') + + log_parameter = {'username': 'mr_orange', + 'passwd': '121176', + 'remember': 'yes', + 'Submit': 'Login', + 'remember': 'yes', + 'option': 'com_user', + 'task': 'login', + 'silent': 'true', + 'return': match.group(1), match.group(2): match.group(3) + } + + self.session = requests.session() + r = self.session.post(self.server_url + 'index.php', data=log_parameter) + if not re.search('logouticon.png', r.content, re.IGNORECASE | re.DOTALL): + raise ServiceError('Itasa Login Failed') + + @cachedmethod + def get_series_id(self, name): + """Get the show page and cache every show found in it""" + r = self.session.get(self.server_url + 'index.php?option=com_remository&Itemid=9') + soup = BeautifulSoup(r.content, self.required_features) + all_series = soup.find('div', attrs = {'id' : 'remositorycontainerlist'}) + for tv_series in all_series.find_all(href=re.compile('func=select')): + series_name = tv_series.text.lower().strip() + match = re.search('&id=([0-9]+)', tv_series['href']) + if match is None: + continue + series_id = int(match.group(1)) + self.cache_for(self.get_series_id, args=(series_name,), result=series_id) + return self.cached_value(self.get_series_id, args=(name,)) + + def get_episode_id(self, series, series_id, season, episode, quality): + """Get the episode subtitle with the given quality""" + + season_link = None + quality_link = None + episode_id = None + + r = self.session.get(self.server_url + 'index.php?option=com_remository&Itemid=6&func=select&id=' + str(series_id)) + soup = BeautifulSoup(r.content, self.required_features) + all_seasons = soup.find('div', attrs = {'id' : 'remositorycontainerlist'}) + for seasons in all_seasons.find_all(href=re.compile('func=select')): + if seasons.text.lower().strip() == 'stagione %s' % str(season): + season_link = seasons['href'] + break + + if not season_link: + logger.debug(u'Could not find season %s for series %s' % (series, str(season))) + return None + + r = self.session.get(season_link) + soup = BeautifulSoup(r.content, self.required_features) + + all_qualities = soup.find('div', attrs = {'id' : 'remositorycontainerlist'}) + for qualities in all_qualities.find_all(href=re.compile('func=select')): + if qualities.text.lower().strip() == self.quality_dict[quality]: + quality_link = qualities['href'] + r = self.session.get(qualities['href']) + soup = BeautifulSoup(r.content, self.required_features) + break + + if not quality == Quality.SDTV and not quality_link: + logger.debug(u'Could not find a subtitle with required quality for series %s season %s' % (series, str(season))) + return None + + all_episodes = soup.find('div', attrs = {'id' : 'remositoryfilelisting'}) + for episodes in all_episodes.find_all(href=re.compile('func=fileinfo')): + ep_string = "%(seasonnumber)dx%(episodenumber)02d" % {'seasonnumber': season, 'episodenumber': episode} + if re.search(ep_string, episodes.text): + match = re.search('&id=([0-9]+)', episodes['href']) + if match: + episode_id = match.group(1) + return episode_id + + return episode_id + + def list_checked(self, video, languages): + return self.query(video.path or video.release, languages, get_keywords(video.guess), video.series, video.season, video.episode) + + def query(self, filepath, languages, keywords, series, season, episode): + + logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) + self.init_cache() + try: + series_id = self.get_series_id(series.lower()) + except KeyError: + logger.debug(u'Could not find series id for %s' % series) + return [] + + episode_id = self.get_episode_id(series.lower(), series_id, season, episode, Quality.nameQuality(filepath)) + if not episode_id: + logger.debug(u'Could not find subtitle for series %s' % series) + return [] + + r = self.session.get(self.server_url + 'index.php?option=com_remository&Itemid=6&func=fileinfo&id=' + episode_id) + soup = BeautifulSoup(r.content) + + sub_link = soup.find('div', attrs = {'id' : 'remositoryfileinfo'}).find(href=re.compile('func=download'))['href'] + sub_language = self.get_language('it') + path = get_subtitle_path(filepath, sub_language, self.config.multi) + subtitle = ResultSubtitle(path, sub_language, self.__class__.__name__.lower(), sub_link) + + return [subtitle] + + def download(self, subtitle): + self.download_zip_file(subtitle.link, subtitle.path) + return subtitle + + +Service = Itasa \ No newline at end of file -- GitLab