Great software! - Quick question though *Automated file moving


#1

I’ve been looking for a replacement for MusicBrainz - as that GUI can only handle about 20 - 30 albums at once before crashing and burning in the sand. I’m also a fan of command driven software so it’s easier to throw in a batch / automation script.

This software fits the bill PERFECTLY.

I do have a quick question about the auto tagging/ file moving, and I haven’t been able to find any good write-ups that go over the same issue. The software is able to tag and move everything great, but when an artist features another singer, the software creates a folder such as this: “original artist featuring secondary artist”.

It moves the mp3 into the new folder, so everything is great. Except, how do I make it so it stops adding the “featuring secondary artist” stuff to the folder name? i.e. Moving into the folder based solely on the primary artist?

. . . Also, I love the walkthrough you guys put together on how to get it up and running, but it would be helpful to include some sample config files. I do understand why you don’t include them though, as a million users could potentially cry in agony when the rules are applied wrongly on their music directory than they were expecting. Forcing them to read the documentation and build their own cfg, it means any errors in processing is on their own hands. - Just saying it would be nice to see a few more examples on the cfg file to base references on.

Please ignore the criticism, this software is the perfect solution.


#2

Hi! You might want to try the ftintitle plugin.

As for config examples, I have noticed people like sharing their configurations. Maybe a thread on here for that kind of exchange would be useful.


#3

Fast forward almost 2 years, browsing these forums again, and I just realized I never thanked you for the answer you provided.

Thanks for all the hard work. I still use this software extensively as it actually makes management of these massive libraries manageable. - For the original question, I did end up adding the “ftintitle” plugin, although no matter which option it had available (auto/drop/format) - the auto moving still continuously created the “featuring” folder as described above.

Not any issue at all though, as I just threw together a quick VBScript to rectify everything after the beets processing has finished. It’s not the most friendly to a processor, or I/O on a drive - but whatever. This “beets” software is absolute genius!


#4

Damn yea, I am having the same problem.


#5

Matt,

If, you’re interested, here’s the VBScript I wrote that handles the exceptions this software leaves behind in my music library.

*Use this script at your own risk, it works perfect for my library, but I won’t take responsibility if it does things to somebody else’s, outside what they’d like their library to be organized.

  • My library is sorted only into artist folders. I do not include the Album folder. This makes it so bands who release the same song multiple times, that I don’t end up having a billion copies of the same song (i.e. “The Eagles”, etc.). Every artist folder exists in the same directory (i.e. C:\MP3) <-- I don’t really keep them on my local drive, this is just as an example.

  • It runs off these rules:

  1. Kill duplicates (identical name only).
    [SongName.1.mp3, SongName.2.mp3, SongName.3.mp3] … Up to # 9.
    [SongName (1).mp3, SongName (2).mp3, SongName (3).mp3] … Up to # 9.
    It checks for the existence of SongName.mp3 then acts accordlingly. [Rename/Copy/Delete]

  2. Deletes empty folders.

  3. Confirms for the existence of the following words within the Artist’s name (the folder that gets created for the artist I was referring to above):
    feat, presents, &, ;. with, and

    If any of those above words are present, it splits the folder name accordingly, and strips the unwanted crap from the folder name. (i.e. in the case of “Artist feat. Another Artist”, the script strips everything out and leaves only the first Artist. It checks if the folder already exists and moves everything over if it does, while it simply renames the folder to the correct version if it doesn’t exist.)

    For the “&” and “and” verification, I put some exceptions in that it ignores the split if the following word is “the”, or “his”, and a couple others [you can see from the script itself]. This ensures that it ignores folder names like “Artist and His Orchestra” or “Artist and the Band” etc.

    It also ignores if the # of words after “&” or “and” are only 1 that they get ignored too. (like artist & wife, or similar). There are probably a million better ways to handle this, but it works for what I need it to.

  4. I was going to add logging, but I never got around to it. It’d be easy enough to do, but I never had time to circle the wagons for it.

******* A FEW REQUIRED ITEMS FOR USING THIS SCRIPT *******

  1. Understand that I am NOT a programmer. I can just read VBScript and putting things together like this in that language is fairly easy. There are WAY better languages like PowerShell that could probably handle this way better and are better on drive I/O and processor power. The way I’m looping through everything, the script I believe uses more memory and read/writes to the drive than it should. Do not expect a miracle in processing speed here.

  2. Use this AT YOUR OWN RISK. It absolutely renames folders as required, and has served me since I wrote it back then. Just don’t scream if the script does something to your library you didn’t intend. Use it on a test folder first to make sure it has your desired results.

  3. As I stated above, my library is simply Artist/SongName.mp3 This script will not work without modification if you have the album title in your folder structure like Artist/AlbumTitle/Songname.mp3. It wouldn’t be hard to modify to work with album titles, but read above to the reason as why, why I don’t give 2 craps about what album a song came from. :slight_smile:


#6

’ **********************************
’ *** MP3 File Management Script ***
’ **********************************

’ ==================================
’ ==================================

’ User Defined Variables

 strBaseFileShare = "<Base Directory _ Change Me!>"
 strFileExtension = ".mp3"

’ Standard Environment Variables

 Set objFSO = CreateObject("Scripting.FileSystemObject")
 Set objBaseDir = objFSO.GetFolder(strBaseFileShare)

’ Dictionaries

 Set dicSubFolders = CreateObject("Scripting.Dictionary")
 Set dicMP3s = CreateObject("Scripting.Dictionary")

’ ==================================

For Each objSubFolder in objBaseDir.SubFolders
If Not dicSubFolders.Exists(objSubFolder.Name) Then
strSubFolderName = objSubFolder.Name
strSubFolderPath = objSubFolder.Path
dicSubFolders.Add strSubFolderPath, strSubFolderName
Set colFiles = objSubFolder.Files
If colFiles.Count > 0 Then
For Each objFile In colFiles
If InStr(objFile.Name, strFileExtension) Then
If Not dicMP3s.Exists(objFile.Name) Then
dicMP3s.Add objFile.Path, objFile.Name
End If
End If
Next
Else
objFSO.DeleteFolder objSubfolder.Path
End If
End If
For Each strFilePath In dicMP3s
strFileName = dicMP3s.Item(strFilePath)
subRemoveDuplicates strFileName, strFilePath
Next
If objFSO.FolderExists(strSubFolderPath) Then
subValidateFolderName(objSubFolder.Path)
End If
dicMP3s.RemoveAll
Set colFiles = Nothing
Next

’ Process Complete =================

WScript.Echo “MP3 Processing Complete”
WScript.Quit

’ Functions ========================

Function fncWordCount(strEvaluationString)
If strEvaluationString <> “” Then
arrStringWords = Split(strEvaluationString, " ")
fncWordCount = UBound(arrStringWords) + 1
Else
fncWordCount = 0
End If
End Function

’ Sub Routines =====================

Sub subCorrectFolder(strFolderPath, strFolderBase)
If objFSO.FolderExists(strFolderPath) Then
Set objSourceDirectory = objFSO.GetFolder(strFolderPath)
If objFSO.FolderExists(strFolderBase) Then
For Each strSourceFile In dicMP3s
strDestFile = strFolderBase & “” & dicMP3s.Item(strSourceFile)
If objFSO.FileExists(strSourceFile) And Not objFSO.FileExists(strDestFile) Then
objFSO.CopyFile strSourceFile, strDestFile, True
objFSO.DeleteFile strSourceFile
End If
Next
objFSO.DeleteFolder objSourceDirectory.Path
Else
objFSO.MoveFolder strFolderPath, strFolderBase
End If
Set objSourceDirectory = Nothing
End If
End Sub

Sub subValidateFolderName(strFolderPath)
arrFolderRenameValues = Array( _
“feat”, _
“presents”, _
“&”, _
“;”, _
" with ", _
" and ")
For Each strFolderRenameValue In arrFolderRenameValues
blnActionRequired = False
If InStr(strFolderPath, strFolderRenameValue) Then
blnActionRequired = True
arrFolderDetails = Split(strFolderPath, strFolderRenameValue)
strFolderBase = Trim(arrFolderDetails(0))
If Right(strFolderBase, 1) = “.” Then
strFolderBase = Left(strFolderBase, Len(strFolderBase) - 1)
End If
strFolderExtension = Trim(arrFolderDetails(1))
intWordCount_FolderBase = fncWordCount(strFolderBase)
intWordCount_FolderExtension = fncWordCount(strFolderExtension)
Select Case strFolderRenameValue
Case “feat”, “with”, “presents”, “;”
arrRenameExceptions = Array( _
“Little Feat”, _
“Man With No Name”)
For Each strRenameException in arrRenameExceptions
If Left(LCase(strFolderPath), Len(strRenameException)) = LCase(strRenameException) Then
blnActionRequired = False
End If
Next
If blnActionRequired Then
subCorrectFolder strFolderPath, strFolderBase
End If
Case “&”, “and”
arrRenameExceptions = Array( _
“choir”, _
“drums”, _
“famous”, _
“farrar”, _
“friends”, _
“his”, _
“linda mccartney”, _
“lopez”, _
“the”)
For Each strRenameException in arrRenameExceptions
If Left(LCase(strFolderExtension), Len(strRenameException)) = LCase(strRenameException) Then
blnActionRequired = False
End If
Next
If IntWordCount_FolderBase = 0 Then
blnActionRequired = False
ElseIf intWordCount_FolderBase = 1 And intWordCount_FolderExtension = 1 Then
blnActionRequired = False
End If
If blnActionRequired Then
subCorrectFolder strFolderPath, strFolderBase
End If
End Select
End If
Next
End Sub

Sub subRemoveDuplicates(strFileName, strFilePath)
blnActionRequired = False
For intDuplicateCheck = 1 To 9
strIncorrectName_Parenth = “(” & intDuplicateCheck & “)” & strFileExtension
strIncorrectName_NumberOnly = “.” & intDuplicateCheck & strFileExtension
If InStr(strFileName, strIncorrectName_Parenth) Then
strCorrectedPath = Replace(strFilePath, strIncorrectName_Parenth, strFileExtension)
blnActionRequired = True
ElseIf InStr(strFileName, strIncorrectName_NumberOnly) Then
strCorrectedPath = Replace(strFilePath, strIncorrectName_NumberOnly, strFileExtension)
blnActionRequired = True
End If
Next
If InStr(strFileName, " - Copy") Then
arrFileDetails = Split(strFileName, " - Copy")
strCorrectedPath = arrFileDetails(0)
blnActionRequired = True
End If
If blnActionRequired Then
If objFSO.FileExists(strCorrectedPath) And objFSO.FileExists(strFilePath) Then
objFSO.DeleteFile strFilePath
Else
If objFSO.FileExists(strFilePath) Then
objFSO.MoveFile strFilePath, strCorrectedPath
End If
End If
End If
End Sub


#7

*Apologies for script formatting, this discourse stripped all the tabs out.


#8

Oh - forgot to mention - that if you hadn’t guessed, that since I wrote it in VBS, it’s a script that needs to be run from a windows box.


#9

Please see Discourse’s Markdown formatting instructions to see how to demarcate code blocks so they display correctly.


#10
' ===================================================
' ===================================================

' User Defined Variables

	strBaseFileShare = "<ChangeMe!_PathToMP3s>"
	strFileExtension = ".mp3"

' Standard Environment Variables

	Set objFSO = CreateObject("Scripting.FileSystemObject")
	Set objBaseDir = objFSO.GetFolder(strBaseFileShare)

' Dictionaries

	Set dicSubFolders = CreateObject("Scripting.Dictionary")
	Set dicMP3s = CreateObject("Scripting.Dictionary")

' ===================================================

For Each objSubFolder in objBaseDir.SubFolders
	If Not dicSubFolders.Exists(objSubFolder.Name) Then
		strSubFolderName = objSubFolder.Name
		strSubFolderPath = objSubFolder.Path
		dicSubFolders.Add strSubFolderPath, strSubFolderName
		Set colFiles = objSubFolder.Files
		If colFiles.Count > 0 Then
			For Each objFile In colFiles
				If InStr(objFile.Name, strFileExtension) Then
					If Not dicMP3s.Exists(objFile.Name) Then
						dicMP3s.Add objFile.Path, objFile.Name
					End If
				End If
			Next
		Else
			objFSO.DeleteFolder objSubfolder.Path
		End If	
	End If
	For Each strFilePath In dicMP3s
		strFileName = dicMP3s.Item(strFilePath)
		subRemoveDuplicates strFileName, strFilePath
	Next
	If objFSO.FolderExists(strSubFolderPath) Then
		subValidateFolderName(objSubFolder.Path)
	End If
	dicMP3s.RemoveAll
	Set colFiles = Nothing
Next

' Process Complete ==================================

WScript.Echo "MP3 Processing Complete"
WScript.Quit

' Functions =========================================

Function fncWordCount(strEvaluationString)
	If strEvaluationString <> "" Then
		arrStringWords = Split(strEvaluationString, " ")
		fncWordCount = UBound(arrStringWords) + 1
	Else
		fncWordCount = 0
	End If
End Function

' Sub Routines ======================================

Sub subCorrectFolder(strFolderPath, strFolderBase)
	If objFSO.FolderExists(strFolderPath) Then
		Set objSourceDirectory = objFSO.GetFolder(strFolderPath)
		If objFSO.FolderExists(strFolderBase) Then
			For Each strSourceFile In dicMP3s
				strDestFile = strFolderBase & "\" & dicMP3s.Item(strSourceFile)
				If objFSO.FileExists(strSourceFile) And Not objFSO.FileExists(strDestFile) Then
					objFSO.CopyFile strSourceFile, strDestFile, True
					objFSO.DeleteFile strSourceFile
				End If
			Next
			objFSO.DeleteFolder objSourceDirectory.Path
		Else
			objFSO.MoveFolder strFolderPath, strFolderBase
		End If
		Set objSourceDirectory = Nothing
	End If
End Sub

Sub subValidateFolderName(strFolderPath)
	arrFolderRenameValues = Array( _
		"feat", _
		"presents", _
		"&", _
		";", _
		" with ", _
		" and ")
	For Each strFolderRenameValue In arrFolderRenameValues
		blnActionRequired = False
		If InStr(strFolderPath, strFolderRenameValue) Then
			blnActionRequired = True
			arrFolderDetails = Split(strFolderPath, strFolderRenameValue)
			strFolderBase = Trim(arrFolderDetails(0))
			If Right(strFolderBase, 1) = "." Then
				strFolderBase = Left(strFolderBase, Len(strFolderBase) - 1)
			End If
			strFolderExtension = Trim(arrFolderDetails(1))
			intWordCount_FolderBase = fncWordCount(strFolderBase)
			intWordCount_FolderExtension = fncWordCount(strFolderExtension)
			Select Case strFolderRenameValue
				Case "feat", "with", "presents", ";"
					arrRenameExceptions = Array( _
						"Little Feat", _
						"Man With No Name")
					For Each strRenameException in arrRenameExceptions
						If Left(LCase(strFolderPath), Len(strRenameException)) = LCase(strRenameException) Then
							blnActionRequired = False
						End If
					Next
					If blnActionRequired Then
						subCorrectFolder strFolderPath, strFolderBase
					End If
				Case "&", "and"
					arrRenameExceptions = Array( _
						"choir", _
						"drums", _
						"famous", _
						"farrar", _
						"friends", _
						"his", _
						"linda mccartney", _
						"lopez", _
						"the")
					For Each strRenameException in arrRenameExceptions
						If Left(LCase(strFolderExtension), Len(strRenameException)) = LCase(strRenameException) Then
							blnActionRequired = False
						End If
					Next
						If IntWordCount_FolderBase = 0 Then
							blnActionRequired = False
						ElseIf intWordCount_FolderBase = 1 And intWordCount_FolderExtension = 1 Then
							blnActionRequired = False
						End If
					If blnActionRequired Then
						subCorrectFolder strFolderPath, strFolderBase
					End If
			End Select
		End If
	Next
End Sub

Sub subRemoveDuplicates(strFileName, strFilePath)
	blnActionRequired = False
	For intDuplicateCheck = 1 To 9
		strIncorrectName_Parenth = "(" & intDuplicateCheck & ")" & strFileExtension
		strIncorrectName_NumberOnly = "." & intDuplicateCheck & strFileExtension
		If InStr(strFileName, strIncorrectName_Parenth) Then
			strCorrectedPath = Replace(strFilePath, strIncorrectName_Parenth, strFileExtension)
			blnActionRequired = True
		ElseIf InStr(strFileName, strIncorrectName_NumberOnly) Then
			strCorrectedPath = Replace(strFilePath, strIncorrectName_NumberOnly, strFileExtension)
			blnActionRequired = True
		End If
	Next
	If InStr(strFileName, " - Copy") Then
		arrFileDetails = Split(strFileName, " - Copy")
		strCorrectedPath = arrFileDetails(0)
		blnActionRequired = True
	End If
	If blnActionRequired Then
		If objFSO.FileExists(strCorrectedPath) And objFSO.FileExists(strFilePath) Then
			objFSO.DeleteFile strFilePath
		Else
			If objFSO.FileExists(strFilePath) Then
				objFSO.MoveFile strFilePath, strCorrectedPath
			End If
		End If
	End If
End Sub


#11

Thanks for the tip Adrian. - Keep up the great work!