Is this work flow possible?

Running FileBot from the console, Groovy scripting, shell scripts, etc
Post Reply
ratkid132
Posts: 3
Joined: 15 Mar 2012, 02:56

Is this work flow possible?

Post by ratkid132 »

Hi guys, I've just stumbled accross filebot and before I get into the nitty gritty with Groovy scripts I wanted to make sure this is possible:

(( To be run when torrent finishes, client can notify of that ))
Check if torrent was archive
- if so unpack to Z:/Staging
-if not copy folder to Z:/Staging
Work out if video files are movie / tv (assume they will always be one of either)
- move to Z:/Movies/filmname or Z:/TV/tvshowname/series x/sXXeXX
Clearup old files from Z:/Staging
Update XBMC library

If it could work out if they are music that would be swell too, guessing that's very easy though.

So what do you think, doable?
User avatar
rednoah
The Source
Posts: 22974
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Is this work flow possible?

Post by rednoah »

Yep, all of that is possible. How to do each step is probably spread across the sample scripts, but should be mostly copy & paste from there:

* Simple example for extract&delete
http://filebot.sourceforge.net/scripts/sorteps.groovy

* Sort out Movie VS TV Show (on an per file basis)
http://filebot.sourceforge.net/forums/v ... 4&t=5#p512

* Unrar / notify xmbc
http://filebot.sourceforge.net/forums/v ... =4&t=5#p52

* Fetch artwork / write nfo files
http://filebot.sourceforge.net/forums/v ... 4&t=5#p204
http://filebot.sourceforge.net/forums/v ... 4&t=5#p205

* cleanup
http://filebot.sourceforge.net/scripts/cleaner.groovy

=> FileBot predefines a bunch of useful things on top of the standard Groovy stuff:
http://filebot.svn.sourceforge.net/view ... iew=markup
e.g. Move files/folders => File.moveTo()


Never tried music. There's nothing predefined like rename() for music, but i guess you'll already get a long way with File.isAudio() -> getMediaInfo() -> File.moveTo()


That sounds like a really good idea for an advanced example / copy-to-go script. Let me know if you need any help.
:idea: Please read the FAQ and How to Request Help.
User avatar
rednoah
The Source
Posts: 22974
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Is this work flow possible?

Post by rednoah »

Any progress with this? Mind sharing with what you came up with?
:idea: Please read the FAQ and How to Request Help.
ratkid132
Posts: 3
Joined: 15 Mar 2012, 02:56

Re: Is this work flow possible?

Post by ratkid132 »

Not had any luck, as I don't really understand how to turn String objects into File objects, here's my code atm but it fails on

Code: Select all

 dir.copyTo(staging) 
because dir is a String.

Code: Select all

/*

(( To be run when torrent finishes))
Check if torrent was archive
- if so unpack to Z:/Staging
-if not copy folder to Z:/Staging
Work out if video files are movie / tv (assume they will always be one of either)
- move to Z:/Movies/filmname or Z:/TV/tvshowname/series x/sXXeXX
Update XBMC library
Clearup old files from Z:/Staging

*/
// arg[0] eventually
def dir = "D:/Finished Downloads/House.S08E16.720p.HDTV.X264-DIMENSION"
println dir
def staging = "D:/Staging"
def tvdir = "E:/TV"
def moviedir = "D:/Films"
def episodeFormat = "{n}{'/Season '+s}/{episode}"
def movieFormat   = "{movie}/{movie}"

// XBMC
def xbmc = ['localhost']

/*
 * Delete orphaned "clutter" files like nfo, jpg, etc
 */
def isClutter(file) {
	return file.hasExtension("nfo", "txt", "jpg", "jpeg")
}

dir.copyTo(staging)

extract(folder:staging, output:staging) 
println "Copied and extracted RARs."	

// List video files, rename on per name basis/
staging.getFiles{ it.isVideo() }.each {
   println it.moveTo(new File(getMediaInfo(file:it, format:"{fn} [{resolution}].{ext}")))
}


/*
 * Move/Rename a mix of episodes and movies that are all in the same folder.
 */
def groups = staging.getFiles().groupBy{
	def tvs = detectSeriesName(it)
	def mov = detectMovie(it, false)
	println "$it.name [series: $tvs, movie: $mov]"
	
	// DECIDE EPISODE VS MOVIE (IF NOT CLEAR)
	if (tvs && mov) {
		if (it.name =~ "(?i:$tvs - .+)" || parseEpisodeNumber(it.name) || parseDate(it.name)) {
			println "Exclude Movie: $mov"
			mov = null
		} else if (detectMovie(it, true)) {
			println "Exclude Series: $tvs"
			tvs = null
		}
	}
	return [tvs:tvs, mov:mov]
}


groups.each{ group, files ->
	// EPISODE MODE
	if (group.tvs && !group.mov) {
		return rename(file:files, format:episodeFormat, db:'TheTVDB', output:tvdir)
	}
	
	// MOVIE MODE
	if (group.mov && !group.tvs) {
		return rename(file:files, format:movieFormat, db:'TheMovieDB', output:moviedir)
	}
}

xbmc.each { host ->
	telnet(host, 9090) { writer, reader ->
		writer.println('{"jsonrpc": "2.0", "method": "VideoLibrary.ScanForContent", "id": 1}')
	}
}



// delete clutter files in orphaned media folders
staging.getFiles{ isClutter(it) && !it.staging.hasFile{ it.isVideo() }}.each {
	println "Delete file $it: " + it.delete()
}

// delete empty folders but exclude roots
/*staging.getFolders{ it.getFiles().isEmpty() && !staging.contains(it) }.each {
	println "Delete dir $it: " + it.deleteDir()
}*/
User avatar
rednoah
The Source
Posts: 22974
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Is this work flow possible?

Post by rednoah »

Alright, I try to convert String/File automatically in all of my functions but String.copyTo is not defined obviously.

This is how you convert String to File in Groovy:

Code: Select all

def dir = "D:/Finished Downloads/House.S08E16.720p.HDTV.X264-DIMENSION" as File
:idea: Please read the FAQ and How to Request Help.
User avatar
rednoah
The Source
Posts: 22974
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Is this work flow possible?

Post by rednoah »

Why do you do this? Don't you rename your files later anyway via rename()?

Code: Select all

// List video files, rename on per name basis/
staging.getFiles{ it.isVideo() }.each {
   println it.moveTo(new File(getMediaInfo(file:it, format:"{fn} [{resolution}].{ext}")))
}
:idea: Please read the FAQ and How to Request Help.
ratkid132
Posts: 3
Joined: 15 Mar 2012, 02:56

Re: Is this work flow possible?

Post by ratkid132 »

For reseeding, I don't ever want to touch stuff in Finished Downloads, so I copy *everything* that finishes to staging, and then deal with it from their.
User avatar
rednoah
The Source
Posts: 22974
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Is this work flow possible?

Post by rednoah »

Yep, that's what copyTo() does.

This code just adds video resolution to each filename. Basically renames all video files in place. But then you move/rename everything later anyway. So this part of the script is useless.

Code: Select all

staging.getFiles{ it.isVideo() }.each {
   println it.moveTo(new File(getMediaInfo(file:it, format:"{fn} [{resolution}].{ext}")))
}
:idea: Please read the FAQ and How to Request Help.
User avatar
rednoah
The Source
Posts: 22974
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Is this work flow possible?

Post by rednoah »

The new utorrent-postprocess script is doing something very similar so you can use that as template:
http://filebot.sourceforge.net/forums/v ... 4&t=5#p802
:idea: Please read the FAQ and How to Request Help.
part timer
Posts: 181
Joined: 09 May 2012, 23:35

Re: Is this work flow possible?

Post by part timer »

So I still think a utorrent script like this is awesome, but I'm wondering if you could add something to it?

You could comment it out so only the people that want to use it could enable it if you want, but I think it would help with the decision making.
The utorrent label gets passed to the script but never used. I think most people are like me and use that label to sort things themselves from before they ever found this program, so it could come in handy. At the top of the script you could customize it like you have in some of your other scripts where you say which folders are for movies and tv.

In my case and I'm assuming lots of other people it would be:
If label starts with "movie" then file is movie
if label starts with "tv" then file is tv show
you could put anime and docu as they come in if you want.

I would love it, but I already know it would work a lot better if you wrote it than if I did it.
User avatar
rednoah
The Source
Posts: 22974
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Is this work flow possible?

Post by rednoah »

Yep, that's why I'm passing that one in already as well even though it's not used.

Really depends on how everybody tags their files. Adding some extra logic isn't hard and very body gets what they want. If there is some sort of consensus on standard tags i can add that to the online script.

You can always throw in another code path before it starts differentiating and grouping stuff:

Code: Select all

if (ut_label =~ /movie/) {
	rename(file:input, format:'Movies/{n} ({y})/{n} ({y}){" CD$pi"}', 'TheMovieDB')
	return
}
or if you want it to continue it's normal flow and fetch artwork and stuff you can just

Code: Select all

def groups = [:]
if (ut_label =~ /movie/) {
	groups << [[tvs:null, mov:detectMovie(f, false)], input]
} else { 
	groups = input.groupBy{ f ->
...
:idea: Please read the FAQ and How to Request Help.
lordCONAN
Posts: 11
Joined: 23 Sep 2012, 07:15

Re: Is this work flow possible?

Post by lordCONAN »

Bit of a thread revival

I've been working on modifying the utorrent-postprocess script to suit my needs but have come upon a block.

Like the OP, I'm trying to extract archives to a scratch dir, or if they are not archives then copy to the scratch dir.

I have managed to modify the original script to extract to a folder based on the ut_label arg, I can also test if something is an archive or not, I just have no idea how to use the copyto function to copy non-archived files to my scratch dir.

Just looking for one line of code that will copy the input files to a scratch dir.

Any help would be appreciated.
User avatar
rednoah
The Source
Posts: 22974
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Is this work flow possible?

Post by rednoah »

You can use

Code: Select all

File.copyTo(dir)
e.g. in the utorrent script you have a List of Files so you could do something like this:

Code: Select all

input.findAll{ it.isVideo() }*.copyTo('E:/scratchdir')
:idea: Please read the FAQ and How to Request Help.
lordCONAN
Posts: 11
Joined: 23 Sep 2012, 07:15

Re: Is this work flow possible?

Post by lordCONAN »

Worked flawlessly! Cheers!
lordCONAN
Posts: 11
Joined: 23 Sep 2012, 07:15

Re: Is this work flow possible?

Post by lordCONAN »

I should say almost flawlessly.

The problem isn't with the file copying, or even the script itself, I've got that all good.

The problem is the fact that if I use utorrent to start filebot with cml options, the cmd.exe window pops up in the foreground, right in front of xbmc.

I thought maybe I could get around this by using

Code: Select all

cmd.exe /c start /min filebot -script d:/Scripts/utorrent-postprocess.groovy --output d:/test/ --action move --conflict override -non-strict --def subtitles=n artwork=n xbmc=localhost "ut_dir=%D" "ut_file=%F" "ut_kind=%K" "ut_title=%N" "ut_label=%L" "ut_state=%S"
to start the shell minimized, and that does indeed work, but after completion the window is left open at the command prompt. I can't work out how to either auto-exit, or avoid using start and having the shell start minimized.
lordCONAN
Posts: 11
Joined: 23 Sep 2012, 07:15

Re: Is this work flow possible?

Post by lordCONAN »

Never mind!

was able to solve the problem by adding

Code: Select all

^& exit
at the end of the command in utorrent. Hope this helps anyone that has a similar problem.
User avatar
rednoah
The Source
Posts: 22974
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Is this work flow possible?

Post by rednoah »

Hey! That sounds like an issue a lot of people have been trying to solve, but nobody ever got back to me on that!

So how does that work? It'll still open a cmdline window, so it's not hidden, but thanks to /min it'll at least can't steal the focus of your running application.

Can you copy the full cmdline from your utorrent for me so i can add it to the utorrent script page?
:idea: Please read the FAQ and How to Request Help.
lordCONAN
Posts: 11
Joined: 23 Sep 2012, 07:15

Re: Is this work flow possible?

Post by lordCONAN »

No worries.

The full cmdline I'm using now is

Code: Select all

cmd.exe /c start /min filebot -script d:/Scripts/utorrent-postprocess.groovy --output f:/ --action move --conflict override -non-strict --def subtitles=n artwork=n xbmc=localhost "ut_dir=%D" "ut_file=%F" "ut_kind=%K" "ut_title=%N" "ut_label=%L" "ut_state=%S" ^& exit
With this the shell will pop-up in the foreground for a fraction of a second before being minimized (no idea how to prevent that). After filebot has finished running it will autmoatically exit the cmd window. For me it doesn't steal focus from xbmc, or if it does it's only for a fraction of a second, but after minimizing, the video is still running fullscreen.
Post Reply