AniDB O'Matic - Documentation: Local file renaming
File renaming patterns
AoM contains a comprehensive number of patterns to fully customize file names and paths. In order for the pattern to allow very complex rules it essentially allows light scripting. The path can be a complete path or a partial path, in case of a partial path the current file manager is used to place the file based on a known root or from the root folder of the file manager, see file managers below for more details. File extensions are automatically added to the end of the pattern.
Sample patters
English anime title with fallback
set('atitle', at('en')) if(length(atitle)=0, set('atitle', at('x-jat'))) if(length(atitle)=0, set('atitle', at('ja'))) if(length(atitle)=0, set('atitle', A.Name))
Japanese transcription anime title with fallback
set('atitle', at('x-jat')) if(length(atitle)=0, set('atitle', at('en'))) if(length(atitle)=0, set('atitle', A.Name))
Japanese kanji anime title with fallback
set('atitle', at('ja')) if(length(atitle)=0, set('atitle', at('x-jat'))) if(length(atitle)=0, set('atitle', at('en'))) if(length(atitle)=0, set('atitle', A.Name))
English episode title with fallback
set('etitle', et('en')) if(length(etitle)=0, set('etitle', et('x-jat'))) if(length(etitle)=0, set('etitle', et('ja')))
Japanese transcription episode title with fallback
set('etitle', et('x-jat')) if(length(etitle)=0, set('etitle', et('en')))
Japanese kanji episode title with fallback
set('etitle', et('ja')) if(length(etitle)=0, set('etitle', et('x-jat'))) if(length(etitle)=0, set('etitle', et('en')))
File version
set('version', if(F.Version>1, 'v'+F.Version,))
Padded episode number
set('mepno', max(A.TotalEpisodeCount, E.EpisodeTypeCount)) set('epno', padl(E.EpisodeNo, max(1, length(mepno)), '0')) if(E.TypeId=2, set('epno', 'S'+epno)) if(E.TypeId=3, set('epno', 'C'+epno)) if(E.TypeId=4, set('epno', 'T'+epno)) if(E.TypeId=5, set('epno', 'P'+epno)) if(E.TypeId=6, set('epno', 'O'+epno))
First letter for organizing by letter
set('head', copy(atitle, 1, 1)) if(numeric(head), set('head', '0-9'))
Group name
set('groupname', if(F.GroupId>0, if(length(G.Name)>0, G.Name, G.Shortname), 'no group')) set('groupname', if(length(groupname)>0, '['+groupname+']'))
Group short name
set('groupname', if(F.GroupId>0, if(length(G.Shortname)>0, G.Shortname, G.Name), 'no group')) set('groupname', if(length(groupname)>0, '['+groupname+']'))
CRC32
set('crc', '('+uc(H.Crc32)+')')
Default pattern
set('atitle', at('x-jat'))
if(length(atitle)=0, set('atitle', at('x-jat', 'short')))
if(length(atitle)=0, set('atitle', at('en')))
set('etitle', et('en'))
if(length(etitle)=0, set('etitle', et('x-jat')))
if(length(etitle)=0, set('etitle', et('ja')))
set('version', if(F.Version>1, 'v'+F.Version, ''))
set('mepno', max(A.TotalEpisodeCount, E.EpisodeTypeCount))
set('epno', padl(E.EpisodeNo, max(1, length(mepno)), '0') + version)
if(E.TypeId=2, set('epno', 'S'+epno))
if(E.TypeId=3, set('epno', 'C'+epno))
if(E.TypeId=4, set('epno', 'T'+epno))
if(E.TypeId=5, set('epno', 'P'+epno))
if(E.TypeId=6, set('epno', 'O'+epno))
set('crc', '('+uc(H.Crc32)+')')
atitle + ' - ' + epno + ' - ' + etitle + ' ' + groupname + crc + '.' + F.FileType
Objects
A / ANIME
AnimeNFOId | integer | |
AnimeNFOStr | string | |
Category | integer | |
Date | integer | |
Description | string | |
Name | string | |
PictureUrl | string | |
Producer | string | |
ReviewAverage | integer | |
ReviewCount | integer | |
TotalEpisodeCount | integer | |
Updated | integer | |
Url | string | |
VoteAverage | integer | |
VoteCount | integer | |
Year | string | |
EpisodeCount | integer | |
GenreCount | integer | |
GenreString | string | |
SpecialEpisodeCount | integer | |
CategoryStr | string | |
DownloadState | TAniDBAnimeDownloadState | |
WatchedState | TAniDBAnimeWatchedState | |
StatusState | TAniDBAnimeStatusState | |
StartYear | integer |
E / EPISODE
Aired | integer | |
AnimeId | integer | |
Date | integer | |
EpisodeNo | integer | |
EpisodeStr | string | |
EpisodeStrPadded | string | |
IsSpecial | boolean | |
Length | integer | |
Name | string | |
Other | string | |
Updated | integer | |
TypeId | integer | |
IsRecap | boolean |
F / FILE
AnimeId | integer | |
BitrateAudio | integer | |
BitrateVideo | integer | |
Crc | string | |
CrcStatus | TAniDBCRCStatus | |
Date | integer | |
Ed2k | string | |
EpisodeId | integer | |
FileType | string | |
GroupId | integer | |
LanguageId | integer | |
Length | integer | |
Md5 | string | |
Name | string | |
Other | string | |
QualityId | integer | |
Released | integer | |
ResolutionHeight | integer | |
ResolutionWidth | integer | |
Sha1 | string | |
Size | int64 | |
State | integer | |
SubtitleId | integer | |
TypeId | integer | |
TypeState | integer | |
Updated | integer | |
UserCount | integer | |
UserCountRelease | integer | |
UserCountShare | integer | |
Version | integer | |
GroupShort | string | |
GroupLong | string | |
DubLanguageString | string | |
SubLanguageString | string | |
QualityString | string | |
ResolutionString | string | |
TypeString | string |
G / GROUP
string | ||
IrcChannel | string | |
IrcServer | string | |
Name | string | |
Other | string | |
Rating | integer | |
Shortname | string | |
Url | string | |
Votes | integer |
H / HASH
Crc32 | string | |
Ed2k | string | |
Md5 | string | |
Sha1 | string | |
Size | int64 | |
FPS | double | |
Length | double | |
VideoFourCC | string | |
VideoCompression | string | |
VideoCodec | string | |
VideoHeight | integer | |
VideoWidth | integer | |
VideoBitrate | double | |
VideoVBR | boolean | |
AudioIdentCodec | integer | |
AudioCodec | string | |
AudioSamplerate | integer | |
AudioBitrate | double | |
AudioVBR | boolean |
M / MYLIST
AnimeId | integer | |
Date | integer | |
EpisodeId | integer | |
FileId | integer | |
MylistId | integer | |
Other | string | |
Source | string | |
State | integer | |
Storage | string | |
Watched | boolean | |
WatchedDate | integer |
Functions
at(lang) | text | Returns a main/official anime title in lang. lang can be either a text or a number. Example: at(2) = japanese title Example: at('japanese (transcription)') = japanese transcription Example: at('en') = english title |
contains(find, text) | boolean | Returns true if find is found in text. Example: contains('bcd', 'abcdef') = true |
copy(text, start[, length]) | string | Returns length letters from letter number start of text. Example: copy('abcdefgh', 3, 2) = 'cd' |
et(lang) | text | Returns an episode title in lang. lang can be either a text or a number. Example: et(2) = japanese title Example: et('en') = english title |
if(test, trueval[, falseval]) | any | If statement, returns trueval if test is true, otherwise returns falseval. Example: if(23=23, 'equal', 'not equal') = 'equal' |
in(find, text...) | boolean | Checks if find is present in a number of text parameters. Example: in('bb', 'aa', 'bb', 'cc', 'dd') = true |
join(glue, text...) | string | Joins together two or more texts, empty parameters are ignored with no glue added. Example: join(' ', 'a', 'b', 'c') = 'a b c' |
lc(text) | string | Converts text to lower case. Example: lc('ABCDEF') = 'abcdef' |
length(text) | number | Returns the length of text. Example: length('abcdef') = 6 |
limit(text, length[, end]) | string | Limits the length of text to at most length characters. End is optional, if specified and the text is cropped, it'll be added at the end of text. Example: limit(e, 100) or limit('abcdefghijklmnop', 7, '...') = 'abcd...' |
max(number...) | number | Returns the highest supplied number Example: max(1, 7, 3, 9, 2) = 9 |
min(number...) | number | Returns the lowest supplied number Example: min(1, 7, 3, 9, 2) = 1 |
numeric(var) | boolean | Returns true if var contains a numeric value. Example: numeric('11') = true |
pad(text, newlength[, padchar]) | string | Pads text on both sides to make it length characters long. Example ?pad('hello', 9, '_') = '__hello__' |
padl(text, newlength[, padchar]) | string | Pads text on the left side to make it length characters long. Example ?padl('hello', 9, '_') = '____hello' |
padr(text, newlength[, padchar]) | string | Pads text on the right side to make it length characters long. Example ?padr('hello', 9, '_') = 'hello____' |
replace(text, find[, replace]) | string | Replaces all occurences of find with replace in text. Example: replace('HELLO THERE!', 'THERE', 'TREES') = 'HELLO TREES!' |
replacei(text, find[, replace]) | string | Case insensitive replace of all occurences of find with replace in text. Example: replace('HELLO tHeRe!', 'ThErE', 'TREES') = 'HELLO TREES!' |
sc(text) | string | Converts text to sentence case. Example: sc('HELLO THERE!') = 'Hello there!' |
set(name, data) | nothing | Declares a new variable called name containing data. Example: set('temp', 'text') |
split(text, find, index) | string | Splits text on find and returns the specified index. Index starts from 1. Example: split('2011-05-19', '-', 2) = 05 |
start(text, find) | boolean | Checks if find matches the start of text. Example: start('1999', '199') = true |
substr(text, start[, length]) | string | Alias for copy. |
tc(text) | string | Converts text to title case. Example: tc('HELLO THERE!') = 'Hello There!' |
uc(text) | string | Converts text to upper case. Example: uc('abcd') = 'ABCD' |
Operators
Arithmetic operators
A+B | returns A plus B |
A-B | returns A minus B |
A*B | returns A multiplied B |
A/B | returns A divided by B |
Comparison operators
A=B | true if A equals B |
A<>B | true if A does not equal B |
A<B | true if A is less than B |
A>B | true if A is more than B |
A<=B | true if A is less or equal to B |
A>=B | true if A is more or equal to B |
Logical operators
A and B | true if both A and B are true |
A or B | true if either A or B is true |
A xor B | true if either A or B is true but not both |
not A | true if A is false |
Constant expressions
There are two ways to specify string literals:
'text' - use '' to insert a ' (e.g. 'her''s')
or
"text" - use \" to insert a " (e.g. "a \"quotation\"")
Number literals are simply written as numbers:
1234
There are also boolean constants:
true
false
File managers
File managers are used to automatically manage file renaming / removing and adding / updating files in your MyList.
Source paths
Each file manager can have multiple source folders. File managers can be set to search these folders recursively or only the folder itself for files. While it's possible adding a source path to multiple file managers is strongly discouraged.
Rename pattern
Each file manager can have 1 renaming pattern. To use multiple patterns you need to specify multiple patterns. The rename pattern can contain a part of a path or a full path to indicate where the file should be stored. The path part of a rename might be ignored under certain circumstances however, see below.
Target paths
A file manager can have one or more target paths for moving files. If no target path is specified the folder the file was found in will be used instead. If there are multiple target paths the file manager will try to figure out where the file has the most related files. This is determined by a) the anime the file belongs to and b) the anime group the file belongs to. If there's not enough space available on the target drive it'll check the next preferred target if there's enough space and so on. If no space is available in any target path the file will be renamed in it's current location, but with any path part of the file removed, aka the filename part of the rename pattern will be used but the file will remain in the folder it was found in.
Only move known files
This will make the file manager ignore files which are not in AniDB, they'll be visible on the known files page, but they will never be moved or renamed.
Automatically remove deleted files
This will make the file manager remove files it can't find any more from the known files page. This rule ignores files stored on removable media.
Don't remove files if the volume can't be found
This will prevent the file manager from removing files it can't find when the whole volume is gone, this rule would for example prevent your known files from being cleared if your network cable is unplugged or a HDD is disconnected.
Add new files to AniDB
This will make the file manager automatically add found files to your MyList.
Automatically update the storage field of MyList entries
This will make the file manager automatically update the storage field of MyList entries based on the volume it's stored on. This field currently only works for files on a removable storage such as a DVD. The label used will be the label of the removable media, e.g. DVD #013.
Automatically mark found files as OnHDD or OnRemovable in MyList
This will make the file manager update your MyList to OnHDD if the file was found on a HDD or Network drive, or OnRemovable if the file is on a CD/DVD.
Automatically mark removed files as Deleted in MyList
This will make the file manager update your MyList to indicate the file has been deleted if removed by the above rule.