Skip to content
Browse files

Fix PodnapisiWeb and add unittests

  • Loading branch information...
1 parent 35f2e47 commit 38cc8422b655b9c52860d87579b1925c421a8196 @Diaoul committed Sep 23, 2012
Showing with 109 additions and 125 deletions.
  1. +70 −113 subliminal/services/podnapisiweb.py
  2. +39 −12 tests/test_services.py
View
183 subliminal/services/podnapisiweb.py
@@ -18,149 +18,106 @@
from . import ServiceBase
from ..exceptions import DownloadFailedError
from ..language import Language, language_set
-from ..subtitles import get_subtitle_path, ResultSubtitle
+from ..subtitles import ResultSubtitle
+from ..utils import get_keywords
from ..videos import Episode, Movie
from bs4 import BeautifulSoup
+import guessit
import logging
-import os.path
import re
+from subliminal.subtitles import get_subtitle_path
logger = logging.getLogger(__name__)
class PodnapisiWeb(ServiceBase):
server_url = 'http://simple.podnapisi.net'
- search_path = 'http://simple.podnapisi.net/ppodnapisi/search?'
- api_based = False
+ api_based = True
+ user_agent = 'Subliminal/0.6'
videos = [Episode, Movie]
require_video = False
required_features = ['xml']
- language_map = {
- Language('Albanian'): '29',
- Language('Arabic'): '12',
- Language('spanish-Argentina'): '14',
- Language('Belarusian'): '50',
- Language('Bosnian'): '10',
- Language('portuguese-Brazil'): '48',
- Language('Bulgarian'): '33',
- Language('Catalan'): '53',
- Language('Chinese'): '17',
- Language('Croatian'): '38',
- Language('Czech'): '7',
- Language('Danish'): '24',
- Language('Dutch'): '23',
- Language('English'): '2',
- Language('Estonian'): '20',
- Language('Persian'): '52',
- Language('Finnish'): '31',
- Language('French'): '8',
- Language('German'): '5',
- Language('gre'): '16',
- Language('kal'): '57',
- Language('Hebrew'): '22',
- Language('Hindi'): '42',
- Language('Hungarian'): '15',
- Language('Icelandic'): '6',
- Language('Indonesian'): '54',
- Language('Irish'): '49',
- Language('Italian'): '9',
- Language('Japanese'): '11',
- Language('Kazakh'): '58',
- Language('Korean'): '4',
- Language('Latvian'): '21',
- Language('Lithuanian'): '19',
- Language('Macedonian'): '35',
- Language('Malay'): '55',
- Language('mdr'): '40',
- Language('Norwegian'): '3',
- Language('Polish'): '26',
- Language('Portuguese'): '32',
- Language('Romanian'): '13',
- Language('Russian'): '27',
- Language('srp'): '36',
- #Language('srp'): '47',
- Language('Sinhala'): '56',
- Language('Slovak'): '37',
- Language('Slovenian'): '1',
- Language('Spanish'): '28',
- Language('Swedish'): '25',
- Language('Thai'): '44',
- Language('Turkish'): '30',
- Language('Ukrainian'): '46',
- Language('Vietnamese'): '51',
- }
+ languages = language_set(['Albanian', 'Arabic', 'Spanish (Argentina)', 'Belarusian', 'Bosnian', 'Portuguese (Brazil)', 'Bulgarian', 'Catalan',
+ 'Chinese', 'Croatian', 'Czech', 'Danish', 'Dutch', 'English', 'Estonian', 'Persian',
+ 'Finnish', 'French', 'German', 'gre', 'Kalaallisut', 'Hebrew', 'Hindi', 'Hungarian',
+ 'Icelandic', 'Indonesian', 'Irish', 'Italian', 'Japanese', 'Kazakh', 'Korean', 'Latvian',
+ 'Lithuanian', 'Macedonian', 'Malay', 'Norwegian', 'Polish', 'Portuguese', 'Romanian',
+ 'Russian', 'Serbian', 'Sinhala', 'Slovak', 'Slovenian', 'Spanish', 'Swedish', 'Thai',
+ 'Turkish', 'Ukrainian', 'Vietnamese'])
+ language_map = {Language('Albanian'): 29, Language('Arabic'): 12, Language('Spanish (Argentina)'): 14, Language('Belarusian'): 50,
+ Language('Bosnian'): 10, Language('Portuguese (Brazil)'): 48, Language('Bulgarian'): 33, Language('Catalan'): 53,
+ Language('Chinese'): 17, Language('Croatian'): 38, Language('Czech'): 7, Language('Danish'): 24,
+ Language('Dutch'): 23, Language('English'): 2, Language('Estonian'): 20, Language('Persian'): 52,
+ Language('Finnish'): 31, Language('French'): 8, Language('German'): 5, Language('gre'): 16,
+ Language('Kalaallisut'): 57, Language('Hebrew'): 22, Language('Hindi'): 42, Language('Hungarian'): 15,
+ Language('Icelandic'): 6, Language('Indonesian'): 54, Language('Irish'): 49, Language('Italian'): 9,
+ Language('Japanese'): 11, Language('Kazakh'): 58, Language('Korean'): 4, Language('Latvian'): 21,
+ Language('Lithuanian'): 19, Language('Macedonian'): 35, Language('Malay'): 55,
+ Language('Norwegian'): 3, Language('Polish'): 26, Language('Portuguese'): 32, Language('Romanian'): 13,
+ Language('Russian'): 27, Language('Serbian'): 36, Language('Sinhala'): 56, Language('Slovak'): 37,
+ Language('Slovenian'): 1, Language('Spanish'): 28, Language('Swedish'): 25, Language('Thai'): 44,
+ Language('Turkish'): 30, Language('Ukrainian'): 46, Language('Vietnamese'): 51,
+ 29: Language('Albanian'), 12: Language('Arabic'), 14: Language('Spanish (Argentina)'), 50: Language('Belarusian'),
+ 10: Language('Bosnian'), 48: Language('Portuguese (Brazil)'), 33: Language('Bulgarian'), 53: Language('Catalan'),
+ 17: Language('Chinese'), 38: Language('Croatian'), 7: Language('Czech'), 24: Language('Danish'),
+ 23: Language('Dutch'), 2: Language('English'), 20: Language('Estonian'), 52: Language('Persian'),
+ 31: Language('Finnish'), 8: Language('French'), 5: Language('German'), 16: Language('gre'),
+ 57: Language('Kalaallisut'), 22: Language('Hebrew'), 42: Language('Hindi'), 15: Language('Hungarian'),
+ 6: Language('Icelandic'), 54: Language('Indonesian'), 49: Language('Irish'), 9: Language('Italian'),
+ 11: Language('Japanese'), 58: Language('Kazakh'), 4: Language('Korean'), 21: Language('Latvian'),
+ 19: Language('Lithuanian'), 35: Language('Macedonian'), 55: Language('Malay'), 40: Language('Chinese'),
+ 3: Language('Norwegian'), 26: Language('Polish'), 32: Language('Portuguese'), 13: Language('Romanian'),
+ 27: Language('Russian'), 36: Language('Serbian'), 47: Language('Serbian'), 56: Language('Sinhala'),
+ 37: Language('Slovak'), 1: Language('Slovenian'), 28: Language('Spanish'), 25: Language('Swedish'),
+ 44: Language('Thai'), 30: Language('Turkish'), 46: Language('Ukrainian'), Language('Vietnamese'): 51}
def list_checked(self, video, languages):
if isinstance(video, Movie):
- return self.query(video.path or video.release,
- languages=languages,
- title=video.title,
- year=video.year)
- else:
- return self.query(video.path or video.release,
- languages=languages,
- title=video.series,
- season=video.season,
- episode=video.episode)
+ return self.query(video.path or video.release, languages, video.title, year=video.year,
+ keywords=get_keywords(video.guess))
+ if isinstance(video, Episode):
+ return self.query(video.path or video.release, languages, video.series, season=video.season,
+ episode=video.episode, keywords=get_keywords(video.guess))
- def query(self, filepath, languages, title=None, season=None, episode=None, year=None):
- release, extension = os.path.splitext(os.path.basename(filepath))
- params = {'sXML': 1}
- if len(languages) == 1:
- params['sJ'] = self.get_code(list(languages)[0])
- else:
- params['sJ'] = 0
- if release is not None: params['sR'] = release
- if title is not None: params['sK'] = title
- if season is not None: params['sTS'] = season
- if episode is not None: params['sTE'] = episode
- if year is not None: params['sY'] = year
- # Only request the first page (30 results). This might be a problem if
- # multiple language are requested (sJ=0 won't filter by language, so a
- # lot of results might be returned).
- r = self.session.get(self.search_path, params=params)
+ def query(self, filepath, languages, title, season=None, episode=None, year=None, keywords=None):
+ params = {'sXML': 1, 'sK': title, 'sJ': ','.join([str(self.get_code(l)) for l in languages])}
+ if season is not None:
+ params['sTS'] = season
+ if episode is not None:
+ params['sTE'] = episode
+ if year is not None:
+ params['sY'] = year
+ if keywords is not None:
+ params['sR'] = keywords
+ r = self.session.get(self.server_url + '/ppodnapisi/search', params=params)
if r.status_code != 200:
logger.error(u'Request %s returned status code %d' % (r.url, r.status_code))
return []
-
- results = []
+ subtitles = []
soup = BeautifulSoup(r.content, self.required_features)
- for subtitle in soup('subtitle'):
- lang_code = subtitle.languageId.text
- language = self.get_language(lang_code)
- if language not in languages:
- continue
- found_title = subtitle.title.text.strip()
- if not self.match_title(title, found_title):
+ for sub in soup('subtitle'):
+ if 'n' in sub.flags:
+ logger.debug(u'Skipping hearing impaired')
continue
- download_link = subtitle.url.text
- found_releases = subtitle.release.text
- for frelease in found_releases:
- results.append(ResultSubtitle(
- path=get_subtitle_path(filepath, language, self.config.multi),
- language=language,
- service=self.__class__.__name__.lower(),
- link=download_link,
- release=frelease + extension))
- return results
+ language = self.get_language(sub.languageId.text)
+ confidence = float(sub.rating.text) / 5.0
+ sub_keywords = set()
+ for release in sub.release.text.split():
+ sub_keywords |= get_keywords(guessit.guess_file_info(release + '.srt', 'autodetect'))
+ sub_path = get_subtitle_path(filepath, language, self.config.multi)
+ subtitle = ResultSubtitle(sub_path, language, self.__class__.__name__.lower(),
+ sub.url.text, confidence=confidence, keywords=sub_keywords)
+ subtitles.append(subtitle)
+ return subtitles
def download(self, subtitle):
r = self.session.get(subtitle.link)
if r.status_code != 200:
raise DownloadFailedError()
soup = BeautifulSoup(r.content)
- real_link = self.server_url + soup.find('img', title='Download').parent['href']
- self.download_zip_file(real_link, subtitle.path)
+ self.download_zip_file(self.server_url + soup.find('a', href=re.compile('download'))['href'], subtitle.path)
return subtitle
- def match_title(self, a, b):
- def clean(x):
- return re.sub('[^a-zA-Z0-9]', '', x).lower()
- return clean(a) == clean(b)
-
-
-PodnapisiWeb.languages = language_set(PodnapisiWeb.language_map.keys())
-PodnapisiWeb.language_map.update(dict((v, k) for k, v in PodnapisiWeb.language_map.iteritems()))
Service = PodnapisiWeb
View
51 tests/test_services.py
@@ -300,24 +300,51 @@ def test_query_wrong_languages(self):
class PodnapisiWebTestCase(ServiceTestCase):
- query_tests = []
- list_tests = []
- download_tests = ['test_download_movie', 'test_download_episode']
+ query_tests = ['test_query_movie', 'test_query_series', 'test_query_wrong_series', 'test_query_wrong_languages']
+ list_tests = ['test_list_episode', 'test_list_movie', 'test_list_wrong_languages']
+ download_tests = ['test_download_episode', 'test_download_movie']
cache_tests = []
service = PodnapisiWeb
def setUp(self):
- super(ServiceTestCase, self).setUp()
+ super(PodnapisiWebTestCase, self).setUp()
self.config = ServiceConfig(multi=True, cache_dir=cache_dir)
- self.languages = language_set(['en'])
- self.movie_path = '/path/Ferris.Buellers.Day.Off.1986.BluRay.720p.x264.DTS-HDChina.mkv'
+ self.fake_file = u'/tmp/fake_file'
+ self.languages = language_set(['en', 'es'])
+ self.movie_path = u'Soul Surfer (2011)/Soul.Surfer.(2011).DVDRip.XviD-TWiZTED.mkv'
self.movie_sublanguage = 'en'
- self.movie_subfilesizes = [89637]
- self.episode_path = '/path/Game.of.Thrones.S01E01.720p.BluRay.DTS.x264-HDC.mkv'
- self.episode_sublanguage = 'en'
- self.season = 1
- self.episode = 1
- self.episode_subfilesizes = [44741]
+ self.movie_subfilesizes = [87528]
+ self.movie_keywords = set(['TWiZTED'])
+ self.movie = u'Soul Surfer'
+ self.movie_year = 2011
+ self.episode_path = u'The Big Bang Theory/Season 05/The.Big.Bang.Theory.S05E06.HDTV.XviD-ASAP.mkv'
+ self.episode_sublanguage = 'es'
+ self.episode_subfilesizes = [33098]
+ self.episode_keywords = set(['asap', 'hdtv'])
+ self.series = 'The Big Bang Theory'
+ self.wrong_series = 'No Existent Show Name'
+ self.season = 5
+ self.episode = 6
+
+ def test_query_series(self):
+ with self.service(self.config) as service:
+ results = service.query(self.fake_file, self.languages, self.series, self.season, self.episode, keywords=self.episode_keywords)
+ self.assertTrue(len(results) > 0)
+
+ def test_query_wrong_series(self):
+ with self.service(self.config) as service:
+ results = service.query(self.fake_file, self.languages, self.wrong_series, self.season, self.episode, keywords=self.episode_keywords)
+ self.assertTrue(len(results) == 0)
+
+ def test_query_wrong_languages(self):
+ with self.service(self.config) as service:
+ results = service.query(self.fake_file, self.wrong_languages, self.series, self.season, self.episode, keywords=self.episode_keywords)
+ self.assertTrue(len(results) == 0)
+
+ def test_query_movie(self):
+ with self.service(self.config) as service:
+ results = service.query(self.fake_file, self.languages, self.movie, year=self.movie_year, keywords=self.movie_keywords)
+ self.assertTrue(len(results) > 0)
class SubsWikiTestCase(ServiceTestCase):

0 comments on commit 38cc842

Please sign in to comment.
Something went wrong with that request. Please try again.