Problem adding year to path only if year tag exists

Hey everyone.

I created the following action, but when I run it on some test files, the files are not structured into directories, or renamed. Some of the files have the year tag and some do not. I'm sure I've made an error in the scripting syntax or the nesting of the script, but I'm just not seeing it. Would anyone be able to help me out?

FORMAT TAG FIELD
FIELD: _FILENAME
FORMAT: /$if2(%albumartist%,%artist%)/%album% $if([%year],$left(%year%,4),)/[$num(%discnumber%,2)_]$num(%track%,2) %title%
FILE: 
FILENAME: ~/Desktop/Testing/Song of Storms.mp3
YEAR: 2013-11-10
ALBUM ARTIST: BLAKE

My intent is to change the filename to...

~/Desktop/Testing/BLAKE 2013/Song of Storms.mp3

If a file does not have a year tag, then I want the same structure, but the space and file name in the parent directory name. Any idea what I'm doing wrong?

Try
%album%[ $num(%year%,4)]
instead

Thanks! That resolved it. Here is my working script for anyone else in need.

FORMAT TAG FIELD
FIELD: _FILENAME
FORMAT: $if2(%albumartist%,%artist%)/%album%[ $num(%year%,4)]/[$num(%discnumber%,2)_]$num(%track%,2) %title%

With that said, now I'm having an issue with the next action in the same action group and I'm stumped on this one too. Here are the actions:


Format tag field "TRACK": $if ([%TRACK%], $num(%TRACK%,2),)

Format tag field "_FILENAME": /$if2(%albumartist%,%artist%)/%album%[ $num(%year%,4)]/[$num(%discnumber%,2)_]$num(%track%,2) %title%

Format tag field "_DIRECTORY": /Volumes/Samsung 860 1TB SSD/3. Organized/$if2(%albumartist%,%artist%)/%album%/

The goal is to rename the files with the above action, then move the entire parent directory and all files (including, images, video, documents, etc.) to a new grandparent directory while keeping the folder structure. For example, here are some files before running the action group:

/Volumes/Samsung 860 1TB SSD/1. Unsorted/James Horner/Braveheart/abc.mp3
/Volumes/Samsung 860 1TB SSD/1. Unsorted/James Horner/Braveheart/art.jpg
/Volumes/Samsung 860 1TB SSD/1. Unsorted/James Horner/Braveheart/braveOST.mp3
/Volumes/Samsung 860 1TB SSD/1. Unsorted/James Horner/Braveheart/notes.pdf
/Volumes/Samsung 860 1TB SSD/1. Unsorted/James Horner/Braveheart/song1.mp3

After running the action group I expect to get:

/Volumes/Samsung 860 1TB SSD/3. Organized/James Horner/Braveheart_ Original Motion Picture Soundtrack 1995/01_02 A Gift of a Thistle.flac
/Volumes/Samsung 860 1TB SSD/3. Organized/James Horner/Braveheart_ Original Motion Picture Soundtrack 1995/01_03 Wallace Courts Murron.flac
/Volumes/Samsung 860 1TB SSD/3. Organized/James Horner/Braveheart_ Original Motion Picture Soundtrack 1995/01_04 The Secret Wedding.flac
/Volumes/Samsung 860 1TB SSD/3. Organized/James Horner/Braveheart_ Original Motion Picture Soundtrack 1995/art.jpg
/Volumes/Samsung 860 1TB SSD/3. Organized/James Horner/Braveheart_ Original Motion Picture Soundtrack 1995/notes.pdf

Instead, when the selected files are moved to the destination, all of the other directories at the destination are moved into the album folder of the selected files and the selected files are not moved at all. So, this would the end result of my example:

/Volumes/Samsung 860 1TB SSD/3. Organized/James Horner/Braveheart_ Original Motion Picture Soundtrack 1995/Yu Takami/Album 1/
/Volumes/Samsung 860 1TB SSD/3. Organized/James Horner/Braveheart_ Original Motion Picture Soundtrack 1995/Yugo Kanno/Album 2/
/Volumes/Samsung 860 1TB SSD/3. Organized/James Horner/Braveheart_ Original Motion Picture Soundtrack 1995/Yuki Hayashi/Album 3/

I'm guessing it must be something I've done wrong with the $if2 condition in the third action, but I haven't figured it out. Does anyone see my mistake?

Does it work if you execute the 3rd step separate from the other 2?

It sort of works, but not really. If I run Format tag field "_DIRECTORY": /Volumes/Samsung 860 1TB SSD/3. Organized/$if2(%albumartist%,%artist%)/%album%/ or /Volumes/Samsung 860 1TB SSD/3. Organized/albumartist%/%album%/ the files move to the root of the destination without any folder structure. It seems to be ignoring /%albumartist%/%album%/.

As an experiment, I also tried running it without the final /, but the result didn't change. I did verify that the album and albumartist tags exist on those test tracks.

Any other ideas?

EDIT: Reading this again, didn't seem as clear as I intended. I meant that when I run it the individual songs move to Volumes/Samsung 860 1TB SSD/3. Organized/, but not into their own /%albumartist%/%album%/ under the 3. Organized directory. And I meant that I tried with and without the final / in Volumes/Samsung 860 1TB SSD/3. Organized/ and /Volumes/Samsung 860 1TB SSD/3. Organized/albumartist%/%album%/ and /Volumes/Samsung 860 1TB SSD/3. Organized/$if2(%albumartist%,%artist%)/%album%/ and it seemed to have no impact at all.

You can test a format string in Convert>Tag-Tag.
There you could check what the result of

would be

Just getting back to this. Thanks for the suggestion. How would I test setting the "_DIRECTORY" using the Tag-Tag converter? %_directory% isn't a valid place holder I can choose in that converter. This is the Mac version of Mp3Tag in case that's a difference with the Windows version. I haven't used the Windows version in so long I don't recall.

Actually, for testing - which means that you see a possible result in the preview - it is not even necessary to select the correct field or property.

If you are asked to select a field from a list and the name is not already there, then simply type it in. Fieldnames as a target field from a list never have the % characters, so it would simply be
_DIRECTORY

The _DIRECTORY field (as well as _FILENAME) is not available at Convert → Tag - Tag, but you can simply check via Convert → Tag - Filename if the format string of your third action is producing the desired output.


Going over all posts in this topic, I'm not sure if all examples describe what's really going on. What's important to understand is that an action Format tag field for _DIRECTORY renames the directory of the file.

So if you even have only one file in the root directory
/Volumes/Samsung 860 1TB SSD/1. Unsorted/
it'll rename the folder 1. Unsorted according to the format string you provide and, thus, move all files and folders that were below 1. Unsorted to the new artist- and album-specific destination.

Thanks Gentlemen. I was overthinking the whole preview concept. When @ohrenkino mentioned the "preview" function I wasn't thinking about the literal preview that is shown in the converter so we can validate our format string, I was thinking doing a test execution of the action. I also didn't realize I could use fields incompatible with the converter and still get a valid preview.

I did test the _FILENAME and _DIRECTORY format strings and both returned the result I expected in the preview. I then ran them individually use the FORMAT TAG FIELD Quick Action, and once again they worked as expected. I then tried running them as the only two actions in an Action Group, but here I encountered error messages with the directory rename as seen in the screenshots below. If I'm understanding Florian correctly, this seems to be an issue of the directory being renamed to the albumartist (or artist depending on tags) and then attempting to rename that same directory to album? My intention was to ensure that the directory is moved to the absolute path specified, then renamed to albumartist, or artist if albumartist does not exist, then a subdirectory with the album name. I had this action group working as expected before I added the if2 statement to try to account for missing albumartist with the backup option of the artist, but I must have modified something else without realizing it.

Below are screenshots with descriptive names of the steps I took to reproduce. I deliberately modified the filename of one of the tracks before running the action group for testing. That the file referenced in the second error message. The file name was changed by the first action in the group, so when this second action ran it could no longer find the file as it had been renamed?



3. Directory rename error

Unfortunately, I can't reproduce the error here. Can you show the original file structure (maybe in Mp3tag's File List), the actions applied, the produced error, and the resulting file structure?

I'm having mixed results now in my testing. It sometimes seems to work as intended. So maybe this comes down to having a file at the root level like you mentioned in your earlier message. I ran another test and took screenshots in sequence of the events as seen below.

EDIT: I think I just realized the issue. I was assuming that the first action (_FILENAME changes) in the Action Group was running on the entire batch before the second action (_DIRECTORY) changes, but instead the whole action group is running on each file one at a time, and then running on the next file until it loops through the group, right? To my thinking, the filename changes were ensuring that there wouldn't be any audio files sitting at the root level as they would now be within an albumartist/album/track structure, but instead each of those root level items was moving the entire contents of the Test folder each time the next file was renamed. This caused some of the next audio files in the list in Mp3Tag to be moved before they were processed and so Mp3Tag through the error. So I think I just need to run the _FILENAME action separately on all tracks so that they are all within some kind of subfolder structure at a minimum, before the _DIRECTORY action runs.

Does that sound right and make sense of the results?







Yes, and changing the directory of one file also affects all the other files in the directory. This makes it difficult at times to reason about what's actually happening.

This is the way. I now also understand why you were replicating the creation of the directory structure in the _FILENAME action.

Thanks for confirming. So now that I understand the cause of the issue, is there some way to execute the filename action on the entire file group, and then the directory action on the entire file group, with a single input from me? I have a keyboard shortcut assigned to that action group, so it is incredibly helpful to my workflow when I can just launch that single command and do everything I want with the files and move on to the new group of files. So I'm trying to figure out how to keep it a single step process instead of needing to manually select two separate actions each time.

EDIT: To clarify, I mean is there an option to keep it a single step process within Mp3Tag. Action groups aren't an option due to causing the issues in this thread, and it seems that an action Category behaves the same way (running all actions on each individual file before the next action is executed).

Not on such a mixed batch of files and folders. I'd use this feature only on files that are on the same level in the directory tree and which would produce a consistent target directory for the sets of files that belong together.

I just realized that even if I tried, I'd be losing the non-audio contents in the directory after running the filename action, at least for directories that have such extra contents. So I can run the action group on a structure like:

 Drive/Music/Unsorted/Artist/Album/track1.mp3
 Drive/Music/Unsorted/Artist/Album/track2.mp3
 Drive/Music/Unsorted/Artist/Album2/track1.mp3
 Drive/Music/Unsorted/Artist/Album3/track1.mp3
 Drive/Music/Unsorted/Artist/Album3/Artwork/cover.jpg

However, there isn't a single action group option for:

 Drive/Music/Unsorted/Artist//track1.mp3
 Drive/Music/Unsorted/Artist/Album/track2.mp3
 Drive/Music/Unsorted/Artist/Album2/track1.mp3
 Drive/Music/Unsorted/Artist/Album3/Disc1/track1.mp3
 Drive/Music/Unsorted/Artist/Artwork/track12.mp3
 Drive/Music/Unsorted/Miscellaneous/Artist/Album3/Disc1/track1.mp3

That's correct as far as I know. I've been using an action group to create my target directory structure for a while now. The first Format value action uses _DIRECTORY to rename the folder containing the songs, thusly moving along any logs, artwork files etc. within the source folder, followed up by an action that changes the _FILENAME of the songs to rename the songs themselves.
As you've found that only works when everything you want to move along is contained in the source folder and also only if one source folder should result in one target folder.
It won't move along separate artwork folders one level up, and it also won't work properly if you for example have the contents of 2 different albums in the same folder before running the action. It will in those cases move everything to a target folder based on one of the albums.

I handle these limitations by going through the source folders once and separating everything that will end up separated anyways in temporary folders. Since my actions move the finished files to a different location, afterwards I check if the source folders are empty (artwork folders one level up often stay behind) and move these to the new directory structure manually.
Once you know what you need to look for prior to editing that step doesn't take much time at all.

It's not perfect but very efficient. For example if you like to have double CD albums split per disc but the source folder contains the tracks of both discs, plus artwork, logs for disc 1 and disc 2 etc., how would any action know which of these non music files should go into which target directory?
I mean you could probably script it if you knew the names of all files ahead of time but that would take far more time than simply creating 2 new temporary folders (I often name them CD1 and CD2), moving everything that belongs to disc 1 into CD1 and doing the same for disc 2 and CD2. After that, the action group in mp3tag renames both the folders and files perfectly.

Here are the actions in my group btw. in case you're curious.
Format value:
Field:
_DIRECTORY
Format string:

D:\rips\beets\$validate($regexp(%albumartist%,'^([^;]+)(;\s)?([^;]+)(?:.*)',$1$2$3),-)\$validate(%album%,-)

Format value:
Field:
_FILENAME
Format string:

$num(%track%,2) $validate($regexp(%title%,^(.{90})(.*),$1..),-)

The rule of thumb is:
if the folders have to be added when distributing the files across the file system, then every _FILENAME has to treated.
If the number of folders stays the same or can be decreased then the _DIRECTORY can be renamed.
The _DIRECTORY also has to be renamed if auxiliary files should get moved along.

Thanks for sharing your workflow. My issue is that I'm working on about a 100k files and hundreds to thousands of folders. I've been chipping away at it for a few years. Right now I have a fairly solid workflow with Picard doing the initial sorting and tagging, then using a few deduplication apps, then using Mp3Tag to do additional tagging and cleanup (like exporting resizing artwork), as well as using using Hazel to remove empty folders, apply file system tags, and some other repetitive tasks.

So, I'm just trying to automate as much as I can, but there are lots of edge cases as my library has a lot of indie music and foreign language releases with very inconsistent tagging from the source and often confusing duplication or variety of releases, on top of several false starts at organizing the whole collection over the years that has resulted in even more duplication and variety of directory structures and such.

So getting everything tagged, then getting the _FILENAME convention and structure in place is the most critical. The _DIRECTORY action is important for gathering the related files that aren't the music. Currently I'm moving everything into a structure of:

$if2(%albumartist%,%artist%)/%album%['['$num(%year%,4)']']/[$num(%discnumber%,2)_]$num(%track%,2) %title%

Mp3Tag exports album art with the name of the album, resolution of the artwork, and the keyword "cover" in the filename.

Then Hazel sorts the non-audio files into Covers, Images, Videos, or Notes (and will create those folders as needed) and will delete any empty folders left behind such as an "artwork" folder. Covers is for any image with cover in the file name, Images is for all other image files, Videos for all videos, and Notes for all for documents from PDFs to PowerPoints. n all images with cover in the name into a Covers folder at the root of the album, sorts all other image into Images, all videos into Videos and all other documents like PDF, TXT, PowerPoint, .docs, and so on, into Notes.

@ohrenkino Understood. My intent in using _DIRECTORY is for moving the associated non-audio files with the music as it is organized.

While I'm at it, any suggestions on how to tweak this action to add additional padding to tracks if the track number is higher than 99, or even 999? I can put this in a new thread if need be, but this is the first action I run before running the _FILENAME action.

$if([%TRACK%],$num(%TRACK%,2),)

This works well the vast majority of my files, but I have a few albums with more than 100 tracks and one or two "albums" with more than 1000. It would be nice to account for those edge cases in the same action so I don't have to be concerned I'll forget and accidentally convert them all to two integer tracks.

The $num() function does 2 things: convert any string in to a number (and be it that it gets a value of 0) and then adds padding according to the given additional number or digits.
So, $num(1000,2) does not convert the 1000 to 10 but leaves it as it is at 1000 as no additional leading zeros have to be added.

The expression

could be shortened to
[$num(%track%,2)]
as the square brackets serve as an $if() for fields
See the documentation about the characters with special functionality: