Page 1 of 1

file placement by drive size

Posted: 14 Sep 2014, 22:25
by Amishman
I was looking through the forum and found a script by bonelifer.

http://www.filebot.net/forums/viewtopic ... =608#p4889.

I would like just the portion that
which drive you defined has more space and puts new series on the drive with the largest available space. If another drive has more space but the series already exist then it goes to the current drive.
I would like to use it for movies and TV shows.

I tried to remove the renaming .csv and the TV portion so I could use my own naming scheme but I keep receiving errors. So I tried leaving in the renaming.csv to make less changes but it didn't help.

This is my script:

Code: Select all

filebot -script fn:amc  --output "H:/" --log-file amc.log --action test --conflict auto -non-strict "F:/test" --def "movieFormat={["H:", "G:"].collect{ drive -> def a=n; new File('G:/names.csv').splitEachLine(';'){if (n==it[0]) a=it[1]}; return new File(drive+"/Movies/", a)}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{def a; new File('G:/names.csv').splitEachLine(';'){ if (n == it[0]) a = it[1]}; a ?: n.upperInitial().replaceTrailingBrackets()}/{collection}/{n.replaceFirst(/^(?i)(The|A|An)\\s(.+)/, /$2, $1/)} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':\"\"}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, \" \") + ')'} ({y}) {genres[0]} {\"[$vf]\"}/{n} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':\"\"}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, \" \") + ')'} ({y})"
Any help figuring this out is greatly appreciated.

Re: file placement by drive size

Posted: 15 Sep 2014, 04:05
by rednoah

Re: file placement by drive size

Posted: 15 Sep 2014, 23:36
by Amishman
Ok, I have the TV portion working.

Code: Select all

filebot -script fn:amc  --output "Z:/" --log-file amc.log --action move --conflict auto -non-strict "F:/test" --def "seriesFormat={[\"E:\", \"F:\", \"G:\", \"H:\"].collect{ drive -> def a=n; new File('C:/Scripts/names.csv').splitEachLine(';'){if (n==it[0]) a=it[1]}; return new File(drive+\"/TV/\", a)}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{episode.special ? \"Season \"+s.pad(2) : \"Season \"+s.pad(1)}/{s00e00} {t}"
Now, I just need to make it work for movies. I thought I could leave most of it the same but that doesn't work.

Here is my script:

Code: Select all

filebot -script fn:amc  --output "Z:/" --log-file amc.log --action test --conflict auto -non-strict "F:/test" --def "movieFormat={[\"E:\", \"F:\", \"G:\", \"H:\"].collect{ drive -> def a=n; new File('C:/Scripts/names.csv').splitEachLine(';'){if (n==it[0]) a=it[1]}; return new File(drive+\"/Movies/\", a)}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{n}"
This is the result:
Parameter: movieFormat = {["E:", "F:", "G:", "H:"].collect{ drive -> def a=n; new File('C:/Scripts/names.csv').splitEachLine(';'){if (n==it[0]) a=it[1]}; return new File(drive+"/Movies/", a)}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{n}
Argument: F:\test
Input: F:\test\9 (2009) Animation [1080p]\9 (2009).mp4
Input: F:\test\9 (2009) Animation [1080p]\9 (2009).srt
9 (2009).mp4 [series: null, movie: 9 (2009)]
9 (2009).srt [series: null, movie: null]
Unable to differentiate: [9 (2009).srt] => [null] VS [null]
Group: [tvs:null, mov:9 2009, anime:null] => [9 (2009).mp4]
Group: [tvs:null, mov:null, anime:null] => [9 (2009).srt]
Rename movies using [TheMovieDB]
Auto-detect movie from context: [F:\test\9 (2009) Animation [1080p]\9 (2009).mp4]
net.filebot.cli.CmdlineException: Unable to identify or process any files
Finished without processing any files
Failure (°_°)
Why is it not able to identify or process the file?

How do I take out the renaming.csv portion?

Re: file placement by drive size

Posted: 16 Sep 2014, 00:35
by rednoah
1.
Because the movie name is a single digit. Auto-detection requires at least 3 characters.

2.
You just take it out? CTRL+X

Code: Select all

new File('C:/Scripts/names.csv').splitEachLine(';'){if (n==it[0]) a=it[1]};

Re: file placement by drive size

Posted: 16 Sep 2014, 01:07
by Amishman
Thank you rednoah. I wasn't sure where it ended. I tried using a different movie to test with. It process the movie but it ignores the the drive size and if the file already exits. It places the movie in the output drive.

Here is my script:

Code: Select all

filebot -script fn:amc  --output "E:/" --log-file amc.log --action test --conflict auto -non-strict "F:/test" --def "moviesFormat={[\"E:\", \"F:\", \"H:\"].collect{ drive -> def a=n; return new File(drive+\"/Movies/\", a)}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{n}"
Here is the result:
Parameter: moviesFormat = {["E:", "F:", "H:"].collect{ drive -> def a=n; return new File(drive+"/Movies/", a)}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{n}
Argument: F:\test
Input: F:\test\Bulletproof Monk (2003) Action [1080p]\Bulletproof Monk (2003).mp4
Input: F:\test\Bulletproof Monk (2003) Action [1080p]\Bulletproof Monk (2003).srt
Bulletproof Monk (2003).mp4 [series: Monk, movie: Bulletproof Monk (2003)]
Exclude Series: Monk
Bulletproof Monk (2003).srt [series: Monk, movie: Bulletproof Monk (2003)]
Exclude Series: Monk
Group: [tvs:null, mov:bulletproof monk 2003, anime:null] => [Bulletproof Monk (2003).mp4, Bulletproof Monk (2003).srt]
Rename movies using [TheMovieDB]
Auto-detect movie from context: [F:\test\Bulletproof Monk (2003) Action [1080p]\Bulletproof Monk (2003).mp4]
[TEST] Rename [F:\test\Bulletproof Monk (2003) Action [1080p]\Bulletproof Monk (2003).mp4] to [E:\Movies\Bulletproof Monk (2003)\Bulletproof Monk (2003).mp4]
[TEST] Rename [F:\test\Bulletproof Monk (2003) Action [1080p]\Bulletproof Monk (2003).srt] to [E:\Movies\Bulletproof Monk (2003)\Bulletproof Monk (2003).eng.srt]
Processed 2 files
Done ヾ(@⌒ー⌒@)ノ
The Movie is on the F drive and drive H has the most room available on it.

Re: file placement by drive size

Posted: 16 Sep 2014, 02:14
by rednoah
--def movieFormat

Re: file placement by drive size

Posted: 16 Sep 2014, 02:56
by Amishman
Thanks rednoah! I should have caught that.

One last thing.

When I ran the script this time it placed the movie on the H drive. The H drive does have the most room on it but it didn't look to see if the movie was on a different drive like it did for the TV shows.

The movie is located on the F drive. It should have said it couldn't do it because the file already existed.

Re: file placement by drive size

Posted: 16 Sep 2014, 10:42
by Amishman
After adding my naming scheme, I found it is checking to see if the movie already exists.

This is my script:

Code: Select all

filebot -script fn:amc  --output "E:/" --log-file amc.log --action test --conflict auto -non-strict "F:/test" --def "movieFormat={[\"E:\", \"F:\", \"H:\"].collect{ drive -> def a=n; return new File(drive+\"/Movies/\", a)}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{collection}/{n.replaceFirst(/^(?i)(The|A|An)\s(.+)/, /$2, $1/)} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':\"\"}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, \" \") + ')'} ({y}) {\"[$vf]\"}/{n} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':\"\"}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, \" \") + ')'} ({y})"
This is the result:
Parameter: movieFormat = {["E:", "F:", "H:"].collect{ drive -> def a=n; return new File(drive+"/Movies/", a)}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{collection}/{n.replaceFirst(/^(?i)(The|A|An)\s(.+)/, /$2, $1/)} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':""}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, " ") + ')'} ({y}) {"[$vf]"}/{n} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':""}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, " ") + ')'} ({y})
Argument: F:\test
Input: F:\test\Live Free or Die Hard (2007) Action [1080p]\Live Free or Die Hard (2007).mp4
Live Free or Die Hard (2007).mp4 [series: Live Free or Die Hard, movie: Live Free or Die Hard (2007)]
Exclude Series: Live Free or Die Hard
Group: [tvs:null, mov:live free or die hard 2007, anime:null] => [Live Free or Die Hard (2007).mp4]
Rename movies using [TheMovieDB]
Auto-detect movie from context: [F:\test\Live Free or Die Hard (2007) Action [1080p]\Live Free or Die Hard (2007).mp4]
[TEST] Rename [F:\test\Live Free or Die Hard (2007) Action [1080p]\Live Free or Die Hard (2007).mp4] to [H:\Movies\Live Free or Die Hard\Die Hard Collection\Live Free or Die Hard (2007) [1080p]\Live Free or Die Hard (2007).mp4]
Processed 1 files
Done ヾ(@⌒ー⌒@)ノ
It is applying the name of the movie before my naming scheme. How do I remove the "Live Free or Die Hard" after Movies so the path looks like "H:\Movies\Die Hard Collection\Live Free or Die Hard (2007) [1080p]\Live Free or Die Hard (2007).mp4"?

Re: file placement by drive size

Posted: 18 Sep 2014, 00:39
by Amishman
The script outputs the name of the movie. For some reason, everything I try doesn't change it. It just adds on to the movie name. I have tried changing things earlier in the script but then it skips the check to see which drive has more room and drops it on the output drive.

Everything I am trying is not working. It seems like there has to be a way for the name to be easily passed into my naming scheme but I just don't have any idea how to do it or where to start. If anyone has an idea, a web page, or a hint as to where to start, I would greatly appreciate it.

Re: file placement by drive size

Posted: 18 Sep 2014, 05:08
by rednoah
You probably need to focus on this expression:

Code: Select all

["E:", "F:", "H:"].collect{ drive -> def a=n; return new File(drive+"/Movies/", a)}
You need to somewhat understand what it does though, otherwise making changes will be difficult. ;)

Re: file placement by drive size

Posted: 18 Sep 2014, 10:00
by Amishman
Thanks rednoah. I am almost there. I have the naming scheme working properly and it places the movie on the drive with the most amount of space.

It just does not check to see if the folder already exits.

Here is the expression:

Code: Select all

{ drive -> def a=n; return new File(drive+\"/Movies/\")}


I am guessing it's because I removed the , a but I'm not sure. I don't exactly understand how the def a=n works.

Does the , a pass along the name to be sorted and since there is no information in a, it automatically chooses b?

Re: file placement by drive size

Posted: 18 Sep 2014, 10:13
by rednoah
a=n is an assignment, the most basic thing in programming
?: is not what you think it is
{collection} inside an expression is also not what you think it is
n is obviously the movie name, def a=n means new variable a is the same as n, b no idea how you came up with that one, there is no b

I guess it'll actually save me time to just solve this for you:

Code: Select all

{['E:', 'F:', 'H:'].collect{ new File(it+'/Movies/'+any{collection+'/'}{''}) }}

Re: file placement by drive size

Posted: 18 Sep 2014, 10:27
by Amishman
Thanks rednoah.

When I try that in my script, I receive an error.

Here is my script:

Code: Select all

filebot -script fn:amc  --output "E:/" --log-file amc.log --action test --conflict auto -non-strict "F:/test" --def "movieFormat={['E:', 'F:', 'H:'].collect{ new File(it+'/Movies/'+any{collection+'/'}{''}) }}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{n.replaceFirst(/^(?i)(The|A|An)\s(.+)/, /$2, $1/)} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':\"\"}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, \" \") + ')'} ({y}) {\"[$vf]\"}/{n} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':\"\"}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, \" \") + ')'} ({y})"
Here is the error:
Parameter: movieFormat = {['E:', 'F:', 'H:'].collect{ new File(it+'/Movies/'+any{collection+'/'}{''}) }}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{n.replaceFirst(/^(?i)(The|A|An)\s(.+)/, /$2, $1/)} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':""}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, " ") + ')'} ({y}) {"[$vf]"}/{n} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':""}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, " ") + ')'} ({y})
Argument: F:\test
Input: F:\test\Live Free or Die Hard (2007) Action [1080p]\Live Free or Die Hard (2007).mp4
Input: F:\test\The Day After (1983) Disaster [1080p]\The Day After (1983).mp4
Live Free or Die Hard (2007).mp4 [series: Live Free or Die Hard, movie: Live Free or Die Hard (2007)]
Exclude Series: Live Free or Die Hard
The Day After (1983).mp4 [series: After, movie: The Day After (1983)]
Exclude Series: After
Group: [tvs:null, mov:live free or die hard 2007, anime:null] => [Live Free or Die Hard (2007).mp4]
Group: [tvs:null, mov:the day after 1983, anime:null] => [The Day After (1983).mp4]
javax.script.ScriptException: SyntaxError: unexpected token: a
javax.script.ScriptException: SyntaxError: unexpected token: a
Finished without processing any files
Failure (°_°)

Re: file placement by drive size

Posted: 18 Sep 2014, 14:07
by rednoah
Your braces are wrong.

Correct:

Code: Select all

{['E:', 'F:', 'H:'].collect{ new File(it+'/Movies/'+any{collection+'/'}{''}) }.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}

Re: file placement by drive size

Posted: 23 Sep 2014, 09:49
by Amishman
Thanks rednoah. It works great!

I thought I would share my scripts with everone.

I use uTorrent and a watch folder. The output of both scripts is same. Here is what the scripts do.
  • Places the file on the drive with the most space.
    Checks to see if the file already exists.
    Makes a "collection" folder if there is one.
    Moves "The, A" to the end.
    Keeps 3D in the name if it is there.
    Keeps "Extended, Unrated,etc..." in the name if it is there.
    Places the resolution in the folder name.
    Watch folder checks every 5 seconds to see if a file has been added.
    Extracts files
    Deletes any extra folders/files.
    Sends a pushbullet notification when completed.
    Notifies Plex.
This is the output for movies.

H:\Movies\Die Hard Collection\Live Free or Die Hard 3D (Extended) (2007) [1080p]\Live Free or Die Hard 3D (Extended) (2007).mp4

or

D:\Movies\47 Ronin (2013) [1080p]\47 Ronin (2013).mp4


This is the output for TV Shows.

G:\TV\Arrested Development\Season 3\S03E03 Forget Me Now.mkv


Here is my uTorrent script:

Code: Select all

filebot -script fn:amc  --output "E:/" --log-file amc.log --action move --conflict auto -non-strict --def "seriesFormat={[\"E:\", \"F:\", \"G:\", \"H:\"].collect{ drive -> def a=n; return new File(drive+\"/TV/\", a)}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{episode.special ? \"Season \"+s.pad(2) : \"Season \"+s.pad(1)}/{s00e00} {t}" "movieFormat={['E:', 'F:', 'H:'].collect{ new File(it+'/Movies/'+any{collection+'/'}{''}) }.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{n.replaceFirst(/^(?i)(The|A|An)\s(.+)/, /$2, $1/)} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':\"\"}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, \" \") + ')'} ({y}) {\"[$vf]\"}/{n} {fn.contains('3d') || fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':\"\"}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, \" \") + ')'} ({y})" --def deleteAfterExtract=y --def clean=y --def plex=localhost --def pushbullet=******************** "ut_label=%L" "ut_state=%S" "ut_title=%N" "ut_kind=%K" "ut_file=%F" "ut_dir=%D"
My watch folder script is placed in a batch file. I have the the batch file set to start whenever the computer is restarted.

Here is the watch folder script:

Code: Select all

def watchman = args[0].watch { changes ->
execute('''filebot -script fn:amc -non-strict --output "E:/" "G:/Watched" --log-file amc.log --action move --conflict auto --def "seriesFormat={['E:', 'F:', 'G:', 'H:'].collect{ drive -> def a=n; return new File(drive+'/TV/', a)}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{episode.special ? 'Season '+s.pad(2) : 'Season '+s.pad(1)}/{s00e00} {t}" \"movieFormat={['E:', 'F:', 'G:', 'H:'].collect{ new File(it+'/Movies/'+any{collection+'/'}{''}) }.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}/{n.replaceFirst(/^(?i)(The|A|An)\\s(.+)/, /$2, $1/)} {fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':''}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, ' ') + ')'} ({y}) {[vf]}/{n}{fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':''}{' (' + fn.matchAll(/extended|uncensored|remastered|unrated|uncut|directors.cut|special.edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[._]/, ' ') + ')'} ({y})\" \"musicFormat=Music/{n}/{\$album/}{\${pi.pad(2)}. } {t}\" --def plex=localhost --def clean=y --def deleteAfterExtract=y''')
  }

watchman.commitDelay = 5 * 1000
watchman.commitPerFolder = false

println "Waiting for events"
if (console) { console.readLine() } else { sleep(Long.MAX_VALUE) } // keep running and watch for changes

Re: file placement by drive size

Posted: 13 Dec 2019, 10:01
by b0ssem
Hi,

I have been looking at some similar solution for it to put the file on the drive with most space. But I would like to tweak it a bit.
As I understand the following will check all the defined drives and put it where there is most free space.

Code: Select all

--def "seriesFormat={[\"E:\", \"F:\", \"G:\", \"H:\"].collect{ drive -> def a=n; return new File(drive+\"/TV/\", a)}.sort{ a,b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()}


But I want it to also check if the season folder (e.g. S03) already is on one of the drives it should place the file there. But if its a new season, it should place it on the drive with the most free space.

This is because I dont want to have a season for a tv-show divided on several different drives.

So if TV show episode 1-8 for season 03 is on drive A and then I dont want episode 9 for season 03 to be moved to drive B.
But if its a totaly new season, then it can be moved to the drive with most free space.

Does this make sense?

Thanks!

Re: file placement by drive size

Posted: 13 Dec 2019, 12:34
by rednoah
The code above already does that, on the series level, not on the season level.

Re: file placement by drive size

Posted: 13 Dec 2019, 16:59
by kim
Maybe if you change to

Code: Select all

def a = n + "/Season " + s;
?
Not testet