From 1ae6ca07f5ab33df3f25a092a908556075d796d1 Mon Sep 17 00:00:00 2001 From: Toilal Date: Thu, 5 Nov 2015 23:24:20 +0100 Subject: [PATCH] Add docs and better migration path --- HISTORY.rst | 1 + MIGRATION.rst | 141 ++++++++++++++++++++++++--- README.rst | 106 ++++++++++++++++---- guessit/__init__.py | 2 +- guessit/__main__.py | 7 +- guessit/options.py | 18 ++-- guessit/rules/properties/mimetype.py | 2 +- guessit/rules/properties/type.py | 2 +- guessit/test/episodes.yml | 6 +- guessit/test/movies.yml | 9 +- guessit/test/test_main.py | 8 -- guessit/test/various.yml | 48 +++------ pytest.ini | 2 +- setup.py | 2 +- 14 files changed, 253 insertions(+), 101 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 4913750..30258af 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -4,3 +4,4 @@ History 2.0.0-alpha.0 (unreleased) -------------------------- * Rewrite from scratch using `Rebulk `_ +* Read `MIGRATION.rst `_ for migration guidelines. diff --git a/MIGRATION.rst b/MIGRATION.rst index c239fd6..0c4c2ad 100644 --- a/MIGRATION.rst +++ b/MIGRATION.rst @@ -1,28 +1,145 @@ Migration ========= -For version 2, has been rewritten from scratch. You can find in this file all information required to perform a -migration from previous version. +Guessit 2 has been rewritten from scratch. You can find in this file all information required to perform a +migration from previous version ``0.x`` or ``1.x``. API ---- -*Work in progress ...* +---- +``guess_video_info``, ``guess_movie_info`` and ``guess_episode_info`` have been removed in favor of a unique function +``guessit``. -Options -------- -*Work in progress ...* +Example:: + + >>> from guessit import guessit + >>> guessit('Treme.1x03.Right.Place,.Wrong.Time.HDTV.XviD-NoTV.avi') + MatchesDict([('title', 'Treme'), ('season', 1), ('episodeNumber', 3), ('episodeTitle', 'Right Place, Wrong Time'), ('format', 'HDTV'), ('videoCodec', 'XviD'), ('releaseGroup', 'NoTV'), ('container', 'avi'), ('mimetype', 'video/x-msvideo'), ('type', 'episode')]) + +Command line options can be given as dict or string to the second argument. Properties ---------- -For episode type, some properties have been renamed +For ``episode`` type, some properties have been renamed - ``series`` is now ``title``. - ``title`` is now ``episodeTitle``. -For movie type, some properties have been renamed +``episodeList`` and ``partList`` were removed. ``episodeNumber`` and ``part`` properties that can now be a ``list`` +when multiple values are found. + +For ``movie`` type, some properties have been renamed - ``filmtitle`` is now ``filmSeries`` -All info type (``seriesinfo``, ``movieinfo``) have been removed in favor of checking the ``extension`` property for -``nfo`` value. +All info ``type``, like ``seriesinfo`` and ``movieinfo``, have been removed in favor of checking the ``container`` +property for ``nfo`` value. -All other properties have been ported with the same name (*Work in progress ...*) \ No newline at end of file +All other properties have been ported with the same name. + +Options +------- +Some options have been removed. + +- ``-t TYPE, --type TYPE`` + + GuessIt now guess filetype after all other matches and doesn't require user to specify the filetype in advance. + +- ``-X DISABLED_TRANSFORMERS``, ``-s, --transformers`` + + There's no transformer anymore. + +- ``-S EXPECTED_SERIES`` + + As ``series`` was renamed to ``title``, use ``-T EXPECTED_TITLE`` instead. + +- ``-G EXPECTED_GROUP`` + + GuessIt is now better to guess release group, so this option has been removed. + +- ``-d, --demo`` + + Probably not that useful. + +- ``-i INFO, --info INFO`` + + Features related to this option have been removed. + +- ``-c, --split-camel``, ``-u, --unidentified``, ``-b, --bug``, ``-p, --properties``, ``-V, --values`` + + Will be back soon... (work in progress) + +Others GuessIt ``1.x`` options have been kept. + +Output +------ +Output produced by ``guessit`` api function is now an instance or +[OrderedDict](https://docs.python.org/2/library/collections.html#collections.OrderedDict). Property values are +automatically ordered based on filename, and you can still use this output as a default python ``dict``. + +If multiple values are available for a property, value in the dict will be a ``list`` instance. + +Advanced display option (``-a, --advanced``) output is also changed. It now list ``Match`` objects from +`Rebulk `_, and may display duplicates that would have been merged in standard +output.:: + + $ guessit "Treme.1x03.Right.Place,.Wrong.Time.HDTV.XviD-NoTV.avi" -a + For: Treme.1x03.Right.Place,.Wrong.Time.HDTV.XviD-NoTV.avi + GuessIt found: { + "title": { + "value": "Treme", + "raw": "Treme.", + "start": 0, + "end": 6 + }, + "season": { + "value": 1, + "raw": "1", + "start": 6, + "end": 7 + }, + "episodeNumber": { + "value": 3, + "raw": "03", + "start": 8, + "end": 10 + }, + "episodeTitle": { + "value": "Right Place, Wrong Time", + "raw": ".Right.Place,.Wrong.Time.", + "start": 10, + "end": 35 + }, + "format": { + "value": "HDTV", + "raw": "HDTV", + "start": 35, + "end": 39 + }, + "videoCodec": { + "value": "XviD", + "raw": "XviD", + "start": 40, + "end": 44 + }, + "releaseGroup": { + "value": "NoTV", + "raw": "-NoTV", + "start": 44, + "end": 49 + }, + "container": { + "value": "avi", + "raw": ".avi", + "start": 49, + "end": 53 + }, + "mimetype": { + "value": "video/x-msvideo", + "start": 53, + "end": 53 + }, + "type": { + "value": "episode", + "start": 53, + "end": 53 + } + } diff --git a/README.rst b/README.rst index 5b341a9..ccd260e 100644 --- a/README.rst +++ b/README.rst @@ -20,17 +20,38 @@ GuessIt `HuBoard `_ -GuessIt is a python library that extracts as much information as possible from a video file. +GuessIt is a python library that extracts as much information as possible from a video filename. -It has a very powerful filename matcher that allows to guess a lot of metadata from a video using its filename only. +It has a very powerful matcher that allows to guess a lot of metadata from a video using its filename only. This matcher works with both movies and tv shows episodes. -Important note -============== -GuessIt 2.x is a rewrite from scratch and is currently in Alpha. Support for additional features like hashes -computations has been dropped. GuessIt is now a release name parser only. +For example, GuessIt can do the following:: -Previous stable version of GuessIt is still available in ``1.x`` branch and using `pip install guessit<2`. + $ guessit "Treme.1x03.Right.Place,.Wrong.Time.HDTV.XviD-NoTV.avi" + For: Treme.1x03.Right.Place,.Wrong.Time.HDTV.XviD-NoTV.avi + GuessIt found: { + "title": "Treme", + "season": 1, + "episodeNumber": 3, + "episodeTitle": "Right Place, Wrong Time", + "format": "HDTV", + "videoCodec": "XviD", + "releaseGroup": "NoTV", + "container": "avi", + "mimetype": "video/x-msvideo", + "type": "episode" + } + +Important note +-------------- +GuessIt 2 has been rewriten from scratch and is currently in Alpha. GuessIt is now a release name parser only, and +support for additional features like hashes computations has been dropped. + +To migrate from guessit ``0.x`` or ``1.x``, please read +`MIGRATION.rst `_. + +Previous version of GuessIt is still available in ``1.x`` branch and using ``pip install guessit<2``, but won't be +maintained anymore. Install ------- @@ -39,12 +60,6 @@ Installing GuessIt is simple with `pip `_:: $ pip install guessit -or, with `easy_install `_:: - - $ easy_install guessit - -But, you really `shouldn't do that `_. - Filename matcher ---------------- @@ -54,16 +69,73 @@ exactly the raw filename. Usage ----- -Work in progress ... + +guessit can be use from command line:: + + $ guessit + usage: __main__.py [-h] [-n] [-Y] [-D] [-L ALLOWED_LANGUAGES] + [-C ALLOWED_COUNTRIES] [-E] [-T EXPECTED_TITLE] [-v] + [-P SHOW_PROPERTY] [-u] [-a] [-j] [-y] [-f INPUT_FILE] + [--version] + [filename [filename ...]] + + positional arguments: + filename Filename or release name to guess + + optional arguments: + -h, --help show this help message and exit + + Naming: + -Y, --date-year-first + If short date is found, consider the first digits as + the year. + -D, --date-day-first If short date is found, consider the second digits as + the day. + -L ALLOWED_LANGUAGES, --allowed-languages ALLOWED_LANGUAGES + Allowed language (can be used multiple times) + -C ALLOWED_COUNTRIES, --allowed-countries ALLOWED_COUNTRIES + Allowed country (can be used multiple times) + -E, --episode-prefer-number + Guess "serie.213.avi" as the episodeNumber 213. + Without this option, it will be guessed as season 2, + episodeNumber 13 + -T EXPECTED_TITLE, --expected-title EXPECTED_TITLE + Expected title to parse (can be used multiple times) + + Output: + -v, --verbose Display debug output + -P SHOW_PROPERTY, --show-property SHOW_PROPERTY + Display the value of a single property (title, series, + videoCodec, year, ...) + -u, --unidentified Display the unidentified parts. + -a, --advanced Display advanced information for filename guesses, as + json output + -j, --json Display information for filename guesses as json + output + -y, --yaml Display information for filename guesses as yaml + output (like unit-test) + -f INPUT_FILE, --input-file INPUT_FILE + Read filenames from an input file. + + Information: + --version Display the guessit version. + +It can also be used as a python module:: + + >>> from guessit import guessit + >>> guessit('Treme.1x03.Right.Place,.Wrong.Time.HDTV.XviD-NoTV.avi') + MatchesDict([('title', 'Treme'), ('season', 1), ('episodeNumber', 3), ('episodeTitle', 'Right Place, Wrong Time'), ('format', 'HDTV'), ('videoCodec', 'XviD'), ('releaseGroup', 'NoTV'), ('container', 'avi'), ('mimetype', 'video/x-msvideo'), ('type', 'episode')]) + +``MatchesDict`` is a dict that keeps matches ordering. + Support ------- -The project website for GuessIt is hosted at `ReadTheDocs `_. -There you will also find the User guide and Developer documentation. - This project is hosted on GitHub: ``_ +Docs will be available soon availabe ReadTheDocs. + Contribute ---------- diff --git a/guessit/__init__.py b/guessit/__init__.py index dad3da4..2defeaf 100644 --- a/guessit/__init__.py +++ b/guessit/__init__.py @@ -4,4 +4,4 @@ Extracts as much information as possible from a video file. """ from .api import guessit -from .rules import REBULK as _REBULK +from .rules import REBULK diff --git a/guessit/__main__.py b/guessit/__main__.py index 0c1f010..d4bcf52 100644 --- a/guessit/__main__.py +++ b/guessit/__main__.py @@ -27,7 +27,8 @@ class GuessitEncoder(json.JSONEncoder): if isinstance(o, Match): ret = OrderedDict() ret['value'] = o.value - ret['raw'] = o.raw + if o.raw: + ret['raw'] = o.raw ret['start'] = o.start ret['end'] = o.end return ret @@ -95,10 +96,6 @@ def main(args=None): # pylint:disable=too-many-branches logging.getLogger().setLevel(logging.DEBUG) help_required = True - if options.properties or options.values: - # display_properties(options) - # TODO: Add display of available properties - help_required = False if options.version: print('+-------------------------------------------------------+') diff --git a/guessit/options.py b/guessit/options.py index db3bbc3..a3aa272 100644 --- a/guessit/options.py +++ b/guessit/options.py @@ -20,10 +20,8 @@ def build_argument_parser(): opts.add_argument(dest='filename', help='Filename or release name to guess', nargs='*') naming_opts = opts.add_argument_group("Naming") - # naming_opts.add_argument('-t', '--type', dest='type', default=None, - # help='The suggested file type: movie, episode. If undefined, type will be guessed.') naming_opts.add_argument('-n', '--name-only', dest='name_only', action='store_true', default=False, - help='Parse files as name only (consider "/" and "\\" like other characters)') + help='Parse files as name only (consider "/" and "\\" like other separators)') naming_opts.add_argument('-Y', '--date-year-first', action='store_true', dest='date_year_first', default=None, help='If short date is found, consider the first digits as the year.') naming_opts.add_argument('-D', '--date-day-first', action='store_true', dest='date_day_first', default=None, @@ -39,29 +37,25 @@ def build_argument_parser(): naming_opts.add_argument('-T', '--expected-title', action='append', dest='expected_title', help='Expected title to parse (can be used multiple times)') + input_opts = opts.add_argument_group("Input") + input_opts.add_argument('-f', '--input-file', dest='input_file', default=False, + help='Read filenames from an input file.') + output_opts = opts.add_argument_group("Output") output_opts.add_argument('-v', '--verbose', action='store_true', dest='verbose', default=False, help='Display debug output') output_opts.add_argument('-P', '--show-property', dest='show_property', default=None, help='Display the value of a single property (title, series, videoCodec, year, ...)') - output_opts.add_argument('-u', '--unidentified', dest='unidentified', action='store_true', default=False, - help='Display the unidentified parts.') output_opts.add_argument('-a', '--advanced', dest='advanced', action='store_true', default=False, help='Display advanced information for filename guesses, as json output') output_opts.add_argument('-j', '--json', dest='json', action='store_true', default=False, help='Display information for filename guesses as json output') output_opts.add_argument('-y', '--yaml', dest='yaml', action='store_true', default=False, - help='Display information for filename guesses as yaml output (like unit-test)') - output_opts.add_argument('-f', '--input-file', dest='input_file', default=False, - help='Read filenames from an input file.') + help='Display information for filename guesses as yaml output') information_opts = opts.add_argument_group("Information") - information_opts.add_argument('-p', '--properties', dest='properties', action='store_true', default=False, - help='Display properties that can be guessed.') - information_opts.add_argument('-V', '--values', dest='values', action='store_true', default=False, - help='Display property values that can be guessed.') information_opts.add_argument('--version', dest='version', action='store_true', default=False, help='Display the guessit version.') diff --git a/guessit/rules/properties/mimetype.py b/guessit/rules/properties/mimetype.py index 1572c47..471b002 100644 --- a/guessit/rules/properties/mimetype.py +++ b/guessit/rules/properties/mimetype.py @@ -18,4 +18,4 @@ def mimetype_processor(matches): """ mime, _ = mimetypes.guess_type(matches.input_string, strict=False) if mime is not None: - matches.append(Match(0, len(matches.input_string), name='mimetype', value=mime)) + matches.append(Match(len(matches.input_string), len(matches.input_string), name='mimetype', value=mime)) diff --git a/guessit/rules/properties/type.py b/guessit/rules/properties/type.py index 64a974d..8dadcbe 100644 --- a/guessit/rules/properties/type.py +++ b/guessit/rules/properties/type.py @@ -13,7 +13,7 @@ def _type(matches, value): :param value: :return: """ - matches.append(Match(0, len(matches.input_string), name='type', value=value)) + matches.append(Match(len(matches.input_string), len(matches.input_string), name='type', value=value)) def type_processor(matches): diff --git a/guessit/test/episodes.yml b/guessit/test/episodes.yml index 050ff56..ece1639 100644 --- a/guessit/test/episodes.yml +++ b/guessit/test/episodes.yml @@ -979,8 +979,7 @@ episodeTitle: FlexGet # 1.x guess this as releaseGroup, but it's better to guess it as episodeTitle ? FlexGet.US.S2013E14.Title.Here.720p.HDTV.AAC5.1.x264-NOGRP -: options: -n - audioChannels: '5.1' +: audioChannels: '5.1' audioCodec: AAC country: US episodeNumber: 14 @@ -994,8 +993,7 @@ year: 2013 ? FlexGet.14.of.21.Title.Here.720p.HDTV.AAC5.1.x264-NOGRP -: options: -n - audioChannels: '5.1' +: audioChannels: '5.1' audioCodec: AAC episodeCount: 21 episodeNumber: 14 diff --git a/guessit/test/movies.yml b/guessit/test/movies.yml index 592e2f0..51368f9 100644 --- a/guessit/test/movies.yml +++ b/guessit/test/movies.yml @@ -704,16 +704,14 @@ videoCodec: h265 ? Barbecue-2014-French-mHD-1080p -: options: -n - language: fr +: language: fr other: mHD screenSize: 1080p title: Barbecue year: 2014 ? Underworld Quadrilogie VO+VFF+VFQ 1080p HDlight.x264~Tonyk~Monde Infernal -: options: -n - language: fr +: language: fr other: - HDLight - OV @@ -722,8 +720,7 @@ videoCodec: h264 ? A Bout Portant (The Killers).PAL.Multi.DVD-R-KZ -: options: -n - format: DVD +: format: DVD language: mul releaseGroup: KZ title: A Bout Portant diff --git a/guessit/test/test_main.py b/guessit/test/test_main.py index f08b19f..9183f62 100644 --- a/guessit/test/test_main.py +++ b/guessit/test/test_main.py @@ -46,11 +46,3 @@ def test_main_help(): def test_main_version(): main(['--version']) - - -def test_main_properties(): - main(['--properties']) - - -def test_main_value(): - main(['--values']) diff --git a/guessit/test/various.yml b/guessit/test/various.yml index 996d29a..c6aceb9 100644 --- a/guessit/test/various.yml +++ b/guessit/test/various.yml @@ -287,8 +287,7 @@ episodeDetails: Special ? Wicked.Tuna.S03E00.Head.To.Tail.Special.HDTV.x264-YesTV -: options: -n - type: episode +: type: episode title: Wicked Tuna episodeTitle: Head To Tail Special releaseGroup: YesTV @@ -299,8 +298,7 @@ episodeDetails: Special ? The.Voice.UK.S03E12.HDTV.x264-C4TV -: options: -n - episodeNumber: 12 +: episodeNumber: 12 videoCodec: h264 format: HDTV title: The Voice (GB) @@ -318,8 +316,7 @@ title: star trek 9 ? FlexGet.S01E02.TheName.HDTV.xvid -: options: -n - episodeNumber: 2 +: episodeNumber: 2 format: HDTV season: 1 title: FlexGet @@ -328,8 +325,7 @@ videoCodec: XviD ? FlexGet.S01E02.TheName.HDTV.xvid -: options: -n - episodeNumber: 2 +: episodeNumber: 2 format: HDTV season: 1 title: FlexGet @@ -338,8 +334,7 @@ videoCodec: XviD ? some.series.S03E14.Title.Here.720p -: options: -n - episodeNumber: 14 +: episodeNumber: 14 screenSize: 720p season: 3 title: some series @@ -347,8 +342,7 @@ type: episode ? '[the.group] Some.Series.S03E15.Title.Two.720p' -: options: -n - episodeNumber: 15 +: episodeNumber: 15 releaseGroup: the.group screenSize: 720p season: 3 @@ -357,8 +351,7 @@ type: episode ? 'HD 720p: Some series.S03E16.Title.Three' -: options: -n - episodeNumber: 16 +: episodeNumber: 16 other: HD screenSize: 720p season: 3 @@ -377,8 +370,7 @@ container: torrent ? Show-A (US) - Episode Title S02E09 hdtv -: options: -n - country: US +: country: US episodeNumber: 9 format: HDTV season: 2 @@ -386,8 +378,7 @@ type: episode ? Jack's.Show.S03E01.blah.1080p -: options: -n - episodeNumber: 1 +: episodeNumber: 1 screenSize: 1080p season: 3 title: Jack's Show @@ -395,23 +386,19 @@ type: episode ? FlexGet.epic -: options: -n - title: FlexGet epic +: title: FlexGet epic type: movie ? FlexGet.Apt.1 -: options: -n - title: FlexGet Apt 1 +: title: FlexGet Apt 1 type: movie ? FlexGet.aptitude -: options: -n - title: FlexGet aptitude +: title: FlexGet aptitude type: movie ? FlexGet.Step1 -: options: -n - title: FlexGet Step1 +: title: FlexGet Step1 type: movie ? Movies/El Bosque Animado (1987)/El.Bosque.Animado.[Jose.Luis.Cuerda.1987].[Xvid-Dvdrip-720 * 432].avi @@ -431,8 +418,7 @@ type: movie ? 2009.shoot.fruit.chan.multi.dvd9.pal -: options: -n - format: DVD +: format: DVD language: mul other: PAL title: shoot fruit chan @@ -440,8 +426,7 @@ year: 2009 ? 2009.shoot.fruit.chan.multi.dvd5.pal -: options: -n - format: DVD +: format: DVD language: mul other: PAL title: shoot fruit chan @@ -460,8 +445,7 @@ year: 2014 ? Ice.Lake.Rebels.S01E06.Ice.Lake.Games.720p.HDTV.x264-DHD -: options: -n - episodeNumber: 6 +: episodeNumber: 6 format: HDTV releaseGroup: DHD screenSize: 720p diff --git a/pytest.ini b/pytest.ini index d3625ab..eea5cce 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,2 +1,2 @@ [pytest] -addopts =-s --ignore=setup.py --ignore=build --doctest-modules --doctest-glob='README.rst' +addopts =-s --ignore=setup.py --ignore=build --doctest-modules --doctest-glob='*.rst' diff --git a/setup.py b/setup.py index a9fe9ec..686d1b8 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ exec(open("guessit/__version__.py").read()) # load version without importing gu args = dict(name='guessit', version=__version__, - description='GuessIt - a library for guessing information from video files.', + description='GuessIt - a library for guessing information from video filenames.', long_description=README + '\n\n' + HISTORY, # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers classifiers=['Development Status :: 3 - Alpha',