3636# Author: Andrey Prygunkov ([email protected] ). 3737# Web-site: http://nzbget.sourceforge.net/VideoSort.
3838# License: GPLv3 (http://www.gnu.org/licenses/gpl.html).
39- # PP-Script Version: 3 .0.
39+ # PP-Script Version: 4 .0.
4040#
4141# NOTE: This script requires Python 2.x to be installed on your system.
4242
106106# %y - year;
107107# %decade - two-digits decade (90, 00, 10);
108108# %0decade - four-digits decade (1990, 2000, 2010).
109+ # %imdb - IMDb ID;
110+ # %cpimdb - IMDb ID (formatted for CouchPotato);
109111#
110112# Common specifiers (for movies, series and dated tv shows):
111113# %dn - original directory name (nzb-name);
191193# This option has effect on "case-adjusted"-specifiers.
192194#UpperWords=III,II,IV
193195
196+ # Use information from Direct-NZB headers (yes, no).
197+ #
198+ # NZB-sites may provide extended information about videos,
199+ # which is usually more confident than the information extracted
200+ # from file names.
201+ #DNZBHeaders=yes
202+
194203# Overwrite files at destination (yes, no).
195204#
196205# If not active the files are still moved into destination but
224233sys .path .append (dirname (__file__ ) + '/lib' )
225234
226235import os
227- import string
228236import traceback
229237import re
230238import shutil
288296series_year = os .environ .get ('NZBPO_SERIESYEAR' , 'yes' ) == 'yes'
289297
290298tv_categories = os .environ ['NZBPO_TVCATEGORIES' ].lower ().split (',' )
291- category = os .environ .get ('NZBPP_CATEGORY' , '' );
299+ category = os .environ .get ('NZBPP_CATEGORY' , '' )
292300force_tv = category .lower () in tv_categories
293301
294- force_nzbname = os .environ .get ('NZBPR__DNZB_USENZBNAME' , '' ).lower () == 'yes'
302+ dnzb_headers = os .environ .get ('NZBPO_DNZBHEADERS' , 'yes' ) == 'yes'
303+ dnzb_proper_name = os .environ .get ('NZBPR__DNZB_PROPERNAME' , '' )
304+ dnzb_episode_name = os .environ .get ('NZBPR__DNZB_EPISODENAME' , '' )
305+ dnzb_movie_year = os .environ .get ('NZBPR__DNZB_MOVIEYEAR' , '' )
306+ dnzb_more_info = os .environ .get ('NZBPR__DNZB_MOREINFO' , '' )
295307
296308if preview :
297309 print ('[WARNING] *** PREVIEW MODE ON - NO CHANGES TO FILE SYSTEM ***' )
298310
299- if verbose and force_nzbname :
300- print ('[INFO] Forcing use of nzb-name (X-DNZB-UseNZBName)' )
301-
302311if verbose and force_tv :
303312 print ('[INFO] Forcing TV sorting (category: %s)' % category )
304313
@@ -425,7 +434,7 @@ def cleanup_download_dir():
425434 ' ' : ' ' ,
426435 '//' : '/' ,
427436 ' - - ' : ' - ' ,
428- '__ ' : '_ '
437+ '-- ' : '- '
429438}
430439
431440def path_subst (path , mapping ):
@@ -458,9 +467,9 @@ def get_titles(name, titleing=False):
458467 a lot of little hacks to make it better and for more control
459468 '''
460469
461- title = name . replace ( '.' , ' ' ). replace ( '_' , ' ' )
462- title = title . strip (). strip ( '(' ). strip ( '_' ). strip ( '-' ). strip (). strip ( '_' )
463-
470+ #make valid filename
471+ title = re . sub ( '[ \" \:\?\* \\ \/\<\>\|]' , ' ' , name )
472+
464473 if titleing :
465474 title = titler (title ) # title the show name so it is in a consistant letter case
466475
@@ -702,6 +711,10 @@ def add_movies_mapping(guess, mapping):
702711 mapping .append (('%decade' , decade ))
703712 mapping .append (('%0decade' , decade_two ))
704713
714+ # imdb
715+ mapping .append (('%imdb' , guess .get ('imdb' , '' )))
716+ mapping .append (('%cpimdb' , guess .get ('cpimdb' , '' )))
717+
705718def add_dated_mapping (guess , mapping ):
706719
707720 # title
@@ -753,22 +766,110 @@ def add_dated_mapping(guess, mapping):
753766 mapping .append (('%d' , day ))
754767 mapping .append (('%0d' , day .rjust (2 , '0' )))
755768
756- def guess_info (filename ):
757- """ Parses the filename using guessit-library """
769+ def os_path_split (path ):
770+ parts = []
771+ while True :
772+ newpath , tail = os .path .split (path )
773+ if newpath == path :
774+ if path : parts .append (path )
775+ break
776+ parts .append (tail )
777+ path = newpath
778+ parts .reverse ()
779+ return parts
780+
781+ def deobfuscate_path (filename ):
782+ start = os .path .dirname (download_dir )
783+ new_name = filename [len (start )+ 1 :]
784+ if verbose :
785+ print ('stripped filename: %s' % new_name )
758786
759- use_nzbname = force_nzbname
787+ parts = os_path_split (new_name )
788+ if verbose :
789+ print (parts )
760790
761- if not use_nzbname :
762- fn = os .path .splitext (os .path .basename (filename ))[0 ]
791+ part_removed = 0
792+ for x in range (0 , len (parts )- 1 ):
793+ fn = parts [x ]
763794 if fn .find ('.' )== - 1 and fn .find ('_' )== - 1 and fn .find (' ' )== - 1 :
764- print ("Detected obfuscated filename %s, using NZB-Name instead" % os .path .basename (filename ))
765- use_nzbname = True
766-
767- if use_nzbname :
768- guessfilename = os .path .join (os .path .dirname (filename ), os .path .basename (download_dir )) + os .path .splitext (filename )[1 ]
795+ print ('Detected obfuscated directory name %s, removing from guess path' % fn )
796+ parts [x ] = None
797+ part_removed += 1
798+
799+ fn = os .path .splitext (parts [len (parts )- 1 ])[0 ]
800+ if fn .find ('.' )== - 1 and fn .find ('_' )== - 1 and fn .find (' ' )== - 1 :
801+ print ('Detected obfuscated filename %s, removing from guess path' % os .path .basename (filename ))
802+ parts [len (parts )- 1 ] = '-' + os .path .splitext (filename )[1 ]
803+ part_removed += 1
804+
805+ if part_removed < len (parts ):
806+ new_name = ''
807+ for x in range (0 , len (parts )):
808+ if parts [x ] != None :
809+ new_name = os .path .join (new_name , parts [x ])
769810 else :
770- guessfilename = filename
811+ print ("All file path parts are obfuscated, using obfuscated NZB-Name" )
812+ new_name = os .path .basename (download_dir ) + os .path .splitext (filename )[1 ]
813+
814+ return new_name
815+
816+ def remove_year (title ):
817+ """ Removes year from series name (if exist) """
818+ m = re .compile ('..*(\((19|20)\d\d\))' ).search (title )
819+ if not m :
820+ m = re .compile ('..*((19|20)\d\d)' ).search (title )
821+ if m :
822+ if verbose :
823+ print ('Removing year from series name' )
824+ title = title .replace (m .group (1 ), '' ).strip ()
825+ return title
771826
827+ def apply_dnzb_headers (guess ):
828+ """ Applies DNZB headers (if exist) """
829+
830+ dnzb_used = False
831+ if dnzb_proper_name != '' :
832+ dnzb_used = True
833+ if verbose :
834+ print ('Using DNZB-ProperName' )
835+ if guess ['vtype' ] == 'series' :
836+ proper_name = dnzb_proper_name
837+ if not series_year :
838+ proper_name = remove_year (proper_name )
839+ guess ['series' ] = proper_name
840+ else :
841+ guess ['title' ] = dnzb_proper_name
842+
843+ if dnzb_episode_name != '' and guess ['vtype' ] == 'series' :
844+ dnzb_used = True
845+ if verbose :
846+ print ('Using DNZB-EpisodeName' )
847+ guess ['title' ] = dnzb_episode_name
848+
849+ if dnzb_movie_year != '' :
850+ dnzb_used = True
851+ if verbose :
852+ print ('Using DNZB-MovieYear' )
853+ guess ['year' ] = dnzb_movie_year
854+
855+ if dnzb_more_info != '' :
856+ dnzb_used = True
857+ if verbose :
858+ print ('Using DNZB-MoreInfo' )
859+ if guess ['type' ] == 'movie' :
860+ regex = re .compile (r'^http://www.imdb.com/title/(tt[0-9]+)/$' , re .IGNORECASE )
861+ matches = regex .match (dnzb_more_info )
862+ if matches :
863+ guess ['imdb' ] = matches .group (1 )
864+ guess ['cpimdb' ] = 'cp(' + guess ['imdb' ] + ')'
865+
866+ if verbose and dnzb_used :
867+ print (guess .nice_string ())
868+
869+ def guess_info (filename ):
870+ """ Parses the filename using guessit-library """
871+
872+ guessfilename = deobfuscate_path (filename )
772873 if verbose :
773874 print ('Guessing: %s' % guessfilename )
774875
@@ -818,6 +919,9 @@ def guess_info(filename):
818919 elif guess ['type' ] == 'episode' :
819920 guess ['vtype' ] = 'series'
820921
922+ if dnzb_headers :
923+ apply_dnzb_headers (guess )
924+
821925 if verbose :
822926 print ('Type: %s' % guess ['vtype' ])
823927
@@ -829,7 +933,7 @@ def construct_path(filename):
829933 if verbose :
830934 print ("filename: %s" % filename )
831935
832- guess = guess_info (filename );
936+ guess = guess_info (filename )
833937 type = guess .get ('vtype' )
834938 mapping = []
835939 add_common_mapping (filename , guess , mapping )
0 commit comments