AniDB O'Matic - Documentation: Local file renaming: Difference between revisions
m (→E / EPISODE: fandubs are normal eps with audio track type fandub) |
|||
(131 intermediate revisions by 3 users not shown) | |||
Line 7: | Line 7: | ||
File extensions are automatically added to the end of the pattern. | File extensions are automatically added to the end of the pattern. | ||
==Sample patterns== | |||
'''English anime title with fallback''' | |||
<pre> | |||
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)) | |||
</pre> | |||
'''Japanese transcription anime title with fallback''' | |||
<pre> | |||
set('atitle', at('x-jat')) | |||
if(length(atitle)=0, set('atitle', at('en'))) | |||
if(length(atitle)=0, set('atitle', A.Name)) | |||
</pre> | |||
'''Japanese kanji anime title with fallback''' | |||
<pre> | |||
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)) | |||
</pre> | |||
'''English episode title with fallback''' | |||
<pre>set('etitle', et('en')) | |||
if(length(etitle)=0, set('etitle', et('x-jat'))) | |||
if(length(etitle)=0, set('etitle', et('ja'))) | |||
if(length(etitle)=0, set('etitle', E.Name)) | |||
</pre> | |||
'''Japanese transcription episode title with fallback''' | |||
<pre> | |||
set('etitle', et('x-jat')) | |||
if(length(etitle)=0, set('etitle', et('en'))) | |||
if(length(etitle)=0, set('etitle', E.Name)) | |||
</pre> | |||
'''Japanese kanji episode title with fallback''' | |||
<pre> | |||
set('etitle', et('ja')) | |||
if(length(etitle)=0, set('etitle', et('x-jat'))) | |||
if(length(etitle)=0, set('etitle', et('en'))) | |||
if(length(etitle)=0, set('etitle', E.Name)) | |||
</pre> | |||
'''File version and censor flag | |||
<pre> | |||
set('censored', 'unknown') | |||
set('version', F.Version) | |||
set('state_map', F.State mod 4096) | |||
if(state_map>=2048, set('version', 9) + set('state_map', state_map - 2048)) | |||
if(state_map>=1024, if(version<9,set('version', 8)) + set('state_map', state_map - 1024)) | |||
if(state_map>=512, if(version<9,set('version', 7)) + set('state_map', state_map - 512)) | |||
if(state_map>=256, if(version<9,set('version', 6)) + set('state_map', state_map - 256)) | |||
if(state_map>=128, set('censored', 'yes') + set('state_map', state_map - 128)) | |||
if(state_map>=64, set('censored', 'no') + set('state_map', state_map - 64)) | |||
set('version', if(version>1, 'v'+F.Version, '')) | |||
set('censored',if(censored='yes','[Censored]','')) | |||
</pre> | |||
'''Padded episode number''' | |||
<pre> | |||
set('mepno', if(E.TypeId=1, max(A.TotalEpisodeCount, E.EpisodeTypeCount), 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)) | |||
</pre> | |||
'''First letter for organizing by letter''' | |||
<pre> | |||
set('head', copy(atitle, 1, 1)) | |||
if(numeric(head), set('head', '0-9')) | |||
</pre> | |||
'''Group name''' | |||
<pre> | |||
set('groupname', if(G, if(length(G.Name)>0, G.Name, G.Shortname), 'no group')) | |||
set('groupname', if(length(groupname)>0, '['+groupname+']')) | |||
</pre> | |||
'''Group short name''' | |||
<pre> | |||
set('groupname', if(G, if(length(G.Shortname)>0, G.Shortname, G.Name), 'no group')) | |||
set('groupname', if(length(groupname)>0, '['+groupname+']')) | |||
</pre> | |||
'''CRC32''' | |||
<pre> | |||
set('crc', if(H, H.Crc32, F.Crc)) | |||
if(length(crc)>0, set('crc', '('+uc(crc)+')') | |||
</pre> | |||
'''Current filename (removing the path)''' | |||
<pre>set('path_filename', PATH) | |||
set('path_parts', 1) | |||
for('i', 1, length(path_filename), if(copy(path_filename, i, 1) = '\', set('path_parts', path_parts+1))) | |||
set('path_filename', split(path_filename, '\', path_parts))</pre> | |||
===Complex samples=== | |||
See [[AniDB O'Matic - Documentation: Local file renaming - Samples | the article with samples]] | |||
==Default pattern== | |||
The | '''ATTENTION!''' The default pattern has a bug. See below for instructions to fix it. | ||
<pre>set('atitle', at('x-jat')) | |||
=== | if(length(atitle)=0, set('atitle', at('en'))) | ||
if(length(atitle)=0, set('atitle', A.Name)) | |||
& | set('atitle', replace(atitle, '\', ' ')) | ||
set('etitle', et('en')) | |||
if(length(etitle)=0, set('etitle', et('x-jat'))) | |||
if(length(etitle)=0, set('etitle', et('ja'))) | |||
if(length(etitle)=0, set('etitle', E.Name)) | |||
set('etitle', replace(etitle, '\', ' ')) | |||
< | 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('groupname', if(G, if(length(G.Shortname)>0, G.Shortname, G.Name), 'no group')) | |||
set('groupname', if(length(groupname)>0, '['+groupname+']')) | |||
set('groupname', replace(groupname, '\', ' ')) | |||
set('crc', if(H, H.Crc32, F.Crc)) | |||
if(length(crc)>0, set('crc', '('+uc(crc)+')')) | |||
set('filename', limit(limit(limit(atitle, 90) + ' - ' + epno + ' - ' + etitle, 200) + ' ' + groupname, 235) + crc + '.' + F.FileType) | |||
set('filename', replace(filename, '*', ' ')) | |||
set('filename', replace(filename, '/', ' ')) | |||
set('filename', replace(filename, '?', ' ')) | |||
set('filename', replace(filename, ':', ' ')) | |||
set('filename', replace(filename, '"', ' ')) | |||
set('filename', replace(filename, '<', ' ')) | |||
set('filename', replace(filename, '>', ' ')) | |||
set('filename', replace(filename, '|', ' ')) | |||
set('filename', replace(filename, '`', "'")) | |||
set('filename', replace(filename, ' ', ' ')) | |||
filename | |||
</pre> | |||
'''ATTENTION!''' The default pattern has a bug. To fix it, find the following line: | |||
<pre>set('mepno', max(A.TotalEpisodeCount, E.EpisodeTypeCount))</pre> | |||
And replace it with: | |||
<pre>set('mepno', if(E.TypeId=1, max(A.TotalEpisodeCount, E.EpisodeTypeCount), E.EpisodeTypeCount))</pre> | |||
==Objects== | ==Objects== | ||
Line 48: | Line 146: | ||
===A / ANIME=== | ===A / ANIME=== | ||
{| | {| | ||
| | ! scope="col" width="180" | Name | ||
| | ! scope="col" width="60" | Type | ||
| | ! scope="col" | Description | ||
|- | |-valign=top | ||
|Category||integer|| | |Category||integer||Anime Type<br> | ||
|- | 1: Unknown<br> | ||
| | 2: TV Series<br> | ||
|- | 3: OVA<br> | ||
| | 4: Movie<br> | ||
|- | 5: Other<br> | ||
| | 6: Web<br> | ||
|- | 7: TV Special<br> | ||
| | 8: Music Video | ||
|- | |-valign=top | ||
| | |CategoryStr||string||Category text value. | ||
|- | |-valign=top | ||
| | |Name||string||Anime main title | ||
|- | |-valign=top | ||
| | |ReviewAverage||integer||Average review score | ||
|- | |-valign=top | ||
| | |ReviewCount||integer||Total number of reviews | ||
|- | |-valign=top | ||
| | |TotalEpisodeCount||integer||Number of episodes according to AniDB. 0 if unknown. | ||
|- | |-valign=top | ||
| | |VoteAverage||integer||Average voter score | ||
|- | |-valign=top | ||
| | |VoteCount||integer||Total number of votes | ||
|- | |-valign=top | ||
| | |Year||string||Anime airing year(s). For example 2007-2008. | ||
|- | |-valign=top | ||
| | |EpisodeCount||integer||Number of normal episodes according to AoM. | ||
|- | |-valign=top | ||
| | |SpecialEpisodeCount||integer||Number of special episodes according to AoM. | ||
|- | |-valign=top | ||
| | |DownloadState||String||Current download state according to AoM:<br> | ||
|- | adsIgnore: not yet calculated<br> | ||
| | adsComplete: have all normal episodes<br> | ||
|- | adsHaveAll: have all available normal episodes<br> | ||
| | adsIncomplete: have some of the available normal episodes<br> | ||
|- | adsHaveNone: have no files in mylist for this anime | ||
| | |-valign=top | ||
|- | |WatchedState||string||Current watched state according to AoM:<br> | ||
| | awsIgnore: not yet calculated<br> | ||
|- | awsAll: All episodes watched<br> | ||
| | awsPartial: Some episodes watched<br> | ||
|- | awsNone: No episodes watched | ||
| | |-valign=top | ||
|- | |StatusState||string||Current status of mylist entries according to AoM, my contain multiple values separated by commas:<br> | ||
| | assIgnore: not yet calculated<br> | ||
assUnknown: Uknown<br> | |||
assOnHDD: On HDD<br> | |||
assOnCD: On CD<br> | |||
assDeleted: Deleted | |||
|-valign=top | |||
|StartYear||integer||Numeric start year from AirDate. | |||
|-valign=top | |||
|EndYear||integer||Numeric end year from EndDate. | |||
|-valign=top | |||
|AirDate||integer||Air date in unix time, AniDB format. | |||
|-valign=top | |||
|EndDate||integer||End date in unix time, AniDB format. | |||
|-valign=top | |||
|Restricted||boolean||'''Unreliable''' True for hentai, otherwise false. | |||
|-valign=top | |||
|MylistCurrentEpisodeCount||integer||Number of episodes in mylist. | |||
|-valign=top | |||
|MylistSpecialEpisodeCount||integer||Number of special episodes in mylist. | |||
|-valign=top | |||
|WatchedCount||integer||Number of episodes watched. | |||
|-valign=top | |||
|SpecialWatchedCount||integer||Number of special episodes watched. | |||
|} | |} | ||
===E / EPISODE=== | ===E / EPISODE=== | ||
{| | {| | ||
| | ! scope="col" width="180" | Name | ||
|- | ! scope="col" width="60" | Type | ||
| | ! scope="col" | Description | ||
|- | |-valign="top" | ||
| | |AirDate||integer||Episode first air date. | ||
|- | |-valign="top" | ||
| | |EpisodeNo||integer||AniDB episode number. | ||
|- | |-valign="top" | ||
| | |EpisodeStr||string||Episode number with type prefix. | ||
|- | |-valign="top" | ||
| | |EpisodeStrPadded||string||Episode number with type prefix padded based on the total number of episodes of that particular type. | ||
|- | |-valign="top" | ||
|IsSpecial||boolean|| | |EpisodeTypeCount||integer||Number of episodes in this anime with the same type. | ||
|- | |-valign="top" | ||
|Length||integer|| | |IsSpecial||boolean||True if not a normal episode. False otherwise. | ||
|- | |-valign="top" | ||
|Name||string|| | |Length||integer||Length in minutes. | ||
|- | |-valign="top" | ||
|Other||string|| | |Name||string||AniDB main title. | ||
|- | |-valign="top" | ||
| | |Other||string||Description field from AniDB. | ||
|-valign="top" | |||
|TypeId||integer||Episode type:<br> | |||
|- | 1: Regular Episode<br> | ||
|IsRecap||boolean|| | 2: Special<br> | ||
3: Opening/Ending/Credits<br> | |||
4: Trailer/Promo/Ads<br> | |||
5: Parody<br> | |||
6: Other | |||
|-valign="top" | |||
|IsRecap||boolean||True if episode is a recap. | |||
|} | |} | ||
===F / FILE=== | ===F / FILE=== | ||
{| | {| | ||
| | ! scope="col" width="180" | Name | ||
| | ! scope="col" width="60" | Type | ||
| | ! scope="col" | Description | ||
|- | |-valign="top" | ||
| | |Crc||string||AniDB CRC32 value. | ||
|- | |-valign="top" | ||
| | |CrcStatus||string||CRC32 status according to AnIDB:<br> | ||
crcUnknown: unkwnown<br> | |||
crcOk: known valid<br> | |||
|- | crcInvalid: known invalid | ||
| | |-valign="top" | ||
|- | |Ed2k||string||AniDB ED2K value. | ||
| | |-valign="top" | ||
|- | |EpisodeStart||integer||Lowest related episode number of the same type within this anime. | ||
| | |-valign="top" | ||
|- | |EpisodeEnd||integer||Highest related episode number of the same type within this anime. | ||
| | |-valign="top" | ||
|- | |EpisodeList||string||List of episodes within this anime covered by this file.<br>Format: 1,2,3,7,17,93,O1,C3,U77 | ||
| | |-valign="top" | ||
|- | |EpisodeListDetails||string||Detailed list of episodes covered by this file.<br>Format: (EpisodeStr:EpisodeTypeId:AnimeId:EpisodeId:StartPercent:EndPercent)<br>Example: | ||
| | 1:1:357:95304:0:10,2:1:357:95960:0:100,6:1:357:108200:0:100,C1:3:357:108202:0:100 | ||
|- | |-valign="top" | ||
|Length||integer|| | |FileType||string||File extension. | ||
|- | |-valign="top" | ||
|Md5||string|| | |Length||integer||File length in seconds. | ||
|- | |-valign="top" | ||
| | |Md5||string||AniDB MD5 value. | ||
|- | |-valign="top" | ||
| | |Other||string||File description. | ||
|-valign="top" | |||
|Quality||integer||File quality, possible values:<br> | |||
|- | unknown<br> | ||
|Released||integer|| | very high<br> | ||
|- | high<br> | ||
|ResolutionHeight||integer|| | med<br> | ||
|- | low<br> | ||
|ResolutionWidth||integer|| | very low<br> | ||
|- | corrupted<br> | ||
|Sha1||string|| | eyecancer | ||
|- | |-valign="top" | ||
|Size||int64|| | |Released||integer||Release date in unix time. | ||
|- | |-valign="top" | ||
|State||integer|| | |ResolutionHeight||integer||'''Does not work''' Video height in pixels. | ||
|- | |-valign="top" | ||
| | |ResolutionWidth||integer||'''Does not work''' Video width in pixels. | ||
|-valign="top" | |||
|Sha1||string||AniDB SHA1 value. | |||
|-valign="top" | |||
|Size||int64||Size in bytes. | |||
|-valign="top" | |||
|State||integer||AniDB state bitmap. | |||
|-valign="top" | |||
|Source||string||Source media, possible values:<br> | |||
|- | unknown<br> | ||
| | camcorder<br> | ||
|- | TV<br> | ||
| | VHS<br> | ||
|- | DTV<br> | ||
|Version||integer|| | LD<br> | ||
|- | DVD<br> | ||
|GroupShort||string|| | SVCD<br> | ||
|- | VCD<br> | ||
|GroupLong||string|| | HKDVD<br> | ||
|- | www<br> | ||
HDTV<br> | |||
HD-DVD<br> | |||
Blu-ray | |||
|-valign="top" | |||
|TypeState||integer||Source ID. | |||
|-valign="top" | |||
|ResolutionString||string|| | |UserCount||integer||Number of users with this file. (Wildly inaccurate.) | ||
|-valign="top" | |||
|Version||integer||File version from state. | |||
|-valign="top" | |||
|GroupShort||string||Short group name. | |||
|-valign="top" | |||
|GroupLong||string||Long group name. | |||
|-valign="top" | |||
|ResolutionString||string||'''Does not work''' Video WidthxHeight. | |||
|} | |} | ||
===G / GROUP=== | ===G / GROUP=== | ||
{| | {| | ||
! scope="col" width="180" | Name | |||
! scope="col" width="60" | Type | |||
! scope="col" | Description | |||
|Name | |||
| | |||
| | |||
|- | |- | ||
| | |colspan="3"|''Warning, this object might be unassigned. If so all values return False.'' | ||
|- | |-valign="top" | ||
| | |Name||string||Group name. | ||
|- | |-valign="top" | ||
| | |Other||string||Group description. | ||
|- | |-valign="top" | ||
|Votes||integer|| | |Rating||integer||Average vote rating for this group. | ||
|-valign="top" | |||
|Shortname||string||Short group name. | |||
|-valign="top" | |||
|Votes||integer||Number of votes for this group. | |||
|} | |} | ||
===H / HASH=== | ===H / HASH=== | ||
{| | {| | ||
| | ! scope="col" width="180" | Name | ||
| | ! scope="col" width="60" | Type | ||
| | ! scope="col" | Description | ||
|- | |-valign="top" | ||
| | |colspan="3"|''Warning, this object might be unassigned. If so all values return False.'' | ||
|- | |-valign="top" | ||
| | |Crc32||string||AoM CRC32 value. | ||
|- | |-valign="top" | ||
| | |Ed2k||string||AoM ED2K value. | ||
|-valign="top" | |||
|Md5||string||AoM MD5 value. | |||
|-valign="top" | |||
|Sha1||string||AoM SHA1 value. | |||
|-valign="top" | |||
|Size||integer||AoM size in bytes. | |||
|- | |||
| | |||
|- | |||
| | |||
|- | |||
| | |||
|} | |} | ||
===M / MYLIST=== | ===M / MYLIST=== | ||
{| | {| | ||
| | ! scope="col" width="180" | Name | ||
|- | ! scope="col" width="60" | Type | ||
| | ! scope="col" | Description | ||
|- | |-valign="top" | ||
| | |colspan="3"|''Warning, this object might be unassigned. If so all values return False.'' | ||
|- | |-valign="top" | ||
| | |Other||string||Entry other/description text. | ||
|- | |-valign="top" | ||
| | |Source||string||Entry source text. | ||
|- | |-valign="top" | ||
| | |State||integer||Entry state, possible values:<br> | ||
|- | 0: unknown<br> | ||
| | 1: internal storage (hdd)<br> | ||
|- | 2: external storage (cd/dvd/...)<br> | ||
| | 3: deleted<br> | ||
|- | |-valign="top" | ||
| | |Storage||string||Entry storage text. | ||
|- | |-valign="top" | ||
| | |Watched||boolean||True if watched, otherwise false. | ||
|- | |-valign="top" | ||
| | |WatchedDate||integer||Watched date in unixtime. | ||
|} | |||
==Properties== | |||
{| | |||
|-valign=top | |||
|ACTIVEPATTERN||string||The current rename pattern after cleanup. | |||
|-valign=top | |||
|PATH||string||Current path to the file. May be ''. | |||
|-valign=top | |||
|BASEPATH||string||Base path of the current file manager. May be ''. | |||
|} | |} | ||
==Functions== | ==Functions== | ||
{| | {| | ||
! scope="col" | Function | |||
! scope="col" width="60" | Type | |||
! scope="col" | Description | |||
|-valign="top" | |||
|at(lang)||text||Returns a main/official anime title in '''lang'''. '''lang''' can be either a text or a number. <br>Example: at(2) = japanese title<br>Example: at('japanese (transcription)') = japanese transcription<br>Example: at('en') = english title | |||
|-valign="top" | |||
|atr(id, lang)||text||Returns a main/official anime title of anime with '''id''' in '''lang'''. '''lang''' can be either a text or a number. <br>Example: at(2) = japanese title<br>Example: at('japanese (transcription)') = japanese transcription<br>Example: at('en') = english title | |||
|-valign="top" | |||
|contains(find, text)||boolean||Returns true if '''find''' is found in '''text'''.<br>Example: contains('bcd', 'abcdef') = true | |contains(find, text)||boolean||Returns true if '''find''' is found in '''text'''.<br>Example: contains('bcd', 'abcdef') = true | ||
|- | |-valign="top" | ||
|copy(text, start[, length])|| | |copy(text, start[, length])||string||Returns '''length''' letters from letter number '''start''' of '''text'''.<br>Example: copy('abcdefgh', 3, 2) = 'cd' | ||
|- | |-valign="top" | ||
|et(lang)||text||Returns an episode title in '''lang'''. '''lang''' can be either a text or a number.<br>Example: et(2) = japanese title<br>Example: et('en') = english title | |||
|-valign="top" | |||
|etr(id, lang)||text||Returns an episode title of episode with '''id''' in '''lang'''. '''lang''' can be either a text or a number.<br>Example: et(2) = japanese title<br>Example: et('en') = english title | |||
|-valign="top" | |||
|for(name, start, end, task)||string||Runs '''task''' '''start''' to '''end''' times setting '''name''' to t1he current position each round.<br>Example: for('i', 1, 5, '?'+i) = '?1?2?3?4?5' | |||
|-valign="top" | |||
|function(name, stmt, stmt, ...)||string||Declares the function '''name''' which will execute stmt1, stmt2 etc. Parameters can be sent to function calls but there is only 1 GLOBAL scope.<br>Example: function('rreplace', set('temp', param1), for('i', 1, 10, set('temp', replace(temp, ' ', ' '))), temp)<br>rreplace(somevalue) | |||
|-valign="top" | |||
|getanime(name, id)||object||Sets the variable '''name''' to the anime object for '''id'''.<br>Example: getanime('a2', 78) | |||
|-valign="top" | |||
|getepisode(name, id)||object||Sets the variable '''name''' to the episode object for '''id'''.<br>Example: getepisode('e2', 8878) | |||
|-valign="top" | |||
|if(test, trueval[, falseval])||any||If statement, returns '''trueval''' if '''test''' is true, otherwise returns '''falseval'''.<br> Example: if(23=23, 'equal', 'not equal') = 'equal' | |if(test, trueval[, falseval])||any||If statement, returns '''trueval''' if '''test''' is true, otherwise returns '''falseval'''.<br> Example: if(23=23, 'equal', 'not equal') = 'equal' | ||
|- | |-valign="top" | ||
|in(find, text...)||boolean||Checks if '''find''' is present in a number of '''text''' parameters.<br>Example: in('bb', 'aa', 'bb', 'cc', 'dd') = true | |in(find, text...)||boolean||Checks if '''find''' is present in a number of '''text''' parameters.<br>Example: in('bb', 'aa', 'bb', 'cc', 'dd') = true | ||
|- | |-valign="top" | ||
|join(glue, text...)|| | |join(glue, text...)||string||Joins together two or more '''text'''s, empty parameters are ignored with no glue added.<br>Example: join(' ', 'a', 'b', 'c') = 'a b c' | ||
|- | |-valign="top" | ||
|lc(text)|| | |lc(text)||string||Converts '''text''' to lower case.<br>Example: lc('ABCDEF') = 'abcdef' | ||
|- | |-valign="top" | ||
|length(text)||number||Returns the length of '''text'''.<br>Example: length('abcdef') = 6 | |length(text)||number||Returns the length of '''text'''.<br>Example: length('abcdef') = 6 | ||
|- | |-valign="top" | ||
|limit(text, length[, end])|| | |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.<br>Example: limit(e, 100) or limit('abcdefghijklmnop', 7, '...') = 'abcd...' | ||
|- | |-valign="top" | ||
|max(number...)||number||Returns the highest supplied number<br>Example: max(1, 7, 3, 9, 2) = 9 | |||
|-valign="top" | |||
|min(number...)||number||Returns the lowest supplied number<br>Example: min(1, 7, 3, 9, 2) = 1 | |min(number...)||number||Returns the lowest supplied number<br>Example: min(1, 7, 3, 9, 2) = 1 | ||
|- | |-valign="top" | ||
| | |numeric(var)||boolean||Returns true if '''var''' contains a numeric value.<br>Example: numeric('11') = true | ||
|- | |-valign="top" | ||
| | |pad(text, newlength[, padchar])||string||Pads '''text''' on both sides to make it '''length''' characters long.<br>Example ?pad('hello', 9, '_') = '__hello__' | ||
|- | |-valign="top" | ||
| | |padl(text, newlength[, padchar])||string||Pads '''text''' on the left side to make it '''length''' characters long.<br>Example ?padl('hello', 9, '_') = '____hello' | ||
|- | |-valign="top" | ||
| | |padr(text, newlength[, padchar])||string||Pads '''text''' on the right side to make it '''length''' characters long.<br>Example ?padr('hello', 9, '_') = 'hello____' | ||
|- | |-valign="top" | ||
|sc(text)|| | |replace(text, find[, replace])||string||Replaces all occurences of '''find''' with '''replace''' in '''text'''.<br>Example: replace('HELLO THERE!', 'THERE', 'TREES') = 'HELLO TREES!' | ||
|- | |-valign="top" | ||
|replacei(text, find[, replace])||string||Case insensitive replace of all occurences of '''find''' with '''replace''' in '''text'''.<br>Example: replace('HELLO tHeRe!', 'ThErE', 'TREES') = 'HELLO TREES!' | |||
|-valign="top" | |||
|sc(text)||string||Converts '''text''' to sentence case.<br>Example: sc('HELLO THERE!') = 'Hello there!' | |||
|-valign="top" | |||
|set(name, data)||nothing||Declares a new variable called '''name''' containing '''data'''.<br>Example: set('temp', 'text') | |set(name, data)||nothing||Declares a new variable called '''name''' containing '''data'''.<br>Example: set('temp', 'text') | ||
|- | |-valign="top" | ||
|split(text, find, index)|| | |split(text, find, index)||string||Splits '''text''' on '''find''' and returns the specified '''index'''. Index starts from 1.<br>Example: split('2011-05-19', '-', 2) = 05 | ||
|- | |-valign="top" | ||
|start(text, find)||boolean||Checks if '''find''' matches the start of '''text'''.<br>Example: start('1999', '199') = true | |start(text, find)||boolean||Checks if '''find''' matches the start of '''text'''.<br>Example: start('1999', '199') = true | ||
|- | |-valign="top" | ||
|tc(text)|| | |starti(text, find)||boolean||Checks if '''find''' matches the start of '''text'''. Case insensitive.<br>Example: start('1999', '199') = true | ||
|- | |-valign="top" | ||
|uc(text)|| | |substr(text, start[, length])||string||Alias for copy. | ||
|-valign="top" | |||
|tc(text)||string||Converts '''text''' to title case.<br>Example: tc('HELLO THERE!') = 'Hello There!' | |||
|-valign="top" | |||
|trim(text)||string||Removes leading and trailing spaces from '''text'''. | |||
|-valign="top" | |||
|uc(text)||string||Converts '''text''' to upper case.<br>Example: uc('abcd') = 'ABCD' | |||
|} | |} | ||
Line 360: | Line 511: | ||
|A>=B||true if A is more 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 and B||true if both A and B are true | ||
Line 371: | Line 522: | ||
|} | |} | ||
== | ==Constant expressions== | ||
There are two ways to specify string literals:<br> | |||
'text'<br> | |||
or<br> | |||
"text" | |||
Number literals are simply written as numbers:<br> | |||
1234<br> | |||
<br> | |||
There are also boolean constants:<br> | |||
true<br> | |||
false | |||
== | ==Comments== | ||
Start a line with // if you wish to write a comment:<br> | |||
<pre>// This is a comment</pre> | |||
== | ==File managers== | ||
File managers are used to automatically manage file renaming / removing and adding / updating files in your MyList. | |||
Latest revision as of 17:35, 3 February 2019
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 patterns
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'))) if(length(etitle)=0, set('etitle', E.Name))
Japanese transcription episode title with fallback
set('etitle', et('x-jat')) if(length(etitle)=0, set('etitle', et('en'))) if(length(etitle)=0, set('etitle', E.Name))
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'))) if(length(etitle)=0, set('etitle', E.Name))
File version and censor flag
set('censored', 'unknown') set('version', F.Version) set('state_map', F.State mod 4096) if(state_map>=2048, set('version', 9) + set('state_map', state_map - 2048)) if(state_map>=1024, if(version<9,set('version', 8)) + set('state_map', state_map - 1024)) if(state_map>=512, if(version<9,set('version', 7)) + set('state_map', state_map - 512)) if(state_map>=256, if(version<9,set('version', 6)) + set('state_map', state_map - 256)) if(state_map>=128, set('censored', 'yes') + set('state_map', state_map - 128)) if(state_map>=64, set('censored', 'no') + set('state_map', state_map - 64)) set('version', if(version>1, 'v'+F.Version, '')) set('censored',if(censored='yes','[Censored]',''))
Padded episode number
set('mepno', if(E.TypeId=1, max(A.TotalEpisodeCount, E.EpisodeTypeCount), 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(G, if(length(G.Name)>0, G.Name, G.Shortname), 'no group')) set('groupname', if(length(groupname)>0, '['+groupname+']'))
Group short name
set('groupname', if(G, if(length(G.Shortname)>0, G.Shortname, G.Name), 'no group')) set('groupname', if(length(groupname)>0, '['+groupname+']'))
CRC32
set('crc', if(H, H.Crc32, F.Crc)) if(length(crc)>0, set('crc', '('+uc(crc)+')')
Current filename (removing the path)
set('path_filename', PATH) set('path_parts', 1) for('i', 1, length(path_filename), if(copy(path_filename, i, 1) = '\', set('path_parts', path_parts+1))) set('path_filename', split(path_filename, '\', path_parts))
Complex samples
Default pattern
ATTENTION! The default pattern has a bug. See below for instructions to fix it.
set('atitle', at('x-jat')) if(length(atitle)=0, set('atitle', at('en'))) if(length(atitle)=0, set('atitle', A.Name)) set('atitle', replace(atitle, '\', ' ')) set('etitle', et('en')) if(length(etitle)=0, set('etitle', et('x-jat'))) if(length(etitle)=0, set('etitle', et('ja'))) if(length(etitle)=0, set('etitle', E.Name)) set('etitle', replace(etitle, '\', ' ')) 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('groupname', if(G, if(length(G.Shortname)>0, G.Shortname, G.Name), 'no group')) set('groupname', if(length(groupname)>0, '['+groupname+']')) set('groupname', replace(groupname, '\', ' ')) set('crc', if(H, H.Crc32, F.Crc)) if(length(crc)>0, set('crc', '('+uc(crc)+')')) set('filename', limit(limit(limit(atitle, 90) + ' - ' + epno + ' - ' + etitle, 200) + ' ' + groupname, 235) + crc + '.' + F.FileType) set('filename', replace(filename, '*', ' ')) set('filename', replace(filename, '/', ' ')) set('filename', replace(filename, '?', ' ')) set('filename', replace(filename, ':', ' ')) set('filename', replace(filename, '"', ' ')) set('filename', replace(filename, '<', ' ')) set('filename', replace(filename, '>', ' ')) set('filename', replace(filename, '|', ' ')) set('filename', replace(filename, '`', "'")) set('filename', replace(filename, ' ', ' ')) filename
ATTENTION! The default pattern has a bug. To fix it, find the following line:
set('mepno', max(A.TotalEpisodeCount, E.EpisodeTypeCount))
And replace it with:
set('mepno', if(E.TypeId=1, max(A.TotalEpisodeCount, E.EpisodeTypeCount), E.EpisodeTypeCount))
Objects
A / ANIME
Name | Type | Description |
---|---|---|
Category | integer | Anime Type 1: Unknown |
CategoryStr | string | Category text value. |
Name | string | Anime main title |
ReviewAverage | integer | Average review score |
ReviewCount | integer | Total number of reviews |
TotalEpisodeCount | integer | Number of episodes according to AniDB. 0 if unknown. |
VoteAverage | integer | Average voter score |
VoteCount | integer | Total number of votes |
Year | string | Anime airing year(s). For example 2007-2008. |
EpisodeCount | integer | Number of normal episodes according to AoM. |
SpecialEpisodeCount | integer | Number of special episodes according to AoM. |
DownloadState | String | Current download state according to AoM: adsIgnore: not yet calculated |
WatchedState | string | Current watched state according to AoM: awsIgnore: not yet calculated |
StatusState | string | Current status of mylist entries according to AoM, my contain multiple values separated by commas: assIgnore: not yet calculated |
StartYear | integer | Numeric start year from AirDate. |
EndYear | integer | Numeric end year from EndDate. |
AirDate | integer | Air date in unix time, AniDB format. |
EndDate | integer | End date in unix time, AniDB format. |
Restricted | boolean | Unreliable True for hentai, otherwise false. |
MylistCurrentEpisodeCount | integer | Number of episodes in mylist. |
MylistSpecialEpisodeCount | integer | Number of special episodes in mylist. |
WatchedCount | integer | Number of episodes watched. |
SpecialWatchedCount | integer | Number of special episodes watched. |
E / EPISODE
Name | Type | Description |
---|---|---|
AirDate | integer | Episode first air date. |
EpisodeNo | integer | AniDB episode number. |
EpisodeStr | string | Episode number with type prefix. |
EpisodeStrPadded | string | Episode number with type prefix padded based on the total number of episodes of that particular type. |
EpisodeTypeCount | integer | Number of episodes in this anime with the same type. |
IsSpecial | boolean | True if not a normal episode. False otherwise. |
Length | integer | Length in minutes. |
Name | string | AniDB main title. |
Other | string | Description field from AniDB. |
TypeId | integer | Episode type: 1: Regular Episode |
IsRecap | boolean | True if episode is a recap. |
F / FILE
Name | Type | Description |
---|---|---|
Crc | string | AniDB CRC32 value. |
CrcStatus | string | CRC32 status according to AnIDB: crcUnknown: unkwnown |
Ed2k | string | AniDB ED2K value. |
EpisodeStart | integer | Lowest related episode number of the same type within this anime. |
EpisodeEnd | integer | Highest related episode number of the same type within this anime. |
EpisodeList | string | List of episodes within this anime covered by this file. Format: 1,2,3,7,17,93,O1,C3,U77 |
EpisodeListDetails | string | Detailed list of episodes covered by this file. Format: (EpisodeStr:EpisodeTypeId:AnimeId:EpisodeId:StartPercent:EndPercent) Example: 1:1:357:95304:0:10,2:1:357:95960:0:100,6:1:357:108200:0:100,C1:3:357:108202:0:100 |
FileType | string | File extension. |
Length | integer | File length in seconds. |
Md5 | string | AniDB MD5 value. |
Other | string | File description. |
Quality | integer | File quality, possible values: unknown |
Released | integer | Release date in unix time. |
ResolutionHeight | integer | Does not work Video height in pixels. |
ResolutionWidth | integer | Does not work Video width in pixels. |
Sha1 | string | AniDB SHA1 value. |
Size | int64 | Size in bytes. |
State | integer | AniDB state bitmap. |
Source | string | Source media, possible values: unknown |
TypeState | integer | Source ID. |
UserCount | integer | Number of users with this file. (Wildly inaccurate.) |
Version | integer | File version from state. |
GroupShort | string | Short group name. |
GroupLong | string | Long group name. |
ResolutionString | string | Does not work Video WidthxHeight. |
G / GROUP
Name | Type | Description |
---|---|---|
Warning, this object might be unassigned. If so all values return False. | ||
Name | string | Group name. |
Other | string | Group description. |
Rating | integer | Average vote rating for this group. |
Shortname | string | Short group name. |
Votes | integer | Number of votes for this group. |
H / HASH
Name | Type | Description |
---|---|---|
Warning, this object might be unassigned. If so all values return False. | ||
Crc32 | string | AoM CRC32 value. |
Ed2k | string | AoM ED2K value. |
Md5 | string | AoM MD5 value. |
Sha1 | string | AoM SHA1 value. |
Size | integer | AoM size in bytes. |
M / MYLIST
Name | Type | Description |
---|---|---|
Warning, this object might be unassigned. If so all values return False. | ||
Other | string | Entry other/description text. |
Source | string | Entry source text. |
State | integer | Entry state, possible values: 0: unknown |
Storage | string | Entry storage text. |
Watched | boolean | True if watched, otherwise false. |
WatchedDate | integer | Watched date in unixtime. |
Properties
ACTIVEPATTERN | string | The current rename pattern after cleanup. |
PATH | string | Current path to the file. May be . |
BASEPATH | string | Base path of the current file manager. May be . |
Functions
Function | Type | Description |
---|---|---|
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 |
atr(id, lang) | text | Returns a main/official anime title of anime with id 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 |
etr(id, lang) | text | Returns an episode title of episode with id in lang. lang can be either a text or a number. Example: et(2) = japanese title Example: et('en') = english title |
for(name, start, end, task) | string | Runs task start to end times setting name to t1he current position each round. Example: for('i', 1, 5, '?'+i) = '?1?2?3?4?5' |
function(name, stmt, stmt, ...) | string | Declares the function name which will execute stmt1, stmt2 etc. Parameters can be sent to function calls but there is only 1 GLOBAL scope. Example: function('rreplace', set('temp', param1), for('i', 1, 10, set('temp', replace(temp, ' ', ' '))), temp) rreplace(somevalue) |
getanime(name, id) | object | Sets the variable name to the anime object for id. Example: getanime('a2', 78) |
getepisode(name, id) | object | Sets the variable name to the episode object for id. Example: getepisode('e2', 8878) |
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 |
starti(text, find) | boolean | Checks if find matches the start of text. Case insensitive. 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!' |
trim(text) | string | Removes leading and trailing spaces from text. |
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'
or
"text"
Number literals are simply written as numbers:
1234
There are also boolean constants:
true
false
Comments
Start a line with // if you wish to write a comment:
// This is a comment
File managers
File managers are used to automatically manage file renaming / removing and adding / updating files in your MyList.