Updates vendored subliminal to 2.1.0

Updates rarfile to 3.1
Updates stevedore to 3.5.0
Updates appdirs to 1.4.4
Updates click to 8.1.3
Updates decorator to 5.1.1
Updates dogpile.cache to 1.1.8
Updates pbr to 5.11.0
Updates pysrt to 1.1.2
Updates pytz to 2022.6
Adds importlib-metadata version 3.1.1
Adds typing-extensions version 4.1.1
Adds zipp version 3.11.0
This commit is contained in:
Labrys of Knossos 2022-11-29 00:08:39 -05:00
commit f05b09f349
694 changed files with 16621 additions and 11056 deletions

View file

@ -5,6 +5,9 @@ import logging
import os
from guessit import guessit
from rebulk.loose import ensure_list
from subliminal.utils import matches_title
logger = logging.getLogger(__name__)
@ -12,10 +15,10 @@ logger = logging.getLogger(__name__)
VIDEO_EXTENSIONS = ('.3g2', '.3gp', '.3gp2', '.3gpp', '.60d', '.ajp', '.asf', '.asx', '.avchd', '.avi', '.bik',
'.bix', '.box', '.cam', '.dat', '.divx', '.dmf', '.dv', '.dvr-ms', '.evo', '.flc', '.fli',
'.flic', '.flv', '.flx', '.gvi', '.gvp', '.h264', '.m1v', '.m2p', '.m2ts', '.m2v', '.m4e',
'.m4v', '.mjp', '.mjpeg', '.mjpg', '.mkv', '.moov', '.mov', '.movhd', '.movie', '.movx', '.mp4',
'.mpe', '.mpeg', '.mpg', '.mpv', '.mpv2', '.mxf', '.nsv', '.nut', '.ogg', '.ogm' '.ogv', '.omf',
'.ps', '.qt', '.ram', '.rm', '.rmvb', '.swf', '.ts', '.vfw', '.vid', '.video', '.viv', '.vivo',
'.vob', '.vro', '.wm', '.wmv', '.wmx', '.wrap', '.wvx', '.wx', '.x264', '.xvid')
'.m4v', '.mjp', '.mjpeg', '.mjpg', '.mk3d', '.mkv', '.moov', '.mov', '.movhd', '.movie', '.movx',
'.mp4', '.mpe', '.mpeg', '.mpg', '.mpv', '.mpv2', '.mxf', '.nsv', '.nut', '.ogg', '.ogm', '.ogv',
'.omf', '.ps', '.qt', '.ram', '.rm', '.rmvb', '.swf', '.ts', '.vfw', '.vid', '.video', '.viv',
'.vivo', '.vob', '.vro', '.webm', '.wm', '.wmv', '.wmx', '.wrap', '.wvx', '.wx', '.x264', '.xvid')
class Video(object):
@ -24,8 +27,9 @@ class Video(object):
Represent a video, existing or not.
:param str name: name or path of the video.
:param str format: format of the video (HDTV, WEB-DL, BluRay, ...).
:param str source: source of the video (HDTV, Web, Blu-ray, ...).
:param str release_group: release group of the video.
:param str streaming_service: streaming_service of the video.
:param str resolution: resolution of the video stream (480p, 720p, 1080p or 1080i).
:param str video_codec: codec of the video stream.
:param str audio_codec: codec of the main audio stream.
@ -35,17 +39,20 @@ class Video(object):
:param set subtitle_languages: existing subtitle languages.
"""
def __init__(self, name, format=None, release_group=None, resolution=None, video_codec=None, audio_codec=None,
imdb_id=None, hashes=None, size=None, subtitle_languages=None):
def __init__(self, name, source=None, release_group=None, resolution=None, streaming_service=None,
video_codec=None, audio_codec=None, imdb_id=None, hashes=None, size=None, subtitle_languages=None):
#: Name or path of the video
self.name = name
#: Format of the video (HDTV, WEB-DL, BluRay, ...)
self.format = format
#: Source of the video (HDTV, Web, Blu-ray, ...)
self.source = source
#: Release group of the video
self.release_group = release_group
#: Streaming service of the video
self.streaming_service = streaming_service
#: Resolution of the video stream (480p, 720p, 1080p or 1080i)
self.resolution = resolution
@ -118,16 +125,19 @@ class Episode(Video):
:param str series: series of the episode.
:param int season: season number of the episode.
:param int episode: episode number of the episode.
:param int or list episodes: episode numbers of the episode.
:param str title: title of the episode.
:param int year: year of the series.
:param country: Country of the series.
:type country: :class:`~babelfish.country.Country`
:param bool original_series: whether the series is the first with this name.
:param int tvdb_id: TVDB id of the episode.
:param list alternative_series: alternative names of the series
:param \*\*kwargs: additional parameters for the :class:`Video` constructor.
"""
def __init__(self, name, series, season, episode, title=None, year=None, original_series=True, tvdb_id=None,
series_tvdb_id=None, series_imdb_id=None, **kwargs):
def __init__(self, name, series, season, episodes, title=None, year=None, country=None, original_series=True,
tvdb_id=None, series_tvdb_id=None, series_imdb_id=None, alternative_series=None, **kwargs):
super(Episode, self).__init__(name, **kwargs)
#: Series of the episode
@ -136,8 +146,8 @@ class Episode(Video):
#: Season number of the episode
self.season = season
#: Episode number of the episode
self.episode = episode
#: Episode numbers of the episode
self.episodes = ensure_list(episodes)
#: Title of the episode
self.title = title
@ -148,6 +158,9 @@ class Episode(Video):
#: The series is the first with this name
self.original_series = original_series
#: Country of the series
self.country = country
#: TVDB id of the episode
self.tvdb_id = tvdb_id
@ -157,6 +170,16 @@ class Episode(Video):
#: IMDb id of the series
self.series_imdb_id = series_imdb_id
#: Alternative names of the series
self.alternative_series = alternative_series or []
@property
def episode(self):
return min(self.episodes) if self.episodes else None
def matches(self, series):
return matches_title(series, self.series, self.alternative_series)
@classmethod
def fromguess(cls, name, guess):
if guess['type'] != 'episode':
@ -165,9 +188,12 @@ class Episode(Video):
if 'title' not in guess or 'episode' not in guess:
raise ValueError('Insufficient data to process the guess')
return cls(name, guess['title'], guess.get('season', 1), guess['episode'], title=guess.get('episode_title'),
year=guess.get('year'), format=guess.get('format'), original_series='year' not in guess,
release_group=guess.get('release_group'), resolution=guess.get('screen_size'),
return cls(name, guess['title'], guess.get('season', 1), guess.get('episode'), title=guess.get('episode_title'),
year=guess.get('year'), country=guess.get('country'),
original_series='year' not in guess and 'country' not in guess,
source=guess.get('source'), alternative_series=ensure_list(guess.get('alternative_title')),
release_group=guess.get('release_group'), streaming_service=guess.get('streaming_service'),
resolution=guess.get('screen_size'),
video_codec=guess.get('video_codec'), audio_codec=guess.get('audio_codec'))
@classmethod
@ -175,10 +201,13 @@ class Episode(Video):
return cls.fromguess(name, guessit(name, {'type': 'episode'}))
def __repr__(self):
if self.year is None:
return '<%s [%r, %dx%d]>' % (self.__class__.__name__, self.series, self.season, self.episode)
return '<%s [%r, %d, %dx%d]>' % (self.__class__.__name__, self.series, self.year, self.season, self.episode)
return '<{cn} [{series}{open}{country}{sep}{year}{close} s{season:02d}e{episodes}]>'.format(
cn=self.__class__.__name__, series=self.series, year=self.year or '', country=self.country or '',
season=self.season, episodes='-'.join(map(lambda v: '{:02d}'.format(v), self.episodes)),
open=' (' if not self.original_series else '',
sep=') (' if self.year and self.country else '',
close=')' if not self.original_series else ''
)
class Movie(Video):
@ -186,10 +215,13 @@ class Movie(Video):
:param str title: title of the movie.
:param int year: year of the movie.
:param country: Country of the movie.
:type country: :class:`~babelfish.country.Country`
:param list alternative_titles: alternative titles of the movie
:param \*\*kwargs: additional parameters for the :class:`Video` constructor.
"""
def __init__(self, name, title, year=None, **kwargs):
def __init__(self, name, title, year=None, country=None, alternative_titles=None, **kwargs):
super(Movie, self).__init__(name, **kwargs)
#: Title of the movie
@ -198,6 +230,15 @@ class Movie(Video):
#: Year of the movie
self.year = year
#: Country of the movie
self.country = country
#: Alternative titles of the movie
self.alternative_titles = alternative_titles or []
def matches(self, title):
return matches_title(title, self.title, self.alternative_titles)
@classmethod
def fromguess(cls, name, guess):
if guess['type'] != 'movie':
@ -206,16 +247,20 @@ class Movie(Video):
if 'title' not in guess:
raise ValueError('Insufficient data to process the guess')
return cls(name, guess['title'], format=guess.get('format'), release_group=guess.get('release_group'),
return cls(name, guess['title'], source=guess.get('source'), release_group=guess.get('release_group'),
streaming_service=guess.get('streaming_service'),
resolution=guess.get('screen_size'), video_codec=guess.get('video_codec'),
audio_codec=guess.get('audio_codec'), year=guess.get('year'))
alternative_titles=ensure_list(guess.get('alternative_title')),
audio_codec=guess.get('audio_codec'), year=guess.get('year'), country=guess.get('country'))
@classmethod
def fromname(cls, name):
return cls.fromguess(name, guessit(name, {'type': 'movie'}))
def __repr__(self):
if self.year is None:
return '<%s [%r]>' % (self.__class__.__name__, self.title)
return '<%s [%r, %d]>' % (self.__class__.__name__, self.title, self.year)
return '<{cn} [{title}{open}{country}{sep}{year}{close}]>'.format(
cn=self.__class__.__name__, title=self.title, year=self.year or '', country=self.country or '',
open=' (' if self.year or self.country else '',
sep=') (' if self.year and self.country else '',
close=')' if self.year or self.country else ''
)