Added in untracked files for guessit.

Fixed issue #332, we confirm if str or list and take action depending on result.
This commit is contained in:
echel0n 2014-04-20 07:49:46 -07:00
commit 0fac36b4fc
42 changed files with 4188 additions and 14 deletions

View file

@ -0,0 +1,26 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
import logging
from guessit.slogging import setupLogging
setupLogging()
logging.disable(logging.INFO)

View file

@ -0,0 +1,40 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test import (test_api, test_autodetect, test_autodetect_all, test_doctests,
test_episode, test_hashes, test_language, test_main,
test_matchtree, test_movie, test_quality, test_utils)
from unittest import TextTestRunner
import logging
def main():
for suite in [test_api.suite, test_autodetect.suite,
test_autodetect_all.suite, test_doctests.suite,
test_episode.suite, test_hashes.suite, test_language.suite,
test_main.suite, test_matchtree.suite, test_movie.suite,
test_quality.suite, test_utils.suite]:
TextTestRunner(verbosity=2).run(suite)
if __name__ == '__main__':
main()

View file

@ -0,0 +1,289 @@
? Movies/Fear and Loathing in Las Vegas (1998)/Fear.and.Loathing.in.Las.Vegas.720p.HDDVD.DTS.x264-ESiR.mkv
: type: movie
title: Fear and Loathing in Las Vegas
year: 1998
screenSize: 720p
format: HD-DVD
audioCodec: DTS
videoCodec: h264
releaseGroup: ESiR
? Leopard.dmg
: type: unknown
extension: dmg
? Series/Duckman/Duckman - 101 (01) - 20021107 - I, Duckman.avi
: type: episode
series: Duckman
season: 1
episodeNumber: 1
title: I, Duckman
date: 2002-11-07
? Series/Neverwhere/Neverwhere.05.Down.Street.[tvu.org.ru].avi
: type: episode
series: Neverwhere
episodeNumber: 5
title: Down Street
website: tvu.org.ru
? Neverwhere.05.Down.Street.[tvu.org.ru].avi
: type: episode
series: Neverwhere
episodeNumber: 5
title: Down Street
website: tvu.org.ru
? Series/Breaking Bad/Minisodes/Breaking.Bad.(Minisodes).01.Good.Cop.Bad.Cop.WEBRip.XviD.avi
: type: episode
series: Breaking Bad
episodeFormat: Minisode
episodeNumber: 1
title: Good Cop Bad Cop
format: WEBRip
videoCodec: XviD
? Series/Kaamelott/Kaamelott - Livre V - Ep 23 - Le Forfait.avi
: type: episode
series: Kaamelott
episodeNumber: 23
title: Le Forfait
? Movies/The Doors (1991)/09.03.08.The.Doors.(1991).BDRip.720p.AC3.X264-HiS@SiLUHD-English.[sharethefiles.com].mkv
: type: movie
title: The Doors
year: 1991
date: 2008-03-09
format: BluRay
screenSize: 720p
audioCodec: AC3
videoCodec: h264
releaseGroup: HiS@SiLUHD
language: english
website: sharethefiles.com
? Movies/M.A.S.H. (1970)/MASH.(1970).[Divx.5.02][Dual-Subtitulos][DVDRip].ogm
: type: movie
title: M.A.S.H.
year: 1970
videoCodec: DivX
format: DVD
? the.mentalist.501.hdtv-lol.mp4
: type: episode
series: The Mentalist
season: 5
episodeNumber: 1
format: HDTV
releaseGroup: LOL
? the.simpsons.2401.hdtv-lol.mp4
: type: episode
series: The Simpsons
season: 24
episodeNumber: 1
format: HDTV
releaseGroup: LOL
? Homeland.S02E01.HDTV.x264-EVOLVE.mp4
: type: episode
series: Homeland
season: 2
episodeNumber: 1
format: HDTV
videoCodec: h264
releaseGroup: EVOLVE
? /media/Band_of_Brothers-e01-Currahee.mkv
: type: episode
series: Band of Brothers
episodeNumber: 1
title: Currahee
? /media/Band_of_Brothers-x02-We_Stand_Alone_Together.mkv
: type: episode
series: Band of Brothers
bonusNumber: 2
bonusTitle: We Stand Alone Together
? /movies/James_Bond-f21-Casino_Royale-x02-Stunts.mkv
: type: movie
title: Casino Royale
filmSeries: James Bond
filmNumber: 21
bonusNumber: 2
bonusTitle: Stunts
? /TV Shows/new.girl.117.hdtv-lol.mp4
: type: episode
series: New Girl
season: 1
episodeNumber: 17
format: HDTV
releaseGroup: LOL
? The.Office.(US).1x03.Health.Care.HDTV.XviD-LOL.avi
: type: episode
series: The Office (US)
country: US
season: 1
episodeNumber: 3
title: Health Care
format: HDTV
videoCodec: XviD
releaseGroup: LOL
? The_Insider-(1999)-x02-60_Minutes_Interview-1996.mp4
: type: movie
title: The Insider
year: 1999
bonusNumber: 2
bonusTitle: 60 Minutes Interview-1996
? OSS_117--Cairo,_Nest_of_Spies.mkv
: type: movie
title: OSS 117--Cairo, Nest of Spies
? Rush.._Beyond_The_Lighted_Stage-x09-Between_Sun_and_Moon-2002_Hartford.mkv
: type: movie
title: Rush Beyond The Lighted Stage
bonusNumber: 9
bonusTitle: Between Sun and Moon-2002 Hartford
? House.Hunters.International.S56E06.720p.hdtv.x264.mp4
: type: episode
series: House Hunters International
season: 56
episodeNumber: 6
screenSize: 720p
format: HDTV
videoCodec: h264
? White.House.Down.2013.1080p.BluRay.DTS-HD.MA.5.1.x264-PublicHD.mkv
: type: movie
title: White House Down
year: 2013
screenSize: 1080p
format: BluRay
audioCodec: DTS
audioProfile: HDMA
videoCodec: h264
releaseGroup: PublicHD
audioChannels: "5.1"
? Hostages.S01E01.Pilot.for.Air.720p.WEB-DL.DD5.1.H.264-NTb.nfo
: type: episodeinfo
series: Hostages
title: Pilot for Air
season: 1
episodeNumber: 1
screenSize: 720p
format: WEB-DL
audioChannels: "5.1"
videoCodec: h264
audioCodec: DolbyDigital
releaseGroup: NTb
? Despicable.Me.2.2013.1080p.BluRay.x264-VeDeTT.nfo
: type: movieinfo
title: Despicable Me 2
year: 2013
screenSize: 1080p
format: BluRay
videoCodec: h264
releaseGroup: VeDeTT
? Le Cinquieme Commando 1971 SUBFORCED FRENCH DVDRiP XViD AC3 Bandix.mkv
: type: movie
audioCodec: AC3
format: DVD
releaseGroup: Bandix
subtitleLanguage: French
title: Le Cinquieme Commando
videoCodec: XviD
year: 1971
? Le Seigneur des Anneaux - La Communauté de l'Anneau - Version Longue - BDRip.mkv
: type: movie
format: BluRay
title: Le Seigneur des Anneaux
? La petite bande (Michel Deville - 1983) VF PAL MP4 x264 AAC.mkv
: type: movie
audioCodec: AAC
language: French
title: La petite bande
videoCodec: h264
year: 1983
? Retour de Flammes (Gregor Schnitzler 2003) FULL DVD.iso
: type: movie
format: DVD
title: Retour de Flammes
type: movie
year: 2003
? A.Common.Title.Special.2014.avi
: type: movie
year: 2014
title: A Common Title Special
? A.Common.Title.2014.Special.avi
: type: episode
year: 2014
series: A Common Title
title: Special
special: Special
? A.Common.Title.2014.Special.Edition.avi
: type: movie
year: 2014
title: A Common Title
edition: Special Edition
? Downton.Abbey.2013.Christmas.Special.HDTV.x264-FoV.mp4
: type: episode
year: 2013
series: Downton Abbey
title: Christmas Special
videoCodec: h264
releaseGroup: FoV
format: HDTV
special: Special
? Doctor_Who_2013_Christmas_Special.The_Time_of_The_Doctor.HD
: options: -n
type: episode
series: Doctor Who
other: HD
special: Special
title: Christmas Special The Time of The Doctor
year: 2013
? Doctor Who 2005 50th Anniversary Special The Day of the Doctor 3.avi
: type: episode
series: Doctor Who
special: Special
title: 50th Anniversary Special The Day of the Doctor 3
year: 2005
? Robot Chicken S06-Born Again Virgin Christmas Special HDTV x264.avi
: type: episode
series: Robot Chicken
format: HDTV
season: 6
title: Born Again Virgin Christmas Special
videoCodec: h264
special: Special
? Wicked.Tuna.S03E00.Head.To.Tail.Special.HDTV.x264-YesTV
: options: -n
type: episode
series: Wicked Tuna
title: Head To Tail Special
releaseGroup: YesTV
season: 3
episodeNumber: 0
videoCodec: h264
format: HDTV
special: Special

View file

@ -0,0 +1 @@
Just a dummy srt file (used for unittests: do not remove!)

View file

@ -0,0 +1,569 @@
# Dubious tests
#
#? "finale "
#: releaseGroup: FiNaLe
# extension: ""
? Series/Californication/Season 2/Californication.2x05.Vaginatown.HDTV.XviD-0TV.avi
: series: Californication
season: 2
episodeNumber: 5
title: Vaginatown
format: HDTV
videoCodec: XviD
releaseGroup: 0TV
? Series/dexter/Dexter.5x02.Hello,.Bandit.ENG.-.sub.FR.HDTV.XviD-AlFleNi-TeaM.[tvu.org.ru].avi
: series: Dexter
season: 5
episodeNumber: 2
title: Hello, Bandit
language: English
subtitleLanguage: French
format: HDTV
videoCodec: XviD
releaseGroup: AlFleNi-TeaM
website: tvu.org.ru
? Series/Treme/Treme.1x03.Right.Place,.Wrong.Time.HDTV.XviD-NoTV.avi
: series: Treme
season: 1
episodeNumber: 3
title: Right Place, Wrong Time
format: HDTV
videoCodec: XviD
releaseGroup: NoTV
? Series/Duckman/Duckman - 101 (01) - 20021107 - I, Duckman.avi
: series: Duckman
season: 1
episodeNumber: 1
title: I, Duckman
date: 2002-11-07
? Series/Duckman/Duckman - S1E13 Joking The Chicken (unedited).avi
: series: Duckman
season: 1
episodeNumber: 13
title: Joking The Chicken
? Series/Simpsons/Saison 12 Français/Simpsons,.The.12x08.A.Bas.Le.Sergent.Skinner.FR.avi
: series: The Simpsons
season: 12
episodeNumber: 8
title: A Bas Le Sergent Skinner
language: French
? Series/Futurama/Season 3 (mkv)/[™] Futurama - S03E22 - Le chef de fer à 30% ( 30 Percent Iron Chef ).mkv
: series: Futurama
season: 3
episodeNumber: 22
title: Le chef de fer à 30%
? Series/The Office/Season 6/The Office - S06xE01.avi
: series: The Office
season: 6
episodeNumber: 1
? series/The Office/Season 4/The Office [401] Fun Run.avi
: series: The Office
season: 4
episodeNumber: 1
title: Fun Run
? Series/Mad Men Season 1 Complete/Mad.Men.S01E01.avi
: series: Mad Men
season: 1
episodeNumber: 1
other: complete
? series/Psych/Psych S02 Season 2 Complete English DVD/Psych.S02E02.65.Million.Years.Off.avi
: series: Psych
season: 2
episodeNumber: 2
title: 65 Million Years Off
language: english
format: DVD
other: complete
? series/Psych/Psych S02 Season 2 Complete English DVD/Psych.S02E03.Psy.Vs.Psy.Français.srt
: series: Psych
season: 2
episodeNumber: 3
title: Psy Vs Psy
format: DVD
language: English
subtitleLanguage: French
other: complete
? Series/Pure Laine/Pure.Laine.1x01.Toutes.Couleurs.Unies.FR.(Québec).DVB-Kceb.[tvu.org.ru].avi
: series: Pure Laine
season: 1
episodeNumber: 1
title: Toutes Couleurs Unies
format: DVB
releaseGroup: Kceb
language: french
website: tvu.org.ru
? Series/Pure Laine/2x05 - Pure Laine - Je Me Souviens.avi
: series: Pure Laine
season: 2
episodeNumber: 5
title: Je Me Souviens
? Series/Tout sur moi/Tout sur moi - S02E02 - Ménage à trois (14-01-2008) [Rip by Ampli].avi
: series: Tout sur moi
season: 2
episodeNumber: 2
title: Ménage à trois
date: 2008-01-14
? The.Mentalist.2x21.18-5-4.ENG.-.sub.FR.HDTV.XviD-AlFleNi-TeaM.[tvu.org.ru].avi
: series: The Mentalist
season: 2
episodeNumber: 21
title: 18-5-4
language: english
subtitleLanguage: french
format: HDTV
videoCodec: Xvid
releaseGroup: AlFleNi-TeaM
website: tvu.org.ru
? series/__ Incomplete __/Dr Slump (Catalan)/Dr._Slump_-_003_DVB-Rip_Catalan_by_kelf.avi
: series: Dr Slump
episodeNumber: 3
format: DVB
language: catalan
? series/Ren and Stimpy - Black_hole_[DivX].avi
: series: Ren and Stimpy
title: Black hole
videoCodec: DivX
? Series/Walt Disney/Donald.Duck.-.Good.Scouts.[www.bigernie.jump.to].avi
: series: Donald Duck
title: Good Scouts
website: www.bigernie.jump.to
? Series/Neverwhere/Neverwhere.05.Down.Street.[tvu.org.ru].avi
: series: Neverwhere
episodeNumber: 5
title: Down Street
website: tvu.org.ru
? Series/South Park/Season 4/South.Park.4x07.Cherokee.Hair.Tampons.DVDRip.[tvu.org.ru].avi
: series: South Park
season: 4
episodeNumber: 7
title: Cherokee Hair Tampons
format: DVD
website: tvu.org.ru
? Series/Kaamelott/Kaamelott - Livre V - Ep 23 - Le Forfait.avi
: series: Kaamelott
episodeNumber: 23
title: Le Forfait
? Series/Duckman/Duckman - 110 (10) - 20021218 - Cellar Beware.avi
: series: Duckman
season: 1
episodeNumber: 10
date: 2002-12-18
title: Cellar Beware
? Series/Ren & Stimpy/Ren And Stimpy - Onward & Upward-Adult Party Cartoon.avi
: series: Ren And Stimpy
title: Onward & Upward-Adult Party Cartoon
? Series/Breaking Bad/Minisodes/Breaking.Bad.(Minisodes).01.Good.Cop.Bad.Cop.WEBRip.XviD.avi
: series: Breaking Bad
episodeFormat: Minisode
episodeNumber: 1
title: Good Cop Bad Cop
format: WEBRip
videoCodec: XviD
? Series/My Name Is Earl/My.Name.Is.Earl.S01Extras.-.Bad.Karma.DVDRip.XviD.avi
: series: My Name Is Earl
season: 1
title: Bad Karma
format: DVD
special: Extras
videoCodec: XviD
? /mnt/series/The Big Bang Theory/S01/The.Big.Bang.Theory.S01E01.mkv
: series: The Big Bang Theory
season: 1
episodeNumber: 1
? /media/Parks_and_Recreation-s03-e01.mkv
: series: Parks and Recreation
season: 3
episodeNumber: 1
? /media/Parks_and_Recreation-s03-e02-Flu_Season.mkv
: series: Parks and Recreation
season: 3
title: Flu Season
episodeNumber: 2
? /media/Parks_and_Recreation-s03-x01.mkv
: series: Parks and Recreation
season: 3
bonusNumber: 1
? /media/Parks_and_Recreation-s03-x02-Gag_Reel.mkv
: series: Parks and Recreation
season: 3
bonusNumber: 2
bonusTitle: Gag Reel
? /media/Band_of_Brothers-e01-Currahee.mkv
: series: Band of Brothers
episodeNumber: 1
title: Currahee
? /media/Band_of_Brothers-x02-We_Stand_Alone_Together.mkv
: series: Band of Brothers
bonusNumber: 2
bonusTitle: We Stand Alone Together
? /TV Shows/Mad.M-5x9.mkv
: series: Mad M
season: 5
episodeNumber: 9
? /TV Shows/new.girl.117.hdtv-lol.mp4
: series: New Girl
season: 1
episodeNumber: 17
format: HDTV
releaseGroup: LOL
? Kaamelott - 5x44x45x46x47x48x49x50.avi
: series: Kaamelott
season: 5
episodeNumber: 44
episodeList: [44, 45, 46, 47, 48, 49, 50]
? Example S01E01-02.avi
: series: Example
season: 1
episodeNumber: 1
episodeList: [1, 2]
? Example S01E01E02.avi
: series: Example
season: 1
episodeNumber: 1
episodeList: [1, 2]
? Series/Baccano!/Baccano!_-_T1_-_Trailer_-_[Ayu](dae8173e).mkv
: series: Baccano!
other: Trailer
? Series/Doctor Who (2005)/Season 06/Doctor Who (2005) - S06E01 - The Impossible Astronaut (1).avi
: series: Doctor Who
year: 2005
season: 6
episodeNumber: 1
title: The Impossible Astronaut
? The.Office.(US).1x03.Health.Care.HDTV.XviD-LOL.avi
: series: The Office (US)
country: US
season: 1
episodeNumber: 3
title: Health Care
format: HDTV
videoCodec: XviD
releaseGroup: LOL
? /Volumes/data-1/Series/Futurama/Season 3/Futurama_-_S03_DVD_Bonus_-_Deleted_Scenes_Part_3.ogm
: series: Futurama
season: 3
other: Bonus
title: Deleted Scenes Part 3
format: DVD
? Ben.and.Kate.S01E02.720p.HDTV.X264-DIMENSION.mkv
: series: Ben and Kate
season: 1
episodeNumber: 2
screenSize: 720p
format: HDTV
videoCodec: h264
releaseGroup: DIMENSION
? /volume1/TV Series/Drawn Together/Season 1/Drawn Together 1x04 Requiem for a Reality Show.avi
: series: Drawn Together
season: 1
episodeNumber: 4
title: Requiem for a Reality Show
? Sons.of.Anarchy.S05E06.720p.WEB.DL.DD5.1.H.264-CtrlHD.mkv
: series: Sons of Anarchy
season: 5
episodeNumber: 6
screenSize: 720p
format: WEB-DL
audioChannels: "5.1"
audioCodec: DolbyDigital
videoCodec: h264
releaseGroup: CtrlHD
? /media/bdc64bfe-e36f-4af8-b550-e6fd2dfaa507/TV_Shows/Doctor Who (2005)/Saison 6/Doctor Who (2005) - S06E13 - The Wedding of River Song.mkv
: series: Doctor Who
season: 6
episodeNumber: 13
year: 2005
title: The Wedding of River Song
idNumber: bdc64bfe-e36f-4af8-b550-e6fd2dfaa507
? /mnt/videos/tvshows/Doctor Who/Season 06/E13 - The Wedding of River Song.mkv
: series: Doctor Who
season: 6
episodeNumber: 13
title: The Wedding of River Song
? The.Simpsons.S24E03.Adventures.in.Baby-Getting.720p.WEB-DL.DD5.1.H.264-CtrlHD.mkv
: series: The Simpsons
season: 24
episodeNumber: 3
title: Adventures in Baby-Getting
screenSize: 720p
format: WEB-DL
audioChannels: "5.1"
audioCodec: DolbyDigital
videoCodec: h264
releaseGroup: CtrlHD
? /home/disaster/Videos/TV/Merlin/merlin_2008.5x02.arthurs_bane_part_two.repack.720p_hdtv_x264-fov.mkv
: series: Merlin
season: 5
episodeNumber: 2
title: Arthurs bane part two
screenSize: 720p
format: HDTV
videoCodec: h264
releaseGroup: Fov
year: 2008
other: Proper
? "Da Vinci's Demons - 1x04 - The Magician.mkv"
: series: "Da Vinci's Demons"
season: 1
episodeNumber: 4
title: The Magician
? CSI.S013E18.Sheltered.720p.WEB-DL.DD5.1.H.264.mkv
: series: CSI
season: 13
episodeNumber: 18
title: Sheltered
screenSize: 720p
format: WEB-DL
audioChannels: "5.1"
audioCodec: DolbyDigital
videoCodec: h264
? Game of Thrones S03E06 1080i HDTV DD5.1 MPEG2-TrollHD.ts
: series: Game of Thrones
season: 3
episodeNumber: 6
screenSize: 1080i
format: HDTV
audioChannels: "5.1"
audioCodec: DolbyDigital
videoCodec: MPEG2
releaseGroup: TrollHD
? gossip.girl.s01e18.hdtv.xvid-2hd.eng.srt
: series: gossip girl
season: 1
episodeNumber: 18
format: HDTV
videoCodec: XviD
releaseGroup: 2HD
subtitleLanguage: english
? Wheels.S03E01E02.720p.HDTV.x264-IMMERSE.mkv
: series: Wheels
season: 3
episodeNumber: 1
episodeList: [1, 2]
screenSize: 720p
format: HDTV
videoCodec: h264
releaseGroup: IMMERSE
? Wheels.S03E01-02.720p.HDTV.x264-IMMERSE.mkv
: series: Wheels
season: 3
episodeNumber: 1
episodeList: [1, 2]
screenSize: 720p
format: HDTV
videoCodec: h264
releaseGroup: IMMERSE
? Wheels.S03E01-E02.720p.HDTV.x264-IMMERSE.mkv
: series: Wheels
season: 3
episodeNumber: 1
episodeList: [1, 2]
screenSize: 720p
format: HDTV
videoCodec: h264
releaseGroup: IMMERSE
? Wheels.S03E01-03.720p.HDTV.x264-IMMERSE.mkv
: series: Wheels
season: 3
episodeNumber: 1
episodeList: [1, 2, 3]
screenSize: 720p
format: HDTV
videoCodec: h264
releaseGroup: IMMERSE
? Marvels.Agents.of.S.H.I.E.L.D.S01E06.720p.HDTV.X264-DIMENSION.mkv
: series: Marvels Agents of S.H.I.E.L.D.
season: 1
episodeNumber: 6
screenSize: 720p
format: HDTV
videoCodec: h264
releaseGroup: DIMENSION
? Marvels.Agents.of.S.H.I.E.L.D..S01E06.720p.HDTV.X264-DIMENSION.mkv
: series: Marvels Agents of S.H.I.E.L.D.
season: 1
episodeNumber: 6
screenSize: 720p
format: HDTV
videoCodec: h264
releaseGroup: DIMENSION
? Series/Friday Night Lights/Season 1/Friday Night Lights S01E19 - Ch-Ch-Ch-Ch-Changes.avi
: series: Friday Night Lights
season: 1
episodeNumber: 19
title: Ch-Ch-Ch-Ch-Changes
? Dexter Saison VII FRENCH.BDRip.XviD-MiND.nfo
: series: Dexter
season: 7
videoCodec: XviD
language: French
format: BluRay
releaseGroup: MiND
? Dexter Saison sept FRENCH.BDRip.XviD-MiND.nfo
: series: Dexter
season: 7
videoCodec: XviD
language: French
format: BluRay
releaseGroup: MiND
? "Pokémon S16 - E29 - 1280*720 HDTV VF.mkv"
: series: Pokémon
format: HDTV
language: French
season: 16
episodeNumber: 29
screenSize: 720p
? One.Piece.E576.VOSTFR.720p.HDTV.x264-MARINE-FORD.mkv
: episodeNumber: 576
videoCodec: h264
format: HDTV
series: One Piece
releaseGroup: MARINE-FORD
subtitleLanguage: French
screenSize: 720p
? Dexter.S08E12.FINAL.MULTi.1080p.BluRay.x264-MiND.mkv
: videoCodec: h264
episodeNumber: 12
season: 8
format: BluRay
series: Dexter
other: final
language: Multiple languages
releaseGroup: MiND
screenSize: 1080p
? One Piece - E623 VOSTFR HD [www.manga-ddl-free.com].mkv
: website: www.manga-ddl-free.com
episodeNumber: 623
subtitleLanguage: French
series: One Piece
other: HD
? Falling Skies Saison 1.HDLight.720p.x264.VFF.mkv
: language: French
screenSize: 720p
season: 1
series: Falling Skies
videoCodec: h264
? Sleepy.Hollow.S01E09.720p.WEB-DL.DD5.1.H.264-BP.mkv
: episodeNumber: 9
videoCodec: h264
format: WEB-DL
series: Sleepy Hollow
audioChannels: "5.1"
screenSize: 720p
season: 1
videoProfile: BP
audioCodec: DolbyDigital
? Sleepy.Hollow.S01E09.720p.WEB-DL.DD5.1.H.264-BS.mkv
: episodeNumber: 9
videoCodec: h264
format: WEB-DL
series: Sleepy Hollow
audioChannels: "5.1"
screenSize: 720p
season: 1
releaseGroup: BS
audioCodec: DolbyDigital
? Battlestar.Galactica.S00.Pilot.FRENCH.DVDRip.XviD-NOTAG.avi
: series: Battlestar Galactica
season: 0
title: Pilot
special: Pilot
language: French
format: DVD
videoCodec: XviD
releaseGroup: NOTAG
? The Big Bang Theory S00E00 Unaired Pilot VOSTFR TVRip XviD-VioCs
: options: -n
series: The Big Bang Theory
season: 0
episodeNumber: 0
subtitleLanguage: French
format: TV
videoCodec: XviD
releaseGroup: VioCs
special: [Unaired, Pilot]
title: Unaired Pilot
? The Big Bang Theory S01E00 PROPER Unaired Pilot TVRip XviD-GIGGITY
: options: -n
series: The Big Bang Theory
season: 1
episodeNumber: 0
format: TV
videoCodec: XviD
releaseGroup: GIGGITY
other: proper
special: [Unaired, Pilot]
title: Unaired Pilot

View file

@ -0,0 +1,168 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit import base_text_type, u
from unittest import TestCase, TestLoader, TextTestRunner
import shlex
import yaml, logging, sys, os
from os.path import *
def currentPath():
'''Returns the path in which the calling file is located.'''
return dirname(join(os.getcwd(), sys._getframe(1).f_globals['__file__']))
def addImportPath(path):
'''Function that adds the specified path to the import path. The path can be
absolute or relative to the calling file.'''
importPath = abspath(join(currentPath(), path))
sys.path = [importPath] + sys.path
log = logging.getLogger(__name__)
from guessit.plugins import transformers
import guessit
from guessit.options import option_parser
from guessit import *
from guessit.matcher import *
from guessit.fileutils import *
def allTests(testClass):
return TestLoader().loadTestsFromTestCase(testClass)
class TestGuessit(TestCase):
def checkMinimumFieldsCorrect(self, filename, filetype=None, remove_type=True,
exclude_files=None):
groundTruth = yaml.load(load_file_in_same_dir(__file__, filename))
def guess_func(string, options=None):
return guess_file_info(string, options=options, type=filetype)
return self.checkFields(groundTruth, guess_func, remove_type, exclude_files)
def checkFields(self, groundTruth, guess_func, remove_type=True,
exclude_files=None):
total = 0
exclude_files = exclude_files or []
fails = {}
additionals = {}
for filename, required_fields in groundTruth.items():
filename = u(filename)
if filename in exclude_files:
continue
log.debug('\n' + '-' * 120)
log.info('Guessing information for file: %s' % filename)
options = required_fields.pop('options') if 'options' in required_fields else None
if options:
args = shlex.split(options)
options, _ = option_parser.parse_args(args)
options = vars(options)
found = guess_func(filename, options)
total = total + 1
# no need for these in the unittests
if remove_type:
try:
del found['type']
except:
pass
for prop in ('container', 'mimetype'):
if prop in found:
del found[prop]
# props which are list of just 1 elem should be opened for easier writing of the tests
for prop in ('language', 'subtitleLanguage', 'other', 'special'):
value = found.get(prop, None)
if isinstance(value, list) and len(value) == 1:
found[prop] = value[0]
# look for missing properties
for prop, value in required_fields.items():
if prop not in found:
log.debug("Prop '%s' not found in: %s" % (prop, filename))
if not filename in fails:
fails[filename] = []
fails[filename].append("'%s' not found in: %s" % (prop, filename))
continue
# if both properties are strings, do a case-insensitive comparison
if (isinstance(value, base_text_type) and
isinstance(found[prop], base_text_type)):
if value.lower() != found[prop].lower():
log.debug("Wrong prop value [str] for '%s': expected = '%s' - received = '%s'" % (prop, u(value), u(found[prop])))
if not filename in fails:
fails[filename] = []
fails[filename].append("'%s': expected = '%s' - received = '%s'" % (prop, u(value), u(found[prop])))
# if both are lists, we assume list of strings and do a case-insensitive
# comparison on their elements
elif isinstance(value, list) and isinstance(found[prop], list):
s1 = set(u(s).lower() for s in value)
s2 = set(u(s).lower() for s in found[prop])
if s1 != s2:
log.debug("Wrong prop value [list] for '%s': expected = '%s' - received = '%s'" % (prop, u(value), u(found[prop])))
if not filename in fails:
fails[filename] = []
fails[filename].append("'%s': expected = '%s' - received = '%s'" % (prop, u(value), u(found[prop])))
# otherwise, just compare their values directly
else:
if found[prop] != value:
log.debug("Wrong prop value for '%s': expected = '%s' [%s] - received = '%s' [%s]" % (prop, u(value), type(value), u(found[prop]), type(found[prop])))
if not filename in fails:
fails[filename] = []
fails[filename].append("'%s': expected = '%s' [%s] - received = '%s' [%s]" % (prop, u(value), type(value), u(found[prop]), type(found[prop])))
# look for additional properties
for prop, value in found.items():
if prop not in required_fields:
log.debug("Found additional info for prop = '%s': '%s'" % (prop, u(value)))
if not filename in additionals:
additionals[filename] = []
additionals[filename].append("'%s': '%s'" % (prop, u(value)))
correct = total - len(fails)
log.info('SUMMARY: Guessed correctly %d out of %d filenames' % (correct, total))
for failed_entry, failed_properties in fails.items():
log.error('---- ' + failed_entry + ' ----')
for failed_property in failed_properties:
log.error("FAILED: " + failed_property)
for additional_entry, additional_properties in additionals.items():
log.warn('---- ' + additional_entry + ' ----')
for additional_property in additional_properties:
log.warn("ADDITIONAL: " + additional_property)
self.assertTrue(correct == total,
msg='Correct: %d < Total: %d' % (correct, total))

View file

@ -0,0 +1,626 @@
? Movies/Fear and Loathing in Las Vegas (1998)/Fear.and.Loathing.in.Las.Vegas.720p.HDDVD.DTS.x264-ESiR.mkv
: title: Fear and Loathing in Las Vegas
year: 1998
screenSize: 720p
format: HD-DVD
audioCodec: DTS
videoCodec: h264
releaseGroup: ESiR
? Movies/El Dia de la Bestia (1995)/El.dia.de.la.bestia.DVDrip.Spanish.DivX.by.Artik[SEDG].avi
: title: El Dia de la Bestia
year: 1995
format: DVD
language: spanish
videoCodec: DivX
? Movies/Dark City (1998)/Dark.City.(1998).DC.BDRip.720p.DTS.X264-CHD.mkv
: title: Dark City
year: 1998
format: BluRay
screenSize: 720p
audioCodec: DTS
videoCodec: h264
releaseGroup: CHD
? Movies/Sin City (BluRay) (2005)/Sin.City.2005.BDRip.720p.x264.AC3-SEPTiC.mkv
: title: Sin City
year: 2005
format: BluRay
screenSize: 720p
videoCodec: h264
audioCodec: AC3
releaseGroup: SEPTiC
? Movies/Borat (2006)/Borat.(2006).R5.PROPER.REPACK.DVDRip.XviD-PUKKA.avi
: title: Borat
year: 2006
other: PROPER
format: DVD
other: [ R5, Proper ]
videoCodec: XviD
releaseGroup: PUKKA
? "[XCT].Le.Prestige.(The.Prestige).DVDRip.[x264.HP.He-Aac.{Fr-Eng}.St{Fr-Eng}.Chaps].mkv"
: title: Le Prestige
format: DVD
videoCodec: h264
videoProfile: HP
audioCodec: AAC
audioProfile: HE
language: [ french, english ]
subtitleLanguage: [ french, english ]
? Battle Royale (2000)/Battle.Royale.(Batoru.Rowaiaru).(2000).(Special.Edition).CD1of2.DVDRiP.XviD-[ZeaL].avi
: title: Battle Royale
year: 2000
edition: special edition
cdNumber: 1
cdNumberTotal: 2
format: DVD
videoCodec: XviD
releaseGroup: ZeaL
? Movies/Brazil (1985)/Brazil_Criterion_Edition_(1985).CD2.avi
: title: Brazil
edition: Criterion Edition
year: 1985
cdNumber: 2
? Movies/Persepolis (2007)/[XCT] Persepolis [H264+Aac-128(Fr-Eng)+ST(Fr-Eng)+Ind].mkv
: title: Persepolis
year: 2007
videoCodec: h264
audioCodec: AAC
language: [ French, English ]
subtitleLanguage: [ French, English ]
? Movies/Toy Story (1995)/Toy Story [HDTV 720p English-Spanish].mkv
: title: Toy Story
year: 1995
format: HDTV
screenSize: 720p
language: [ english, spanish ]
? Movies/Office Space (1999)/Office.Space.[Dual-DVDRip].[Spanish-English].[XviD-AC3-AC3].[by.Oswald].avi
: title: Office Space
year: 1999
format: DVD
language: [ english, spanish ]
videoCodec: XviD
audioCodec: AC3
? Movies/Wild Zero (2000)/Wild.Zero.DVDivX-EPiC.avi
: title: Wild Zero
year: 2000
videoCodec: DivX
releaseGroup: EPiC
? movies/Baraka_Edition_Collector.avi
: title: Baraka
edition: collector edition
? Movies/Blade Runner (1982)/Blade.Runner.(1982).(Director's.Cut).CD1.DVDRip.XviD.AC3-WAF.avi
: title: Blade Runner
year: 1982
edition: Director's Cut
cdNumber: 1
format: DVD
videoCodec: XviD
audioCodec: AC3
releaseGroup: WAF
? movies/American.The.Bill.Hicks.Story.2009.DVDRip.XviD-EPiSODE.[UsaBit.com]/UsaBit.com_esd-americanbh.avi
: title: American The Bill Hicks Story
year: 2009
format: DVD
videoCodec: XviD
releaseGroup: EPiSODE
website: UsaBit.com
? movies/Charlie.And.Boots.DVDRip.XviD-TheWretched/wthd-cab.avi
: title: Charlie And Boots
format: DVD
videoCodec: XviD
releaseGroup: TheWretched
? movies/Steig Larsson Millenium Trilogy (2009) BRrip 720 AAC x264/(1)The Girl With The Dragon Tattoo (2009) BRrip 720 AAC x264.mkv
: title: The Girl With The Dragon Tattoo
filmSeries: Steig Larsson Millenium Trilogy
filmNumber: 1
year: 2009
format: BluRay
audioCodec: AAC
videoCodec: h264
screenSize: 720p
? movies/Greenberg.REPACK.LiMiTED.DVDRip.XviD-ARROW/arw-repack-greenberg.dvdrip.xvid.avi
: title: Greenberg
format: DVD
videoCodec: XviD
releaseGroup: ARROW
other: ['Proper', 'Limited']
? Movies/Fr - Paris 2054, Renaissance (2005) - De Christian Volckman - (Film Divx Science Fiction Fantastique Thriller Policier N&B).avi
: title: Paris 2054, Renaissance
year: 2005
language: french
videoCodec: DivX
? Movies/[阿维达].Avida.2006.FRENCH.DVDRiP.XViD-PROD.avi
: title: Avida
year: 2006
language: french
format: DVD
videoCodec: XviD
releaseGroup: PROD
? Movies/Alice in Wonderland DVDRip.XviD-DiAMOND/dmd-aw.avi
: title: Alice in Wonderland
format: DVD
videoCodec: XviD
releaseGroup: DiAMOND
? Movies/Ne.Le.Dis.A.Personne.Fr 2 cd/personnea_mp.avi
: title: Ne Le Dis A Personne
language: french
cdNumberTotal: 2
? Movies/Bunker Palace Hôtel (Enki Bilal) (1989)/Enki Bilal - Bunker Palace Hotel (Fr Vhs Rip).avi
: title: Bunker Palace Hôtel
year: 1989
language: french
format: VHS
? Movies/21 (2008)/21.(2008).DVDRip.x264.AC3-FtS.[sharethefiles.com].mkv
: title: "21"
year: 2008
format: DVD
videoCodec: h264
audioCodec: AC3
releaseGroup: FtS
website: sharethefiles.com
? Movies/9 (2009)/9.2009.Blu-ray.DTS.720p.x264.HDBRiSe.[sharethefiles.com].mkv
: title: "9"
year: 2009
format: BluRay
audioCodec: DTS
screenSize: 720p
videoCodec: h264
releaseGroup: HDBRiSe
website: sharethefiles.com
? Movies/Mamma.Mia.2008.DVDRip.AC3.XviD-CrazyTeam/Mamma.Mia.2008.DVDRip.AC3.XviD-CrazyTeam.avi
: title: Mamma Mia
year: 2008
format: DVD
audioCodec: AC3
videoCodec: XviD
releaseGroup: CrazyTeam
? Movies/M.A.S.H. (1970)/MASH.(1970).[Divx.5.02][Dual-Subtitulos][DVDRip].ogm
: title: M.A.S.H.
year: 1970
videoCodec: DivX
format: DVD
? Movies/The Doors (1991)/09.03.08.The.Doors.(1991).BDRip.720p.AC3.X264-HiS@SiLUHD-English.[sharethefiles.com].mkv
: title: The Doors
year: 1991
date: 2008-03-09
format: BluRay
screenSize: 720p
audioCodec: AC3
videoCodec: h264
releaseGroup: HiS@SiLUHD
language: english
website: sharethefiles.com
? Movies/Ratatouille/video_ts-ratatouille.srt
: title: Ratatouille
format: DVD
? Movies/001 __ A classer/Fantomas se déchaine - Louis de Funès.avi
: title: Fantomas se déchaine
? Movies/Comme une Image (2004)/Comme.Une.Image.FRENCH.DVDRiP.XViD-NTK.par-www.divx-overnet.com.avi
: title: Comme une Image
year: 2004
language: french
format: DVD
videoCodec: XviD
releaseGroup: NTK
website: www.divx-overnet.com
? Movies/Fantastic Mr Fox/Fantastic.Mr.Fox.2009.DVDRip.{x264+LC-AAC.5.1}{Fr-Eng}{Sub.Fr-Eng}-™.[sharethefiles.com].mkv
: title: Fantastic Mr Fox
year: 2009
format: DVD
videoCodec: h264
audioCodec: AAC
audioProfile: LC
audioChannels: "5.1"
language: [ french, english ]
subtitleLanguage: [ french, english ]
website: sharethefiles.com
? Movies/Somewhere.2010.DVDRip.XviD-iLG/i-smwhr.avi
: title: Somewhere
year: 2010
format: DVD
videoCodec: XviD
releaseGroup: iLG
? Movies/Moon_(2009).mkv
: title: Moon
year: 2009
? Movies/Moon_(2009)-x01.mkv
: title: Moon
year: 2009
bonusNumber: 1
? Movies/Moon_(2009)-x02-Making_Of.mkv
: title: Moon
year: 2009
bonusNumber: 2
bonusTitle: Making Of
? movies/James_Bond-f17-Goldeneye.mkv
: title: Goldeneye
filmSeries: James Bond
filmNumber: 17
? /movies/James_Bond-f21-Casino_Royale.mkv
: title: Casino Royale
filmSeries: James Bond
filmNumber: 21
? /movies/James_Bond-f21-Casino_Royale-x01-Becoming_Bond.mkv
: title: Casino Royale
filmSeries: James Bond
filmNumber: 21
bonusNumber: 1
bonusTitle: Becoming Bond
? /movies/James_Bond-f21-Casino_Royale-x02-Stunts.mkv
: title: Casino Royale
filmSeries: James Bond
filmNumber: 21
bonusNumber: 2
bonusTitle: Stunts
? OSS_117--Cairo,_Nest_of_Spies.mkv
: title: OSS 117--Cairo, Nest of Spies
? The Godfather Part III.mkv
: title: The Godfather Part III
? Foobar Part VI.mkv
: title: Foobar Part VI
? The_Insider-(1999)-x02-60_Minutes_Interview-1996.mp4
: title: The Insider
year: 1999
bonusNumber: 2
bonusTitle: 60 Minutes Interview-1996
? Rush.._Beyond_The_Lighted_Stage-x09-Between_Sun_and_Moon-2002_Hartford.mkv
: title: Rush Beyond The Lighted Stage
bonusNumber: 9
bonusTitle: Between Sun and Moon-2002 Hartford
? /public/uTorrent/Downloads Finished/Movies/Indiana.Jones.and.the.Temple.of.Doom.1984.HDTV.720p.x264.AC3.5.1-REDµX/Indiana.Jones.and.the.Temple.of.Doom.1984.HDTV.720p.x264.AC3.5.1-REDµX.mkv
: title: Indiana Jones and the Temple of Doom
year: 1984
format: HDTV
screenSize: 720p
videoCodec: h264
audioCodec: AC3
audioChannels: "5.1"
releaseGroup: REDµX
? The.Directors.Notebook.2006.Blu-Ray.x264.DXVA.720p.AC3-de[42].mkv
: title: The Directors Notebook
year: 2006
format: BluRay
videoCodec: h264
videoApi: DXVA
screenSize: 720p
audioCodec: AC3
releaseGroup: de[42]
? Movies/Cosmopolis.2012.LiMiTED.720p.BluRay.x264-AN0NYM0US[bb]/ano-cosmo.720p.mkv
: title: Cosmopolis
year: 2012
screenSize: 720p
videoCodec: h264
releaseGroup: AN0NYM0US[bb]
format: BluRay
other: LIMITED
? movies/La Science des Rêves (2006)/La.Science.Des.Reves.FRENCH.DVDRip.XviD-MP-AceBot.avi
: title: La Science des Rêves
year: 2006
format: DVD
videoCodec: XviD
videoProfile: MP
releaseGroup: AceBot
language: French
? The_Italian_Job.mkv
: title: The Italian Job
? The.Rum.Diary.2011.1080p.BluRay.DTS.x264.D-Z0N3.mkv
: title: The Rum Diary
year: 2011
screenSize: 1080p
format: BluRay
videoCodec: h264
audioCodec: DTS
releaseGroup: D-Z0N3
? Life.Of.Pi.2012.1080p.BluRay.DTS.x264.D-Z0N3.mkv
: title: Life Of Pi
year: 2012
screenSize: 1080p
format: BluRay
videoCodec: h264
audioCodec: DTS
releaseGroup: D-Z0N3
? The.Kings.Speech.2010.1080p.BluRay.DTS.x264.D Z0N3.mkv
: title: The Kings Speech
year: 2010
screenSize: 1080p
format: BluRay
audioCodec: DTS
videoCodec: h264
releaseGroup: D-Z0N3
? Street.Kings.2008.BluRay.1080p.DTS.x264.dxva EuReKA.mkv
: title: Street Kings
year: 2008
format: BluRay
screenSize: 1080p
audioCodec: DTS
videoCodec: h264
videoApi: DXVA
releaseGroup: EuReKa
? 2001.A.Space.Odyssey.1968.HDDVD.1080p.DTS.x264.dxva EuReKA.mkv
: title: 2001 A Space Odyssey
year: 1968
format: HD-DVD
screenSize: 1080p
audioCodec: DTS
videoCodec: h264
videoApi: DXVA
releaseGroup: EuReKa
? 2012.2009.720p.BluRay.x264.DTS WiKi.mkv
: title: "2012"
year: 2009
screenSize: 720p
format: BluRay
videoCodec: h264
audioCodec: DTS
releaseGroup: WiKi
? /share/Download/movie/Dead Man Down (2013) BRRiP XViD DD5_1 Custom NLSubs =-_lt Q_o_Q gt-=_/XD607ebb-BRc59935-5155473f-1c5f49/XD607ebb-BRc59935-5155473f-1c5f49.avi
: title: Dead Man Down
year: 2013
format: BluRay
videoCodec: XviD
audioChannels: "5.1"
audioCodec: DolbyDigital
idNumber: XD607ebb-BRc59935-5155473f-1c5f49
? Pacific.Rim.3D.2013.COMPLETE.BLURAY-PCH.avi
: title: Pacific Rim
year: 2013
format: BluRay
other:
- complete
- 3D
releaseGroup: PCH
? Immersion.French.2011.STV.READNFO.QC.FRENCH.ENGLISH.NTSC.DVDR.nfo
: title: Immersion French
year: 2011
language:
- French
- English
? Immersion.French.2011.STV.READNFO.QC.FRENCH.NTSC.DVDR.nfo
: title: Immersion French
year: 2011
language: French
? Immersion.French.2011.STV.READNFO.QC.NTSC.DVDR.nfo
: title: Immersion French
year: 2011
? French.Immersion.2011.STV.READNFO.QC.ENGLISH.NTSC.DVDR.nfo
: title: French Immersion
year: 2011
language: ENGLISH
? Howl's_Moving_Castle_(2004)_[720p,HDTV,x264,DTS]-FlexGet.avi
: videoCodec: h264
format: HDTV
title: Howl's Moving Castle
screenSize: 720p
year: 2004
audioCodec: DTS
releaseGroup: FlexGet
? Pirates de langkasuka.2008.FRENCH.1920X1080.h264.AVC.AsiaRa.mkv
: screenSize: 1080p
year: 2008
language: French
videoCodec: h264
title: Pirates de langkasuka
releaseGroup: AsiaRa
? Masala (2013) Telugu Movie HD DVDScr XviD - Exclusive.avi
: year: 2013
videoCodec: XviD
title: Masala
format: HD-DVD
other: screener
language: Telugu
releaseGroup: Exclusive
? Django Unchained 2012 DVDSCR X264 AAC-P2P.nfo
: year: 2012
other: screener
videoCodec: h264
title: Django Unchained
audioCodec: AAC
format: DVD
releaseGroup: P2P
? Ejecutiva.En.Apuros(2009).BLURAY.SCR.Xvid.Spanish.LanzamientosD.nfo
: year: 2009
other: screener
format: BluRay
videoCodec: XviD
language: Spanish
title: Ejecutiva En Apuros
? Die.Schluempfe.2.German.DL.1080p.BluRay.x264-EXQUiSiTE.mkv
: title: Die Schluempfe 2
format: BluRay
language:
- Multiple languages
- German
videoCodec: h264
releaseGroup: EXQUiSiTE
screenSize: 1080p
? Rocky 1976 French SubForced BRRip x264 AC3-FUNKY.mkv
: title: Rocky
year: 1976
subtitleLanguage: French
format: BluRay
videoCodec: h264
audioCodec: AC3
releaseGroup: FUNKY
? REDLINE (BD 1080p H264 10bit FLAC) [3xR].mkv
: title: REDLINE
format: BluRay
videoCodec: h264
videoProfile: 10bit
audioCodec: Flac
screenSize: 1080p
? The.Lizzie.McGuire.Movie.(2003).HR.DVDRiP.avi
: title: The Lizzie McGuire Movie
year: 2003
screenSize: 480p
format: DVD
? Hua.Mulan.BRRIP.MP4.x264.720p-HR.avi
: title: Hua Mulan
videoCodec: h264
format: BluRay
screenSize: 720p
? Dr.Seuss.The.Lorax.2012.DVDRip.LiNE.XviD.AC3.HQ.Hive-CM8.mp4
: videoCodec: XviD
title: Dr Seuss The Lorax
format: DVD
other: LiNE
year: 2012
audioCodec: AC3
audioProfile: HQ
releaseGroup: Hive-CM8
? "Star Wars: Episode IV - A New Hope (2004) Special Edition.MKV"
: title: Star Wars Episode IV
year: 2004
edition: Special Edition
? Dr.LiNE.The.Lorax.2012.DVDRip.LiNE.XviD.AC3.HQ.Hive-CM8.mp4
: videoCodec: XviD
title: Dr LiNE The Lorax
format: DVD
other: LiNE
year: 2012
audioCodec: AC3
audioProfile: HQ
releaseGroup: Hive-CM8
? Perfect Child-2007-TRUEFRENCH-TVRip.Xvid-h@mster.avi
: releaseGroup: h@mster
title: Perfect Child
videoCodec: XviD
language: French
format: TV
year: 2007
? entre.ciel.et.terre.(1994).dvdrip.h264.aac-psypeon.avi
: audioCodec: AAC
format: DVD
releaseGroup: psypeon
title: entre ciel et terre
videoCodec: h264
year: 1994
? Yves.Saint.Laurent.2013.FRENCH.DVDSCR.MD.XviD-ViVARiUM.avi
: format: DVD
language: French
other: Screener
releaseGroup: ViVARiUM
title: Yves Saint Laurent
videoCodec: XviD
year: 2013
? Echec et Mort - Hard to Kill - Steven Seagal Multi 1080p BluRay x264 CCATS.avi
: format: BluRay
language: Multiple languages
releaseGroup: CCATS
screenSize: 1080p
title: Echec et Mort
videoCodec: h264
? Paparazzi - Timsit/Lindon (MKV 1080p tvripHD)
: options: -n
title: Paparazzi
screenSize: 1080p
format: HDTV
? some.movie.720p.bluray.x264-mind
: options: -n
title: some movie
screenSize: 720p
videoCodec: h264
releaseGroup: mind
format: BluRay
? Dr LiNE The Lorax 720p h264 BluRay
: options: -n
title: Dr LiNE The Lorax
screenSize: 720p
videoCodec: h264
format: BluRay
? BeatdownFrenchDVDRip.mkv
: title: Beatdown
language: French
format: DVD
? YvesSaintLaurent2013FrenchDVDScrXvid.avi
: format: DVD
language: French
other: Screener
title: Yves saint laurent
videoCodec: XviD
year: 2013

View file

@ -0,0 +1,473 @@
IdSubLanguage ISO639 LanguageName UploadEnabled WebEnabled
aar aa Afar, afar 0 0
abk ab Abkhazian 0 0
ace Achinese 0 0
ach Acoli 0 0
ada Adangme 0 0
ady adyghé 0 0
afa Afro-Asiatic (Other) 0 0
afh Afrihili 0 0
afr af Afrikaans 0 0
ain Ainu 0 0
aka ak Akan 0 0
akk Akkadian 0 0
alb sq Albanian 1 1
ale Aleut 0 0
alg Algonquian languages 0 0
alt Southern Altai 0 0
amh am Amharic 0 0
ang English, Old (ca.450-1100) 0 0
apa Apache languages 0 0
ara ar Arabic 1 1
arc Aramaic 0 0
arg an Aragonese 0 0
arm hy Armenian 1 0
arn Araucanian 0 0
arp Arapaho 0 0
art Artificial (Other) 0 0
arw Arawak 0 0
asm as Assamese 0 0
ast Asturian, Bable 0 0
ath Athapascan languages 0 0
aus Australian languages 0 0
ava av Avaric 0 0
ave ae Avestan 0 0
awa Awadhi 0 0
aym ay Aymara 0 0
aze az Azerbaijani 0 0
bad Banda 0 0
bai Bamileke languages 0 0
bak ba Bashkir 0 0
bal Baluchi 0 0
bam bm Bambara 0 0
ban Balinese 0 0
baq eu Basque 1 1
bas Basa 0 0
bat Baltic (Other) 0 0
bej Beja 0 0
bel be Belarusian 0 0
bem Bemba 0 0
ben bn Bengali 1 0
ber Berber (Other) 0 0
bho Bhojpuri 0 0
bih bh Bihari 0 0
bik Bikol 0 0
bin Bini 0 0
bis bi Bislama 0 0
bla Siksika 0 0
bnt Bantu (Other) 0 0
bos bs Bosnian 1 0
bra Braj 0 0
bre br Breton 1 0
btk Batak (Indonesia) 0 0
bua Buriat 0 0
bug Buginese 0 0
bul bg Bulgarian 1 1
bur my Burmese 0 0
byn Blin 0 0
cad Caddo 0 0
cai Central American Indian (Other) 0 0
car Carib 0 0
cat ca Catalan 1 1
cau Caucasian (Other) 0 0
ceb Cebuano 0 0
cel Celtic (Other) 0 0
cha ch Chamorro 0 0
chb Chibcha 0 0
che ce Chechen 0 0
chg Chagatai 0 0
chi zh Chinese 1 1
chk Chuukese 0 0
chm Mari 0 0
chn Chinook jargon 0 0
cho Choctaw 0 0
chp Chipewyan 0 0
chr Cherokee 0 0
chu cu Church Slavic 0 0
chv cv Chuvash 0 0
chy Cheyenne 0 0
cmc Chamic languages 0 0
cop Coptic 0 0
cor kw Cornish 0 0
cos co Corsican 0 0
cpe Creoles and pidgins, English based (Other) 0 0
cpf Creoles and pidgins, French-based (Other) 0 0
cpp Creoles and pidgins, Portuguese-based (Other) 0 0
cre cr Cree 0 0
crh Crimean Tatar 0 0
crp Creoles and pidgins (Other) 0 0
csb Kashubian 0 0
cus Cushitic (Other)' couchitiques, autres langues 0 0
cze cs Czech 1 1
dak Dakota 0 0
dan da Danish 1 1
dar Dargwa 0 0
day Dayak 0 0
del Delaware 0 0
den Slave (Athapascan) 0 0
dgr Dogrib 0 0
din Dinka 0 0
div dv Divehi 0 0
doi Dogri 0 0
dra Dravidian (Other) 0 0
dua Duala 0 0
dum Dutch, Middle (ca.1050-1350) 0 0
dut nl Dutch 1 1
dyu Dyula 0 0
dzo dz Dzongkha 0 0
efi Efik 0 0
egy Egyptian (Ancient) 0 0
eka Ekajuk 0 0
elx Elamite 0 0
eng en English 1 1
enm English, Middle (1100-1500) 0 0
epo eo Esperanto 1 0
est et Estonian 1 1
ewe ee Ewe 0 0
ewo Ewondo 0 0
fan Fang 0 0
fao fo Faroese 0 0
fat Fanti 0 0
fij fj Fijian 0 0
fil Filipino 0 0
fin fi Finnish 1 1
fiu Finno-Ugrian (Other) 0 0
fon Fon 0 0
fre fr French 1 1
frm French, Middle (ca.1400-1600) 0 0
fro French, Old (842-ca.1400) 0 0
fry fy Frisian 0 0
ful ff Fulah 0 0
fur Friulian 0 0
gaa Ga 0 0
gay Gayo 0 0
gba Gbaya 0 0
gem Germanic (Other) 0 0
geo ka Georgian 1 1
ger de German 1 1
gez Geez 0 0
gil Gilbertese 0 0
gla gd Gaelic 0 0
gle ga Irish 0 0
glg gl Galician 1 1
glv gv Manx 0 0
gmh German, Middle High (ca.1050-1500) 0 0
goh German, Old High (ca.750-1050) 0 0
gon Gondi 0 0
gor Gorontalo 0 0
got Gothic 0 0
grb Grebo 0 0
grc Greek, Ancient (to 1453) 0 0
ell el Greek 1 1
grn gn Guarani 0 0
guj gu Gujarati 0 0
gwi Gwich´in 0 0
hai Haida 0 0
hat ht Haitian 0 0
hau ha Hausa 0 0
haw Hawaiian 0 0
heb he Hebrew 1 1
her hz Herero 0 0
hil Hiligaynon 0 0
him Himachali 0 0
hin hi Hindi 1 1
hit Hittite 0 0
hmn Hmong 0 0
hmo ho Hiri Motu 0 0
hrv hr Croatian 1 1
hun hu Hungarian 1 1
hup Hupa 0 0
iba Iban 0 0
ibo ig Igbo 0 0
ice is Icelandic 1 1
ido io Ido 0 0
iii ii Sichuan Yi 0 0
ijo Ijo 0 0
iku iu Inuktitut 0 0
ile ie Interlingue 0 0
ilo Iloko 0 0
ina ia Interlingua (International Auxiliary Language Asso 0 0
inc Indic (Other) 0 0
ind id Indonesian 1 1
ine Indo-European (Other) 0 0
inh Ingush 0 0
ipk ik Inupiaq 0 0
ira Iranian (Other) 0 0
iro Iroquoian languages 0 0
ita it Italian 1 1
jav jv Javanese 0 0
jpn ja Japanese 1 1
jpr Judeo-Persian 0 0
jrb Judeo-Arabic 0 0
kaa Kara-Kalpak 0 0
kab Kabyle 0 0
kac Kachin 0 0
kal kl Kalaallisut 0 0
kam Kamba 0 0
kan kn Kannada 0 0
kar Karen 0 0
kas ks Kashmiri 0 0
kau kr Kanuri 0 0
kaw Kawi 0 0
kaz kk Kazakh 1 0
kbd Kabardian 0 0
kha Khasi 0 0
khi Khoisan (Other) 0 0
khm km Khmer 1 1
kho Khotanese 0 0
kik ki Kikuyu 0 0
kin rw Kinyarwanda 0 0
kir ky Kirghiz 0 0
kmb Kimbundu 0 0
kok Konkani 0 0
kom kv Komi 0 0
kon kg Kongo 0 0
kor ko Korean 1 1
kos Kosraean 0 0
kpe Kpelle 0 0
krc Karachay-Balkar 0 0
kro Kru 0 0
kru Kurukh 0 0
kua kj Kuanyama 0 0
kum Kumyk 0 0
kur ku Kurdish 0 0
kut Kutenai 0 0
lad Ladino 0 0
lah Lahnda 0 0
lam Lamba 0 0
lao lo Lao 0 0
lat la Latin 0 0
lav lv Latvian 1 0
lez Lezghian 0 0
lim li Limburgan 0 0
lin ln Lingala 0 0
lit lt Lithuanian 1 0
lol Mongo 0 0
loz Lozi 0 0
ltz lb Luxembourgish 1 0
lua Luba-Lulua 0 0
lub lu Luba-Katanga 0 0
lug lg Ganda 0 0
lui Luiseno 0 0
lun Lunda 0 0
luo Luo (Kenya and Tanzania) 0 0
lus lushai 0 0
mac mk Macedonian 1 1
mad Madurese 0 0
mag Magahi 0 0
mah mh Marshallese 0 0
mai Maithili 0 0
mak Makasar 0 0
mal ml Malayalam 0 0
man Mandingo 0 0
mao mi Maori 0 0
map Austronesian (Other) 0 0
mar mr Marathi 0 0
mas Masai 0 0
may ms Malay 1 1
mdf Moksha 0 0
mdr Mandar 0 0
men Mende 0 0
mga Irish, Middle (900-1200) 0 0
mic Mi'kmaq 0 0
min Minangkabau 0 0
mis Miscellaneous languages 0 0
mkh Mon-Khmer (Other) 0 0
mlg mg Malagasy 0 0
mlt mt Maltese 0 0
mnc Manchu 0 0
mni Manipuri 0 0
mno Manobo languages 0 0
moh Mohawk 0 0
mol mo Moldavian 0 0
mon mn Mongolian 1 0
mos Mossi 0 0
mwl Mirandese 0 0
mul Multiple languages 0 0
mun Munda languages 0 0
mus Creek 0 0
mwr Marwari 0 0
myn Mayan languages 0 0
myv Erzya 0 0
nah Nahuatl 0 0
nai North American Indian 0 0
nap Neapolitan 0 0
nau na Nauru 0 0
nav nv Navajo 0 0
nbl nr Ndebele, South 0 0
nde nd Ndebele, North 0 0
ndo ng Ndonga 0 0
nds Low German 0 0
nep ne Nepali 0 0
new Nepal Bhasa 0 0
nia Nias 0 0
nic Niger-Kordofanian (Other) 0 0
niu Niuean 0 0
nno nn Norwegian Nynorsk 0 0
nob nb Norwegian Bokmal 0 0
nog Nogai 0 0
non Norse, Old 0 0
nor no Norwegian 1 1
nso Northern Sotho 0 0
nub Nubian languages 0 0
nwc Classical Newari 0 0
nya ny Chichewa 0 0
nym Nyamwezi 0 0
nyn Nyankole 0 0
nyo Nyoro 0 0
nzi Nzima 0 0
oci oc Occitan 1 1
oji oj Ojibwa 0 0
ori or Oriya 0 0
orm om Oromo 0 0
osa Osage 0 0
oss os Ossetian 0 0
ota Turkish, Ottoman (1500-1928) 0 0
oto Otomian languages 0 0
paa Papuan (Other) 0 0
pag Pangasinan 0 0
pal Pahlavi 0 0
pam Pampanga 0 0
pan pa Panjabi 0 0
pap Papiamento 0 0
pau Palauan 0 0
peo Persian, Old (ca.600-400 B.C.) 0 0
per fa Persian 1 1
phi Philippine (Other) 0 0
phn Phoenician 0 0
pli pi Pali 0 0
pol pl Polish 1 1
pon Pohnpeian 0 0
por pt Portuguese 1 1
pra Prakrit languages 0 0
pro Provençal, Old (to 1500) 0 0
pus ps Pushto 0 0
que qu Quechua 0 0
raj Rajasthani 0 0
rap Rapanui 0 0
rar Rarotongan 0 0
roa Romance (Other) 0 0
roh rm Raeto-Romance 0 0
rom Romany 0 0
run rn Rundi 0 0
rup Aromanian 0 0
rus ru Russian 1 1
sad Sandawe 0 0
sag sg Sango 0 0
sah Yakut 0 0
sai South American Indian (Other) 0 0
sal Salishan languages 0 0
sam Samaritan Aramaic 0 0
san sa Sanskrit 0 0
sas Sasak 0 0
sat Santali 0 0
scc sr Serbian 1 1
scn Sicilian 0 0
sco Scots 0 0
sel Selkup 0 0
sem Semitic (Other) 0 0
sga Irish, Old (to 900) 0 0
sgn Sign Languages 0 0
shn Shan 0 0
sid Sidamo 0 0
sin si Sinhalese 1 1
sio Siouan languages 0 0
sit Sino-Tibetan (Other) 0 0
sla Slavic (Other) 0 0
slo sk Slovak 1 1
slv sl Slovenian 1 1
sma Southern Sami 0 0
sme se Northern Sami 0 0
smi Sami languages (Other) 0 0
smj Lule Sami 0 0
smn Inari Sami 0 0
smo sm Samoan 0 0
sms Skolt Sami 0 0
sna sn Shona 0 0
snd sd Sindhi 0 0
snk Soninke 0 0
sog Sogdian 0 0
som so Somali 0 0
son Songhai 0 0
sot st Sotho, Southern 0 0
spa es Spanish 1 1
srd sc Sardinian 0 0
srr Serer 0 0
ssa Nilo-Saharan (Other) 0 0
ssw ss Swati 0 0
suk Sukuma 0 0
sun su Sundanese 0 0
sus Susu 0 0
sux Sumerian 0 0
swa sw Swahili 1 0
swe sv Swedish 1 1
syr Syriac 1 0
tah ty Tahitian 0 0
tai Tai (Other) 0 0
tam ta Tamil 0 0
tat tt Tatar 0 0
tel te Telugu 0 0
tem Timne 0 0
ter Tereno 0 0
tet Tetum 0 0
tgk tg Tajik 0 0
tgl tl Tagalog 1 1
tha th Thai 1 1
tib bo Tibetan 0 0
tig Tigre 0 0
tir ti Tigrinya 0 0
tiv Tiv 0 0
tkl Tokelau 0 0
tlh Klingon 0 0
tli Tlingit 0 0
tmh Tamashek 0 0
tog Tonga (Nyasa) 0 0
ton to Tonga (Tonga Islands) 0 0
tpi Tok Pisin 0 0
tsi Tsimshian 0 0
tsn tn Tswana 0 0
tso ts Tsonga 0 0
tuk tk Turkmen 0 0
tum Tumbuka 0 0
tup Tupi languages 0 0
tur tr Turkish 1 1
tut Altaic (Other) 0 0
tvl Tuvalu 0 0
twi tw Twi 0 0
tyv Tuvinian 0 0
udm Udmurt 0 0
uga Ugaritic 0 0
uig ug Uighur 0 0
ukr uk Ukrainian 1 1
umb Umbundu 0 0
und Undetermined 0 0
urd ur Urdu 1 0
uzb uz Uzbek 0 0
vai Vai 0 0
ven ve Venda 0 0
vie vi Vietnamese 1 1
vol vo Volapük 0 0
vot Votic 0 0
wak Wakashan languages 0 0
wal Walamo 0 0
war Waray 0 0
was Washo 0 0
wel cy Welsh 0 0
wen Sorbian languages 0 0
wln wa Walloon 0 0
wol wo Wolof 0 0
xal Kalmyk 0 0
xho xh Xhosa 0 0
yao Yao 0 0
yap Yapese 0 0
yid yi Yiddish 0 0
yor yo Yoruba 0 0
ypk Yupik languages 0 0
zap Zapotec 0 0
zen Zenaga 0 0
zha za Zhuang 0 0
znd Zande 0 0
zul zu Zulu 0 0
zun Zuni 0 0
rum ro Romanian 1 1
pob pb Brazilian 1 1

View file

@ -0,0 +1,54 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2014 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test.guessittest import *
class TestApi(TestGuessit):
def test_api(self):
movie_path = 'Movies/Dark City (1998)/Dark.City.(1998).DC.BDRip.720p.DTS.X264-CHD.mkv'
movie_info = guessit.guess_movie_info(movie_path)
video_info = guessit.guess_video_info(movie_path)
episode_info = guessit.guess_episode_info(movie_path)
file_info = guessit.guess_file_info(movie_path)
self.assertEqual(guessit.guess_file_info(movie_path, type='movie'), movie_info)
self.assertEqual(guessit.guess_file_info(movie_path, type='video'), video_info)
self.assertEqual(guessit.guess_file_info(movie_path, type='episode'), episode_info)
self.assertEqual(guessit.guess_file_info(movie_path, options={'type': 'movie'}), movie_info)
self.assertEqual(guessit.guess_file_info(movie_path, options={'type': 'video'}), video_info)
self.assertEqual(guessit.guess_file_info(movie_path, options={'type': 'episode'}), episode_info)
self.assertEqual(guessit.guess_file_info(movie_path, options={'type': 'episode'}, type='movie'), episode_info) # kwargs priority other options
movie_path_name_only = 'Movies/Dark City (1998)/Dark.City.(1998).DC.BDRip.720p.DTS.X264-CHD'
file_info_name_only = guessit.guess_file_info(movie_path_name_only, options={"name_only": True})
self.assertFalse('container' in file_info_name_only)
self.assertTrue('container' in file_info)
suite = allTests(TestApi)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

@ -0,0 +1,45 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test.guessittest import *
class TestAutoDetect(TestGuessit):
def testEmpty(self):
result = guessit.guess_file_info('')
self.assertEqual(result, {})
result = guessit.guess_file_info('___-__')
self.assertEqual(result, {})
result = guessit.guess_file_info('__-.avc')
self.assertEqual(result, {'type': 'unknown', 'extension': 'avc'})
def testAutoDetect(self):
self.checkMinimumFieldsCorrect(filename='autodetect.yaml',
remove_type=False)
suite = allTests(TestAutoDetect)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

@ -0,0 +1,46 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test.guessittest import *
IGNORE_EPISODES = []
IGNORE_MOVIES = []
class TestAutoDetectAll(TestGuessit):
def testAutoMatcher(self):
self.checkMinimumFieldsCorrect(filename='autodetect.yaml',
remove_type=False)
def testAutoMatcherMovies(self):
self.checkMinimumFieldsCorrect(filename='movies.yaml',
exclude_files=IGNORE_MOVIES)
def testAutoMatcherEpisodes(self):
self.checkMinimumFieldsCorrect(filename='episodes.yaml',
exclude_files=IGNORE_EPISODES)
suite = allTests(TestAutoDetectAll)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

@ -0,0 +1,45 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2014 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test.guessittest import *
import guessit
import guessit.hash_ed2k
import unittest
import doctest
def load_tests(loader, tests, ignore):
tests.addTests(doctest.DocTestSuite(guessit))
tests.addTests(doctest.DocTestSuite(guessit.date))
tests.addTests(doctest.DocTestSuite(guessit.fileutils))
tests.addTests(doctest.DocTestSuite(guessit.guess))
tests.addTests(doctest.DocTestSuite(guessit.hash_ed2k))
tests.addTests(doctest.DocTestSuite(guessit.language))
tests.addTests(doctest.DocTestSuite(guessit.matchtree))
tests.addTests(doctest.DocTestSuite(guessit.textutils))
return tests
suite = unittest.TestSuite()
load_tests(None, suite, None)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

@ -0,0 +1,35 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test.guessittest import *
class TestEpisode(TestGuessit):
def testEpisodes(self):
self.checkMinimumFieldsCorrect(filetype='episode',
filename='episodes.yaml')
suite = allTests(TestEpisode)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

@ -0,0 +1,46 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test.guessittest import *
class TestHashes(TestGuessit):
def test_hashes(self):
hashes = (
('hash_mpc', '1MB', u'8542ad406c15c8bd'), # TODO: Check if this value is valid
('hash_ed2k', '1MB', u'ed2k://|file|1MB|1048576|AA3CC5552A9931A76B61A41D306735F7|/'), # TODO: Check if this value is valid
('hash_md5', '1MB', u'5d8dcbca8d8ac21766f28797d6c3954c'),
('hash_sha1', '1MB', u'51d2b8f3248d7ee495b7750c8da5aa3b3819de9d'),
('hash_md5', 'dummy.srt', u'64de6b5893cac24456c46a935ef9c359'),
('hash_sha1', 'dummy.srt', u'a703fc0fa4518080505809bf562c6fc6f7b3c98c')
)
for hash_type, filename, expected_value in hashes:
guess = guess_file_info(file_in_same_dir(__file__, filename), hash_type)
computed_value = guess.get(hash_type)
self.assertEqual(expected_value, guess.get(hash_type), "Invalid %s for %s: %s != %s" % (hash_type, filename, computed_value, expected_value))
suite = allTests(TestHashes)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

@ -0,0 +1,138 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test.guessittest import *
import io
class TestLanguage(TestGuessit):
def check_languages(self, languages):
for lang1, lang2 in languages.items():
self.assertEqual(Language(lang1),
Language(lang2))
def test_addic7ed(self):
languages = {'English': 'en',
'English (US)': 'en',
'English (UK)': 'en',
'Italian': 'it',
'Portuguese': 'pt',
'Portuguese (Brazilian)': 'pt',
'Romanian': 'ro',
'Español (Latinoamérica)': 'es',
'Español (España)': 'es',
'Spanish (Latin America)': 'es',
'Español': 'es',
'Spanish': 'es',
'Spanish (Spain)': 'es',
'French': 'fr',
'Greek': 'el',
'Arabic': 'ar',
'German': 'de',
'Croatian': 'hr',
'Indonesian': 'id',
'Hebrew': 'he',
'Russian': 'ru',
'Turkish': 'tr',
'Swedish': 'se',
'Czech': 'cs',
'Dutch': 'nl',
'Hungarian': 'hu',
'Norwegian': 'no',
'Polish': 'pl',
'Persian': 'fa'}
self.check_languages(languages)
def test_subswiki(self):
languages = {'English (US)': 'en', 'English (UK)': 'en', 'English': 'en',
'French': 'fr', 'Brazilian': 'po', 'Portuguese': 'pt',
'Español (Latinoamérica)': 'es', 'Español (España)': 'es',
'Español': 'es', 'Italian': 'it', 'Català': 'ca'}
self.check_languages(languages)
def test_tvsubtitles(self):
languages = {'English': 'en', 'Español': 'es', 'French': 'fr', 'German': 'de',
'Brazilian': 'br', 'Russian': 'ru', 'Ukrainian': 'ua', 'Italian': 'it',
'Greek': 'gr', 'Arabic': 'ar', 'Hungarian': 'hu', 'Polish': 'pl',
'Turkish': 'tr', 'Dutch': 'nl', 'Portuguese': 'pt', 'Swedish': 'sv',
'Danish': 'da', 'Finnish': 'fi', 'Korean': 'ko', 'Chinese': 'cn',
'Japanese': 'jp', 'Bulgarian': 'bg', 'Czech': 'cz', 'Romanian': 'ro'}
self.check_languages(languages)
def test_opensubtitles(self):
opensubtitles_langfile = file_in_same_dir(__file__, 'opensubtitles_languages_2012_05_09.txt')
for l in [u(l).strip() for l in io.open(opensubtitles_langfile, encoding='utf-8')][1:]:
idlang, alpha2, _, upload_enabled, web_enabled = l.strip().split('\t')
# do not test languages that are too esoteric / not widely available
if int(upload_enabled) and int(web_enabled):
# check that we recognize the opensubtitles language code correctly
# and that we are able to output this code from a language
self.assertEqual(idlang, Language(idlang).opensubtitles)
if alpha2:
# check we recognize the opensubtitles 2-letter code correctly
self.check_languages({idlang: alpha2})
def test_tmdb(self):
# examples from http://api.themoviedb.org/2.1/language-tags
for lang in ['en-US', 'en-CA', 'es-MX', 'fr-PF']:
self.assertEqual(lang, Language(lang).tmdb)
def test_subtitulos(self):
languages = {'English (US)': 'en', 'English (UK)': 'en', 'English': 'en',
'French': 'fr', 'Brazilian': 'po', 'Portuguese': 'pt',
'Español (Latinoamérica)': 'es', 'Español (España)': 'es',
'Español': 'es', 'Italian': 'it', 'Català': 'ca'}
self.check_languages(languages)
def test_thesubdb(self):
languages = {'af': 'af', 'cs': 'cs', 'da': 'da', 'de': 'de', 'en': 'en', 'es': 'es', 'fi': 'fi',
'fr': 'fr', 'hu': 'hu', 'id': 'id', 'it': 'it', 'la': 'la', 'nl': 'nl', 'no': 'no',
'oc': 'oc', 'pl': 'pl', 'pt': 'pt', 'ro': 'ro', 'ru': 'ru', 'sl': 'sl', 'sr': 'sr',
'sv': 'sv', 'tr': 'tr'}
self.check_languages(languages)
def test_language_object(self):
self.assertEqual(len(list(set([Language('qwerty'), Language('asdf')]))), 1)
d = {Language('qwerty'): 7}
d[Language('asdf')] = 23
self.assertEqual(d[Language('qwerty')], 23)
def test_exceptions(self):
self.assertEqual(Language('br'), Language('pt(br)'))
# languages should be equal regardless of country
self.assertEqual(Language('br'), Language('pt'))
self.assertEqual(Language('unknown'), Language('und'))
suite = allTests(TestLanguage)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

@ -0,0 +1,70 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2014 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test.guessittest import *
from guessit.fileutils import split_path, file_in_same_dir
from guessit.textutils import strip_brackets, str_replace, str_fill
from guessit import PY2
from guessit import __main__
if PY2:
from StringIO import StringIO
else:
from io import StringIO
class TestMain(TestGuessit):
def setUp(self):
self._stdout = sys.stdout
string_out = StringIO()
sys.stdout = string_out
def tearDown(self):
sys.stdout = self._stdout
def test_list_properties(self):
__main__.main(["-p"], False)
__main__.main(["-l"], False)
def test_list_transformers(self):
__main__.main(["--transformers"], False)
__main__.main(["-l", "--transformers"], False)
def test_demo(self):
__main__.main(["-d"], False)
__main__.main(["-l"], False)
def test_filename(self):
__main__.main(["A.Movie.2014.avi"], False)
__main__.main(["A.Movie.2014.avi", "A.2nd.Movie.2014.avi"], False)
__main__.main(["-y", "A.Movie.2014.avi"], False)
__main__.main(["-a", "A.Movie.2014.avi"], False)
__main__.main(["-v", "A.Movie.2014.avi"], False)
__main__.main(["-t", "movie", "A.Movie.2014.avi"], False)
__main__.main(["-t", "episode", "A.Serie.S02E06.avi"], False)
__main__.main(["-i", "hash_mpc", file_in_same_dir(__file__, "1MB")], False)
__main__.main(["-i", "hash_md5", file_in_same_dir(__file__, "1MB")], False)
suite = allTests(TestMain)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

@ -0,0 +1,93 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test.guessittest import *
from guessit.transfo.guess_release_group import GuessReleaseGroup
from guessit.transfo.guess_properties import GuessProperties
from guessit.matchtree import BaseMatchTree
keywords = yaml.load("""
? Xvid PROPER
: videoCodec: Xvid
other: PROPER
? PROPER-Xvid
: videoCodec: Xvid
other: PROPER
""")
def guess_info(string, options=None):
mtree = MatchTree(string)
GuessReleaseGroup().process(mtree, options)
GuessProperties().process(mtree, options)
return mtree.matched()
class TestMatchTree(TestGuessit):
def test_base_tree(self):
t = BaseMatchTree('One Two Three(Three) Four')
t.partition((3, 7, 20))
leaves = t.leaves()
self.assertEqual(leaves[0].span, (0, 3))
self.assertEqual('One', leaves[0].value)
self.assertEqual(' Two', leaves[1].value)
self.assertEqual(' Three(Three)', leaves[2].value)
self.assertEqual(' Four', leaves[3].value)
leaves[2].partition((1, 6, 7, 12))
three_leaves = leaves[2].leaves()
self.assertEqual('Three', three_leaves[1].value)
self.assertEqual('Three', three_leaves[3].value)
leaves = t.leaves()
self.assertEqual(len(leaves), 8)
self.assertEqual(leaves[5], three_leaves[3])
self.assertEqual(t.previous_leaf(leaves[5]), leaves[4])
self.assertEqual(t.next_leaf(leaves[5]), leaves[6])
self.assertEqual(t.next_leaves(leaves[5]), [leaves[6], leaves[7]])
self.assertEqual(t.previous_leaves(leaves[5]), [leaves[4], leaves[3], leaves[2], leaves[1], leaves[0]])
self.assertEqual(t.next_leaf(leaves[7]), None)
self.assertEqual(t.previous_leaf(leaves[0]), None)
self.assertEqual(t.next_leaves(leaves[7]), [])
self.assertEqual(t.previous_leaves(leaves[0]), [])
def test_match(self):
self.checkFields(keywords, guess_info)
suite = allTests(TestMatchTree)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

@ -0,0 +1,35 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test.guessittest import *
class TestMovie(TestGuessit):
def testMovies(self):
self.checkMinimumFieldsCorrect(filetype='movie',
filename='movies.yaml')
suite = allTests(TestMovie)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

@ -0,0 +1,126 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.quality import best_quality, best_quality_properties
from guessit.containers import QualitiesContainer
from guessit.test.guessittest import *
class TestQuality(TestGuessit):
def test_container(self):
container = QualitiesContainer()
container.register_quality('color', 'red', 10)
container.register_quality('color', 'orange', 20)
container.register_quality('color', 'green', 30)
container.register_quality('context', 'sun', 100)
container.register_quality('context', 'sea', 200)
container.register_quality('context', 'sex', 300)
g1 = Guess()
g1['color'] = 'red'
g2 = Guess()
g2['color'] = 'green'
g3 = Guess()
g3['color'] = 'orange'
q3 = container.rate_quality(g3)
self.assertEqual(q3, 20, "ORANGE should be rated 20. Don't ask why!")
q1 = container.rate_quality(g1)
q2 = container.rate_quality(g2)
self.assertTrue(q2 > q1, "GREEN should be greater than RED. Don't ask why!")
g1['context'] = 'sex'
g2['context'] = 'sun'
q1 = container.rate_quality(g1)
q2 = container.rate_quality(g2)
self.assertTrue(q1 > q2, "SEX should be greater than SUN. Don't ask why!")
self.assertEqual(container.best_quality(g1, g2), g1, "RED&SEX should be better than GREEN&SUN. Don't ask why!")
self.assertEqual(container.best_quality_properties(['color'], g1, g2), g2, "GREEN should be better than RED. Don't ask why!")
self.assertEqual(container.best_quality_properties(['context'], g1, g2), g1, "SEX should be better than SUN. Don't ask why!")
q1 = container.rate_quality(g1, 'color')
q2 = container.rate_quality(g2, 'color')
self.assertTrue(q2 > q1, "GREEN should be greater than RED. Don't ask why!")
container.unregister_quality('context', 'sex')
container.unregister_quality('context', 'sun')
q1 = container.rate_quality(g1)
q2 = container.rate_quality(g2)
self.assertTrue(q2 > q1, "GREEN&SUN should be greater than RED&SEX. Don't ask why!")
g3['context'] = 'sea'
container.unregister_quality('context', 'sea')
q3 = container.rate_quality(g3, 'context')
self.assertEqual(q3, 0, "Context should be unregistered.")
container.unregister_quality('color')
q3 = container.rate_quality(g3, 'color')
self.assertEqual(q3, 0, "Color should be unregistered.")
container.clear_qualities()
q1 = container.rate_quality(g1)
q2 = container.rate_quality(g2)
self.assertTrue(q1 == q2 == 0, "Empty quality container should rate each guess to 0")
def test_quality_transformers(self):
guess_720p = guessit.guess_file_info("2012.2009.720p.BluRay.x264.DTS WiKi.mkv")
guess_1080p = guessit.guess_file_info("2012.2009.1080p.BluRay.x264.MP3 WiKi.mkv")
self.assertTrue('audioCodec' in guess_720p, "audioCodec should be present")
self.assertTrue('audioCodec' in guess_1080p, "audioCodec should be present")
self.assertTrue('screenSize' in guess_720p, "screenSize should be present")
self.assertTrue('screenSize' in guess_1080p, "screenSize should be present")
best_quality_guess = best_quality(guess_720p, guess_1080p)
self.assertTrue(guess_1080p == best_quality_guess, "1080p+MP3 is not the best global quality")
best_quality_guess = best_quality_properties(['screenSize'], guess_720p, guess_1080p)
self.assertTrue(guess_1080p == best_quality_guess, "1080p is not the best screenSize")
best_quality_guess = best_quality_properties(['audioCodec'], guess_720p, guess_1080p)
self.assertTrue(guess_720p == best_quality_guess, "DTS is not the best audioCodec")
suite = allTests(TestQuality)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

@ -0,0 +1,155 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GuessIt - A library for guessing information from filenames
# Copyright (c) 2013 Nicolas Wack <wackou@gmail.com>
#
# GuessIt is free software; you can redistribute it and/or modify it under
# the terms of the Lesser GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# GuessIt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# Lesser GNU General Public License for more details.
#
# You should have received a copy of the Lesser GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from __future__ import absolute_import, division, print_function, unicode_literals
from guessit.test.guessittest import *
from guessit.fileutils import split_path
from guessit.textutils import strip_brackets, str_replace, str_fill, from_camel, is_camel,\
levenshtein, reorder_title
from guessit import PY2
from guessit.date import search_date, search_year
from datetime import datetime, date, timedelta
class TestUtils(TestGuessit):
def test_splitpath(self):
alltests = {False: {'/usr/bin/smewt': ['/', 'usr', 'bin', 'smewt'],
'relative_path/to/my_folder/': ['relative_path', 'to', 'my_folder'],
'//some/path': ['//', 'some', 'path'],
'//some//path': ['//', 'some', 'path'],
'///some////path': ['///', 'some', 'path']
},
True: {'C:\\Program Files\\Smewt\\smewt.exe': ['C:\\', 'Program Files', 'Smewt', 'smewt.exe'],
'Documents and Settings\\User\\config': ['Documents and Settings', 'User', 'config'],
'C:\\Documents and Settings\\User\\config': ['C:\\', 'Documents and Settings', 'User', 'config'],
# http://bugs.python.org/issue19945
'\\\\netdrive\\share': ['\\\\', 'netdrive', 'share'] if PY2 else ['\\\\netdrive\\share'],
'\\\\netdrive\\share\\folder': ['\\\\', 'netdrive', 'share', 'folder'] if PY2 else ['\\\\netdrive\\share\\', 'folder'],
}
}
tests = alltests[sys.platform == 'win32']
for path, split in tests.items():
self.assertEqual(split, split_path(path))
def test_strip_brackets(self):
allTests = (('', ''),
('[test]', 'test'),
('{test2}', 'test2'),
('(test3)', 'test3'),
('(test4]', '(test4]'),
)
for i, e in allTests:
self.assertEqual(e, strip_brackets(i))
def test_levenshtein(self):
self.assertEqual(levenshtein("abcdef ghijk lmno", "abcdef ghijk lmno"), 0)
self.assertEqual(levenshtein("abcdef ghijk lmnop", "abcdef ghijk lmno"), 1)
self.assertEqual(levenshtein("abcdef ghijk lmno", "abcdef ghijk lmn"), 1)
self.assertEqual(levenshtein("abcdef ghijk lmno", "abcdef ghijk lmnp"), 1)
self.assertEqual(levenshtein("abcdef ghijk lmno", "abcdef ghijk lmnq"), 1)
self.assertEqual(levenshtein("cbcdef ghijk lmno", "abcdef ghijk lmnq"), 2)
self.assertEqual(levenshtein("cbcdef ghihk lmno", "abcdef ghijk lmnq"), 3)
def test_reorder_title(self):
self.assertEqual(reorder_title("Simpsons, The"), "The Simpsons")
self.assertEqual(reorder_title("Simpsons,The"), "The Simpsons")
self.assertEqual(reorder_title("Simpsons,Les", articles=('the', 'le', 'la', 'les')), "Les Simpsons")
self.assertEqual(reorder_title("Simpsons, Les", articles=('the', 'le', 'la', 'les')), "Les Simpsons")
def test_camel(self):
self.assertEqual("", from_camel(""))
self.assertEqual("Hello world", str_replace("Hello World", 6, 'w'))
self.assertEqual("Hello *****", str_fill("Hello World", (6, 11), '*'))
self.assertTrue("This is camel", from_camel("ThisIsCamel"))
self.assertEqual('camel case', from_camel('camelCase'))
self.assertEqual('A case', from_camel('ACase'))
self.assertEqual('MiXedCaSe is not camel case', from_camel('MiXedCaSe is not camelCase'))
self.assertEqual("This is camel cased title", from_camel("ThisIsCamelCasedTitle"))
self.assertEqual("This is camel CASED title", from_camel("ThisIsCamelCASEDTitle"))
self.assertEqual("These are camel CASED title", from_camel("TheseAreCamelCASEDTitle"))
self.assertEqual("Give a camel case string", from_camel("GiveACamelCaseString"))
self.assertEqual("Death TO camel case", from_camel("DeathTOCamelCase"))
self.assertEqual("But i like java too:)", from_camel("ButILikeJavaToo:)"))
self.assertEqual("Beatdown french DVD rip.mkv", from_camel("BeatdownFrenchDVDRip.mkv"))
self.assertEqual("DO NOTHING ON UPPER CASE", from_camel("DO NOTHING ON UPPER CASE"))
self.assertFalse(is_camel("this_is_not_camel"))
self.assertTrue(is_camel("ThisIsCamel"))
self.assertEqual("Dark.City.(1998).DC.BDRIP.720p.DTS.X264-CHD.mkv", from_camel("Dark.City.(1998).DC.BDRIP.720p.DTS.X264-CHD.mkv"))
self.assertFalse(is_camel("Dark.City.(1998).DC.BDRIP.720p.DTS.X264-CHD.mkv"))
self.assertEqual("A2LiNE", from_camel("A2LiNE"))
def test_date(self):
self.assertEqual(search_year(' in the year 2000... '), (2000, (13, 17)))
self.assertEqual(search_year(' they arrived in 1492. '), (None, None))
today = date.today()
today_year_2 = int(str(today.year)[2:])
future = today + timedelta(days=1000)
future_year_2 = int(str(future.year)[2:])
past = today - timedelta(days=10000)
past_year_2 = int(str(past.year)[2:])
self.assertEqual(search_date(' Something before 2002-04-22 '), (date(2002, 4, 22), (18, 28)))
self.assertEqual(search_date(' 2002-04-22 Something after '), (date(2002, 4, 22), (1, 11)))
self.assertEqual(search_date(' This happened on 2002-04-22. '), (date(2002, 4, 22), (18, 28)))
self.assertEqual(search_date(' This happened on 22-04-2002. '), (date(2002, 4, 22), (18, 28)))
self.assertEqual(search_date(' This happened on 13-04-%s. ' % (today_year_2,)), (date(today.year, 4, 13), (18, 26)))
self.assertEqual(search_date(' This happened on 22-04-%s. ' % (future_year_2,)), (date(future.year, 4, 22), (18, 26)))
self.assertEqual(search_date(' This happened on 20-04-%s. ' % (past_year_2)), (date(past.year, 4, 20), (18, 26)))
self.assertEqual(search_date(' This happened on 04-13-%s. ' % (today_year_2,)), (date(today.year, 4, 13), (18, 26)))
self.assertEqual(search_date(' This happened on 04-22-%s. ' % (future_year_2,)), (date(future.year, 4, 22), (18, 26)))
self.assertEqual(search_date(' This happened on 04-20-%s. ' % (past_year_2)), (date(past.year, 4, 20), (18, 26)))
self.assertEqual(search_date(' This happened on 35-12-%s. ' % (today_year_2,)), (None, None))
self.assertEqual(search_date(' This happened on 37-18-%s. ' % (future_year_2,)), (None, None))
self.assertEqual(search_date(' This happened on 44-42-%s. ' % (past_year_2)), (None, None))
self.assertEqual(search_date(' This happened on %s. ' % (today, )), (today, (18, 28)))
self.assertEqual(search_date(' This happened on %s. ' % (future, )), (future, (18, 28)))
self.assertEqual(search_date(' This happened on %s. ' % (past, )), (past, (18, 28)))
self.assertEqual(search_date(' released date: 04-03-1901? '), (None, None))
self.assertEqual(search_date(' There\'s no date in here. '), (None, None))
suite = allTests(TestUtils)
if __name__ == '__main__':
TextTestRunner(verbosity=2).run(suite)

View file

View file

@ -0,0 +1,21 @@
import abc
class FormatterBase(object):
"""Base class for example plugin used in the tutoral.
"""
__metaclass__ = abc.ABCMeta
def __init__(self, max_width=60):
self.max_width = max_width
@abc.abstractmethod
def format(self, data):
"""Format the data and return unicode text.
:param data: A dictionary with string keys and simple types as
values.
:type data: dict(str:?)
:returns: Iterable producing the formatted text.
"""

View file

@ -0,0 +1,36 @@
import textwrap
from stevedore.example import base
class FieldList(base.FormatterBase):
"""Format values as a reStructuredText field list.
For example::
: name1 : value
: name2 : value
: name3 : a long value
will be wrapped with
a hanging indent
"""
def format(self, data):
"""Format the data and return unicode text.
:param data: A dictionary with string keys and simple types as
values.
:type data: dict(str:?)
"""
for name, value in sorted(data.items()):
full_text = ': {name} : {value}'.format(
name=name,
value=value,
)
wrapped_text = textwrap.fill(
full_text,
initial_indent='',
subsequent_indent=' ',
width=self.max_width,
)
yield wrapped_text + '\n'

View file

@ -0,0 +1,37 @@
from __future__ import print_function
import argparse
from stevedore import driver
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'format',
nargs='?',
default='simple',
help='the output format',
)
parser.add_argument(
'--width',
default=60,
type=int,
help='maximum output width for text',
)
parsed_args = parser.parse_args()
data = {
'a': 'A',
'b': 'B',
'long': 'word ' * 80,
}
mgr = driver.DriverManager(
namespace='stevedore.example.formatter',
name=parsed_args.format,
invoke_on_load=True,
invoke_args=(parsed_args.width,),
)
for chunk in mgr.driver.format(data):
print(chunk, end='')

View file

@ -0,0 +1,39 @@
from __future__ import print_function
import argparse
from stevedore import extension
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'--width',
default=60,
type=int,
help='maximum output width for text',
)
parsed_args = parser.parse_args()
data = {
'a': 'A',
'b': 'B',
'long': 'word ' * 80,
}
mgr = extension.ExtensionManager(
namespace='stevedore.example.formatter',
invoke_on_load=True,
invoke_args=(parsed_args.width,),
)
def format_data(ext, data):
return (ext.name, ext.obj.format(data))
results = mgr.map(format_data, data)
for name, result in results:
print('Formatter: {0}'.format(name))
for chunk in result:
print(chunk, end='')
print('')

View file

@ -0,0 +1,46 @@
from setuptools import setup, find_packages
setup(
name='stevedore-examples',
version='1.0',
description='Demonstration package for stevedore',
author='Doug Hellmann',
author_email='doug.hellmann@dreamhost.com',
url='https://github.com/dreamhost/stevedore',
download_url='https://github.com/dreamhost/stevedore/tarball/master',
classifiers=['Development Status :: 3 - Alpha',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Intended Audience :: Developers',
'Environment :: Console',
],
platforms=['Any'],
scripts=[],
provides=['stevedore.examples',
],
packages=find_packages(),
include_package_data=True,
entry_points={
'stevedore.example.formatter': [
'simple = stevedore.example.simple:Simple',
'field = stevedore.example.fields:FieldList',
'plain = stevedore.example.simple:Simple',
],
},
zip_safe=False,
)

View file

@ -0,0 +1,20 @@
from stevedore.example import base
class Simple(base.FormatterBase):
"""A very basic formatter.
"""
def format(self, data):
"""Format the data and return unicode text.
:param data: A dictionary with string keys and simple types as
values.
:type data: dict(str:?)
"""
for name, value in sorted(data.items()):
line = '{name} = {value}\n'.format(
name=name,
value=value,
)
yield line

View file

View file

@ -0,0 +1,59 @@
"""TestExtensionManager
Extension manager used only for testing.
"""
import logging
import warnings
from stevedore import extension
LOG = logging.getLogger(__name__)
class TestExtensionManager(extension.ExtensionManager):
"""ExtensionManager that is explicitly initialized for tests.
.. deprecated:: 0.13
Use the :func:`make_test_instance` class method of the class
being replaced by the test instance instead of using this class
directly.
:param extensions: Pre-configured Extension instances to use
instead of loading them from entry points.
:type extensions: list of :class:`~stevedore.extension.Extension`
:param namespace: The namespace for the entry points.
:type namespace: str
:param invoke_on_load: Boolean controlling whether to invoke the
object returned by the entry point after the driver is loaded.
:type invoke_on_load: bool
:param invoke_args: Positional arguments to pass when invoking
the object returned by the entry point. Only used if invoke_on_load
is True.
:type invoke_args: tuple
:param invoke_kwds: Named arguments to pass when invoking
the object returned by the entry point. Only used if invoke_on_load
is True.
:type invoke_kwds: dict
"""
def __init__(self, extensions,
namespace='test',
invoke_on_load=False,
invoke_args=(),
invoke_kwds={}):
super(TestExtensionManager, self).__init__(namespace,
invoke_on_load,
invoke_args,
invoke_kwds,
)
self.extensions = extensions
warnings.warn(
'TestExtesionManager has been replaced by make_test_instance()',
DeprecationWarning)
def _load_plugins(self, *args, **kwds):
return []

View file

@ -0,0 +1,21 @@
"""Tests for failure loading callback
"""
from stevedore import extension
def test_extension_failure_custom_callback():
errors = []
def failure_callback(manager, entrypoint, error):
errors.append((manager, entrypoint, error))
em = extension.ExtensionManager('stevedore.test.extension',
invoke_on_load=True,
on_load_failure_callback=failure_callback)
extensions = list(em.extensions)
assert len(extensions) > 0
assert len(errors) == 1
(manager, entrypoint, error) = errors[0]
assert manager is em
assert isinstance(error, IOError)

View file

@ -0,0 +1,103 @@
from stevedore import dispatch
def check_dispatch(ep, *args, **kwds):
return ep.name == 't2'
def test_dispatch():
def invoke(ep, *args, **kwds):
return (ep.name, args, kwds)
em = dispatch.DispatchExtensionManager(
'stevedore.test.extension',
lambda *args, **kwds: True,
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
assert len(em.extensions) == 2
assert set(em.names()) == set(['t1', 't2'])
results = em.map(check_dispatch,
invoke,
'first',
named='named value',
)
expected = [('t2', ('first',), {'named': 'named value'})]
assert results == expected
def test_dispatch_map_method():
em = dispatch.DispatchExtensionManager(
'stevedore.test.extension',
lambda *args, **kwds: True,
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
results = em.map_method(check_dispatch, 'get_args_and_data',
'first')
assert results == [(('a',), {'b': 'B'}, 'first')]
def test_name_dispatch():
def invoke(ep, *args, **kwds):
return (ep.name, args, kwds)
em = dispatch.NameDispatchExtensionManager(
'stevedore.test.extension',
lambda *args, **kwds: True,
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
assert len(em.extensions) == 2
assert set(em.names()) == set(['t1', 't2'])
results = em.map(['t2'],
invoke,
'first',
named='named value',
)
expected = [('t2', ('first',), {'named': 'named value'})]
assert results == expected
def test_name_dispatch_ignore_missing():
def invoke(ep, *args, **kwds):
return (ep.name, args, kwds)
em = dispatch.NameDispatchExtensionManager(
'stevedore.test.extension',
lambda *args, **kwds: True,
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
results = em.map(['t3', 't1'],
invoke,
'first',
named='named value',
)
expected = [('t1', ('first',), {'named': 'named value'})]
assert results == expected
def test_name_dispatch_map_method():
em = dispatch.NameDispatchExtensionManager(
'stevedore.test.extension',
lambda *args, **kwds: True,
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
results = em.map_method(['t3', 't1'], 'get_args_and_data',
'first')
assert results == [(('a',), {'b': 'B'}, 'first')]

View file

@ -0,0 +1,61 @@
"""Tests for stevedore.extension
"""
import mock
import pkg_resources
from stevedore import driver
from stevedore.tests import test_extension
def test_detect_plugins():
em = driver.DriverManager('stevedore.test.extension', 't1')
names = sorted(em.names())
assert names == ['t1']
def test_call():
def invoke(ext, *args, **kwds):
return (ext.name, args, kwds)
em = driver.DriverManager('stevedore.test.extension', 't1')
result = em(invoke, 'a', b='C')
assert result == ('t1', ('a',), {'b': 'C'})
def test_driver_property_not_invoked_on_load():
em = driver.DriverManager('stevedore.test.extension', 't1',
invoke_on_load=False)
d = em.driver
assert d is test_extension.FauxExtension
def test_driver_property_invoked_on_load():
em = driver.DriverManager('stevedore.test.extension', 't1',
invoke_on_load=True)
d = em.driver
assert isinstance(d, test_extension.FauxExtension)
def test_no_drivers():
try:
driver.DriverManager('stevedore.test.extension.none', 't1')
except RuntimeError as err:
assert "No 'stevedore.test.extension.none' driver found" in str(err)
def test_multiple_drivers():
# The idea for this test was contributed by clayg:
# https://gist.github.com/clayg/6311348
fep_name = 'stevedore.extension.ExtensionManager._find_entry_points'
with mock.patch(fep_name) as fep:
fep.return_value = [
pkg_resources.EntryPoint.parse('backend = pkg1:driver'),
pkg_resources.EntryPoint.parse('backend = pkg2:driver'),
]
for ep in fep.return_value:
ep.load = lambda *args, **kwds: 'pkg backend'
try:
driver.DriverManager('stevedore.test.multiple_drivers', 'backend')
except RuntimeError as err:
assert "Multiple" in str(err), str(err)
fep.assert_called_with('stevedore.test.multiple_drivers')

View file

@ -0,0 +1,29 @@
from stevedore import enabled
def test_enabled():
def check_enabled(ep):
return ep.name == 't2'
em = enabled.EnabledExtensionManager(
'stevedore.test.extension',
check_enabled,
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
assert len(em.extensions) == 1
assert em.names() == ['t2']
def test_enabled_after_load():
def check_enabled(ext):
return ext.obj and ext.name == 't2'
em = enabled.EnabledExtensionManager(
'stevedore.test.extension',
check_enabled,
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
assert len(em.extensions) == 1
assert em.names() == ['t2']

View file

@ -0,0 +1,27 @@
"""Tests for stevedore.exmaple.fields
"""
from stevedore.example import fields
def test_simple_items():
f = fields.FieldList(100)
text = ''.join(f.format({'a': 'A', 'b': 'B'}))
expected = '\n'.join([
': a : A',
': b : B',
'',
])
assert text == expected
def test_long_item():
f = fields.FieldList(25)
text = ''.join(f.format({'name': 'a value longer than the allowed width'}))
expected = '\n'.join([
': name : a value longer',
' than the allowed',
' width',
'',
])
assert text == expected

View file

@ -0,0 +1,15 @@
"""Tests for stevedore.exmaple.simple
"""
from stevedore.example import simple
def test_simple_items():
f = simple.Simple(100)
text = ''.join(f.format({'a': 'A', 'b': 'B'}))
expected = '\n'.join([
'a = A',
'b = B',
'',
])
assert text == expected

View file

@ -0,0 +1,177 @@
"""Tests for stevedore.extension
"""
import mock
from stevedore import extension
ALL_NAMES = ['e1', 't1', 't2']
WORKING_NAMES = ['t1', 't2']
class FauxExtension(object):
def __init__(self, *args, **kwds):
self.args = args
self.kwds = kwds
def get_args_and_data(self, data):
return self.args, self.kwds, data
class BrokenExtension(object):
def __init__(self, *args, **kwds):
raise IOError("Did not create")
def test_detect_plugins():
em = extension.ExtensionManager('stevedore.test.extension')
names = sorted(em.names())
assert names == ALL_NAMES
def test_get_by_name():
em = extension.ExtensionManager('stevedore.test.extension')
e = em['t1']
assert e.name == 't1'
def test_get_by_name_missing():
em = extension.ExtensionManager('stevedore.test.extension')
try:
em['t3']
except KeyError:
pass
else:
assert False, 'Failed to raise KeyError'
def test_load_multiple_times_entry_points():
# We expect to get the same EntryPoint object because we save them
# in the cache.
em1 = extension.ExtensionManager('stevedore.test.extension')
eps1 = [ext.entry_point for ext in em1]
em2 = extension.ExtensionManager('stevedore.test.extension')
eps2 = [ext.entry_point for ext in em2]
assert eps1[0] is eps2[0]
def test_load_multiple_times_plugins():
# We expect to get the same plugin object (module or class)
# because the underlying import machinery will cache the values.
em1 = extension.ExtensionManager('stevedore.test.extension')
plugins1 = [ext.plugin for ext in em1]
em2 = extension.ExtensionManager('stevedore.test.extension')
plugins2 = [ext.plugin for ext in em2]
assert plugins1[0] is plugins2[0]
def test_use_cache():
# If we insert something into the cache of entry points,
# the manager should not have to call into pkg_resources
# to find the plugins.
cache = extension.ExtensionManager.ENTRY_POINT_CACHE
cache['stevedore.test.faux'] = []
with mock.patch('pkg_resources.iter_entry_points',
side_effect=AssertionError('called iter_entry_points')):
em = extension.ExtensionManager('stevedore.test.faux')
names = em.names()
assert names == []
def test_iterable():
em = extension.ExtensionManager('stevedore.test.extension')
names = sorted(e.name for e in em)
assert names == ALL_NAMES
def test_invoke_on_load():
em = extension.ExtensionManager('stevedore.test.extension',
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
assert len(em.extensions) == 2
for e in em.extensions:
assert e.obj.args == ('a',)
assert e.obj.kwds == {'b': 'B'}
def test_map_return_values():
def mapped(ext, *args, **kwds):
return ext.name
em = extension.ExtensionManager('stevedore.test.extension',
invoke_on_load=True,
)
results = em.map(mapped)
assert sorted(results) == WORKING_NAMES
def test_map_arguments():
objs = []
def mapped(ext, *args, **kwds):
objs.append((ext, args, kwds))
em = extension.ExtensionManager('stevedore.test.extension',
invoke_on_load=True,
)
em.map(mapped, 1, 2, a='A', b='B')
assert len(objs) == 2
names = sorted([o[0].name for o in objs])
assert names == WORKING_NAMES
for o in objs:
assert o[1] == (1, 2)
assert o[2] == {'a': 'A', 'b': 'B'}
def test_map_eats_errors():
def mapped(ext, *args, **kwds):
raise RuntimeError('hard coded error')
em = extension.ExtensionManager('stevedore.test.extension',
invoke_on_load=True,
)
results = em.map(mapped, 1, 2, a='A', b='B')
assert results == []
def test_map_propagate_exceptions():
def mapped(ext, *args, **kwds):
raise RuntimeError('hard coded error')
em = extension.ExtensionManager('stevedore.test.extension',
invoke_on_load=True,
propagate_map_exceptions=True
)
try:
em.map(mapped, 1, 2, a='A', b='B')
assert False
except RuntimeError:
pass
def test_map_errors_when_no_plugins():
def mapped(ext, *args, **kwds):
pass
em = extension.ExtensionManager('stevedore.test.extension.none',
invoke_on_load=True,
)
try:
em.map(mapped, 1, 2, a='A', b='B')
except RuntimeError as err:
assert 'No stevedore.test.extension.none extensions found' == str(err)
def test_map_method():
em = extension.ExtensionManager('stevedore.test.extension',
invoke_on_load=True,
)
result = em.map_method('get_args_and_data', 42)
assert set(r[2] for r in result) == set([42])

View file

@ -0,0 +1,43 @@
from stevedore import hook
def test_hook():
em = hook.HookManager(
'stevedore.test.extension',
't1',
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
assert len(em.extensions) == 1
assert em.names() == ['t1']
def test_get_by_name():
em = hook.HookManager(
'stevedore.test.extension',
't1',
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
e_list = em['t1']
assert len(e_list) == 1
e = e_list[0]
assert e.name == 't1'
def test_get_by_name_missing():
em = hook.HookManager(
'stevedore.test.extension',
't1',
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
try:
em['t2']
except KeyError:
pass
else:
assert False, 'Failed to raise KeyError'

View file

@ -0,0 +1,58 @@
from stevedore import named
import mock
def test_named():
em = named.NamedExtensionManager(
'stevedore.test.extension',
names=['t1'],
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
actual = em.names()
assert actual == ['t1']
def test_enabled_before_load():
# Set up the constructor for the FauxExtension to cause an
# AssertionError so the test fails if the class is instantiated,
# which should only happen if it is loaded before the name of the
# extension is compared against the names that should be loaded by
# the manager.
init_name = 'stevedore.tests.test_extension.FauxExtension.__init__'
with mock.patch(init_name) as m:
m.side_effect = AssertionError
em = named.NamedExtensionManager(
'stevedore.test.extension',
# Look for an extension that does not exist so the
# __init__ we mocked should never be invoked.
names=['no-such-extension'],
invoke_on_load=True,
invoke_args=('a',),
invoke_kwds={'b': 'B'},
)
actual = em.names()
assert actual == []
def test_extensions_listed_in_name_order():
# Since we don't know the "natural" order of the extensions, run
# the test both ways: if the sorting is broken, one of them will
# fail
em = named.NamedExtensionManager(
'stevedore.test.extension',
names=['t1', 't2'],
name_order=True
)
actual = em.names()
assert actual == ['t1', 't2']
em = named.NamedExtensionManager(
'stevedore.test.extension',
names=['t2', 't1'],
name_order=True
)
actual = em.names()
assert actual == ['t2', 't1']

View file

@ -0,0 +1,278 @@
from mock import Mock, sentinel
from nose.tools import raises
from stevedore import (ExtensionManager, NamedExtensionManager, HookManager,
DriverManager, EnabledExtensionManager)
from stevedore.dispatch import (DispatchExtensionManager,
NameDispatchExtensionManager)
from stevedore.extension import Extension
test_extension = Extension('test_extension', None, None, None)
test_extension2 = Extension('another_one', None, None, None)
mock_entry_point = Mock(module_name='test.extension', attrs=['obj'])
a_driver = Extension('test_driver', mock_entry_point, sentinel.driver_plugin,
sentinel.driver_obj)
# base ExtensionManager
def test_instance_should_use_supplied_extensions():
extensions = [test_extension, test_extension2]
em = ExtensionManager.make_test_instance(extensions)
assert extensions == em.extensions
def test_instance_should_have_default_namespace():
em = ExtensionManager.make_test_instance([])
assert em.namespace
def test_instance_should_use_supplied_namespace():
namespace = 'testing.1.2.3'
em = ExtensionManager.make_test_instance([], namespace=namespace)
assert namespace == em.namespace
def test_extension_name_should_be_listed():
em = ExtensionManager.make_test_instance([test_extension])
assert test_extension.name in em.names()
def test_iterator_should_yield_extension():
em = ExtensionManager.make_test_instance([test_extension])
assert test_extension == next(iter(em))
def test_manager_should_allow_name_access():
em = ExtensionManager.make_test_instance([test_extension])
assert test_extension == em[test_extension.name]
def test_manager_should_call():
em = ExtensionManager.make_test_instance([test_extension])
func = Mock()
em.map(func)
func.assert_called_once_with(test_extension)
def test_manager_should_call_all():
em = ExtensionManager.make_test_instance([test_extension2,
test_extension])
func = Mock()
em.map(func)
func.assert_any_call(test_extension2)
func.assert_any_call(test_extension)
def test_manager_return_values():
def mapped(ext, *args, **kwds):
return ext.name
em = ExtensionManager.make_test_instance([test_extension2,
test_extension])
results = em.map(mapped)
assert sorted(results) == ['another_one', 'test_extension']
def test_manager_should_eat_exceptions():
em = ExtensionManager.make_test_instance([test_extension])
func = Mock(side_effect=RuntimeError('hard coded error'))
results = em.map(func, 1, 2, a='A', b='B')
assert results == []
@raises(RuntimeError)
def test_manager_should_propagate_exceptions():
em = ExtensionManager.make_test_instance([test_extension],
propagate_map_exceptions=True)
func = Mock(side_effect=RuntimeError('hard coded error'))
em.map(func, 1, 2, a='A', b='B')
# NamedExtensionManager
def test_named_manager_should_use_supplied_extensions():
extensions = [test_extension, test_extension2]
em = NamedExtensionManager.make_test_instance(extensions)
assert extensions == em.extensions
def test_named_manager_should_have_default_namespace():
em = NamedExtensionManager.make_test_instance([])
assert em.namespace
def test_named_manager_should_use_supplied_namespace():
namespace = 'testing.1.2.3'
em = NamedExtensionManager.make_test_instance([], namespace=namespace)
assert namespace == em.namespace
def test_named_manager_should_populate_names():
extensions = [test_extension, test_extension2]
em = NamedExtensionManager.make_test_instance(extensions)
assert ['test_extension', 'another_one'] == em.names()
# HookManager
def test_hook_manager_should_use_supplied_extensions():
extensions = [test_extension, test_extension2]
em = HookManager.make_test_instance(extensions)
assert extensions == em.extensions
def test_hook_manager_should_be_first_extension_name():
extensions = [test_extension, test_extension2]
em = HookManager.make_test_instance(extensions)
# This will raise KeyError if the names don't match
assert em[test_extension.name]
def test_hook_manager_should_have_default_namespace():
em = HookManager.make_test_instance([test_extension])
assert em.namespace
def test_hook_manager_should_use_supplied_namespace():
namespace = 'testing.1.2.3'
em = HookManager.make_test_instance([test_extension], namespace=namespace)
assert namespace == em.namespace
def test_hook_manager_should_return_named_extensions():
hook1 = Extension('captain', None, None, None)
hook2 = Extension('captain', None, None, None)
em = HookManager.make_test_instance([hook1, hook2])
assert [hook1, hook2] == em['captain']
# DriverManager
def test_driver_manager_should_use_supplied_extension():
em = DriverManager.make_test_instance(a_driver)
assert [a_driver] == em.extensions
def test_driver_manager_should_have_default_namespace():
em = DriverManager.make_test_instance(a_driver)
assert em.namespace
def test_driver_manager_should_use_supplied_namespace():
namespace = 'testing.1.2.3'
em = DriverManager.make_test_instance(a_driver, namespace=namespace)
assert namespace == em.namespace
def test_instance_should_use_driver_name():
em = DriverManager.make_test_instance(a_driver)
assert ['test_driver'] == em.names()
def test_instance_call():
def invoke(ext, *args, **kwds):
return ext.name, args, kwds
em = DriverManager.make_test_instance(a_driver)
result = em(invoke, 'a', b='C')
assert result == ('test_driver', ('a',), {'b': 'C'})
def test_instance_driver_property():
em = DriverManager.make_test_instance(a_driver)
assert sentinel.driver_obj == em.driver
# EnabledExtensionManager
def test_enabled_instance_should_use_supplied_extensions():
extensions = [test_extension, test_extension2]
em = EnabledExtensionManager.make_test_instance(extensions)
assert extensions == em.extensions
# DispatchExtensionManager
def test_dispatch_instance_should_use_supplied_extensions():
extensions = [test_extension, test_extension2]
em = DispatchExtensionManager.make_test_instance(extensions)
assert extensions == em.extensions
def test_dispatch_map_should_invoke_filter_for_extensions():
em = DispatchExtensionManager.make_test_instance([test_extension,
test_extension2])
filter_func = Mock(return_value=False)
args = ('A',)
kw = {'big': 'Cheese'}
em.map(filter_func, None, *args, **kw)
filter_func.assert_any_call(test_extension, *args, **kw)
filter_func.assert_any_call(test_extension2, *args, **kw)
# NameDispatchExtensionManager
def test_name_dispatch_instance_should_use_supplied_extensions():
extensions = [test_extension, test_extension2]
em = NameDispatchExtensionManager.make_test_instance(extensions)
assert extensions == em.extensions
def test_name_dispatch_instance_should_build_extension_name_map():
extensions = [test_extension, test_extension2]
em = NameDispatchExtensionManager.make_test_instance(extensions)
assert test_extension == em.by_name[test_extension.name]
assert test_extension2 == em.by_name[test_extension2.name]
def test_named_dispatch_map_should_invoke_filter_for_extensions():
em = NameDispatchExtensionManager.make_test_instance([test_extension,
test_extension2])
func = Mock()
args = ('A',)
kw = {'BIGGER': 'Cheese'}
em.map(['test_extension'], func, *args, **kw)
func.assert_called_once_with(test_extension, *args, **kw)

View file

@ -84,6 +84,7 @@ DELUGEPORT = None
DELUGEUSR = None
DELUGEPWD = None
EXTCONTAINER = None
COMPRESSEDCONTAINER = None
MEDIACONTAINER = None
AUDIOCONTAINER = None
@ -136,7 +137,7 @@ def initialize(section=None):
TRANSCODE, GIT_PATH, GIT_USER, GIT_BRANCH, GIT_REPO, SYS_ENCODING, NZB_CLIENTAGENT, SABNZBDHOST, SABNZBDPORT, SABNZBDAPIKEY, \
DUPLICATE, IGNOREEXTENSIONS, OUTPUTVIDEOEXTENSION, OUTPUTVIDEOCODEC, OUTPUTVIDEOPRESET, OUTPUTVIDEOFRAMERATE, \
OUTPUTVIDEOBITRATE, OUTPUTAUDIOCODEC, OUTPUTAUDIOBITRATE, OUTPUTSUBTITLECODEC, OUTPUTFASTSTART, OUTPUTQUALITYPERCENT, \
NICENESS, LOG_DEBUG, FORCE_CLEAN, FFMPEG_PATH, FFMPEG, FFPROBE, AUDIOCONTAINER
NICENESS, LOG_DEBUG, FORCE_CLEAN, FFMPEG_PATH, FFMPEG, FFPROBE, AUDIOCONTAINER, EXTCONTAINER
if __INITIALIZED__:
return False
@ -240,12 +241,19 @@ def initialize(section=None):
DELUGEUSR = CFG["Torrent"]["DelugeUSR"] # mysecretusr
DELUGEPWD = CFG["Torrent"]["DelugePWD"] # mysecretpwr
COMPRESSEDCONTAINER = (CFG["Extensions"]["compressedExtensions"]) # .zip,.rar,.7z
MEDIACONTAINER = (CFG["Extensions"]["mediaExtensions"]) # .mkv,.avi,.divx
AUDIOCONTAINER = (CFG["Extensions"]["audioExtensions"])
METACONTAINER = (CFG["Extensions"]["metaExtensions"]) # .nfo,.sub,.srt
COMPRESSEDCONTAINER = CFG["Extensions"]["compressedExtensions"]
MEDIACONTAINER = CFG["Extensions"]["mediaExtensions"]
AUDIOCONTAINER = CFG["Extensions"]["audioExtensions"]
METACONTAINER = CFG["Extensions"]["metaExtensions"] # .nfo,.sub,.srt
if not isinstance(COMPRESSEDCONTAINER, list):COMPRESSEDCONTAINER = [COMPRESSEDCONTAINER]
if not isinstance(MEDIACONTAINER, list): MEDIACONTAINER = [MEDIACONTAINER]
if not isinstance(AUDIOCONTAINER, list): AUDIOCONTAINER = [AUDIOCONTAINER]
if not isinstance(METACONTAINER, list): METACONTAINER = [METACONTAINER]
EXTCONTAINER = [y for x in COMPRESSEDCONTAINER,MEDIACONTAINER,AUDIOCONTAINER,METACONTAINER for y in x]
MINSAMPLESIZE = int(CFG["Extensions"]["minSampleSize"]) # 200 (in MB)
SAMPLEIDS = (CFG["Extensions"]["SampleIDs"]) # sample,-s.
SAMPLEIDS = CFG["Extensions"]["SampleIDs"]
TRANSCODE = int(CFG["Transcoder"]["transcode"])
DUPLICATE = int(CFG["Transcoder"]["duplicate"])

View file

@ -581,19 +581,18 @@ def clean_nzbname(nzbname):
nzbname = re.sub("^\[.*\]", "", nzbname)
return nzbname.strip()
def isMediaFile(filename):
def isMediaFile(mediafile):
fileName, fileExt = os.path.splitext(mediafile)
# ignore MAC OS's retarded "resource fork" files
if filename.startswith('._'):
if fileName.startswith('._'):
return False
sepFile = filename.rpartition(".")
if re.search('extras?$', sepFile[0], re.I):
logger.info("Ignoring extras file: %s " % (filename))
if re.search('extras?$', fileName, re.I):
logger.info("Ignoring extras file: %s " % (mediafile))
return False
if sepFile[2].lower() in [i.replace(".","") for i in
(nzbtomedia.MEDIACONTAINER + nzbtomedia.AUDIOCONTAINER + nzbtomedia.COMPRESSEDCONTAINER)]:
if fileExt.lower() in nzbtomedia.EXTCONTAINER:
return True
else:
return False

View file

@ -19,6 +19,23 @@ copy_list = []
# Initialize the config
nzbtomedia.initialize()
EXTCONTAINER = []
try:
EXTCONTAINER += nzbtomedia.COMPRESSEDCONTAINER.split(',')
except:
EXTCONTAINER.extend(nzbtomedia.COMPRESSEDCONTAINER)
try:
EXTCONTAINER += nzbtomedia.MEDIACONTAINER.split(',')
except:
EXTCONTAINER.extend(nzbtomedia.MEDIACONTAINER)
try:
EXTCONTAINER += nzbtomedia.AUDIOCONTAINER.split(',')
except:
EXTCONTAINER.extend(nzbtomedia.AUDIOCONTAINER)
inputDirectory = "Z:\complete\movie\The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_0166_-_The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_yEn.cp(tt1490017)"
inputName = "The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_0166_-_The.Lego.Movie.2014.R5.x264.English.XviD-vTg.nfo_yEn.cp(tt1490017)"
inputCategory = 'movie'