Merge pull request #484 from guessit-io/feature/size-output

Enhance size output value / Detect bit rate
This commit is contained in:
Rato
2017-12-02 21:53:39 +01:00
committed by GitHub
9 changed files with 214 additions and 8 deletions
+4
View File
@@ -97,6 +97,10 @@ History
- Added default and configurable list of allowed languages and countries
- Added `VC-1` as new `video_codec` possible value
- Enhanced dash-separated `release_group` detection.
- Changed `size` output to return `guessit.Quantity` object.
- Changed `size` output to return `guessit.Size` object.
- Added `audio_video_rate` as new possible property.
- Added `video_video_rate` as new possible property.
2.1.4 (2017-06-01)
------------------
+17 -1
View File
@@ -180,6 +180,13 @@ Video properties
- ``DXVA``
- **video_bit_rate**
Video bit rate (Mbps). Examples: ``25Mbps`` (``<BitRate [25Mbps]>``), ``40Mbps`` (``<BitRate [40Mbps]>``).
- ``[<guessit.BitRate>]`` (object has ``magnitude`` and ``units``)
Audio properties
----------------
@@ -206,6 +213,13 @@ Audio properties
``Master Audio``
- **audio_bit_rate**
Audio bit rate (Kbps, Mbps). Examples: ``448Kbps`` (``<BitRate [448Kbps]>``), ``1.5Mbps`` (``<BitRate [1.5Mbps]>``).
- ``[<guessit.BitRate>]`` (object has ``magnitude`` and ``units``)
Localization properties
-----------------------
@@ -265,7 +279,9 @@ Other properties
- **size**
Size (MB, GB, TB).
Size (MB, GB, TB). Examples: ``1.2GB`` (``<Size [1.2GB]>``), ``430MB`` (``<Size [430MB]>``).
- ``[<guessit.Size>]`` (object has ``magnitude`` and ``units``)
- **edition**
+1
View File
@@ -5,5 +5,6 @@ Extracts as much information as possible from a video file.
"""
from .api import guessit, GuessItApi
from .options import ConfigurationException
from .rules.common.quantity import Size
from .__version__ import __version__
+2
View File
@@ -24,6 +24,7 @@ from .properties.release_group import release_group
from .properties.streaming_service import streaming_service
from .properties.other import other
from .properties.size import size
from .properties.bit_rate import bit_rate
from .properties.edition import edition
from .properties.cds import cds
from .properties.bonus import bonus
@@ -63,6 +64,7 @@ def rebulk_builder():
rebulk.rebulk(streaming_service())
rebulk.rebulk(other())
rebulk.rebulk(size())
rebulk.rebulk(bit_rate())
rebulk.rebulk(edition())
rebulk.rebulk(cds())
rebulk.rebulk(bonus())
+90
View File
@@ -0,0 +1,90 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Quantities: Size
"""
import re
from abc import abstractmethod
import six
from ..common import seps
class Quantity(object):
"""
Represent a quantity object with magnitude and units.
"""
parser_re = re.compile(r'(?P<magnitude>\d+(?:[.]\d+)?)(?P<units>[^\d]+)')
def __init__(self, magnitude, units):
self.magnitude = magnitude
self.units = units
@classmethod
@abstractmethod
def parse_units(cls, value):
"""
Parse a string to a proper unit notation.
"""
raise NotImplementedError
@classmethod
def fromstring(cls, string):
"""
Parse the string into a quantity object.
:param string:
:return:
"""
values = cls.parser_re.match(string).groupdict()
try:
magnitude = int(values['magnitude'])
except ValueError:
magnitude = float(values['magnitude'])
units = cls.parse_units(values['units'])
return cls(magnitude, units)
def __hash__(self):
return hash(str(self))
def __eq__(self, other):
if isinstance(other, six.string_types):
return str(self) == other
if not isinstance(other, self.__class__):
return NotImplemented
return self.magnitude == other.magnitude and self.units == other.units
def __ne__(self, other):
return not self == other
def __repr__(self):
return '<{0} [{1}]>'.format(self.__class__.__name__, self)
def __str__(self):
return '{0}{1}'.format(self.magnitude, self.units)
class Size(Quantity):
"""
Represent size.
e.g.: 1.1GB, 300MB
"""
@classmethod
def parse_units(cls, value):
return value.strip(seps).upper()
class BitRate(Quantity):
"""
Represent bit rate.
e.g.: 320Kbps, 1.5Mbps
"""
@classmethod
def parse_units(cls, value):
return value.strip(seps).capitalize()
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
video_bit_rate and audio_bit_rate properties
"""
import re
from rebulk import Rebulk
from rebulk.rules import Rule, RenameMatch
from ..common import dash, seps
from ..common.quantity import BitRate
from ..common.validators import seps_surround
def bit_rate():
"""
Builder for rebulk object.
:return: Created Rebulk object
:rtype: Rebulk
"""
rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash])
rebulk.defaults(name='audio_bit_rate', validator=seps_surround)
rebulk.regex(r'\d+-?[kmg]bps', r'\d+\.\d+-?[kmg]bps',
conflict_solver=(
lambda match, other: match
if other.name == 'audio_channels' and 'weak-audio_channels' not in other.tags
else other
),
formatter=BitRate.fromstring, tags=['release-group-prefix'])
rebulk.rules(BitRateTypeRule)
return rebulk
class BitRateTypeRule(Rule):
"""
Convert audio bit rate guess into video bit rate.
"""
consequence = RenameMatch('video_bit_rate')
def when(self, matches, context):
for match in matches.named('audio_bit_rate'):
previous = matches.previous(match, index=0,
predicate=lambda m: m.name in ('source', 'screen_size', 'video_codec'))
if previous and not matches.holes(previous.end, match.start, predicate=lambda m: m.value.strip(seps)):
yield match
+3 -7
View File
@@ -7,8 +7,9 @@ import re
from rebulk import Rebulk
from ..common.validators import seps_surround
from ..common import dash
from ..common.quantity import Size
from ..common.validators import seps_surround
def size():
@@ -17,13 +18,8 @@ def size():
:return: Created Rebulk object
:rtype: Rebulk
"""
def format_size(value):
"""Format size using uppercase and no space."""
return re.sub(r'(?<=\d)[.](?=[^\d])', '', value.upper())
rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash])
rebulk.defaults(name='size', validator=seps_surround)
rebulk.regex(r'\d+\.?[mgt]b', r'\d+\.\d+[mgt]b', formatter=format_size, tags=['release-group-prefix'])
rebulk.regex(r'\d+-?[mgt]b', r'\d+\.\d+-?[mgt]b', formatter=Size.fromstring, tags=['release-group-prefix'])
return rebulk
+11
View File
@@ -4338,3 +4338,14 @@
episode_title: AKA Sin Bin
container: mkv
type: episode
? Hotel.Hell.S01E01.720p.DD5.1.448kbps-ALANiS
: title: Hotel Hell
season: 1
episode: 1
screen_size: 720p
audio_codec: Dolby Digital
audio_channels: '5.1'
audio_bit_rate: 448Kbps
release_group: ALANiS
type: episode
+38
View File
@@ -864,3 +864,41 @@
video_codec: H.264
release_group: SDH
type: episode
? Katy Perry - Pepsi & Billboard Summer Beats Concert Series 2012 1080i HDTV 20 Mbps DD2.0 MPEG2-TrollHD.ts
: title: Katy Perry
alternative_title: Pepsi & Billboard Summer Beats Concert
year: 2012
screen_size: 1080i
source: HDTV
video_bit_rate: 20Mbps
audio_codec: Dolby Digital
audio_channels: '2.0'
video_codec: MPEG-2
release_group: TrollHD
container: ts
? Justin Timberlake - MTV Video Music Awards 2013 1080i 32 Mbps DTS-HD 5.1.ts
: title: Justin Timberlake
alternative_title: MTV Video Music Awards
year: 2013
screen_size: 1080i
video_bit_rate: 32Mbps
audio_codec: DTS-HD
audio_channels: '5.1'
container: ts
type: movie
? Chuck Berry The Very Best Of Chuck Berry(2010)[320 Kbps]
: title: Chuck Berry The Very Best Of Chuck Berry
year: 2010
audio_bit_rate: 320Kbps
type: movie
? Title Name [480p][1.5Mbps][.mp4]
: title: Title Name
screen_size: 480p
video_bit_rate: 1.5Mbps
container: mp4
type: movie