VBS script to move unused files in an iTunes media folder

All the random crap I spend all day long figuring out.
Post Reply
User avatar
syntax
Site Admin
Posts: 54
Joined: Tue Jan 06, 2009 9:25 pm

VBS script to move unused files in an iTunes media folder

Post by syntax » Fri Feb 05, 2016 3:56 am

Export your library to an XML file.

Change the line to point to it: sLibraryXML = "C:\Users\syntax\desktop\Library.xml"

Specify where you want the files moved to with: sDestination = "C:\Users\syntax\Music\iTunes_Unused"

Log file will be created under the destination folder. Unused files will be moved to the destination folder, maintaining the folders structure as currently is in the iTunes Media folder.

Code: Select all

Option Explicit
Dim objShell, objFSO, oFolder, oSubFolder, oLogFile, oLog, x
Dim xmlDoc, strQuery, colNodes, objNode, objNodeTemp
Dim sLibraryXML, sItunesFolder, sDestination, sFile
ReDim Preserve sItunesLibraryItems(0)

sLibraryXML = "C:\Users\syntax\desktop\Library.xml"
sDestination = "C:\Users\syntax\Music\iTunes_Unused"

Set objShell = WScript.CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")

Const NODE_INVALID = 0  '&H0
Const NODE_ELEMENT = 1  '&H1
Const NODE_ATTRIBUTE = 2  '&H2
Const NODE_TEXT = 3  '&H3
Const NODE_CDATA_SECTION = 4  '&H4
Const NODE_ENTITY_REFERENCE = 5  '&H5
Const NODE_ENTITY = 6  '&H6
Const NODE_PROCESSING_INSTRUCTION = 7  '&H7
Const NODE_COMMENT = 8  '&H8
Const NODE_DOCUMENT = 9  '&H9
Const NODE_DOCUMENT_TYPE = 10  '&HA
Const NODE_DOCUMENT_FRAGMENT = 11  '&HB
Const NODE_NOTATION = 12  '&HC

Sub forceCScriptExecution
    Dim Arg, Str
    If Not LCase( Right( WScript.FullName, 12 ) ) = "\cscript.exe" Then
        For Each Arg In WScript.Arguments
            If InStr( Arg, " " ) Then Arg = """" & Arg & """"
            Str = Str & " " & Arg
        Next
        CreateObject( "WScript.Shell" ).Run _
            "cscript //nologo """ & _
            WScript.ScriptFullName & _
            """ " & Str
        WScript.Quit
    End If
End Sub
forceCScriptExecution

if objFSO.FileExists(sLibraryXML)=False then WScript.Quit
if objFSO.FolderExists(sDestination)=False then call CreateFolderRecursive(sDestination)
if objFSO.FolderExists(sDestination)=False then WScript.Quit

Set oLogFile = objFSO.OpenTextFile(sDestination & "\log.txt", 8, True)

Set xmlDoc = CreateObject( "Microsoft.XMLDOM" )
xmlDoc.Async = "False"
xmlDoc.Load( sLibraryXML )

strQuery = "/plist/dict/key[. = ""Music Folder""]"
Set colNodes = xmlDoc.selectNodes( strQuery )
For Each objNode in colNodes
	Set objNodeTemp = objNode.nextSibling
	sItunesFolder = objNodeTemp.text
	sItunesFolder = ParseXMLFileLocation(sItunesFolder)
	if right(sItunesFolder, 1) = "\" then sItunesFolder = mid(sItunesFolder, 1, len(sItunesFolder)-1)
Next

if objFSO.FolderExists(sItunesFolder)=False then
	LogIt("iTunes folder not found")
	CleanQuit
end if

x = 0
strQuery = "/plist/dict/dict/dict/key[. = ""Location""]"
Set colNodes = xmlDoc.selectNodes( strQuery )
For Each objNode in colNodes
	Set objNodeTemp = objNode.nextSibling
	sFile = ParseXMLFileLocation(objNodeTemp.text)
	if objFSO.FileExists(sFile) = False then
		LogIt("ERROR: File from iTunes library XML not found: " & sFile)
	else
		if x > 0 then
			ReDim Preserve sItunesLibraryItems(x)
		end if
		sItunesLibraryItems(x) = sFile
		x = x + 1
	end if
Next

if UBound(sItunesLibraryItems) < 1 then
	LogIt("No itunes library items found")
	CleanQuit
end if

call ScanFolder(sItunesFolder & "\Music", "mp3")
call ScanFolder(sItunesFolder & "\Music", "m4a")

call ScanFolder(sItunesFolder & "\Audiobooks", "mp3")
call ScanFolder(sItunesFolder & "\Audiobooks", "m4a")

call ScanFolder(sItunesFolder & "\Books", "mp3")
call ScanFolder(sItunesFolder & "\Books", "m4a")

call ScanFolder(sItunesFolder & "\Home Videos", "m4v")

call ScanFolder(sItunesFolder & "\Movies", "m4v")

call ScanFolder(sItunesFolder & "\Music", "mp3")
call ScanFolder(sItunesFolder & "\Music", "m4a")

call ScanFolder(sItunesFolder & "\Tones", "mp3")
call ScanFolder(sItunesFolder & "\Tones", "m4a")

call ScanFolder(sItunesFolder & "\TV Shows", "m4v")

call ScanFolder(sItunesFolder & "\Voice Memos", "mp3")
call ScanFolder(sItunesFolder & "\Voice Memos", "m4a")

Sub ScanFolder(sFolder, sExtension)
    dim objFolder, objSubFolder, colFiles, objFile
	dim sOldPath, sNewPath, sFileName
	
	if objFSO.FolderExists(sFolder) then
		Set objFolder = objFSO.GetFolder(sFolder)
		Set colFiles = objFolder.Files
		For Each objFile in colFiles
			sFileName = objFile.name
			If UCase(objFSO.GetExtensionName(objFile.name)) = UCase(sExtension) Then
				sOldPath = sFolder & "\" & sFileName
				If Ubound(Filter(sItunesLibraryItems, sFileName, True, 1)) > -1 Then
					'in library
				Else
					'LogIt("UNUSED: " & sOldPath)
					
					sNewPath = Replace(sFolder, sItunesFolder, sDestination, 1, -1, 1)
					call CreateFolderRecursive(sNewPath)
					sNewPath = sNewPath & "\"
					LogIt("Old: " & sOldPath & ", New: " & sNewPath)
					objFSO.MoveFile sOldPath, sNewPath
					
					if objFSO.FileExists(sOldPath) = True then
						LogIt("ERROR: Error moving unused file from " & sOldPath & " to " & sNewPath)
					elseif objFSO.FileExists(sNewPath & sFileName) = True then
						LogIt("Unused file moved: " & sOldPath)
					else
						LogIt("ERROR: Unknown error moving file.  Old: " & sOldPath & ", New: " & sNewPath)
					end if
				End If
			End If
		Next

		For Each objSubFolder in objFolder.SubFolders
			call ScanFolder(objSubFolder.Path, sExtension)
		Next
	end if
End Sub

Function CreateFolderRecursive(sFullPath)
	Dim arr, dir, path
	
	arr = split(sFullPath, "\")
	path = ""
	For Each dir In arr
		If path <> "" Then path = path & "\"
		path = path & dir
		If objFSO.FolderExists(path) = False Then objFSO.CreateFolder(path)
	Next
End Function

Function ParseXMLFileLocation(sFile)
	ParseXMLFileLocation = sFile
	sFile = Replace(sFile,"file://localhost/","",1,-1,1) 
	sFile = Replace(sFile,"&","&",1,-1,1)
	sFile = Replace(sFile,"%20"," ",1,-1,1)
	sFile = Replace(sFile,"%21","!",1,-1,1)
	sFile = Replace(sFile,"%22","""",1,-1,1)
	sFile = Replace(sFile,"%23","#",1,-1,1)
	sFile = Replace(sFile,"%24","$",1,-1,1)
	sFile = Replace(sFile,"%25","%",1,-1,1)
	sFile = Replace(sFile,"%26","&",1,-1,1)
	sFile = Replace(sFile,"%27","'",1,-1,1)
	sFile = Replace(sFile,"%28","(",1,-1,1)
	sFile = Replace(sFile,"%29",")",1,-1,1)
	sFile = Replace(sFile,"%2a","*",1,-1,1)
	sFile = Replace(sFile,"%2b","+",1,-1,1)
	sFile = Replace(sFile,"%2c",",",1,-1,1)
	sFile = Replace(sFile,"%2d","-",1,-1,1)
	sFile = Replace(sFile,"%2e",".",1,-1,1)
	sFile = Replace(sFile,"%2f","/",1,-1,1)
	sFile = Replace(sFile,"%3a",":",1,-1,1)
	sFile = Replace(sFile,"%3b",";",1,-1,1)
	sFile = Replace(sFile,"%3c","<",1,-1,1)
	sFile = Replace(sFile,"%3d","=",1,-1,1)
	sFile = Replace(sFile,"%3e",">",1,-1,1)
	sFile = Replace(sFile,"%3f","?",1,-1,1)
	sFile = Replace(sFile,"%40","@",1,-1,1)
	sFile = Replace(sFile,"%5b","[",1,-1,1)
	sFile = Replace(sFile,"%5c","\",1,-1,1)
	sFile = Replace(sFile,"%5d","]",1,-1,1)
	sFile = Replace(sFile,"%5e","^",1,-1,1)
	sFile = Replace(sFile,"%5f","_",1,-1,1)
	sFile = Replace(sFile,"%60","`",1,-1,1)
	sFile = Replace(sFile,"%7b","{",1,-1,1)
	sFile = Replace(sFile,"%7c","|",1,-1,1)
	sFile = Replace(sFile,"%7d","}",1,-1,1)
	sFile = Replace(sFile,"%7e","~",1,-1,1)
	sFile = Replace(sFile,"%c2%a1","¡",1,-1,1)
	sFile = Replace(sFile,"%c2%a2","¢",1,-1,1)
	sFile = Replace(sFile,"%c2%a3","£",1,-1,1)
	sFile = Replace(sFile,"%c2%a4","¤",1,-1,1)
	sFile = Replace(sFile,"%c2%a5","¥",1,-1,1)
	sFile = Replace(sFile,"%c2%a6","¦",1,-1,1)
	sFile = Replace(sFile,"%c2%a7","§",1,-1,1)
	sFile = Replace(sFile,"%c2%a8","¨",1,-1,1)
	sFile = Replace(sFile,"%c2%a9","©",1,-1,1)
	sFile = Replace(sFile,"%c2%aa","ª",1,-1,1)
	sFile = Replace(sFile,"%c2%ab","«",1,-1,1)
	sFile = Replace(sFile,"%c2%ac","¬",1,-1,1)
	sFile = Replace(sFile,"%c2%ad","­",1,-1,1)
	sFile = Replace(sFile,"%c2%ae","®",1,-1,1)
	sFile = Replace(sFile,"%c2%af","¯",1,-1,1)
	sFile = Replace(sFile,"%c2%b0","°",1,-1,1)
	sFile = Replace(sFile,"%c2%b1","±",1,-1,1)
	sFile = Replace(sFile,"%c2%b2","²",1,-1,1)
	sFile = Replace(sFile,"%c2%b3","³",1,-1,1)
	sFile = Replace(sFile,"%c2%b4","´",1,-1,1)
	sFile = Replace(sFile,"%c2%b5","µ",1,-1,1)
	sFile = Replace(sFile,"%c2%b6","¶",1,-1,1)
	sFile = Replace(sFile,"%c2%b7","·",1,-1,1)
	sFile = Replace(sFile,"%c2%b8","¸",1,-1,1)
	sFile = Replace(sFile,"%c2%b9","¹",1,-1,1)
	sFile = Replace(sFile,"%c2%ba","º",1,-1,1)
	sFile = Replace(sFile,"%c2%bb","»",1,-1,1)
	sFile = Replace(sFile,"%c2%bc","¼",1,-1,1)
	sFile = Replace(sFile,"%c2%bd","½",1,-1,1)
	sFile = Replace(sFile,"%c2%be","¾",1,-1,1)
	sFile = Replace(sFile,"%c2%bf","¿",1,-1,1)
	sFile = Replace(sFile,"%c3%80","À",1,-1,1)
	sFile = Replace(sFile,"%c3%81","Á",1,-1,1)
	sFile = Replace(sFile,"%c3%82","Â",1,-1,1)
	sFile = Replace(sFile,"%c3%83","Ã",1,-1,1)
	sFile = Replace(sFile,"%c3%84","Ä",1,-1,1)
	sFile = Replace(sFile,"%c3%85","Å",1,-1,1)
	sFile = Replace(sFile,"%c3%86","Æ",1,-1,1)
	sFile = Replace(sFile,"%c3%87","Ç",1,-1,1)
	sFile = Replace(sFile,"%c3%88","È",1,-1,1)
	sFile = Replace(sFile,"%c3%89","É",1,-1,1)
	sFile = Replace(sFile,"%c3%8a","Ê",1,-1,1)
	sFile = Replace(sFile,"%c3%8b","Ë",1,-1,1)
	sFile = Replace(sFile,"%c3%8c","Ì",1,-1,1)
	sFile = Replace(sFile,"%c3%8d","Í",1,-1,1)
	sFile = Replace(sFile,"%c3%8e","Î",1,-1,1)
	sFile = Replace(sFile,"%c3%8f","Ï",1,-1,1)
	sFile = Replace(sFile,"%c3%90","Ð",1,-1,1)
	sFile = Replace(sFile,"%c3%91","Ñ",1,-1,1)
	sFile = Replace(sFile,"%c3%92","Ò",1,-1,1)
	sFile = Replace(sFile,"%c3%93","Ó",1,-1,1)
	sFile = Replace(sFile,"%c3%94","Ô",1,-1,1)
	sFile = Replace(sFile,"%c3%95","Õ",1,-1,1)
	sFile = Replace(sFile,"%c3%96","Ö",1,-1,1)
	sFile = Replace(sFile,"%c3%97","×",1,-1,1)
	sFile = Replace(sFile,"%c3%98","Ø",1,-1,1)
	sFile = Replace(sFile,"%c3%99","Ù",1,-1,1)
	sFile = Replace(sFile,"%c3%9a","Ú",1,-1,1)
	sFile = Replace(sFile,"%c3%9b","Û",1,-1,1)
	sFile = Replace(sFile,"%c3%9c","Ü",1,-1,1)
	sFile = Replace(sFile,"%c3%9d","Ý",1,-1,1)
	sFile = Replace(sFile,"%c3%9e","Þ",1,-1,1)
	sFile = Replace(sFile,"%c3%9f","ß",1,-1,1)
	sFile = Replace(sFile,"%c3%a0","à",1,-1,1)
	sFile = Replace(sFile,"%c3%a1","á",1,-1,1)
	sFile = Replace(sFile,"%c3%a2","â",1,-1,1)
	sFile = Replace(sFile,"%c3%a3","ã",1,-1,1)
	sFile = Replace(sFile,"%c3%a4","ä",1,-1,1)
	sFile = Replace(sFile,"%c3%a5","å",1,-1,1)
	sFile = Replace(sFile,"%c3%a6","æ",1,-1,1)
	sFile = Replace(sFile,"%c3%a7","ç",1,-1,1)
	sFile = Replace(sFile,"%c3%a8","è",1,-1,1)
	sFile = Replace(sFile,"%c3%a9","é",1,-1,1)
	sFile = Replace(sFile,"%c3%aa","ê",1,-1,1)
	sFile = Replace(sFile,"%c3%ab","ë",1,-1,1)
	sFile = Replace(sFile,"%c3%ac","ì",1,-1,1)
	sFile = Replace(sFile,"%c3%ad","í",1,-1,1)
	sFile = Replace(sFile,"%c3%ae","î",1,-1,1)
	sFile = Replace(sFile,"%c3%af","ï",1,-1,1)
	sFile = Replace(sFile,"%c3%b0","ð",1,-1,1)
	sFile = Replace(sFile,"%c3%b1","ñ",1,-1,1)
	sFile = Replace(sFile,"%c3%b2","ò",1,-1,1)
	sFile = Replace(sFile,"%c3%b3","ó",1,-1,1)
	sFile = Replace(sFile,"%c3%b4","ô",1,-1,1)
	sFile = Replace(sFile,"%c3%b5","õ",1,-1,1)
	sFile = Replace(sFile,"%c3%b6","ö",1,-1,1)
	sFile = Replace(sFile,"%c3%b7","÷",1,-1,1)
	sFile = Replace(sFile,"%c3%b8","ø",1,-1,1)
	sFile = Replace(sFile,"%c3%b9","ù",1,-1,1)
	sFile = Replace(sFile,"%c3%ba","ú",1,-1,1)
	sFile = Replace(sFile,"%c3%bb","û",1,-1,1)
	sFile = Replace(sFile,"%c3%bc","ü",1,-1,1)
	sFile = Replace(sFile,"%c3%bd","ý",1,-1,1)
	sFile = Replace(sFile,"%c3%be","þ",1,-1,1)
	sFile = Replace(sFile,"%c3%bf","ÿ",1,-1,1)
	sFile = Replace(sFile,"/","\",1,-1,1)
	if sFile <> "" Then ParseXMLFileLocation = sFile
End Function

Sub CleanQuit()
	On Error Resume Next
	oLogFile.Close
	Set oLogFile = Nothing
	WScript.Quit
End Sub

Sub LogIt(sText)
	oLogFile.WriteLine(Now() & " " & sText)
	WScript.Echo sText
End Sub

Post Reply