Run python script as tool?

I've written a python script that takes a folderpath as parameter and then renames that folder based on what is in the folder.
If it's only mp3s all with the same bitrate it appends [MP3 320] for example.
If it's a mixed bag with varied bitrates it appends the min and max bitrate, like [MP3 156-256].
If it's mp3s + flacs it appends the file types + average bitrate of the mp3s, like [FLAC+MP3 156].
etc. etc.
Now I'm trying to implement this in mp3tag as a tool.

However it simply does not execute and I'm unsure why.

I tried adding my script as the "Path" in the tool and then using "$cutRight(%_folderpath%,1)" as the "Parameter" (since mp3-tag returns D:\rips\Ragnarök\3 Signs\ for %_folderpath% and my script expects "D:\rips\Ragnarök\3 Signs").
However that does nothing.

I also tried adding python.exe as the "Path" in the tool and then using the path to my script as the first parameter and "$cutRight(%_folderpath%,1)" as the second parameter. That opens a console window for the fraction of a second before closing again.

I even tried a workaround by calling cmd.exe as the "Path" in the tool and giving that python "path-to-my-script" "$cutRight(%_folderpath%,1) as parameters, which simply opens a cmd window at the folder from which it was called.

What I also tried was using my script as the "Path" in the tool and simply hardcoding a known working directory name as the "Parameter". Which also did nothing.

In a cmd window I can execute my script simply by name "C:\path\to\" "C:\path\to\folder"
or via python "C:\path\to\" "C:\path\to\folder".
Both work.

As usual any help is appreciated.

This is what an example of a tool call looks like:

Perhaps you have to experiment a little with the " around the path variable.

I already have 5 other working tools so I'm fairly familiar with how they work.

I've verified that "$cutRight(%_folderpath%,1)" returns what my script expects by testing it in a "Format Value" action that overwrites the COMMENT field for my test file with "$cutRight(%_folderpath%,1)", which in my example yields:
exactly what my script expects as the parameter and what I tested to be working in a cmd window.
Calling my script like this works and renames the directory.
However the tool version in mp3tag does nothing:

The easiest way to debug the error is to use a (temporary) CMD file.

Call a TempBatchFile.cmd with the path and then have a look what exactly do you get in this batch file by ECHO %1 from inside the batch file to see what you get passed from Mp3tag.

It could be that the call of from Mp3tag does not use the underlying python environment. In a batch file you could easy start it with
C:\PathToPython\python.exe D:\rips\_IN\ %1

And you could try to use the current parameter without double quotes, just

1 Like

What I expected.

Doesn't work either.

That is very curious. A cmd window opens and executes up to the point where it's supposed to rename the folder, which fails with a permission error:

PermissionError: [WinError 32] Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird: 'D:\\rips\\Ragnarök\\3 Signs' -> 'D:\\rips\\Ragnarök\\3 Signs [MP3 320]'

However the only thing accessing the folder is the script itself or rather the cmd window.

I've reproduced that error by first navigating to the album folder in cmd and then running the script from there. Can I call cmd from another directory or navigate out of the folder of the album before executing the script?

All of this doesn't answer why I can't run my script directly from within mp3tag tho. Using a batch file to call it seems like a crutch.

Thanks for your help so far tho, very insightful!

In a CMD file you can do whatever you like :wink:, including a simple CD\ to change to the root directory of the current drive or even change the drive with C: or D:.

If the directory change solves your permission error, I would use it like that in CMD file.
I don't know how to achieve the same in the PATH or PARAMETER of Mp3tag tool definition.

Just to be sure:

The double backslashes are the usual syntax from python to separate directories?
Or could this also be a problem?

And you don't use some kind of synchronization into a cloud where such a process could block the rename process?

1 Like

As I have no idea about python, I just assume you use something like this to rename an entire folder:

I've added
at the top of the batch file and now my script works.

That is the usual syntax, yes.

That's a pity.

Nah, all local files.

Indeed, os.rename(directory, os.path.join(os.path.dirname(directory), new_name)) within my script to be exact.

Thanks a lot!

I'd still be interested to learn how I can execute my script directly instead of via a batch file tho.

Just a wild guess:
What if you try something like
C:\PathToPython\python.exe D:\rips\_IN\
in your Mp3tag-Tool-PATH
as Mp3tag-Tool-PARAMETER?

Maybe you can change your current path inside your python script with an equivalent of CD.. ?

I can't edit the path within mp3tag like that. I can only browse to one specific executable.

My script does not care from where it is executed, mp3tag must run cmd from the album folder. All my script does is take a folderpath parameter, analyze the files within that folder and rename it as a last step, it does not change directories itself nor does it care from where it is called (unless it's called from the folder which it tries to rename -the album folder-, which fails because that folder is in use).

If MP3tag is required for all this, then a different approach could be worthwhile:
Let your script create a text file in each folder
Import the contents of the text file into each file with an action of the type

and import the data into a user-defined field, e.g. FUTURE_PATH
run an action of the type "Format value" for _DIRECTORY to rename the current folder with the contents of the FUTURE_PATH
Remove FUTURE_PATH afterwards.

Before I created the script I did the same (with fewer features) via 2 mp3tag actions, 1 exporting the bitrate information of all files in a folder to a temporary text file and calculating the average bitrate and then (since mp3tag can't write to and read from the same file in the same action), a second action that imports the thusly created value from the temporary text file to a temporary tag, renames the folder based on that tag and removes the tag afterwards.
However I hate having to run 2 actions to achieve 1 thing and my script offers far more functionality than the solution I realized within mp3tag. This approach also creates a junk text file. None of which is necessary.

I've tinkered with my script a bit more and now it does a few things:

  1. Checks if a folder contains mp3, m4a and/or flac files (could be extended to include more formats but I hardly ever use other formats).
  2. If the folder only contains flac files or neither flac, mp3 or m4a files, the script exits.
  3. Gets the bitrates of each mp3/m4a file via a call to exiftool and stores the values in a list.
  4. Calculates average, minimal and maximal bitrate for the mp3/m4a files in the folder.
  5. If the folder only contains mp3 or only m4a files and average bitrate = min bitrate or max bitrate, it renames the folder by appending " [MP3 bitrate]" or " [M4A bitrate]".
  6. If the folder contains only mp3 or only m4a files and average bitrate is not equal to min bitrate or max bitrate, it renames the folder by appending " [MP3 min bitrate-max bitrate]" or " [M4A min bitrate-max bitrate]".
  7. If the folder contains a mix of flac and mp3 or flac and m4a files it appends " [FLAC+MP3 average bitrate]" or " [FLAC+M4A average bitrate]"
  8. It also prevents appending that information multiple times by trimming the current folder name via a regular expression before appending the new information. That allows multiple consecutive runs of the script without errors. It also allows an easy adjustment should the contents of the folder change. If for example an album that so far consisted of variable bitrate mp3s with bitrates ranging from 156-256kbit/s, resulting in " [MP3 156-256]" is replaced with mp3 files of a constant bitrate of 320kbit/s, rerunning the script will change " [MP3 156-256]" to " [MP3 320]".
  9. As a last step the script adds the renamed folder back to mp3tag via an external command line call. This leads to the album showing up in mp3tag twice until the user refreshes in mp3tag, then the duplicate entries vanish and only the folder with the new name remains in mp3tag.

My script achieves all this without creating temporary text documents or temporary tags, in a single call as an mp3tag tool. And since python is (at least for me) for more readable and easier to write than the scripting within mp3tag, for me my script is far easier to expand/extend.

The initial question was "Run python script as tool".
There have been a couple suggestions from the community and some doubts.
So: has your problem been solved and if yes, how?

Yes and no.

I am able to run my python script as a tool from within mp3tag. However, not directly. I added a .bat file to mp3tag as a tool like this:

That batch file changes out of the album directory to avoid a permission error preventing the script from renaming the folder. It then calls the python.exe and my script directly via full paths and also adds the parameter given by mp3tag, which is the full path to the album folder.

"C:\Users\User\AppData\Local\Programs\Python\Python311\python.exe" "D:\rips\_IN\" %1

This was basically the solution.

However I was hoping that someone knew how to avoid the workaround of calling my script via a batch file instead of directly calling it. Which is why I haven't marked that post as the solution yet.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.