Help with utorrent AMC

Running FileBot from the console, Groovy scripting, shell scripts, etc
Post Reply
mjdavila
Posts: 7
Joined: 13 Feb 2013, 06:27

Help with utorrent AMC

Post by mjdavila »

Hi there...

I've spent all evening trying to get this working... please help.

I followed the AMC guide - viewtopic.php?f=4&t=215

I played with custom paths and it drove me nuts so i just modified the script - just changed it to TV instead of TV Shows and also removed a space in Season01 and changed TV file name from ' - ' to just '.' in between.

I don't think that's the problem...

Here's my command:

Code: Select all

filebot -script "c:/Program Files/FileBot/md.groovy" --output "J:/" --action hardlink --conflict override -non-strict --def music=n artwork=n clean=y xbmc=192.168.5.4 "ut_dir=%D" "ut_file=%F" "ut_kind=%K" "ut_title=%N" "ut_label=%L" "ut_state=%S" >> J:/log.txt 2>&1

Code: Select all

[2013-02-13 01:15:29]  Executing: filebot -script "c:/Program Files/FileBot/md.groovy" --output "J:/" --action hardlink --conflict override -non-strict --def music=n artwork=n clean=y xbmc=192.168.5.4 "ut_dir=J:\Tv\Unsorted\" "ut_file=Family.Guy.S11E12.HDTV.x264-LOL.mp4" "ut_kind=single" "ut_title=Family.Guy.S11E12.HDTV.x264-LOL.mp4" "ut_label=TvTorrents" "ut_state=5" >> J:/log.txt 2>&1

Here's my output log:

Code: Select all

Parameter: music = n
Parameter: artwork = n
Parameter: clean = y
Parameter: xbmc = 192.168.5.4
Parameter: ut_dir = J:\Tv\Unsorted" ut_file=Family.Guy.S11E12.HDTV.x264-LOL.mp4 ut_kind=single ut_title=Family.Guy.S11E12.HDTV.x264-LOL.mp4 ut_label= ut_state=5
MissingPropertyException: No such property: ut_kind for class: Script3
groovy.lang.MissingPropertyException: No such property: ut_kind for class: Script3
	at Script3.run(Script3.groovy:70)
	at net.sourceforge.filebot.cli.ScriptShell.evaluate(Unknown Source)
	at net.sourceforge.filebot.cli.ScriptShell.runScript(Unknown Source)
	at net.sourceforge.filebot.cli.ArgumentProcessor.process(Unknown Source)
	at net.sourceforge.filebot.Main.main(Unknown Source)
Failure (°_°)
and here's my script:

Code: Select all

// filebot -script "fn:utorrent-postprocess" --output "X:/media" --action copy --conflict override --def subtitles=true artwork=true xbmc=localhost plex=10.0.0.1 gmail=username:password "ut_dir=%D" "ut_file=%F" "ut_kind=%K" "ut_title=%N" "ut_label=%L" "ut_state=%S"
def input = []
def failOnError = _args.conflict == 'fail'

// print input parameters
_args.bindings?.each{ _log.finest("Parameter: $it.key = $it.value") }
args.each{ _log.finest("Argument: $it") }
args.findAll{ !it.exists() }.each{ throw new Exception("File not found: $it") }

// check user-defined pre-condition
if (tryQuietly{ ut_state != ut_state_allow }) {
	throw new Exception("Invalid state: ut_state = $ut_state (expected $ut_state_allow)")
}

// enable/disable features as specified via --def parameters
def music     = tryQuietly{ music.toBoolean() }
def subtitles = tryQuietly{ subtitles.toBoolean() ? ['en'] : subtitles.split(/[ ,|]+/).findAll{ it.length() >= 2 } }
def artwork   = tryQuietly{ artwork.toBoolean() }
def backdrops = tryQuietly{ backdrops.toBoolean() }
def clean     = tryQuietly{ clean.toBoolean() }

// array of xbmc/plex hosts
def xbmc = tryQuietly{ xbmc.split(/[ ,|]+/) }
def plex = tryQuietly{ plex.split(/[ ,|]+/) }

// myepisodes updates and email notifications
def myepisodes = tryQuietly { myepisodes.split(':', 2) }
def gmail = tryQuietly{ gmail.split(':', 2) }
def pushover = tryQuietly{ pushover }


// series/anime/movie format expressions
def format = [
	tvs:   tryQuietly{ seriesFormat } ?: '''TV/{n}/{episode.special ? "Special" : "Season"+s}/{n}.{episode.special ? "S00E"+special.pad(2) : s00e00}.{t}{".$lang"}''',
	anime: tryQuietly{ animeFormat  } ?: '''Anime/{n}/{n} - {sxe} - {t}''',
	mov:   tryQuietly{ movieFormat  } ?: '''Movies/{n} ({y})/{n} ({y}){" CD$pi"}{".$lang"}''',
	music: tryQuietly{ musicFormat  } ?: '''Music/{n}/{album}/{n} - {t}'''
]


// force movie/series/anime logic
def forceMovie(f) {
	tryQuietly{ ut_label } =~ /^(?i:Movie|Couch.Potato)/
}

def forceSeries(f) {
	parseEpisodeNumber(f) || parseDate(f) || tryQuietly{ ut_label } =~ /^(?i:TV|Kids.Shows|TvTorrents)/
}

def forceAnime(f) {
	tryQuietly{ ut_label } =~ /^(?i:Anime)/ || (f.isVideo() && (f.name =~ "[\\(\\[]\\p{XDigit}{8}[\\]\\)]" || getMediaInfo(file:f, format:'''{media.AudioLanguageList} {media.TextCodecList}''').tokenize().containsAll(['Japanese', 'ASS'])))
}

def forceIgnore(f) {
	tryQuietly{ ut_label } =~ /^(?i:ebook|other|ignore)/ || f.path =~ tryQuietly{ ignore }
}


// specify how to resolve input folders, e.g. grab files from all folders except disk folders
def resolveInput(f) {
	if (f.isDirectory() && !f.isDisk())
		return f.listFiles().toList().findResults{ resolveInput(it) }
	else
		return f
}

// collect input fileset as specified by the given --def parameters
if (args.empty) {
	// assume we're called with utorrent parameters (account for older and newer versions of uTorrents)
	if (ut_kind == 'single' || (ut_kind != 'multi' && ut_dir && ut_file)) {
		input += new File(ut_dir, ut_file) // single-file torrent
	} else {
		input += resolveInput(ut_dir as File) // multi-file torrent
	}
} else {
	// assume we're called normally with arguments
	input += args.findResults{ resolveInput(it) }
}


// flatten nested file structure
input = input.flatten()

// extract archives (zip, rar, etc) that contain at least one video file
def extractedFiles = extract(file: input.findAll{ it.isArchive() }, output: null, conflict: 'override', filter: { it.isVideo() || (music && it.isAudio()) }, forceExtractAll: true)
input += extractedFiles

// sanitize input
input = input.findAll{ it?.exists() }.collect{ it.canonicalFile }.unique()

// process only media files
input = input.findAll{ it.isVideo() || it.isSubtitle() || it.isDisk() || (music && it.isAudio()) }

// ignore clutter files
input = input.findAll{ !(it.path =~ /\b(?i:sample|trailer|extras|deleted.scenes|music.video|scrapbook|behind.the.scenes)\b/) }

// print input fileset
input.each{ f -> _log.finest("Input: $f") }

// artwork/nfo utility
include('fn:lib/htpc')

// group episodes/movies and rename according to XBMC standards
def groups = input.groupBy{ f ->
	// skip auto-detection if possible
	if (forceIgnore(f))
		return []
	if (f.isAudio() && !f.isVideo()) // PROCESS MUSIC FOLDER BY FOLDER
		return [music: f.dir.name]
	if (forceMovie(f))
		return [mov:   detectMovie(f, false)]
	if (forceSeries(f))
		return [tvs:   detectSeriesName(f) ?: detectSeriesName(f.dir.listFiles{ it.isVideo() })]
	if (forceAnime(f))
		return [anime: detectSeriesName(f) ?: detectSeriesName(f.dir.listFiles{ it.isVideo() })]
	
	
	def tvs = detectSeriesName(f)
	def mov = detectMovie(f, false)
	println "$f.name [series: $tvs, movie: $mov]"
	
	// DECIDE EPISODE VS MOVIE (IF NOT CLEAR)
	if (tvs && mov) {
		def norm = { s -> s.lower().space(' ') }
		def dn = norm(guessMovieFolder(f)?.name ?: '')
		def fn = norm(f.nameWithoutExtension)
		def sn = norm(tvs)
		def mn = norm(mov.name)
		
		// S00E00 | 2012.07.21 | One Piece 217 | Firefly - Serenity | [Taken 1, Taken 2, Taken 3, Taken 4, ..., Taken 10]
		if (parseEpisodeNumber(fn, true) || parseDate(fn) || (fn =~ sn && parseEpisodeNumber(fn.after(sn), false)) || fn.after(sn) =~ / - .+/ || f.dir.listFiles{ it.isVideo() && norm(it.name) =~ sn && it.name =~ /\b\d{1,3}\b/}.size() >= 10) {
			println "Exclude Movie: $mov"
			mov = null
		} else if ((detectMovie(f, true) && [dn, fn].find{ it =~ /(19|20)\d{2}/ }) || [dn, fn].find{ it =~ mn && !(it.after(mn) =~ /\b\d{1,3}\b/) }) {
			println "Exclude Series: $tvs"
			tvs = null
		}
	}
	
	// CHECK CONFLICT
	if (((mov && tvs) || (!mov && !tvs)) && failOnError) {
		throw new Exception("Media detection failed")
	}
	
	return [tvs: tvs, mov: mov, anime: null]
}

// log movie/series/anime detection results
groups.each{ group, files -> _log.finest("Group: $group => ${files*.name}") }

// process each batch
groups.each{ group, files ->
	// fetch subtitles (but not for anime)
	if (subtitles && !group.anime) {
		subtitles.each{ languageCode ->
			files += getMissingSubtitles(file:files, output:'srt', encoding:'UTF-8', lang:languageCode)
		}
	}
	
	// EPISODE MODE
	if ((group.tvs || group.anime) && !group.mov) {
		// choose series / anime config
		def config = group.tvs ? [name:group.tvs,   format:format.tvs,   db:'TheTVDB', seasonFolder:true ]
		                       : [name:group.anime, format:format.anime, db:'AniDB',   seasonFolder:false]
		def dest = rename(file: files, format: config.format, db: config.db)
		if (dest && artwork) {
			dest.mapByFolder().each{ dir, fs ->
				println "Fetching artwork for $dir from TheTVDB"
				def sxe = fs.findResult{ eps -> parseEpisodeNumber(eps) }
				def options = TheTVDB.search(config.name)
				if (options.isEmpty()) {
					println "TV Series not found: $config.name"
					return
				}
				options = options.sortBySimilarity(config.name, { s -> s.name })
				fetchSeriesArtworkAndNfo(config.seasonFolder ? dir.dir : dir, dir, options[0], sxe && sxe.season > 0 ? sxe.season : 1)
			}
		}
		if (dest == null && failOnError) {
			throw new Exception("Failed to rename series: $config.name")
		}
	}
	
	// MOVIE MODE
	if (group.mov && !group.tvs && !group.anime) {
		def dest = rename(file:files, format:format.mov, db:'TheMovieDB')
		if (dest && artwork) {
			dest.mapByFolder().each{ dir, fs ->
				println "Fetching artwork for $dir from TheMovieDB"
				fetchMovieArtworkAndNfo(dir, group.mov, fs.findAll{ it.isVideo() }.sort{ it.length() }.reverse().findResult{ it }, backdrops)
			}
		}
		if (dest == null && failOnError) {
			throw new Exception("Failed to rename movie: $group.mov")
		}
	}
	
	// MUSIC MODE
	if (group.music) {
		def dest = rename(file:files, format:format.music, db:'AcoustID')
		if (dest == null && failOnError) {
			throw new Exception("Failed to rename music: $group.music")
		}
	}
}

// skip notifications if nothing was renamed anyway
if (getRenameLog().isEmpty()) {
	return
}

// make xbmc or plex scan for new content
xbmc?.each{
	println "Notify XBMC: $it"
	invokeScanVideoLibrary(it)
}

plex?.each{
	println "Notify Plex: $it"
	refreshPlexLibrary(it)
}

// mark episodes as 'acquired'
if (myepisodes) {
	println 'Update MyEpisodes'
	include('fn:update-mes', [login:myepisodes.join(':'), addshows:true], getRenameLog().values())
}

if (pushover) {
	// include webservice utility
	include('fn:lib/ws')
	
	println('Sending Pushover notification')
	Pushover(pushover).send("Finished processing ${tryQuietly { ut_title } ?: input*.dir.name.unique()} (${getRenameLog().size()} files).")
}

// send status email
if (gmail) {
	// ant/mail utility
	include('fn:lib/ant')
	
	// send html mail
	def renameLog = getRenameLog()
	def emailTitle = tryQuietly { ut_title } ?: input*.dir.name.unique()
	
	sendGmail(
		subject: "[FileBot] ${emailTitle}",
		message: XML {
			html {
				body {
					p("FileBot finished processing ${emailTitle} (${renameLog.size()} files).");
					hr(); table {
						th("Parameter"); th("Value")
						_args.bindings.findAll{ param -> param.key =~ /^ut_/ }.each{ param ->
							tr { [param.key, param.value].each{ td(it)} }
						}
					}
					hr(); table {
						th("Original Name"); th("New Name"); th("New Location")
						renameLog.each{ from, to ->
							tr { [from.name, to.name, to.parent].each{ cell -> td{ nobr{ code(cell) } } } }
						}
					}
					hr(); small("// Generated by ${net.sourceforge.filebot.Settings.applicationIdentifier} on ${new Date().dateString} at ${new Date().timeString}")
				}
			}
		},
		messagemimetype: 'text/html',
		to: tryQuietly{ mailto } ?: gmail[0] + '@gmail.com', // mail to self by default
		user: gmail[0], password: gmail[1]
	)
}

// clean empty folders, clutter files, etc after move
if (clean) {
	if (['COPY', 'HARDLINK'].find{ it.equalsIgnoreCase(_args.action) } && extractedFiles?.size() > 0) {
		println 'Clean temporary extracted files'
		// delete extracted files
		extractedFiles.each{
			if(it.isFile()) {
				println "Delete $it"
				it.delete()
			}
		}
		// delete remaining empty folders
		extractedFiles*.dir.unique().findAll{ it.listFiles().length == 0 }.each{
			if(it.isDirectory()) {
				println "Delete $it"
				it.delete()
			}
		}
	}
	
	// deleting remaining files only makes sense after moving files
	if ('MOVE'.equalsIgnoreCase(_args.action)) {
		println 'Clean clutter files and empty folders'
		include('fn:cleaner', [:], !args.empty ? args : ut_kind == 'multi' && ut_dir ? [ut_dir as File] : [])
	}
}
Pls help!!! Thanks!
User avatar
rednoah
The Source
Posts: 22976
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Help with utorrent AMC

Post by rednoah »

Look, obviously something got messed up here:

Code: Select all

Parameter: ut_dir = J:\Tv\Unsorted" ut_file=Family.Guy.S11E12.HDTV.x264-LOL.mp4 ut_kind=single ut_title=Family.Guy.S11E12.HDTV.x264-LOL.mp4 ut_label= ut_state=5
Look, you're escaping the last " so it gets passed in as literal along with the rest AS SINGLE ARGUMENT:

Code: Select all

"ut_dir=J:\Tv\Unsorted\" ... more characters"
Should look like this:

Code: Select all

"ut_dir=D:\Media\Aquarion EVOL"
Note that there is no \" at the end messing with the cmd tokenizing arguments.


Not sure why there'd be a \ at the end of the path. Make sure you're using the latest utorrent. Maybe utorrent is just passing in what you set up in the settings. So make sure there's no \ at the end of the downloads folder in settings.
:idea: Please read the FAQ and How to Request Help.
mjdavila
Posts: 7
Joined: 13 Feb 2013, 06:27

Re: Help with utorrent AMC

Post by mjdavila »

Thanks red! Got that sorted out by removing the final \ when putting in the download directory...

I got that sorted out but now I have a second error:

Code: Select all

Parameter: music = n
Parameter: artwork = n
Parameter: clean = y
Parameter: xbmc = 192.168.5.4
Parameter: ut_dir = J:\Tv\Unsorted
Parameter: ut_file = Family.Guy.S11E12.HDTV.x264-LOL.mp4
Parameter: ut_kind = single
Parameter: ut_title = Family.Guy.S11E12.HDTV.x264-LOL.mp4
Parameter: ut_label = 
Parameter: ut_state = 5
Input: J:\Tv\Unsorted\Family.Guy.S11E12.HDTV.x264-LOL.mp4
Group: [tvs:Family Guy] => [Family.Guy.S11E12.HDTV.x264-LOL.mp4]
Rename episodes using [TheTVDB]
Auto-detected query: [Family Guy]
Fetching episode data for [Family Guy]
Fetching episode data for [Family Guns]
Failed to write xattr: java.io.File.toPath()Ljava/nio/file/Path;
[HARDLINK] Rename [J:\Tv\Unsorted\Family.Guy.S11E12.HDTV.x264-LOL.mp4] to [J:\TV\Family Guy\Season11\Family Guy.S11E12.Valentine's Day in Quahog.mp4]
Exception: Unsupported Operation: createLink
Done ?(?????)?
Help?

I'm using Win7 64bit, filebot 64bit , java 7.13 64bit with PATH added only to 64bit java directory.
User avatar
rednoah
The Source
Posts: 22976
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Help with utorrent AMC

Post by rednoah »

I'm 100% sure that this ran on Java 6. ;)

Check your paths and what not. Best to just uninstall anything but 64-bit java 7.
:idea: Please read the FAQ and How to Request Help.
mjdavila
Posts: 7
Joined: 13 Feb 2013, 06:27

Re: Help with utorrent AMC

Post by mjdavila »

Thanks red - i'll give it a shot..

I believe 32bit is needed for 32bit browsers like Chrome etc..

Is there a way to force the script/filebot to use the 64bit only? Or is the best way to just uninstall 64bit filebot and keep everything 32bit?
mjdavila
Posts: 7
Joined: 13 Feb 2013, 06:27

Re: Help with utorrent AMC

Post by mjdavila »

I downgraded to 32bit java and filebot...

Now from utorrent it does nothing - doesn't even create the log..

Here's what utorrent is supposedly running (but does nothing):

Code: Select all

[2013-02-13 17:00:43]  Executing: filebot -script "c:/Program Files (x86)/FileBot/md.groovy" --output "J:/" --action copy --conflict override -non-strict --def music=n artwork=n clean=y xbmc=192.168.5.4 "ut_dir=J:\Tv\Unsorted" "ut_file=Family.Guy.S11E12.HDTV.x264-LOL.mp4" "ut_kind=single" "ut_title=Family.Guy.S11E12.HDTV.x264-LOL.mp4" "ut_label=" "ut_state=5" >> j:/log2.txt 2>&1
I copied and pasted that exact command above into cmd prompt - it somewhat worked but a few errors:

Code: Select all

Parameter: music = n
Parameter: artwork = n
Parameter: clean = y
Parameter: xbmc = 192.168.5.4
Parameter: ut_dir = J:\Tv\Unsorted
Parameter: ut_file = Family.Guy.S11E12.HDTV.x264-LOL.mp4
Parameter: ut_kind = single
Parameter: ut_title = Family.Guy.S11E12.HDTV.x264-LOL.mp4
Parameter: ut_label = 
Parameter: ut_state = 5
Input: J:\Tv\Unsorted\Family.Guy.S11E12.HDTV.x264-LOL.mp4
Group: [tvs:Family Guy] => [Family.Guy.S11E12.HDTV.x264-LOL.mp4]
Rename episodes using [TheTVDB]
Auto-detected query: [Family Guy]
Fetching episode data for [Family Guy]
Fetching episode data for [Family Guns]
Feb 13, 2013 5:02:14 PM net.sourceforge.filebot.media.MediaDetection storeMetaInfo
WARNING: Failed to set xattr: java.nio.file.AccessDeniedException: J:\Tv\Unsorted\Family.Guy.S11E12.HDTV.x264-LOL.mp4:metadata
[COPY] Rename [J:\Tv\Unsorted\Family.Guy.S11E12.HDTV.x264-LOL.mp4] to [J:\TV\Family Guy\Season11\Family Guy.S11E12.Valentine's Day in Quahog.mp4]
Processed 1 files
Notify XBMC: 192.168.5.4
ConnectException: Connection timed out: connect
Done ?(?????)?
Exact same when i do action hardlink.

But how do I get it working in utorrent - the cmd prompt doesn't even flash?

Also - I noticed that both files have a little lock icon on it like: Image
It only adds me, admins and system with access - not other users? Is that normal?
User avatar
rednoah
The Source
Posts: 22976
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Help with utorrent AMC

Post by rednoah »

1.
I guess your PATH is still not set up correctly. Run via absolute path C:/Program Files/filebot.cmd ... and edit filebot.cmd to and make it use the absolute path to your java.exe

2.
I get that little lock as well whenever i create hardlinks on Win 7.
:idea: Please read the FAQ and How to Request Help.
mjdavila
Posts: 7
Joined: 13 Feb 2013, 06:27

Re: Help with utorrent AMC

Post by mjdavila »

Thanks! Seems to be better!

I still get this error in the log but it still seems to work:

WARNING: Failed to set xattr: java.nio.file.AccessDeniedException:

My last bug:

Can you help me get my naming convention the way the rest of my library is

Either by editing the script or maybe by using seriesFormat?

Here's how I'm trying to get: TV/show/season01/show.S01e01.title.ext

I edited the script to remove the space in season and number and replaced - with . But I just noticed that seasons less then 10 will be Season1 instead of season01..

I know it's small but it's how my entire library is named and I would like to keep it consistant.

Thank you sooo much!
User avatar
rednoah
The Source
Posts: 22976
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Help with utorrent AMC

Post by rednoah »

That warning you can ignore. Just optional features.

As for the format there is plenty of examples. Might be easier to edit the script since you don't have to worry about encoding cmdline arguments correctly.
:idea: Please read the FAQ and How to Request Help.
Post Reply