Okay, been trying to figure this out to no avail (obviously)...
I have a subfolder where all "small movies" go into. Basically, anything with an actual run time of under an hour (60 minutes), so that things like TV specials or just one-off shows/etc can automatically go into there. The problem is when there is a movie that is broken into multiple parts and one or more of those parts are under 60 minutes. I've tried a few different ways that either don't work at all, or work one way but not the other. Here are a couple of examples of what I've tried...
The overall code for the entire naming is much bigger, but that's the one area I'm having an issue with. I've tried comparing 'pi' to null/undefined, negating it, so on. I more or less need a to test if it's undefined as well as it having a value. I'm sure there's a way to do it that I don't know of, since there appears to be many 'hidden' expressions/functions available that don't seem to be all on one page. (The 'expressions' help page lists some common ones but there are a lot of things not listed on that page.)
So, how can I get a true result for 'pi' being undefined and where can I find out about more functions that are seemingly like easter eggs to find and use?
1. {minutes} is based on the duration MediaInfo of a given file. Multi-Part movies are tricky, but let's just assume that {pi} is working and that it's only defined for multi-part movies, and throw an exception when it's not defined.
rednoah wrote:1. {minutes} is based on the duration MediaInfo of a given file. Multi-Part movies are tricky, but let's just assume that {pi} is working and that it's only defined for multi-part movies, and throw an exception when it's not defined.
That's actually why I prefer to use 'minutes,' as it gives the actual duration of the video itself vs durations that may include time for commercials. I've seen ones where the reported time is 60 minutes but the time of the video is like 45. I'm fairly certain that the 15 minute difference is for the commercials shown when it originally aired on TV.
Is there a way to compare for an exception? In this instance, I managed to figure something out using the any{}{} function, but checking using an 'if' might be useful at times too.
rednoah wrote:2.
The "correct" solution is probably one that combines all the {minutes} for all model objects that are the same movie:
rednoah wrote:1. {minutes} is based on the duration MediaInfo of a given file. Multi-Part movies are tricky, but let's just assume that {pi} is working and that it's only defined for multi-part movies, and throw an exception when it's not defined.
Just to clarify, {pi} is working when there is a number. The issue was in finding a way to check if there wasn't a number.
rednoah wrote:3.
The built-in help should contain everything you need:
You can click the source link to see the code (and thus every single binding and it's implementation): http://www.filebot.net/naming.html
Both of those links I had already seen. The problem is, the 'naming.html' one doesn't show use of the any{}{} function and neither show the use of if-then-else. There are also many other functions not shown that apparently can be used. So was hoping there was a link to somewhere with a more comprehension list to look at.
any {code that uses pi and fails if pi is undefined} {code for when pi is undefined} {code for the next fallback} ...
2.
The any and allOf functions are documented here. Then there's csv and readLines and that's pretty much it. There's a link to the source at the bottom.
That's why it's best to copy & paste examples and play with it. The comprehensive list of 10.000+ classes and 100.000+ methods is just a bit overwhelming when you just need String.replace(target, replacement).
e.g. if you want to check if a path exists you might create a File object for the given path so you can then call the File.exists() method. I don't think there's any good use case for new File(...) in FileBot format expressions though.
Note that {file} will also give you a File object (and not a String object).
{home} is part of the built-in examples. Works the same as any of the other object/mediainfo bindings, except it's always the same regardless of what object/file match you're formatting.
{self} will self-reference the binding object, so the default String representation will show you all binding names.
PS: Note that these 1000+ character formats are extreme overkill and nobody (including the original author) is expected to understand how it works and what it does exactly.
~path to...~/Movies/{def x,cleanName=n.replaceAll(/:/, ' -').replaceAll(/\?/, '');new File('P:/collections.txt').splitEachLine(':'){if (it[0].matches(/.*${imdbid}.*/)) x=it[1]};A:{any{if (any{collection}{x}) ("_ COLLECTIONS _/${any{collection}{x}}/${y} - ${cleanName}/${cleanName}")}{if (any{pn}{"X"} == "X" && minutes < 60) ("_ MINI MOVIES _/${cleanName} (${y})/${cleanName}")}{"${az}/${cleanName} (${y})/${cleanName}"}}} ({y}){'.CD'+pi}{'.'+minutes+'m'}{'.'+certification}{'.'+resolution}{'.'+source}{'.'+crc32}
In the 'collections.txt' file, I have imdbid's seperated by ;'s and at the end of a list, a colon (:) and the collection name. Helps when there are movies that are part of a collection but not registering as such (not blaming filebot for that, that's user contributed data). I have the James Bond collection on BluRay (got it for a good deal from Amazon) and almost none of the movies are part of a James Bond Collection.
Maybe I missed it, but is there an existing 'name' value that is already cleaned for file name usage? I turn the :'s into -'s and chop off ?'s and will add other illegal characters I come across. However, would feel better if there was a pre-cleansed name or a function to cleanse with an option to override certain characters... Something like this:
* {fn} doesn't do filename validation, but {plex.name} does
* No {y} {n} special case for collections (just don't do it, it looks terrible, even if it sorts nicely )
EDIT:
On second thought, if you want a collections folder and do "Collections/" + null value you'll get "Collectionsnull" which breaks our any cascade. Using String.concat(String) instead of String.plus(Object) will do the trick and make things break when they ought to break.
tt0055928;tt0057076;tt0058150;tt0059800;tt0062512;tt0064757:James Bond Collection
(With the ;'s changed to something else and the : changed to a ; instead.)
To me, it looks better to have multiple titles grouped together to a collection. Still using a few lines to do it, but it's all neatly packed together instead of a bunch of lines with one title to the same collection. If there's a way to have it make a hit using the same line above (again changing the use of :'s and ;'s) then that would prove to be easier.
rednoah wrote:
* {fn} doesn't do filename validation, but {plex.name} does
* No {y} {n} special case for collections (just don't do it, it looks terrible, even if it sorts nicely )
For non collection folder names, it does the "{n} {y}" style. Inside of a collection, I like it to be sorted by year released, since that is *usually* the sequence of events or the best way to watch them, etc. It also doesn't look terrible to me, since the year is a fixed length, it actual name of the movies still line up just fine.
rednoah wrote:
EDIT:
On second thought, if you want a collections folder and do "Collections/" + null value you'll get "Collectionsnull" which breaks our any cascade. Using String.concat(String) instead of String.plus(Object) will do the trick and make things break when they ought to break.
String.tr() should be perfect for any simple character-by-character replacement.
I tried testing .tr() but it wouldn't work for me. However, doing {n.replaceAll(/[:]/,' -').validateFileName()} does and I think gives slightly better control. I can make the desired changes before it does it's cleansing. Much appreciated.
Don't suppose there's some sort of a secret editor that gives more viewing space and let's you use multiple lines, etc...?
Did come across something that I wish I could say is a bug, but arguably it's not. {info.runtime} sometimes returns values as strings vs integers. I've seen before where sometimes it will have a value and "min" as well, depending on the data source, which is why I say it's arguably not a bug. Noticed it happening again but {info.runtime} would display something (vs being null) and so I added .toInteger() to it and it started working.
info.runtime is a String value of whatever the database says. TheMovieDB should give you nice numbers (if somebody has entered the data) but with OMDb all bets are off and you might get String values like "90 min" or "1h 30min" etc.
info.runtime.toInteger() will give you a number, or an exception if it's null or not a number.
If there was a way to do a regex search with csv, then that would definitely be better than what I posted.
With .tr(), when I have .tr('','') then it shows up fine, but if I put anything in either (or both), even just one character in each, then the information just disappears.
Will switch to the .colon() expression, would make it a bit cleaner, especially since it's the only item I can think of at the moment that I'd want changed like that anyways.
So info.runtime isn't too reliable I take it? Is there any sort of conversion available to convert it from "1h 30min" to "90min" which could then get changed to "90"? Or is that not an option?
Doing my best to come up with something that will rarely need any tweaking, despite what I might throw at it. If a part of a movie is encountered, even if it is an only file and thus, doesn't get a part number assigned, would be preferable for it to still be sorted properly (and reliably), but sounds like I might have to accept some chance of it not working as desired. (No fault to filebot, of course.)
{readLines('/path/to/file').find{ it =~ imdbid }.after(':')}
2. String.tr() doesn't seem to work because FileBot somehow interferes with the Groovy runtime.
3.
There is really no reason not to use TheMovieDB anymore. The API is stable and serves good data. The same cannot be said of OMDb (and weird inconsistent runtime values are just one example).
I'd sort all movies with known runtime > 60 into the az folders, and default everything else into the shitty shorts folder. It's either gonna be short movies, or shitty movies where nobody has bothered entering runtime info yet.
1. Very nice. Odd though...
Using that directly within concat works, but if I set it to a variable first and then try to use that, it fails. Of course, since the value is only needed once, it being inside of concat gets the job done. The variable gets the value, because if I remove the concat part and use the variable directly, it appears. Some sort of a bug perhaps?
2. Okay so it's not just me. Phew.
3. I use TMDB mostly, but there are a few things that OMDb has that TMDB doesn't (as far as matching content goes). I think I've come across two or three items where OMDB had a match that TMDB didn't.
Also, they're not necessarily 'shitty' shorts. Just some stuff that might be a one-time thing and the popular thing to do is to label it as a movie (since it certainly doesn't qualify as a TV series). But if it's 60 min or under, then to me, that's not really a movie. A movie is generally over an hour and while there are some things that aren't movies that go over an hour, this at least catches most of those.
Using that 'collections' file, I can more easily group stuff together, multiple items per line, making it much nicer to deal with. I appreciate that solution, it's great!
Just to mention this, I use the P drive as my Plex system drive. Within Plex itself, I redirected the database and other files to P (for Plex obviously), which makes it easier if I have to do a reinstall, also no worries of system drive filling up and crashing the computer, etc. Still doing a little reorganizing, but goal is to have M being the media drive (and using Windows Storage Spaces, a drive that can continue to expand in size when needed).
One issue I'm noticing, and it seems to be random, but when picking different files to test the expressions on, some will load up (download) the meta data right away. Others, nothing, even after repeated attempts. Then after awhile, it might work. If I try a different file, that has a chance of working, but certain ones just continue to fail no matter what. So I doubt I'm being blocked for some reason, but it working for some and not for others tells me that the API is working fine. So I'm baffled. Any ideas? (I've already cleared the cache.)
3.
Do you have any logs or examples? You can make FileBot dump all the network responses to the log if you enabled it with the Developer Options / Java System Properties so you can see what exactly the database is sending back.
Okay, enabled the options in the filebot.l4j.ini file, cleared the cache, then ran it.
Loaded it up, it showed the check for the latest version. Went to 'edit format' and it showed the response (from omdb?) for the file it had marked as the guinea pig. When I clicked the button to choose a new file, a lot of scrolling happened, but with information on the same file. When I pick a file that failed previously, nothing happens. When I pick another file (all while remaining in the "movie bindings" dialog box), data would scroll. So, seems as though certain files just aren't getting a response (or aren't sending requests).
It works just fine when trying to do matches for renaming, which is where it truly counts. It's just the 'bindings' area that it's being weird.