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

Implements foreign parts only support with OpenSubtitles #977

Closed
wants to merge 3 commits into from
Closed
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
16 changes: 14 additions & 2 deletions subliminal/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def __init__(self, path):
self.config.set('general', 'providers', json.dumps(sorted([p.name for p in provider_manager])))
self.config.set('general', 'refiners', json.dumps(sorted([r.name for r in refiner_manager])))
self.config.set('general', 'single', str(0))
self.config.set('general', 'foreign_only', str(0))
self.config.set('general', 'embedded_subtitles', str(1))
self.config.set('general', 'age', str(int(timedelta(weeks=2).total_seconds())))
self.config.set('general', 'hearing_impaired', str(1))
Expand Down Expand Up @@ -135,6 +136,14 @@ def hearing_impaired(self):
def hearing_impaired(self, value):
self.config.set('general', 'hearing_impaired', str(int(value)))

@property
def foreign_only(self):
return self.config.getboolean('general', 'foreign_only')

@foreign_only.setter
def foreign_only(self, value):
self.config.set('general', 'foreign_only', str(int(value)))

@property
def min_score(self):
return self.config.getfloat('general', 'min_score')
Expand Down Expand Up @@ -285,6 +294,7 @@ def cache(ctx, clear_subliminal):
'name, i.e. use .srt extension. Do not use this unless your media player requires it.')
@click.option('-f', '--force', is_flag=True, default=False, help='Force download even if a subtitle already exist.')
@click.option('-hi', '--hearing-impaired', is_flag=True, default=False, help='Prefer hearing impaired subtitles.')
@click.option('-fo', '--foreign-only', is_flag=True, default=False, help='Prefer foreign parts only subtitles.')
@click.option('-m', '--min-score', type=click.IntRange(0, 100), default=0, help='Minimum score for a subtitle '
'to be downloaded (0 to 100).')
@click.option('-w', '--max-workers', type=click.IntRange(1, 50), default=None, help='Maximum number of threads to use.')
Expand All @@ -293,7 +303,7 @@ def cache(ctx, clear_subliminal):
@click.option('-v', '--verbose', count=True, help='Increase verbosity.')
@click.argument('path', type=click.Path(), required=True, nargs=-1)
@click.pass_obj
def download(obj, provider, refiner, language, age, directory, encoding, single, force, hearing_impaired, min_score,
def download(obj, provider, refiner, language, age, directory, encoding, single, force, hearing_impaired, foreign_only, min_score,
max_workers, archives, verbose, path):
"""Download best subtitles.

Expand Down Expand Up @@ -400,7 +410,7 @@ def download(obj, provider, refiner, language, age, directory, encoding, single,
scores = get_scores(v)
subtitles = p.download_best_subtitles(p.list_subtitles(v, language - v.subtitle_languages),
v, language, min_score=scores['hash'] * min_score / 100,
hearing_impaired=hearing_impaired, only_one=single)
hearing_impaired=hearing_impaired, foreign_only=foreign_only, only_one=single)
downloaded_subtitles[v] = subtitles

if p.discarded_providers:
Expand Down Expand Up @@ -445,6 +455,8 @@ def download(obj, provider, refiner, language, age, directory, encoding, single,
scaled_score = score
if s.hearing_impaired == hearing_impaired:
scaled_score -= scores['hearing_impaired']
if s.foreign_only == foreign_only:
scaled_score -= scores['foreign_only']
scaled_score *= 100 / scores['hash']

# echo some nice colored output
Expand Down
21 changes: 12 additions & 9 deletions subliminal/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def download_subtitle(self, subtitle):

return True

def download_best_subtitles(self, subtitles, video, languages, min_score=0, hearing_impaired=False, only_one=False,
def download_best_subtitles(self, subtitles, video, languages, min_score=0, hearing_impaired=False, foreign_only=False, only_one=False,
compute_score=None):
"""Download the best matching subtitles.

Expand All @@ -197,17 +197,18 @@ def download_best_subtitles(self, subtitles, video, languages, min_score=0, hear
:type languages: set of :class:`~babelfish.language.Language`
:param int min_score: minimum score for a subtitle to be downloaded.
:param bool hearing_impaired: hearing impaired preference.
:param bool foreign_only: foreign parts only preference.
:param bool only_one: download only one subtitle, not one per language.
:param compute_score: function that takes `subtitle` and `video` as positional arguments,
`hearing_impaired` as keyword argument and returns the score.
`hearing_impaired` as keyword argument, `foreign_only` as keyword argument and returns the score.
:return: downloaded subtitles.
:rtype: list of :class:`~subliminal.subtitle.Subtitle`

"""
compute_score = compute_score or default_compute_score

# sort subtitles by score
scored_subtitles = sorted([(s, compute_score(s, video, hearing_impaired=hearing_impaired))
scored_subtitles = sorted([(s, compute_score(s, video, hearing_impaired=hearing_impaired, foreign_only=foreign_only))
for s in subtitles], key=operator.itemgetter(1), reverse=True)

# download best subtitles, falling back on the next on error
Expand Down Expand Up @@ -601,7 +602,7 @@ def download_subtitles(subtitles, pool_class=ProviderPool, **kwargs):
pool.download_subtitle(subtitle)


def download_best_subtitles(videos, languages, min_score=0, hearing_impaired=False, only_one=False, compute_score=None,
def download_best_subtitles(videos, languages, min_score=0, hearing_impaired=False, foreign_only=False, only_one=False, compute_score=None,
pool_class=ProviderPool, **kwargs):
"""List and download the best matching subtitles.

Expand All @@ -613,9 +614,10 @@ def download_best_subtitles(videos, languages, min_score=0, hearing_impaired=Fal
:type languages: set of :class:`~babelfish.language.Language`
:param int min_score: minimum score for a subtitle to be downloaded.
:param bool hearing_impaired: hearing impaired preference.
:param bool foreign_only: foreign parts only preference.
:param bool only_one: download only one subtitle, not one per language.
:param compute_score: function that takes `subtitle` and `video` as positional arguments,
`hearing_impaired` as keyword argument and returns the score.
`hearing_impaired` as keyword argument, `foreign_only` as keyword argument and returns the score.
:param pool_class: class to use as provider pool.
:type pool_class: :class:`ProviderPool`, :class:`AsyncProviderPool` or similar
:param \*\*kwargs: additional parameters for the provided `pool_class` constructor.
Expand Down Expand Up @@ -643,7 +645,8 @@ def download_best_subtitles(videos, languages, min_score=0, hearing_impaired=Fal
logger.info('Downloading best subtitles for %r', video)
subtitles = pool.download_best_subtitles(pool.list_subtitles(video, languages - video.subtitle_languages),
video, languages, min_score=min_score,
hearing_impaired=hearing_impaired, only_one=only_one,
hearing_impaired=hearing_impaired,
foreign_only=foreign_only, only_one=only_one,
compute_score=compute_score)
logger.info('Downloaded %d subtitle(s)', len(subtitles))
downloaded_subtitles[video].extend(subtitles)
Expand Down Expand Up @@ -680,11 +683,11 @@ def save_subtitles(video, subtitles, single=False, directory=None, encoding=None

# check language
if subtitle.language in set(s.language for s in saved_subtitles):
logger.debug('Skipping subtitle %r: language already saved', subtitle)
continue
logger.debug('Skipping subtitle %r: language already saved', subtitle)
continue

# create subtitle path
subtitle_path = get_subtitle_path(video.name, None if single else subtitle.language)
subtitle_path = get_subtitle_path(video.name, None if single else subtitle.language, subtitle.foreign_only)
if directory is not None:
subtitle_path = os.path.join(directory, os.path.split(subtitle_path)[1])

Expand Down
7 changes: 4 additions & 3 deletions subliminal/providers/addic7ed.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class Addic7edSubtitle(Subtitle):
"""Addic7ed Subtitle."""
provider_name = 'addic7ed'

def __init__(self, language, hearing_impaired, page_link, series, season, episode, title, year, version,
def __init__(self, language, hearing_impaired, foreign_only, page_link, series, season, episode, title, year, version,
download_link):
super(Addic7edSubtitle, self).__init__(language, hearing_impaired, page_link)
super(Addic7edSubtitle, self).__init__(language, hearing_impaired, foreign_only, page_link)
self.series = series
self.season = season
self.episode = episode
Expand Down Expand Up @@ -255,14 +255,15 @@ def query(self, series, season, year=None, country=None):
# read the item
language = Language.fromaddic7ed(cells[3].text)
hearing_impaired = bool(cells[6].text)
foreign_only = False
page_link = self.server_url + cells[2].a['href'][1:]
season = int(cells[0].text)
episode = int(cells[1].text)
title = cells[2].text
version = cells[4].text
download_link = cells[9].a['href'][1:]

subtitle = Addic7edSubtitle(language, hearing_impaired, page_link, series, season, episode, title, year,
subtitle = Addic7edSubtitle(language, hearing_impaired, foreign_only, page_link, series, season, episode, title, year,
version, download_link)
logger.debug('Found subtitle %r', subtitle)
subtitles.append(subtitle)
Expand Down
2 changes: 1 addition & 1 deletion subliminal/providers/legendastv.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def __init__(self, language, type, title, year, imdb_id, season, archive, name):
def id(self):
return '%s-%s' % (self.archive.id, self.name.lower())

def get_matches(self, video, hearing_impaired=False):
def get_matches(self, video, hearing_impaired=False, foreign_only=False):
matches = set()

# episode
Expand Down
7 changes: 4 additions & 3 deletions subliminal/providers/opensubtitles.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class OpenSubtitlesSubtitle(Subtitle):
provider_name = 'opensubtitles'
series_re = re.compile(r'^"(?P<series_name>.*)" (?P<series_title>.*)$')

def __init__(self, language, hearing_impaired, page_link, subtitle_id, matched_by, movie_kind, hash, movie_name,
def __init__(self, language, hearing_impaired, foreign_only, page_link, subtitle_id, matched_by, movie_kind, hash, movie_name,
movie_release_name, movie_year, movie_imdb_id, series_season, series_episode, filename, encoding):
super(OpenSubtitlesSubtitle, self).__init__(language, hearing_impaired, page_link, encoding)
super(OpenSubtitlesSubtitle, self).__init__(language, hearing_impaired, foreign_only, page_link, encoding)
self.subtitle_id = subtitle_id
self.matched_by = matched_by
self.movie_kind = movie_kind
Expand Down Expand Up @@ -185,6 +185,7 @@ def query(self, languages, hash=None, size=None, imdb_id=None, query=None, seaso
# read the item
language = Language.fromopensubtitles(subtitle_item['SubLanguageID'])
hearing_impaired = bool(int(subtitle_item['SubHearingImpaired']))
foreign_only = bool(int(subtitle_item['SubForeignPartsOnly']))
page_link = subtitle_item['SubtitlesLink']
subtitle_id = int(subtitle_item['IDSubtitleFile'])
matched_by = subtitle_item['MatchedBy']
Expand All @@ -199,7 +200,7 @@ def query(self, languages, hash=None, size=None, imdb_id=None, query=None, seaso
filename = subtitle_item['SubFileName']
encoding = subtitle_item.get('SubEncoding') or None

subtitle = OpenSubtitlesSubtitle(language, hearing_impaired, page_link, subtitle_id, matched_by, movie_kind,
subtitle = OpenSubtitlesSubtitle(language, hearing_impaired, foreign_only, page_link, subtitle_id, matched_by, movie_kind,
hash, movie_name, movie_release_name, movie_year, movie_imdb_id,
series_season, series_episode, filename, encoding)
logger.debug('Found subtitle %r by %s', subtitle, matched_by)
Expand Down
9 changes: 5 additions & 4 deletions subliminal/providers/podnapisi.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ class PodnapisiSubtitle(Subtitle):
"""Podnapisi Subtitle."""
provider_name = 'podnapisi'

def __init__(self, language, hearing_impaired, page_link, pid, releases, title, season=None, episode=None,
def __init__(self, language, hearing_impaired, foreign_only, page_link, pid, releases, title, season=None, episode=None,
year=None):
super(PodnapisiSubtitle, self).__init__(language, hearing_impaired, page_link)
super(PodnapisiSubtitle, self).__init__(language, hearing_impaired, foreign_only, page_link)
self.pid = pid
self.releases = releases
self.title = title
Expand Down Expand Up @@ -120,6 +120,7 @@ def query(self, language, keyword, season=None, episode=None, year=None):
# read xml elements
language = Language.fromietf(subtitle_xml.find('language').text)
hearing_impaired = 'n' in (subtitle_xml.find('flags').text or '')
foreign_only = False
page_link = subtitle_xml.find('url').text
pid = subtitle_xml.find('pid').text
releases = []
Expand All @@ -134,10 +135,10 @@ def query(self, language, keyword, season=None, episode=None, year=None):
year = int(subtitle_xml.find('year').text)

if is_episode:
subtitle = PodnapisiSubtitle(language, hearing_impaired, page_link, pid, releases, title,
subtitle = PodnapisiSubtitle(language, hearing_impaired, foreign_only, page_link, pid, releases, title,
season=season, episode=episode, year=year)
else:
subtitle = PodnapisiSubtitle(language, hearing_impaired, page_link, pid, releases, title,
subtitle = PodnapisiSubtitle(language, hearing_impaired, foreign_only, page_link, pid, releases, title,
year=year)

# ignore duplicates, see http://www.podnapisi.net/forum/viewtopic.php?f=62&t=26164&start=10#p213321
Expand Down
7 changes: 4 additions & 3 deletions subliminal/providers/subscenter.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ class SubsCenterSubtitle(Subtitle):
"""SubsCenter Subtitle."""
provider_name = 'subscenter'

def __init__(self, language, hearing_impaired, page_link, series, season, episode, title, subtitle_id, subtitle_key,
def __init__(self, language, hearing_impaired, foreign_only, page_link, series, season, episode, title, subtitle_id, subtitle_key,
downloaded, releases):
super(SubsCenterSubtitle, self).__init__(language, hearing_impaired, page_link)
super(SubsCenterSubtitle, self).__init__(language, hearing_impaired, foreign_only, page_link)
self.series = series
self.season = season
self.episode = episode
Expand Down Expand Up @@ -187,6 +187,7 @@ def query(self, title, season=None, episode=None):
# read the item
language = Language.fromalpha2(language_code)
hearing_impaired = bool(subtitle_item['hearing_impaired'])
foreign_only = False
subtitle_id = subtitle_item['id']
subtitle_key = subtitle_item['key']
downloaded = subtitle_item['downloaded']
Expand All @@ -200,7 +201,7 @@ def query(self, title, season=None, episode=None):
continue

# otherwise create it
subtitle = SubsCenterSubtitle(language, hearing_impaired, page_link, title, season, episode,
subtitle = SubsCenterSubtitle(language, hearing_impaired, foreign_only, page_link, title, season, episode,
title, subtitle_id, subtitle_key, downloaded, [release])
logger.debug('Found subtitle %r', subtitle)
subtitles[subtitle_id] = subtitle
Expand Down
Loading