Where do I find all the documentation?

All about user-defined episode / movie / file name format expressions
Post Reply
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Where do I find all the documentation?

Post by Wolfie »

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...

Code: Select all

{if (minutes < 60 && ! pi) (code)}
{if (minutes < 60 && (any{pi}{y} != {y})) (code)}
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?
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Trouble with an 'if' condition (minutes/parts)

Post by Wolfie »

Okay managed to figure it out though it's odd that other similar attempts failed.

Code: Select all

{if ((any{pn}{"X"} == "X" && minutes < 60)) (code)}
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Trouble with an 'if' condition (minutes/parts)

Post by rednoah »

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.

@see viewtopic.php?f=5&t=1895


2.
The "correct" solution is probably one that combines all the {minutes} for all model objects that are the same movie:

Code: Select all

{model.findAll{it.id == id}.minutes.sum()}
You could also use the movie runtime (from TheMovieDB, not based on file content) which is probably what you want here:

Code: Select all

{info.runtime}

3.
The built-in help should contain everything you need:
Image

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
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Trouble with an 'if' condition (minutes/parts)

Post by Wolfie »

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.

@see viewtopic.php?f=5&t=1895
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:

Code: Select all

{model.findAll{it.id == id}.minutes.sum()}
You could also use the movie runtime (from TheMovieDB, not based on file content) which is probably what you want here:

Code: Select all

{info.runtime}
I tried using 'info.runtime' but for some reason, it wouldn't let me compare when an integer and when I tried with a string, it was unreliable.


Thanks for the reply. I'll check out the links you provided.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Trouble with an 'if' condition (minutes/parts)

Post by Wolfie »

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.

@see viewtopic.php?f=5&t=1895
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:
Image

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.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Trouble with an 'if' condition (minutes/parts)

Post by rednoah »

1.
You don't need to check, because pi itself will unwind the expression if it's undefined:

Code: Select all

{'CD'+pi}

Code: Select all

{pi; 'This is a multi-part movie'}

Code: Select all

{any{' CD'+pi}{' (Single File Movie)'}}
With any you can avoid most of the if-then-else bloat. But if you really want "value of pi or 0 if pi is undefined", then any{pi}{0} will do that.

e.g.

Code: Select all

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.

The rest is just Groovy: Syntax, Operators, Closures, Semantics and of course the entire Java API plus Groovy Enhancements if you need a complete Object/Method reference.

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). ;)
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Trouble with an 'if' condition (minutes/parts)

Post by Wolfie »

What about 'File()'? I see where someone used that and would like to read up on it. Where would that be at?
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Trouble with an 'if' condition (minutes/parts)

Post by rednoah »

This one is probably about the File class of the Java API:
https://docs.oracle.com/javase/8/docs/a ... /File.html

e.g. get current working directory:

Code: Select all

new File('.').getCanonicalPath()
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).
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Trouble with an 'if' condition (minutes/parts)

Post by Wolfie »

Oh and what about things similar to {home}? Is there a list of defined values (such as {home} and others) in one of those links?
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Trouble with an 'if' condition (minutes/parts)

Post by rednoah »

This code is about reading CSV files.

Groovy defines File.splitEachLine which is great for reading CSV files. SyAccursed knows Groovy so he just did it the Groovy way.

FileBot has the csv(String path) function built-in:

Code: Select all

csv('/path/to/table.csv')
I recommend doing it the easy way. But if you know Java/Groovy you can do it a million different ways. ;)

@see viewtopic.php?f=5&t=2#p12156
:idea: Please read the FAQ and How to Request Help.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Trouble with an 'if' condition (minutes/parts)

Post by rednoah »

{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.

If you click source you will find the implementation details of all bindings:
https://github.com/filebot/filebot/blob ... .java#L897


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.
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

Here is what I have so far and it seems to be working fine... (Watch it blow up in my face...)

Code: Select all

~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:

Code: Select all

n.cleanse() <-- default
n.cleanse(":","-") <-- substitute :'s with -'s
n.cleanse(":?","_-_") <-- substitute :'s and ?'s with _-_'s
Except for optional substitutions, all characters considered 'illegal' by the filesystem get removed completely.

If something like this already exists... what is it? :D
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

1.
WTF? My eyes are bleeding... :shock:

I'd keep my collections.csv file in a simple Key;Value format:

Code: Select all

tt0499549;My Avatar Collection
The rest can be simplified (and made readable):

Code: Select all

{any{collection}
    {csv('X:/collections.csv')[imdbid]}
    {if (minutes < 60 && type != 'MoviePart') 'Mini Movies'} 
    {az}
}
/{ny}/{plex.name}
* {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 :P)


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.

This might be more close to your spec:

Code: Select all

{any{'Collections/'.concat(collection)}
    {'Collections/'.concat(csv('X:/collections.csv')[imdbid])}
    ...
}

2.
FileBot will force valid filenames anyway on rename, but if you want to do it in the format you can:

Code: Select all

{n.validateFileName()}
String.tr() should be perfect for any simple character-by-character replacement.
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

rednoah wrote:1.
WTF? My eyes are bleeding... :shock:

I'd keep my collections.csv file in a simple Key;Value format:

Code: Select all

tt0499549;My Avatar Collection
The rest can be simplified (and made readable):

Code: Select all

{any{collection}
    {csv('X:/collections.csv')[imdbid]}
    {if (minutes < 60 && type != 'MoviePart') 'Mini Movies'} 
    {az}
}
/{ny}/{plex.name}
Will that handle a line like this?

Code: Select all

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 :P)
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.

This might be more close to your spec:

Code: Select all

{any{'Collections/'.concat(collection)}
    {'Collections/'.concat(csv('X:/collections.csv')[imdbid])}
    ...
}
Would this have the same effect?

Code: Select all

{'Collections/'.concat(any{collection}{csv('X:/collections.csv')[imdbid]})}
rednoah wrote:2.
FileBot will force valid filenames anyway on rename, but if you want to do it in the format you can:

Code: Select all

{n.validateFileName()}
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...? :D
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

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.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

1.
Your csv line format will not work. The built-in csv function expects simple Key;Value lines and return a Map<String, String> object.


2.
If none of the Closures passed to any() yield any results, then it'll return null and concat will fail with an NPE, which is what we want here.


3.
tr is about replacing characters. 1 char can only be replaced by 1 other char. Use the replace method for simple String replace:

Code: Select all

n.replace(':', ' -')
I recommend using the built-in colon method:

Code: Select all

n.colon(' - ')
(this will take care of French-style colons with Thin Space)
:idea: Please read the FAQ and How to Request Help.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

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.
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

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.)
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

1.
If I had to parse a text file format like yours, I'd do it like this:

Code: Select all

{readLines('/path/to/file').find{ it =~ imdbid }.after(':')}
2.
String.tr() doesn't seem to work because FileBot somehow interferes with the Groovy runtime. :o

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. :lol:
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

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.)
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

Oh and here's what I have now, in case you're wondering or if anyone else is hoping to try new things...

Code: Select all

...path.to.media.../Movies/{def cleanName=n.colon(" -").validateFileName();A:{any{"_ COLLECTIONS _/".concat(any{MC:{readLines('P:/collections.txt').find{ it =~ imdbid }.after(':')}}{collection})+"/${y} - ${cleanName}"}{if (minutes <= 60 && info.runtime.toInteger() < 75) ("_ MINI MOVIES _/${cleanName} (${y})")}{"${az}/${cleanName} (${y})"}+"/${cleanName} (${y})"}} {'.CD'+pi}{'.'+minutes+'m'}{'.'+certification}{'.'+resolution}{'.'+source}{'.'+crc32}
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

1.
Did you mean something like this? Works fine as far as I can tell:

Code: Select all

{def x = readLines('/path/to/file').find{ it =~ imdbid }.after(':'); 'Collections/'.concat(x)}
:shock: You are the first person to ever use block labels in format expressions... I completely forgot Java/Groovy even had those:

Code: Select all

MC:{readLines('P:/collections.txt').find{ it =~ imdbid }.after(':')}
@see http://groovy-lang.org/semantics.html#_ ... statements


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.
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

1. When I would try it, it wouldn't take. The 'def' would be before the A: block, which could have something to do with it.

2. I was sort of forced into it. Without them, it fusses at me with an error message and tells me to use them.

3. Will have to make a log.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

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.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

Please give me the filenames and how to reproduce this issue so I can try it myself and see what's going on.
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

Sent you a PM.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

For reproducing (forgot to include)..
Clear cache, just to be sure.
Start filebot. Click to edit format. Choose to select a file. Pick one of the non-working ones.

As said before, when doing the actual matching process to rename files (not editing format), it works fine. It's only in the binding area that it's being a problem.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

I see.

So if you open the format editor by double-clicking the "New Name" list item it works? But when opening the format editor via "Edit Format" it doesn't work?

If you double-click a match you can prototype your format with real info/file data.

If you do click "Edit Format" you'll be working default sample info data "Avatar (2009) CD1" and a sample file (if you have set one). The sample info data can only be changed by selecting a sample file that has been tagged with metadata by FileBot.

When in doubt, check the bindings window to see what movie/episode info and file info you're working with.
:idea: Please read the FAQ and How to Request Help.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

Here's a few recommendations for your format:

The colon function takes care of surrounding whitespace, so the replacement must contain surrounding whitespace if you want to keep it:

Code: Select all

n.colon(' - ')
I recommend the [ABCD1234] pattern, because tools like FileBot that deal with CRC32 checksums in the filename expect them to be in brackets:

Code: Select all

.[{crc32}]
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

1. Yes, works there just fine.

2. These are all files that have been processed previously with FileBot.

When I pick a new file to bind, I see if it's using the new file or the file it was already using. I have even let it sit a few minutes just to give it a chance to change.


Thanks, was used to doing ' -' and forgot that it removes a leading and trailing space. Updated it now.

Will there be any noticeable difference in how the files are treated by including the CRC32 inside of brackets?
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

I can't reproduce the issue. Something like this?

1. Start FileBot
2. Click "Edit Format"
3. Click "View Bindings" button (3rd one to the right)
4. Select "Media File"
5. What's happening now? Did "Name" change? What's not working? Which bindings exactly?


Wolfie wrote:Will there be any noticeable difference in how the files are treated by including the CRC32 inside of brackets?
If you use [ABCD1234] then you'll be able to check the CRC32 with FileBot (and other tools) and {crc32} won't need to be calculated every time if it's in the filename.
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

rednoah wrote:I can't reproduce the issue. Something like this?

1. Start FileBot
2. Click "Edit Format"
3. Click "View Bindings" button (3rd one to the right)
4. Select "Media File"
5. What's happening now? Did "Name" change? What's not working? Which bindings exactly?
When I do that, the new file is selected but the bindings remain the same. If I click to use it and then go to change the view the bindings again, it sometimes takes a moment as if it's trying to use the file I chose (which is still selected) before resorting back to the bindings already in use. So the file I last picked remains picked, just the bindings never update/change.

rednoah wrote:
Wolfie wrote:Will there be any noticeable difference in how the files are treated by including the CRC32 inside of brackets?
If you use [ABCD1234] then you'll be able to check the CRC32 with FileBot (and other tools) and {crc32} won't need to be calculated every time if it's in the filename.
Oh wonderful. I already changed it but wanted to know what, if any, true difference it would make. Not having to recalculate the hash each time is a definite winner.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

Once you select a "Media File" that will definitely change the sample file and all file bindings (e.g. vc, ac, fn, etc). If "Name" doesn't change then the sample info hasn't changed and info bindings (e.g. n, y, id, etc) won't change. If "Name" doesn't change, then "Use Bindings" won't give you new sample data to work with in the sample editor.

In your case, when you click "Use Bindings" it's probably just stuck on cancelling the CRC32 computation for a bit.
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

I had thought about that, which is why I've even waited a few minutes to see if it would make a difference. However, the same files that worked before continue to work near instantly even after doing a -clear-cache.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

So you're saying:

Binding Dialog shows "Name" = "Spectre (2015)" and shows [n = Specter, y = 2015, etc] but when you click "Use Bindings" it doesn't take and you get the default sample bindings "Avatar (2009)" [n = Avatar, y = 2009, etc] like this? What exactly is not working? What is showing? What should be shown instead?

Please add some screenshots. I have honestly no idea what the problem you're describing might be.
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

No, the 'Media File' field is filled in with the selected file. Everything else (Name: and Preview:) remain unchanged.

Interesting though. Despite the files having been processed through FileBot before, when I tried it on a file that was re-processed, that file loads up fine. Maybe the metadata didn't save on some of the files. Will have to keep an eye on it to see if there is any sort of a pattern.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

Wolfie wrote:No, the 'Media File' field is filled in with the selected file. Everything else (Name: and Preview:) remain unchanged.
That would be the default behaviour. Since the info object hasn't changed, bindings like n or y won't change. If you scroll down you will find that file bindings like fn or gigabytes will have changed. Changing the sample file path doesn't change the sample info object (unless there is xattr metadata).

e.g.

Code: Select all

$ filebot -script fn:xattr .
Avatar (2009).mp4
	net.filebot.filename: Avatar.mp4
	net.filebot.metadata: {"@type":"net.filebot.web.Movie","year":2009,"imdbId":499549,"tmdbId":19995,"language":"en","id":19995,"name":"Avatar","aliasNames":[]}
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

I'm going to keep an eye on it. The reason I'm doing all this mass changing is the result of realizing that I had copied some files over without running them through filebot (simply had names, no hash or other information). Once that's all done, if I find files that are doing that, I'll let you know. This way, they are certain to have been processed and thus should have the metadata with it.

Of course, now I'm going to have to convert the format expression to the .bat file. But there's some time before I need to take that step, still planning out the juggling of files to make things much simpler to deal with.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

Wolfie wrote:convert the format expression to the .bat file
@files are the sane way of passing complex arguments: viewtopic.php?f=3&t=3244
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

THAT is a god send! Will definitely make use of that.

Here is my current expression (still tweaking it)...

Code: Select all

...path.../Movies/{def cleanName=n.colon(" - ").validateFileName();A:{any{"_ COLLECTIONS _/".concat(any{MC:{readLines('P:/collections.txt').find{ it =~ imdbid }.after(':').match(/(.*?)(?:[:#\t*]|$)/)}}{collection})+"/${y} - ${cleanName}"}{if (minutes <= 60 && info.runtime.toInteger() < 75) ("_ MINI MOVIES _/${cleanName} (${y})")}{"${az}/${cleanName} (${y})"}+"/${cleanName} (${y})"}}{'.'+certification}{'.'+resolution}{'.'+source}{if (fn.find(/[. ]CD\d+[. ]/)) '.CD'+pi}{'.'+any{minutes+'m'}{info.runtime+(info.runtime.toInteger().toString()==info.runtime ? "m" : '')}}{".[${crc32}]"}
You'll notice I made a slight alteration to the collections readLines. It's to allow me to optionally include comments/notes at the end of a line, in case I want something to remind me of what is included (without actually naming everything). I might decide to break the James Bond listings based on the actor of the main character (and include those who weren't in more than two films). That would give me four lines and I'd know which titles are included. Then could also allow me to rename the collection more easily based on that knowledge.

For the .CD#, have it checking the file to see if it's already included. Sometimes, having a couple of different copies of something gets it trying to do .cd1 and .cd2 when they are individual copies rather than parts to combine. This lets me avoid that happening. Granted, there is a chance of a grouping being misnamed, but I'm confident it will be a rare situation if it happens at all.

Then the time of the video. Came across one where the 'minutes' wasn't working, so added in a backup method along with a fix to the chance of 'runtime' not being simply a value. That lack of a time for the video isn't filebot's fault, it's a DVD structured folder.

I have one more tweak in mind for the 'mini' minute check, but will need to find something to test it on first.

Maybe I'm missing something, but I tried to use .match() on {folder} in an attempt to use the same initial structure (there are currently three library areas due to it being on different drives that aren't part of Storage Spaces yet). However, it gets really mad at me saying that it's not supported (I guess?) to use .match on {folder}. Is that right? Is there a way to follow the same/similar root structure? I see there are ways to pick based on free space or first letter of the title, was hoping there would be a way to keep it on the same path without having to change the start of the line based on which library I'm working on.
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

1.
Wouldn't this be more readable?

Code: Select all

{'1: TEST # COMMENT'.after(':').before('#')}
2.
String.match() is only defined for String objects, but folder will give you a File object, hence:

Code: Select all

{folder.path.match(/.../)}
3.
You will find examples for Sort into drive with the most free space and Sort into multiple drives based on initial letter here:
viewtopic.php?f=5&t=2

But if you just want to keep parts of the original path the something like this will do: e.g. keep the first 3 path components:

Code: Select all

{file[0..2]}
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

1. More readable but more restrictive. Being able to use <tab> or # or even * as a separator gives me options depending on my mood or even usage based on the collection.

2. Something new learned. Thank you again.

3. That helps a great deal more than you know! Awesome!
User avatar
rednoah
The Source
Posts: 24657
Joined: 16 Nov 2011, 08:59
Location: Taipei
Contact:

Re: Where do I find all the documentation?

Post by rednoah »

before() and after() do expect a regex, so before(/[#*\t]/) is fine. ;)

EDIT:

before() is also great for keeping parts of the path, and maybe even more readable: e.g. {f.path.before('Movies')}
:idea: Please read the FAQ and How to Request Help.
User avatar
Wolfie
Posts: 156
Joined: 27 Oct 2015, 02:59

Re: Where do I find all the documentation?

Post by Wolfie »

You're starting to spoil me dude... Keep it up! :D
Post Reply