#!/usr/bin/perl
use warnings;
use strict;
use CGI::Carp qw(carpout);
use vars qw($ScriptDir $SaveDir $SaveSub $Rename $Delete $SaveExt $MiscDir $MiscExt $DownLog $Avimerge $Queue $Nice $NumArgs $DownloadDir $NzbFile $ParFile $ParCheck $NzbDone $ParFail @Files $Log $DupeCheck $ExtractedName $NewName $Extension $Spaces $NzbDir $Year);
use File::Copy;

# NZBGet post process script by dave @ http://dalrun.com/nzbgetpp/ (v Jun 03 08)
# See site for detailed script usage/information/details.
# ### Configuration: 
# Edit .nzbget - PostProcess=~/path/to/nzbgetpp.pl
$ScriptDir = '/home/dave/Download/nzbget/nzbgetpp'; # directory to put the script and the files it creates/uses
$Rename = 1; # Rename extracted/saved files, e.g. dvl-tt.avi > The Transporter.avi. See site for details. 1 = yes, 0 = no
$Delete = 1; # Delete all but extracted and SaveExt (below) files, 1 = yes, 0 = no. Use 0 until you know the script is doing what you want.

$SaveDir = '/home/dave/Video'; # where to put the extracted and saved files, _not_ your nzbget download dir (DestDir)
$SaveSub = 0; # 0 = automatic/optional subdirectories, 1 = a subdirectory for every nzb - $SaveDir/nzb base-name (Foo.nzb > $SaveDir/Foo)
# Extentions: none='', single='avi' multiple='avi|mp3|mov' (bar separated list)
$SaveExt = 'nfo|mp3|m3u|jpg|gif|png|avi|txt|sub|srt|idx|zip|pdf|iso'; # All extracted files are saved, this covers all other downloaded files (e.g. nfos and unrared mp3's)

# Send one or more saved extentions to an alternate directory, works with SaveExt files only (not extracted files)
$MiscExt = 'nfo'; # same format as SaveExt, extension(s) must also be in SaveExt (above), '' disables
$MiscDir = '/home/dave/Download/nzbget/nfos'; # Where to save $MiscExt (above), '' disables
# Another optional directory is $SaveDir/Samples. If you use the " kbf" flag your samples will be saved to $SaveDir/Samples if the Samples sub-directory exists.
# NzbDir/kbf and NzbDir/hold are also optional. Each time the script runs it checks to see if there are any nzbs in the nzb/kbf directory. 
# If there are, a 5 rar nzb is created in the parent nzb directory, i.e. save a normal/complete nzb to nzb/kbf and a sample will be downloaded. 
# If you like the sample, move the nzb from nzb/hold (yes, it got moved) to /nzb. Unfortunatly, the sample nzb's won't be created/found/downloaded 
# until the next time the script is run, i.e. after the next regular nzb is downloaded.

$DownLog = 'avi'; # file extensions to include in download.log, '' disables (no download.log is written)
$Avimerge = 1; # requires transcode. if the extraction resulted in foo a.avi and foo b.avi, merge to make foo.avi. If Delete=1, delete foo a and b avi.
$Queue = 0; # create shell scripts for later remote processing of downloaded files, configure lines 53-7
$Nice = 'nice -n19'; # use whatever works on your system, '' disables
$Year = 1; # include year in renamed name, 1 = yes, 0 = no  (not working yet)
# ###

$NumArgs = $#ARGV + 1;
if ($NumArgs == 6) {
	$DownloadDir = $ARGV[0]; # /path, files to extract/save are here
	$NzbFile = $ARGV[1]; # /path/foo.nzb, extracted file gets renamed foo.extension
	$ParFile = $ARGV[2]; # /path/file.par2, used to detect split avi's
	$ParCheck = $ARGV[3]; # 0 - no/not checked pars, 1 - fail, 2 - success, 3 - repairable but disabled
	$NzbDone = $ARGV[4]; # 0 - nzb contains multiple collections, 1 - single/last collection
	$ParFail = $ARGV[5]; # 0 - no par failures, 1 - one or more par checks failed
}
else { printf "Script compiles. Got $NumArgs args (3 = CLI, 5 = old nzbget), need 6 to do anything\n"; exit;}
if ($Queue and $NzbDone == 1 and $ParFail == 0 ){
	# configure note: running the shell scripts from the remote is now the default
	my $shebang = '#!/bin/bash';
	my $connect = ''; # only for running the scripts from the nzbget box (e.g. 'ssh dave@192.168.1.2'), also uncomment line 75 and comment line 76 
	my $remote_script = '/home/dave/Download/nzbget/nzbgetpp/nzbgetpp.pl'; # path to nzbgetpp.pl on remote
# 	my $remote_to_files = '/home/dave/LAN/FIC/dave/Download/nzbget/dst'; # path to download dir from remote
# 	my $remote_to_nzb = '/home/dave/LAN/FIC/dave/Download/nzbget/nzb'; # path to nzb dir from remote
	my $remote_to_files = '/home/dave/Download/nzbget/dst'; # path to download dir from remote
	my $remote_to_nzb = '/home/dave/Download/nzbget/nzb'; # path to nzb dir from remote
	# end configure
	my $sub_dir = ''; # leave empty
	my $nzb_name = ''; # leave empty
	my $par_name = ''; # leave empty
	#if ($NzbFile=~m!/(([^/]+) \d+\-\d+( dir)?\.nzb)$! or $NzbFile=~m!/(([^/]+)( mp3)?\.nzb)$! or $NzbFile=~m!/(([^/]+) \d+( dir)?\.nzb)$! or $NzbFile=~m!/(([^/]+) dir\.nzb)$! or $NzbFile=~m!/(([^/]+)\.nzb)$!) {
	if ($NzbFile=~m!/(([^/]+) \d+\-\d+( dir)?\.nzb)$! or $NzbFile=~m!/(([^/]+)( dir)?\.nzb)$!) {
		$nzb_name = $1;
		$NewName = $2;
	}
	if ($DownloadDir=~ m!/([^/]+)$!){
		$sub_dir = $1; # not always the same as the nzb base-name (special characters)
	}
	if ($ParFile =~ m!/([^/]+)$!){
		$par_name = $1;
	}
	open (WQUE, ">$ScriptDir/$NewName.sh") or die("Couldn't open $ScriptDir/$NewName.sh");
		print WQUE "$shebang\n\n";
		#print WQUE "$connect perl $remote_script \\\"$remote_to_files/$sub_dir\\\" \\\"$remote_to_nzb/$nzb_name\\\" \\\"$remote_to_files/$par_name\\\" $ParCheck $NzbDone $ParFail\n\n";
		print WQUE "perl $remote_script \"$remote_to_files/$sub_dir\" \"$remote_to_nzb/$nzb_name\" \"$remote_to_files/$par_name\" $ParCheck $NzbDone $ParFail\n\n";
	close (WQUE) or warn("Cannot close $ScriptDir/nzbgetpp_remote.sh");
	chmod(0700, "$ScriptDir/$NewName.sh") or warn("Unable to chmod $ScriptDir/$NewName.sh");
}
# change to if to create remote script for testing and process as usual on the nzbget box
elsif ($NzbDone == 1 and $ParFail == 0 ){ # delete "and $ParFail == 0" to always try extraction/save/delete
	if ($ParCheck == 0) { printf "[INFO] Collection contained no pars or par checking is disabled,\nProcessing $NzbFile.\n"; }
	elsif ($ParCheck == 2) { printf "[INFO] Collection passed par check, there were no par check failures.\nProcessing $NzbFile.\n"; }
	my $unrar_log = "$ScriptDir/unrar.log"; 
	my $found = 0;
	@Files = ();
	$Log = 0;
	$DupeCheck = "\t";
	if ($NzbFile=~m!^(.+)/([^/]+) \d+\-\d+( dir)?\.nzb$! or $NzbFile=~m!^(.+)/([^/]+)( dir)?\.nzb$!) { # catch all nzb-name is $2 in 2nd match
		$NzbDir = "$1"; # nzb directory/kbf
		$NewName = $2;
	}
	if (-e "$SaveDir"){
		if ($DownloadDir =~ m!^$SaveDir!){
			printf "[ERROR] \$SaveDir and NZBGet DestDir must be different directories\n";
			exit;
		}
		elsif ($NewName =~ m!^([^-]+ - .+) mp3$!){# mp3 flag sub-directory
			$SaveDir = "$SaveDir/$1";
			use File::Path;
			mkpath ("$SaveDir") or die ("Couldn't create dir, $SaveDir");
			printf "[INFO] Nzb has mp3 flag, using: $SaveDir\n";
		}
		elsif ($NzbFile =~ m!/([^/]+( \d+\-\d+)?) dir\.nzb$!i){# dir flag sub-directory
			$SaveDir = "$SaveDir/$1";
			use File::Path;
			mkpath ("$SaveDir") or die ("Couldn't create dir, $SaveDir");
			printf "[INFO] Nzb has directory flag, using: $SaveDir\n";
		}
		elsif ($SaveSub){
			if ($NzbFile =~ m!/([^/]+ \d+\-\d+)\.nzb$!i){ # since $NewName excludes \d+\-\d+ we pick it up here and use it for dir name only
				$SaveDir = "$SaveDir/$1";
			}
			else {$SaveDir = "$SaveDir/$NewName";} # otherwise we use nzb base-name
			use File::Path;
			mkpath ("$SaveDir") or die ("Couldn't create dir, $SaveDir");
			printf "[INFO] Configuration has sub-directory flag, using: $SaveDir\n";
		}
		else {printf "[INFO] Files will be extracted and/or moved to $SaveDir\n";}
		if ($NzbFile=~m! kbf\.nzb$!){
			system qx($Nice unrar x -y -kb "$DownloadDir/*.rar" "$SaveDir" > "$unrar_log" 2>&1) or die ("Couldn't execte unrar"); # -y(es to all) so unrar will always complete.
		}
		else {
			system qx($Nice unrar x -y "$DownloadDir/*.rar" "$SaveDir" > "$unrar_log" 2>&1) or die ("Couldn't execte unrar"); # -y(es to all) so unrar will always complete.
		}
	}
	else { die("ERROR $SaveDir (line 20) not found")}
	open (ULOG, "<$unrar_log") or die("Couldn't open $unrar_log");
	while (<ULOG>){
		if (m!^No files to extract!){
			printf "[INFO] No rar files to extract\n";
			if ($ParFile =~ m!/([^/]+)\.avi\.par2$!i){ # only nzbget joined ext?
				$ExtractedName = $1; #need for &SPACES
				$Extension = 'avi'; #need for &SPACES
				$ParFile =~ s!\.par2$!!i; # now /path/foo.avi
				if (-e $ParFile) {
					printf "[INFO] Nzbget joined avi, found\n";
					if (-e "$DownloadDir/_brokenlog.txt"){
						unlink ("$DownloadDir/_brokenlog.txt") or warn ("Couldn't delete $DownloadDir/_brokenlog.txt");
					}
				}
				else { # not sure what happens if nzbget cannot join the split avi
					printf "[INFO] ERROR Flawed split avi detection? Found avi.par2 but couldn't find avi\n";
					if ($Delete) {
						$Delete = 0;
						printf "[INFO] Playing it safe, not deleting any files\n";
					}
				}
			}
			if ($SaveExt) { &SAVE; }
			if ($Delete) {
				$Delete = 0;
				printf "[INFO] Playing it safe, not deleting any files\n";
			}
			#if ($Delete) { &DELETE; }
			elsif (!$Delete) {printf "[INFO] Per configuration, nothing deleted\n";}
		}
		elsif (m!\s+(.+)\.(\w{3,4}).+OK $!){ # should match all extracted files 
			$ExtractedName = $1;
			$Extension = $2; # need for rename
			$ExtractedName =~ s!^\Q$SaveDir\E/!!; # some OK lines contain $SaveDir/, some don't
			$found ++;
			if ($Avimerge and $Extension =~ m!^(sub|srt)$!){
				$Avimerge = 0;
				printf "[INFO] Found $1 file, disabling avimerge\n";
			}
			if (-e "$SaveDir/$ExtractedName.$Extension"){# check file existence
				printf "[INFO] Extracted $Extension: $ExtractedName.$Extension\n";
				# ### Extract nested rars
				if ($Extension =~ m!^rar!i){ 
					my $nest_name = '';
					my $nest_ext = '';
					my $nest_ok = 0;
					my $nest_dupe = 0;
					system qx($Nice unrar x -y "$SaveDir/$ExtractedName.rar" "$SaveDir" > "$DownloadDir/nested.log" 2>&1) or die ("Couldn't execute unrar");;
					open (NEST, "<$DownloadDir/nested.log") or die("Couldn't open $DownloadDir/nested.log");
					while (<NEST>){
						if (m!\s+(.+)\.(\w{3,4}).+OK $!){ 
							$nest_name = $1;
							$nest_ext = $2;
							$nest_name =~ s!^\Q$SaveDir\E/!!;
							printf "[INFO] Extracted from nested rar: $nest_name.$nest_ext\n";
							if ($Rename and $NewName) { 
								my $new_name = $NewName;
								$new_name =~ s!(\.|_)! !g; # periods or underscores to spaces
								$new_name =~ s! (HDTV|DVDRip|DVDSCR).+!!i; # remove DVD(Rip|SCR) or HDTV and any trailing stuff |DSR|PDTV|720p|STV
								if ($new_name =~ s! (\()?(19[4-9]|200\d)(\))?.*!!){ # remove year and any trailing stuff
									my $year = $2;
									printf "[INFO] DEV found year in nzb-name?: $year\n";
								}
								$new_name =~ s!^\d+-!!; # remove leading nzbsrus id
								$new_name =~ s!-nzbsrus com-\d+$!!; # remove trailing nzbsrus id
								$new_name =~ s! (\w{2,})! \u$1!g; # convert first word letter to upper case
								$new_name =~ s!^(\w)!\u$1!;
								if ($nest_name =~ m!\bcd(\d+)\b!i or $nest_name =~ m!\b([\dab])$!i) { # e.g. foo.cd1.bar
									my $cd = $1; 
									$cd =~ tr/12/ab/;
									if ($new_name !~ m! $cd$!){ $new_name = "$new_name $cd"; }
									else {printf "[INFO] $new_name has cd label, not adding\n";}
									if ($Extension =~ m!($DownLog)!i){
										$Spaces = '';
										my $num = length ("$new_name$nest_ext"); 
										while ($num < 55) {
											$Spaces.= ' ';
											$num++;
										}
										push (@Files, "$new_name.$nest_ext$Spaces\t$nest_name.$nest_ext");
										$Log = 1;
									}
								}
								if ($Avimerge and $nest_ext =~ m!^(sub|srt)$!){
									$Avimerge = 0;
									printf "[INFO] Found $1 file, disabling avimerge\n";
								}
								if ($DupeCheck =~ s!\t\Q$new_name\E.$nest_ext\t([^\t]+)\t!\t!){
									my $prev_name = $1;
									$nest_dupe = 1;
									move ("$SaveDir/$new_name.$nest_ext", "$SaveDir/$prev_name") or die ("Couldn't move $new_name.$nest_ext, $prev_name");
									printf "[INFO] Rename would overwrite, restored : $prev_name\n";
								}
								if ($nest_dupe){
									printf "[INFO] Saved $nest_ext: $nest_name.$nest_ext\n";
								}
								else {
									move ("$SaveDir/$nest_name.$nest_ext", "$SaveDir/$new_name.$nest_ext") or die ("Couldn't move $nest_name.$nest_ext, $NewName.$nest_ext");
									printf "[INFO] Renamed $nest_name.$nest_ext, $new_name.$nest_ext\n";
									$DupeCheck .= "$new_name.$nest_ext\t$nest_name.$nest_ext\t";
								}
							} 
						}
						elsif (m!^All OK!){
							$nest_ok = 1;
							printf "[INFO] Nested rar successfully extracted, OK to delete\n";
						}
						elsif (m!^Total errors: (\d+)!){ printf "[ERROR] unrar failed with $1 errors, see $ScriptDir/unrar.log.\n\n"; exit;}
					}
					close (NEST) or warn("Cannot close $DownloadDir/NestedRar");
					if ($nest_ok and $Delete) {
						unlink ("$SaveDir/$ExtractedName.rar") or die ("Couldn't delete $ExtractedName.rar");
						printf "[INFO] Deleted nested rar $SaveDir/$ExtractedName.rar\n";
					}
					elsif (!$nest_ok) { printf "[WARNING] Extracting $SaveDir/$ExtractedName.rar failed\n";}
					else { printf "[INFO] Per configuration, $SaveDir/$ExtractedName.rar not deleted\n";}
				}
				# ### Rename if series/cd label... or mp3 flag
				elsif ($Rename and $NewName) { 
					my $new_name = $NewName;
					my $year = '';
					unless ($new_name =~ m! mp3$!){
						$new_name =~ s!(\.|_)! !g; # periods or underscores to spaces
						$new_name =~ s! (HDTV|DVDRip|DVDSCR).+!!i; # remove DVD(Rip|SCR) or HDTV and any trailing stuff |DSR|PDTV|720p|STV
						if ($new_name =~ s! (\()?((19[4-9]|200)\d)(\))?.*!!){ # remove year and any trailing stuff
							$year = $2;
							printf "[INFO] DEV found year in nzb-name?: $year\n";
						}
# 						if ($Year) { # needs work and needs to be put someplace else
# 							$new_name =~ s!(.+)$!$1 ($year!){
# 							printf "[INFO] DEV added $year to nzb-name\n";
# 						}
						$new_name =~ s!^\d+-!!; # remove leading nzbsrus id
						$new_name =~ s!-nzbsrus com-\d+$!!; # remove trailing nzbsrus id
						$new_name =~ s! (\w{2,})! \u$1!g; # convert first word letter to upper case
						$new_name =~ s!^(\w)!\u$1!;
						#$new_name =~ s!(A|B)$!\l$1!; # change back a/b CD labels to lower case
					}
					my $old_name = $ExtractedName;#.$Ext; # using this the following should match save ext regex's ??
					my $path = '';
					if ($ExtractedName =~ m!^(.+/)!){ # save any extracted path (try replacing w/ new/nzb name)
						$path = $1;
					}
					#if ($new_name =~ m! mp3$!){
					if ($new_name =~ m!^([^-]+) - (.+) mp3$!){ # mp3 flag
						my $artist = $1;
						my $album = $2;
						my $temp = $old_name;
						$temp =~ s!^([^/]+/)!!; # strip 1 dir level, only used here (not w/ &SAVE)
						$temp =~ s!_! !g;
						$temp =~ s!\((\d+)\)!$1!; # parenthesis around track number
						$temp =~ s!(\d+)\.!$1!; # period after track number
						$temp =~ s!( |\.|-)?$artist( |\.|-)?! !i;
						if ($temp =~ m!$album\.(\.+)?mp3!i){ # (\.+) = song...mp3 anomaly
							$temp =~ s!^([^\d]+)?$album( |\.|-)?! !i;
						}
						else {$temp =~ s!( |\.|-)?$album( |\.|-)?! !i;}
						$temp =~ s!^[ \.-]+!!g;
						if ($temp =~ s!( |\.|-)?cd ?(\d)( |\.|-)?/!!i){
							my $cd = $2;
							$temp =~ s!^[ \.-]+!!g;
							$temp =~ s!^(\d+)!$cd$1!;
						}
						$temp =~ s!^covers/!!i;
						$temp =~ s!^(\d+) ([^-])!$1 - $2!i;
						$temp =~ s! (\w)! \u$1!g;
						$new_name = $temp;
					}
					#}
					elsif ($new_name =~ m!\b(S0?(\d+)E(\d+))\b(.+)?!i or $new_name =~ m!\b(0?(\d+)X(\d+))\b(.+)?!i) { # TV series
						my $label = $1;
						my $season = $2;
						my $ep = $3;
						my $grp = $4;
						$ep =~ s!00!0!; # seen anomaly
						if ($old_name =~ m!$season.?$ep!){ 
							$new_name =~ s!$label!$season$ep!;
							if ($grp) {
								$new_name =~ s!\Q$grp\E!!;
								printf "[INFO] $grp follows label and will not be used. If you want to use it, let me know.\n";
							}
							printf "[INFO] Found and changed label: $label > $season$ep\n";
						}
						else {printf "[WARNING] Couldn't find $label match in $old_name\n"}
					}
					elsif ($old_name =~ m!(_|\b)S0?(\d+)E(\d+)(_|\b)!i or $old_name =~ m!(_|\b)0?(\d+)X(\d+)(_|\b)!i) { # TV series
						my $season = $2;
						my $ep = $3;
						$ep =~ s!00!0!; # seen anomaly
						if ($new_name !~ m! $season$ep$!){ 
							$new_name = "$new_name $season$ep"; 
							printf "[INFO] Found and added label: $season$ep\n"; 
						}
						else {printf "[INFO] $new_name has label, not adding\n";}
					}
					elsif ($old_name =~ m!(_|\b)cd(\d+)(_|\b)!i or $old_name =~ m!(_|\b)([\dab])$!i) { # CD - foo.cdn.(bar.)ext
						my $cd = $2; 
						$cd =~ tr/12/ab/;
						#my $year = '';
						if ($old_name =~ m!(_|\b)((19[4-9]|200)\d)(_|\b)!){
							$year = $2;
							printf "[INFO] DEV found year in extracted filename?: $year\n";
						}
						if ($new_name !~ m! $cd$!){ 
							if ($year and $new_name !~ m!\b(\()?$year(\))?\b!){
								printf "[INFO] DEV rename w/ year?: $new_name ($year) $cd\n"; 
							}
							$new_name = "$new_name $cd"; 
							printf "[INFO] Found and added label: $cd\n"; 
						}
						else {printf "[INFO] $new_name has label, not adding\n"; }
						# unique to unrar section ### (not really needed)
						if ($Avimerge) {$Avimerge .= "\t$SaveDir/$path$new_name.$Extension\t"}
					}
					elsif ($new_name =~ m!\b(\d{3,4})$!){ # TV series label at end of nzb-name before year exclusion (below)
						my $label = $1;
						if ($old_name =~ m!$label!){ # any SnEn nXn cdn etc. should have been found earlier
							printf "[INFO] Found matching nzb and file name label: $label\n";
						}
						else {
							printf "[INFO] Couldn't find $label match in $old_name, not using\n";
						}
					}
					elsif ($old_name =~ m!(_|\b)((19[4-9]|200)\d)(_|\b)!) { # exclude year unless its at end of nzb-name (or the label was already found)
						if ($new_name !~ m! $2\)?$!){ # foo (2000) or foo 2000.ext
							printf "[INFO] '$2' looks like a year and was not found in nzb-name: $new_name\n"; 
							printf "[INFO] If you want to use '$2' as a label, use nzb-name: $new_name $2 or $new_name ($2)\n"; 
						}
						else {printf "[INFO] $new_name has label, not adding\n";}
					}
					elsif ($old_name =~ m!(_|\b)0?(\d{3,4})(_|\b)(.+)?!i or $old_name =~ m!\w0?(\d{3,4})(_|\b)(.+)?!i) { # TV - foo.(0)nnn(n).(bar.)ext, foonnn(n).(bar.)ext
						if ($new_name !~ m! $2$!){ 
							$new_name = "$new_name $2"; # add episode if we don't have it
							printf "[INFO] Found and added label: $2\n"; 
							printf "[INFO] Please report any false positives\n"; 
						}
						elsif ($new_name =~ m! $2$3$!){ # if we have episode remove following test, typ grp and file type info
							my $grp = $3;
							$new_name =~ s!\Q$grp\E!!;
							printf "[INFO] $grp follows label and will not be used. If you want to use it, let me know.\n";
						}
						else {printf "[INFO] $new_name has episode label, not adding\n";}
					}
					# only in urar section ###
					elsif ($ExtractedName =~ m!(.+)(a|b|1|2)(\.xvid)?$! and $Extension eq 'avi') { # CD - fooa.avi and foob.avi
						my $avi_base = $1;
						my $new_cd = $2;
						my $prev_cd = '';
						if    ($new_cd eq 'a') {$prev_cd = 'b';}
						elsif ($new_cd eq 'b') {$prev_cd = 'a';}
						elsif ($new_cd eq '1') {$prev_cd = 'b'; $new_cd = 'a';}
						elsif ($new_cd eq '2') {$prev_cd = 'a'; $new_cd = 'b';}
						if (-e "$SaveDir/$new_name.avi"){
							printf "[INFO] Found and using $prev_cd/$new_cd labels\n"; 
							move ("$SaveDir/$new_name.avi", "$SaveDir/$path$new_name $prev_cd.avi") or die ("Couldn't move $SaveDir/$new_name.avi, $SaveDir/$path$new_name $prev_cd.avi");
							$DupeCheck =~ s!\Q$new_name\E\.avi!$new_name $prev_cd.avi!;
							if ($Avimerge) {$Avimerge .= "\t$SaveDir/$path$new_name $prev_cd.avi\t"}
							printf "[INFO] Renamed  $new_name.avi, $new_name $prev_cd.avi\n";
							if ($Extension =~ m!($DownLog)!i){
								$Spaces = '';
								my $num = length ("$new_name$Extension"); 
								while ($num < 55) {
									$Spaces.= ' ';
									$num++;
								}
								foreach (@Files) {s!\Q$new_name\E\.avi$Spaces\t\Q$avi_base\E$prev_cd\.avi!$new_name $prev_cd.avi$Spaces\t$avi_base$prev_cd.avi!;}
							}
						}							
					}
					if ($found and -e "$SaveDir/$path$new_name.$Extension"){
						my $prev_name = '';
						my $old_dir = '';
						if ($DupeCheck =~ s!\t\Q$path$new_name\E\.$Extension\t([^\t]+)\t!\t!){
							$prev_name = $1;
						}
						if ($SaveExt !~ m!$Extension!){ # special case exception to saving all extracted files
							unlink ("$SaveDir/$path$ExtractedName.$Extension");
							printf "[INFO] Deleted $ExtractedName.$Extension, its not in SaveExt and saving it would undo rename\n";
							if ($Delete) {
								$Delete = 0;
								printf "[INFO] Playing it safe, not deleting any files\n";
							}
						}
						elsif ($prev_name) {
							printf "[INFO] Rename would overwrite, disabling and undoing rename.\n";
							if ($Delete) {
								$Delete = 0;
								printf "[INFO] Playing it safe, not deleting any files\n";
							}
							if (!$path and !$SaveSub){
								use File::Path;
								mkpath ("$SaveDir/$NewName") or die ("Couldn't create dir, $SaveDir/$NewName");
								printf "[INFO] Enabling sub-directory, files will be saved to: $SaveDir/$NewName\n";
								move ("$SaveDir/$new_name.$Extension", "$SaveDir/$NewName/$prev_name") or die ("Couldn't move $new_name.$Extension, $NewName/$prev_name");
								printf "[INFO] Restored and moved: $prev_name\n";
								move ("$SaveDir/$ExtractedName.$Extension", "$SaveDir/$NewName/") or die ("Couldn't save $ExtractedName.$Extension, does $SaveDir exist?");
								printf "[INFO] Saved: $ExtractedName.$Extension\n";
								$old_dir = $SaveDir;
								$SaveDir = "$SaveDir/$NewName";
							}
							else {
								move ("$SaveDir/$path$new_name.$Extension", "$SaveDir/$prev_name") or die ("Couldn't move $new_name.$Extension, $prev_name");
								printf "[INFO] Restored : $prev_name\n";
							}
							while ($DupeCheck =~ s!^\t([^\t]+)\.(\w{3,4})\t([^\t]+)\t!\t!g){
								my $re_name = $1; # includes path
								my $re_ext = $2;
								my $re_old = $3;
								if (-e "$old_dir/$re_name.$re_ext") {
									move ("$old_dir/$re_name.$re_ext", "$SaveDir/$re_old.$re_ext") or die ("Couldn't move $re_name.$re_ext, $re_old.$re_ext");
									printf "[INFO] Restored and moved: $re_old.$re_ext\n";
								}
								elsif (-e "$SaveDir/$re_name.$re_ext") {
									move ("$SaveDir/$re_name.$re_ext", "$SaveDir/$re_old.$re_ext") or die ("Couldn't move $re_name.$re_ext, $re_old.$re_ext");
									printf "[INFO] Restored: $re_old.$re_ext\n";
								}
								else {printf "[INFO] Cannot find: $re_name.$re_ext\n";}
							}
							$NewName = '';
						}
						else {printf "[INFO] Renaming would overwrite: $SaveDir/$path$new_name.$Extension\n";}
					}
					elsif ($NewName =~ m! mp3$! and !$SaveSub){ # mp3 sub directory when SaveSub = 0
						move ("$SaveDir/$ExtractedName.$Extension", "$SaveDir/$new_name.$Extension") or die ("Couldn't move $ExtractedName.$Extension, $new_name.$Extension, does $SaveDir exist?");
						printf "[INFO] Renamed: $ExtractedName.$Extension, $new_name.$Extension\n";
						if ($Delete and $ExtractedName =~ m!^([^/]+)/!){
							my $del_dir = "$SaveDir/$1";
							rmdir ($del_dir) or printf "[WARNING] Couldn't delete $del_dir\n";
						}
					}
					else {
						move ("$SaveDir/$ExtractedName.$Extension", "$SaveDir/$path$new_name.$Extension") or die ("Couldn't move $ExtractedName.$Extension, $new_name.$Extension");
						printf "[INFO] Renamed: $ExtractedName.$Extension, $path$new_name.$Extension\n";
					}
					$DupeCheck .= "$path$new_name.$Extension\t$ExtractedName.$Extension\t";
					if ($Extension =~ m!($DownLog)!i){
						$Spaces = '';
						#my $num = length ("$old_name"); 
						my $num = length ("$new_name$Extension"); 
						while ($num < 55) {
							$Spaces.= ' ';
							$num++;
						}
						push (@Files, "$new_name.$Extension$Spaces\t$ExtractedName.$Extension");
						$Log = 1;
					}
				}
			}
			else { printf "[WARNING] faulty reg-ex?, couldn't find $ExtractedName.$Extension in $SaveDir\n";} 
			# Download Log (anything not renamed)
			if ($Extension =~ m!($DownLog)!i){
				unless ($Log) {push (@Files, "$ExtractedName.$Extension");}
			}
		}	
		elsif (m!^All OK! and $found){
			if ($SaveExt) { &SAVE; } # ### everything else
			printf "[INFO] Collection(s) successfully extracted and saved.\n";
			if ($Delete) { &DELETE }
			elsif (!$Delete) {printf "[INFO] Per configuration, nothing deleted\n";}
		}
		elsif (m!^All OK!){ printf "[WARNING] faulty reg-ex, extraction OK but no extracted filename was found (nothing deleted or renamed).\n\n";}
		elsif ($NewName =~ m! kbf$! and m!^(.+)\.(\w{3,4})[\s\-]+CRC failed!){ 
			my $old_file = $1;
			my $old_ext = $2;
			$NewName =~ s! kbf! Sample!;
			printf "[INFO] Found 'keep broken file' flag ( kbf)\n";
			if (-e "$SaveDir/Samples"){
				move ("$SaveDir/$old_file.$old_ext", "$SaveDir/Samples/$NewName.$old_ext") or die ("Couldn't move $old_file.$old_ext, $NewName.$old_ext");
			}
			else {
				move ("$SaveDir/$old_file.$old_ext", "$SaveDir/$NewName.$old_ext") or die ("Couldn't move $old_file.$old_ext, $NewName.$old_ext");
			}
			printf "[INFO] Renamed  $old_file.$old_ext, $NewName.$old_ext\n";
			if ($DownloadDir =~ m!(.+/([^/]+)) kbf$!){
				my $new_dir = $1;
				my $dir = $2;
				move ("$DownloadDir", "$new_dir") or die ("Couldn't move $DownloadDir, $new_dir");
				printf "[INFO] Renamed directory: $dir kbf, $dir\n";
			}
			if ($Delete){
				if (unlink ("$NzbFile.queued")){
					printf "[INFO] Deleted nzb: $NzbFile.queued\n";
				}
				else {printf "[WARNING] Couldn't delete nzb: $NzbFile.queued\n";}
			}
		}
		elsif (m!^Total errors: 1! and $NewName =~ m! Sample$!){ printf "[INFO] Ignoring 1 urar error resulting from kbf flag.\n";}
		elsif (m!^Total errors: (\d+)!){ printf "[ERROR] unrar failed with $1 errors, see $ScriptDir/unrar.log.\n\n"; exit;}
		elsif (m!^WARNING: You need to start extraction from a previous volume!){printf "[ERROR] unrar failed with WARNING(s), see $ScriptDir/unrar.log.\n\n"; exit;}

	}
	close (ULOG) or warn("Cannot close $unrar_log");
	if ($Avimerge){
		my $avi_1 = '';
		my $avi_2 = '';
		if ($Avimerge =~ m!\t(\Q$SaveDir\E/[^\t]+ a\.avi)\t!){ 
			$avi_1 = $1;
		}
		if ($Avimerge =~ m!\t(\Q$SaveDir\E/[^\t]+ b\.avi)\t!){
			$avi_2 = $1;
		}
		if ($avi_1 and $avi_2) {
			my $avi_out = $avi_2;
			$avi_out =~ s! b!!;
			system qx($Nice avimerge -c -i "$avi_1" "$avi_2" -o "$avi_out" 1>"$ScriptDir/avimerge.log" 2>/dev/null) or die ("Couldn't execte avimerge, is transcode installed?");
			$avi_out =~ s!\Q$SaveDir\E/!!;
			printf "[INFO] Merged avi's, created $avi_out\n";
			if ($Delete){
				if (unlink ("$avi_1")){ 
					$avi_1 =~ s!$SaveDir!!;
					printf "[INFO] Deleted $avi_1\n";
				}
				else {printf "[WARNING] Unable to delete $avi_1\n";}
				if (unlink ("$avi_2")){
					$avi_2 =~ s!$SaveDir!!;
					printf "[INFO] Deleted $avi_2\n";
				}
				else {printf "[WARNING] Unable to delete $avi_2\n";}
			}
			foreach (@Files) {s! [ab].avi$!.avi!;}
		}
	}	
	if (@Files and $DownLog) {
		# personal usage, injects renamed name into web page
		if (-e "/home/dave/httpd/dave/Movies/Download/index.html"){
			my $page = "/home/dave/httpd/dave/Movies/Download/index.html";
			open (RDLOG, "<$page") or warn("Couldn't read $page");
			open (WDLOG, ">$page.tmp") or warn("Couldn't write $page.tmp");
			while (<RDLOG>) {
				if (m¦^(<!--144--><P>)(.+)¦){ # start of line match
					print WDLOG $1; # print first part of line (<!--144--><P>)
					my $tail = $2;
					foreach my $file (@Files) {
						if ($file =~ m!^(.+)\.[^\.]+\t!){
							print WDLOG "$1<br>"; # inject
						}
					}
					print WDLOG "$tail\n"; # print the rest of the line
				}
				else {print WDLOG;}
			}
			close (WDLOG) or warn("Cannot close $page.tmp");
			rename("$page.tmp", "$page");
			close (RDLOG) or warn("Cannot close $page");
		}
		my $down_log = "$ScriptDir/download.log";
		open (RDLOG, "<$down_log") or die("Couldn't read $down_log");
		while (<RDLOG>) {
			chomp;
			push (@Files, $_);
		}
		close (RDLOG) or warn("Cannot close $down_log");
		open (WDLOG, ">$down_log") or die("Couldn't write $down_log");
		foreach my $file (sort {lc $a cmp lc $b} @Files) { 
			print WDLOG "$file\n";
		}
		close (WDLOG) or warn("Cannot close $down_log");
		
		printf "[INFO] Updated $down_log\n";
	}
	if (-e "$NzbDir/kbf"){ # nzb directory/kbf
		use File::Find;
		find(\&KBF, "$NzbDir/kbf");
	}
}
elsif (!$NzbDone and $ParCheck == 0) { printf "[INFO] Collection contained no pars or par checking is disabled, waiting for last collection.\n"; }
elsif (!$NzbDone and $ParCheck == 1) { 
	$ParFile =~ s!/([^/]+\.par2)$!$1!i;
	printf "[ERROR] Par repair failed for $ParFile, waiting for last collection.\n"; 
}
elsif (!$NzbDone and $ParCheck == 2) { printf "[INFO] Collection passed par check, waiting for last collection.\n"; }
elsif (!$NzbDone and $ParCheck == 3) { printf "[INFO] ERROR Collection could be repaired, but repair is disabled. Waiting for last collection.\n"; }
elsif ($NzbDone and $ParFail == 1) { 
	if ($ParCheck == 1) { 
		$ParFile =~ s!/([^/]+\.par2)$!$1!i;
		printf "[ERROR] Par repair failed for $ParFile.\n"; 
	}
	elsif ($ParCheck == 3) { printf "[INFO] ERROR Collection could be repaired, but repair is disabled.\n"; }
	printf "[ERROR] At least one collection failed par check.\nERROR unable to process $NzbFile.\n\n"; 
}
else { printf "[ERROR] Something is foobar (par check = $ParCheck and nzb state = $NzbDone), cannot process $NzbFile\n\n"; }

sub DELETE {
	if (unlink ("$NzbFile.queued")){
		printf "[INFO] Deleted nzb: $NzbFile.queued\n";
	}
	else {printf "[WARNING] Couldn't delete nzb: $NzbFile.queued\n";}
	use File::Path;
	if (rmtree($DownloadDir)){
		printf "[INFO] Deleted directory: $DownloadDir\n";
	}
	else {printf "[WARNING] Couldn't delete directory: $DownloadDir\n";}
}

sub SAVE {
	use File::Find;
	find(\&wanted, "$DownloadDir");
	sub wanted {
		if (-f and (/\.($SaveExt)$/i or /\.(0\d+)$/)){
			my $ext = $1;
			if ($ext =~ m!^0\d+$! and $Delete){
				$Delete = 0;
				if ($Rename) {$Rename = 0;}
				printf "[WARNING] Found .$ext file (unsupported rar format), disabling deletion\n";
			}
			my $old_name = $_;
			my $new_name = '';
			if ($Avimerge and $ext =~ m!^(sub|srt)$!){
				$Avimerge = 0;
				printf "[INFO] Found $1 file, disabling avimerge\n";
			}
			if ($Rename and $NewName){
				$new_name = $NewName;
				unless ($new_name =~ m! mp3$!){
					$new_name =~ s!(\.|_)! !g; # periods or underscores to spaces
					$new_name =~ s! (HDTV|DVDRip|DVDSCR).+!!i; # remove DVD(Rip|SCR) or HDTV and any trailing stuff |DSR|PDTV|720p|STV
					if ($new_name =~ s! (\()?(19[4-9]|200\d)(\))?.*!!){ # remove year and any trailing stuff
						my $year = $2;
						printf "[INFO] DEV found year in nzb-name?: $year\n";
					}
					$new_name =~ s!^\d+-!!; # remove leading nzbsrus id
					$new_name =~ s!-nzbsrus com-\d+$!!; # remove trailing nzbsrus id
					$new_name =~ s! (\w{2,})! \u$1!g; # convert first word letter to upper case
					$new_name =~ s!^(\w)!\u$1!;
				}
				#if ($new_name =~ m!^([\w\s]+) - ([\w\s]+) mp3$!){
				if ($new_name =~ m!^([^-]+) - (.+) mp3$!){
					my $artist = $1;
					my $album = $2;
					my $temp = $old_name;
					my $track = '';
					$temp =~ s!_! !g;
					$temp =~ s!\((\d+)\)!$1!; # parenthesis around track number
					$temp =~ s!(\d+)\.!$1!; # period after track number
					$temp =~ s!\.\w{3,4}!!;
					$temp =~ s!( |\.|-)?$artist( |\.|-)?! !i;
					if ($temp =~ m!$album(\.+)?$!i){ # (\.+) = album...mp3 anomaly
						$temp =~ s!^([^\d]+)?$album( |\.|-)?! !i;
					}
					else {$temp =~ s!( |\.|-)?$album( |\.|-)?! !i;}
					$temp =~ s!^[ \.-]+!!g;
					if ($temp =~ s!( |\.|-)?cd(\d)( |\.|-)?/!!i){
						my $cd = $2;
						$temp =~ s!^[ \.-]+!!g;
						$temp =~ s!^(\d+)!$cd$1!;
					}
					$temp =~ s!^covers/!!i;
					$temp =~ s!^(\d+) ([^-])!$1 - $2!i;
					$temp =~ s! (\w)! \u$1!g;
					$new_name = $temp;
				}
				elsif ($new_name =~ m!\b(S0?(\d+)E(\d+))\b(.+)?!i or $new_name =~ m!\b(0?(\d+)X(\d+))\b(.+)?!i) {
					my $label = $1;
					my $season = $2;
					my $ep = $3;
					my $grp = $4;
					$ep =~ s!00!0!; # seen anomaly
					if ($old_name =~ m!$season.?$ep!){ 
						$new_name =~ s!$label!$season$ep!;
						if ($grp) {
							$new_name =~ s!\Q$grp\E!!;
							printf "[INFO] $grp follows label and will not be used. If you want to use it, let me know.\n";
						}
						printf "[INFO] Found and changed label: $label > $season$ep\n";
					}
					else {printf "[WARNING] Couldn't find $label match in $old_name\n"}
				}
				elsif ($old_name =~ m!\bS0?(\d+)E(\d+)\b!i or $old_name =~ m!\b0?(\d+)X(\d+)\b!i) {
					my $season = $1;
					my $ep = $2;
					$ep =~ s!00!0!; # seen anomaly
					if ($new_name !~ m! $season$ep$!){
						$new_name = "$new_name $season$ep"; 
						printf "[INFO] Found and added label: $season$ep\n"; 
					}
					else {printf "[INFO] $new_name has episode label, not adding\n";}
				}
				elsif ($old_name =~ m!\bcd(\d+)\b!i or $old_name =~ m!\b([\dab])(\.xvid)?\.\w{3,4}$!i) { # foo.cdn.(bar.)ext foo.bar.n.ext
					my $cd = $1; #						# (\.xvid)? is in diff place in urar section
					$cd =~ tr/12/ab/;
					if ($new_name !~ m! $cd$!){ 
						$new_name = "$new_name $cd"; 
						printf "[INFO] Found and added CD label: $cd\n"; 
					}
					else {printf "[INFO] $new_name already has cd label, not adding\n";}
				}
				elsif ($new_name =~ m!\b(\d{3,4})$!){ # check for series label at end of nzb-name before year exclusion (below)
					my $label = $1;
					if ($old_name =~ m!$label!){ # any SnEn nXn cdn etc. should have been found earlier
						$new_name =~ s!\.! !g;
						printf "[INFO] Found matching nzb and file name label: $label\n";
					}
					else {
						printf "[INFO] Couldn't find $label match in $old_name, not using\n";
					}
				}
				elsif ($old_name =~ m!\b((19[4-9]|200)\d)\b!) { # exclude year unless its at end of nzb-name (or the label was already found)
					if ($new_name !~ m! $1\)?$!){ 
						printf "[INFO] '$1' looks like a year and was not found in nzb-name: $new_name\n"; 
						printf "[INFO] If you want to use '$1' as a label, use nzb-name: $new_name $1\n"; 
					}
					else {printf "[INFO] $new_name has label, not adding\n";}
				}
				elsif ($old_name =~ m!\b0?(\d{3,4})\b(.+)?\.\w{3,4}$!i or $old_name =~ m!\w0?(\d{3,4})\b(.+)?\.\w{3,4}$!i) { # foo.(0)nnn(n).(bar.)ext, foonnn(n).(bar.)ext
					if ($new_name !~ m! $1$!){ 
						$new_name = "$new_name $1"; # add episode if we don't have it
						printf "[INFO] Found and added label: $1\n"; 
						printf "[INFO] Please report any false positives\n"; 
					}
					elsif ($new_name =~ m! $1$2$!){ # if we have episode remove following test, typ grp and file type info
						my $grp = $2;
						$new_name =~ s!\Q$grp\E!!;
						printf "[INFO] $grp follows label and will not be used. If you want to use it, let me know.\n";
					}
					else {printf "[INFO] $new_name has episode label, not adding\n";}
				}
				if ($old_name =~ m!_brokenlog.txt! and $SaveExt =~ m!txt!){$ext = 'nzbget.log';}
				elsif ($old_name =~ m!\bsubs\b! and $ext !~ m!(idx|sub)!){$new_name = "$new_name subs";}
				elsif ($old_name =~ m!\bSample\b!i and $new_name !~ m!Sample!i){$new_name = "$new_name Sample";}
				
				my $prev_name = '';
				if (-e "$SaveDir/$new_name.$ext" and $ext !~ m!($MiscExt)!) {
					if ($DupeCheck =~ s!\t\Q$new_name\E\.$ext\t([^\t]+)\t!\t!){
						$prev_name = $1;
					}
					if ($prev_name eq $old_name){
						$new_name = "$new_name\_dupe";
						move ("$File::Find::name", "$SaveDir/$new_name.$ext") or die ("Couldn't move $old_name, $new_name.$ext, does $SaveDir exist?");
						printf "[INFO] Renamed and saved $ext: $old_name, $SaveDir/$new_name.$ext\n";
					}
					elsif ($prev_name){
						printf "[INFO] Rename would overwrite, disabling and undoing rename.\n";
							if ($Delete) {
								$Delete = 0;
								printf "[INFO] Playing it safe, not deleting any files\n";
							}
						if (!$SaveSub and $DownloadDir !~ m! dir$!i){
							use File::Path;
							mkpath ("$SaveDir/$NewName") or die ("Couldn't create dir, $SaveDir/$NewName");
							printf "[INFO] Enabling sub-directory, files will be saved to: $SaveDir/$NewName\n";
							move ("$SaveDir/$new_name.$ext", "$SaveDir/$NewName/$prev_name") or die ("Couldn't move $new_name.$ext, $NewName/$prev_name");
							printf "[INFO] Restored : $prev_name\n";
							$SaveDir = "$SaveDir/$NewName";
						}
						else {
							move ("$SaveDir/$new_name.$ext", "$SaveDir/$prev_name") or die ("Couldn't move $new_name.$ext, $prev_name");
							printf "[INFO] Restored : $prev_name\n";
						}
						#move ("$SaveDir/$new_name.$ext", "$SaveDir/$prev_name") or die ("Couldn't move $new_name.$ext, $prev_name");
						move ("$File::Find::name", "$SaveDir/") or die ("Couldn't save $old_name, does $SaveDir exist?");
						printf "[INFO] Saved $ext: $old_name\n";
						# go back and undo all renames (including extracted), too paranoid?
						while ($DupeCheck =~ s!^\t([^\t]+)\.(\w{3,4})\t([^\t]+)\t!\t!g){
							my $re_name = $1;
							my $re_ext = $2;
							my $re_old = $3; # note: $re_old includes .ext
							if (-e "$SaveDir/$re_name.$re_ext") {
								move ("$SaveDir/$re_name.$re_ext", "$SaveDir/$re_old") or die ("Couldn't move $re_name.$re_ext, $re_old");
								printf "[INFO] Restored : $re_old\n";
							}
						}
						$NewName = '';
					}
					else { 
						$NewName = '';
						printf "[WARNING] Not getting previous name match for: $SaveDir/$new_name.$ext\n";
						if ($Delete) {
							$Delete = 0;
							printf "[INFO] Playing it safe, not deleting any files\n";
						}
					}
				}
				elsif (-e "$MiscDir/$new_name.$ext") {
					if ($DupeCheck =~ s!\t\Q$new_name\E\.$ext\t([^\t]+)\t!\t!){
						$prev_name = $1;
					}
					if ($prev_name eq $old_name){
						$new_name = "$new_name\_dupe";
						move ("$File::Find::name", "$MiscDir/$new_name.$ext") or die ("Couldn't move $old_name, $new_name.$ext, does $MiscDir exist?");
						printf "[INFO] Renamed and saved $ext: $old_name, $MiscDir/$new_name.$ext\n";
					}
					elsif ($prev_name){
						printf "[INFO] Rename would overwrite, disabling and undoing rename.\n";
							if ($Delete) {
								$Delete = 0;
								printf "[INFO] Playing it safe, not deleting any files\n";
							}
						move ("$MiscDir/$new_name.$ext", "$MiscDir/$prev_name") or die ("Couldn't move $new_name.$ext, $prev_name");
						printf "[INFO] Restored : $prev_name.\n";
						move ("$File::Find::name", "$MiscDir/") or die ("Couldn't save $old_name, does $MiscDir exist?");
						printf "[INFO] Saved $ext: $old_name to $MiscDir\n";
						# go back and undo all renames (including extracted), too paranoid?
						while ($DupeCheck =~ s!^\t([^\t]+)\.(\w{3,4})\t([^\t]+)\t!\t!g){
							my $re_name = $1;
							my $re_ext = $2;
							my $re_old = $3; # note: $re_old includes .ext
							if (-e "$MiscDir/$re_name.$re_ext") {
								move("$MiscDir/$re_name.$re_ext", "$MiscDir/$re_old") or die ("Couldn't move $re_name.$re_ext, $re_old");
								printf "[INFO] Restored : $re_old\n";
							}
						}
						$NewName = '';
					}
					else { 
						$NewName = '';
						printf "[WARNING] Not getting previous name match for: $MiscDir/$new_name.$ext\n";
						if ($Delete) {
							$Delete = 0;
							printf "[INFO] Playing it safe, not deleting any files\n";
						}
					}
				}
				elsif ($MiscExt and $ext =~ m!($MiscExt)! and $MiscDir){
					move ("$File::Find::name", "$MiscDir/$new_name.$ext") or die ("Couldn't move $old_name, $new_name.$ext, does $MiscDir exist?");
					printf "[INFO] Renamed and saved $ext: $old_name, $MiscDir/$new_name.$ext\n";
				}
				elsif ($NewName =~ m! mp3$! and !$SaveSub){
					move ("$File::Find::name", "$SaveDir/$new_name.$ext") or die ("Couldn't move $old_name, $new_name.$ext, does $SaveDir exist?");
					printf "[INFO] Renamed and saved $ext: $old_name, $new_name.$ext\n";
				}
				else {
					move ("$File::Find::name", "$SaveDir/$new_name.$ext") or die ("Couldn't move $old_name, $new_name.$ext");
					printf "[INFO] Renamed and saved $ext: $old_name, $new_name.$ext\n";
				}
				$DupeCheck .= "$new_name.$ext\t$old_name\t"; # note: $old_name includes .ext
				if ($ext =~ m!($DownLog)!i){
					$Spaces = '';
					#my $num = length ("$old_name"); 
					my $num = length ("$new_name$ext"); 
					while ($num < 55) {
						$Spaces.= ' ';
						$num++;
					}
					push (@Files, "$new_name.$ext$Spaces\t$old_name");
					$Log = 1;
				}
			}
			else {
				if ($MiscExt and $ext =~ m!($MiscExt)! and $MiscDir){
					move ("$File::Find::name", "$MiscDir/") or die ("Couldn't move $old_name, does $MiscDir exist?");
					printf "[INFO] Saved $ext: $old_name to $MiscDir\n";
				}
				elsif ($NewName =~ m! mp3$! and !$SaveSub){
					move ("$File::Find::name", "$SaveDir/") or die ("Couldn't move $old_name, does $SaveDir exist?");
					printf "[INFO] Saved $ext: $old_name\n";
				}
				else {
					move ("$File::Find::name", "$SaveDir/") or die ("Couldn't move $old_name to $SaveDir");
					printf "[INFO] Saved $ext: $old_name\n";
				}
			}
		}
	}
}

sub SPACES {
	$Spaces = '';
	my $num = length ("$ExtractedName.$Extension"); 
	while ($num < 64) {
		$Spaces.= ' ';
		$num++;
	}
}

sub KBF {
	if (-f and /\.nzb$/i){ # see if any files match " kbf.nzb"
		my $nzb = $_;
		my $kbf_nzb = $nzb;
		$kbf_nzb =~ s!\.nzb$! kbf.nzb!;
		#$new_name =~ s! kbf!!; # to rename nzb after sample downloaded (remove " kbf")
		#my $NzbDir = $NzbFile;
		#$NzbDir =~ s!(.+)/[^/]+.nzb!$1!; # get parent nzb dir
		my $while_file = 0;
		open (RNZB, "<$NzbDir/kbf/$nzb") or warn("Couldn't read $NzbDir/kbf/$nzb");
		open (WSAM, ">$NzbDir/$kbf_nzb") or warn("Couldn't write $NzbDir/$kbf_nzb");
		while (<RNZB>) { # write 5 rar nzb for sample
			if (m!^<\?xml!i){ # head
				print WSAM $_;
			}
			elsif (m!^<\!DOCTYPE!i){ # head
				print WSAM $_;
			}
			elsif (m!^<\!--!i){ # head
				print WSAM "<!-- NZB Generated by nzbgetpp.pl -->\n";
			}
			elsif (m!^</?nzb!i){ # foot
				print WSAM "$_\n";
			}
			elsif (m!^(\s+)?<file.+\.part0+[1-5]\.rar!i){ # .part01.rar - part05.rar
				my $line = $_;
				unless ($line =~ m!(cd2|\bsubs\b)!){ # b\. i.e. cd2 is questionable
					print WSAM $line;
					$while_file = 1;
				}
			}
			#elsif (m!^(\t+)?<file.+[^\d]+\.rar!i){ # .rar
			elsif (m!^(\s+)?<file.+\.rar[^\w]!i){ # .rar need to allow \d\. but not part\d\.
				my $line = $_;
				unless ($line =~ m!(cd2|\bsubs\b)! or $line =~ m!part\d+\.rar!){
					print WSAM $line;
					$while_file = 1;
				}
			}
			elsif (m!^(\s+)?<file.+\.r(0+)?[0-3][^\d]!i){ # .r00 - .r03 (= 5 w/ rar)
				my $line = $_;
				unless ($line =~ m!(cd2|\bsubs\b)!){
					print WSAM $line;
					$while_file = 1;
				}
			}
			elsif (m!^(\s+)?<file.+\.00[1-5][^\d]!i){ # .001 - .005
				my $line = $_;
				unless ($line =~ m!(cd2|\bsubs\b)!){
					print WSAM $line;
					$while_file = 1;
				}
			}
			elsif ($while_file and m!^(\s+)?</file!i){ # end of <file> block
				print WSAM "$_\n";
				$while_file = 0;
			}
			elsif ($while_file){ # while <file> block
				print WSAM $_;
			}
		}
		close (WSAM) or warn("Cannot close $NzbDir/$kbf_nzb");
		rename("$NzbDir/kbf/$nzb", "$NzbDir/hold/$nzb") or warn("Cannot rename $NzbDir/kbf/$nzb, $NzbDir/hold/$nzb");
		close (RNZB) or warn("Cannot close $NzbDir/hold/$nzb");
		printf "[INFO] Found kbf nzb in $NzbDir/kbf\n";
	}
}
