' ' *************************************************************************** ' * ' * PutAlbumArt - Copies album art from your PC to a SanDisk MP3 player ' * John Holliday - 07/29/07 - 1.0 ' * John Holliday - 07/30/07 - 1.1 - Ask to replace all files and log output ' * John Holliday - 08/01/07 - 1.2 - Added error handler sub ' * John Holliday - 08/04/07 - 1.3 - Added check for source file existance ' * John Holliday - 12/17/07 - 2.0 - Added Rockbox compatibility ' * ' *************************************************************************** ' ' This script makes the following assumptions. ' ' This is NOT GUARANTEED to work on YOUR system! ' Your MP3 player is a SanDisk ' Your SanDisk MP3 player is in MSC mode and connected ' Your album art is located in the standard Windows music folder path, ' that is, it has the same parent folder as your Documents folder ' The album art file is named FOLDER.JPG (it can have hidden/system attributes) ' The Rockbox album art file is named COVER.BMP (it can have hidden/system attributes) ' This is NOT GUARANTEED to work on YOUR system! ' ' There are two files that need to exist in your Artist/AlbumName folder. The first ' is FOLDER.JPG and the second is COVER.BMP. The JPG file is for use with the default ' Sansa setup and the BMP file is for use with Rockbox (www.rockbox.org). If the ' default Rockbox folder is found on the device, you will be prompted if you actively ' use it. If you do, a global variable is set to True. At this point, the COVER.BMP ' file will be copied along with the FOLDER.JPG file. ' ' The search does not begin on your computer, it starts on the MP3 device. All ' folders on the device are checked and matched with folders on the computer. If ' the folder on the computer contains the FOLDER.JPG and COVER.BMP files, they ' are copied to the device. ' ' I store my album art in a separate folder so I don't lose it, but I decided that ' copying the FOLDER.JPG file made more sense. So, I copied my album art to my music ' folders and named the files FOLDER.JPG. Also, NO files are overwritten/deleted ' unless you REQUEST it. That's the reason for the initial request to replace ALL of ' the album art. If you say no, only the album art that is missing from the player ' will be copied to it. ' ' There are three global constants. Make sure they match YOUR system! Change them if ' they don't. ' ' This script uses Hungarian notation for all variables. G is for global variables and L ' is for local variables. All the identifiers (col, obj, str, int, bln), etc., are typical. ' I also don't throw the script together and have one big mess. Everything is in SUBs and ' FUNCTIONs with processing separate. It's easier for Type-A coders like me to follow. ' ' If you pass this script along to anyone else, or you alter it to make it run on something ' other than a SanDisk device, just make sure to leave this header intact. If you do make ' changes, log those changes above and send me a copy at: B17G65VE@hotmail.com - I would ' appreciate it. Make sure that "PutAlbumArt.VBS" is in the subject. You may have to ZIP ' the file to get it past the virus checks on Hotmail. ' ' And, in case you missed it, this is NOT GUARANTEED to work on YOUR system! ' So don't send me flame-mail if it doesn't! ' Option Explicit ' Declare global objects Public gobjFSO Public gobjWshShell Public gobjWMIService ' Declare global variables Public gstrMsgText Public gstrMsgTitle Public gstrUserDocs Public gstrUserDesk Public gstrWSID Public gstrOutputFile Public gintMsgType Public gintMBRetVal Public gblnReplaceAllFiles Public gblnIsRockbox ' Declare global constants ' The DEVICE_LABEL constant string is for the e200 Sansa series - check the drive label ' of your player for something specific to your type of player and change the string. Public Const DEVICE_LABEL = "SANSA" ' The MUSIC_PATH constant string is the name of your music folder. ' For Vista it's Music (c:\users\NAME\Music) ' For XP it's My Music (c:\documents and settings\NAME\My Music) Public Const MUSIC_PATH = "My Music" ' This is the name of the music folder on the DEVICE. Example: E:\MUSIC The drive letter ' will be determined at run time. Do NOT include it here. Public Const DEVICE_PATH = "Music" ' Script processing starts here ScriptInit PutFiles WScript.Quit Sub ScriptInit() On Error Resume Next Set gobjFSO = CreateObject("Scripting.FileSystemObject") Set gobjWshShell = CreateObject("WScript.Shell") gstrWSID = "." Set gobjWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & gstrWSID & "\root\cimv2") End Sub Function GlobalMsg() ' This function shows a message dialog when the variables are initialized. The output ' is a return code that is based on the "vbReturnCode" constants, depending on which ' buttons are shown on the dialog (gintMsgType). The gintMBRetVal public variable has ' already been declared for this use. However, you may use your own variable. ' WARNING! If you don't change the variables prior to calling this sub, it will ' use the previous values! ' GlobalMsg = MsgBox(gstrMsgText, gintMsgType, gstrMsgTitle) End Function Function GetDriveLetter(lstrDeviceLabel) Dim lcolItems, lobjItem Set lcolItems = gobjWMIService.ExecQuery("Select * from Win32_Volume",,48) GetDriveLetter = "Failed" For Each lobjItem in lcolItems If lobjItem.SystemVolume <> True Then If lobjItem.PageFilePresent = False Then If InStr(UCase(lobjItem.Label), lstrDeviceLabel) > 0 Then GetDriveLetter = lobjItem.DriveLetter Exit For End If End If End If Next End Function Function WriteOneLineToFile(lstrFileName, lstrLineToWrite) Dim lobjHeader Set lobjHeader = gobjFSO.OpenTextFile(lstrFileName, 8, True) lobjHeader.WriteLine lstrLineToWrite Set lobjHeader = gobjFSO.OpenTextFile(lstrFileName, 1) WriteOneLineToFile = lobjHeader.ReadAll End Function Function RunIt(lstrRunProc, lintRunStyle, lblnRunWait) ' Options for lintRunStyle ' 0 = Hidden - generally used when a prompt is run ' 2 = Minimized ' 3 = Maximized RunIt = gobjWshShell.Run(lstrRunProc, lintRunStyle, lblnRunWait) End Function Sub AskForAll() gblnReplaceAllFiles = False gstrMsgText = "Would you like to replace ALL of your album" & vbCrLf & "art files on your " & DEVICE_LABEL & " device?" gstrMsgTitle = "Global File Replace" gintMsgType = vbQuestion + vbYesNo + vbDefaultButton2 gintMBRetVal = GlobalMsg() If gintMBRetVal = vbYes Then gintMBRetVal = vbNo gstrMsgText = "Are you SURE you want to replace ALL of your" & vbCrLf & "album art files on your " & DEVICE_LABEL & " device?" gstrMsgTitle = "Global File Replace" gintMsgType = vbQuestion + vbYesNo + vbDefaultButton2 gintMBRetVal = GlobalMsg() If gintMBRetVal = vbYes Then gblnReplaceAllFiles = True End If End If End Sub Sub RockboxQuery(lstrDriveLetter) Dim lstrExistMsg gblnIsRockbox = False lstrExistMsg = FolderStatus(lstrDriveLetter & "\.rockbox") If lstrExistMsg = "notexist" Then Exit Sub gstrMsgText = "It appears that Rockbox is installed on your" & vbCrLf & DEVICE_LABEL & " device. Do you actively use it?" gstrMsgTitle = "Active Rockbox Use" gintMsgType = vbQuestion + vbYesNo + vbDefaultButton2 gintMBRetVal = GlobalMsg() If gintMBRetVal = vbYes Then gblnIsRockbox = True End If End Sub Function FolderStatus(lstrFolderName) If (gobjFSO.FolderExists(lstrFolderName)) Then FolderStatus = "exist" Else FolderStatus = "notexist" End If End Function Sub CreateLogFile() gstrOutputFile = gstrUserDesk & "\" & DEVICE_LABEL & ".log" If (gobjFSO.FileExists(gstrOutputFile)) Then gobjFSO.DeleteFile gstrOutputFile, True End If WriteOneLineToFile gstrOutputFile, "The album art for the following artists and albums was not copied." WriteOneLineToFile gstrOutputFile, "Check to see if the album art files exist in the source folders." WriteOneLineToFile gstrOutputFile, "" End Sub Sub HandleErrors(lstrErrNum, lstrErrDesc, lstrArtistName, lstrAlbumName, lstrMusicFolder) Select Case lstrErrNum Case 70 gstrMsgText = "A permission denied error occurred. You don't have permission to copy" & vbcrlf & "the album art file. If you are on a computer that has multiple user" & vbcrlf & "accounts, make sure you are NOT trying to copy from an account that" & vbcrlf & "is not yours." & vbcrlf & vbcrlf & "If you are on a computer with only one user account, check your music" & vbcrlf & "folder to be sure there isn't something wrong with the FOLDER.JPG files." & vbcrlf & vbcrlf & "In both cases, check the device to make sure there isn't an attribute" & vbcrlf & "set that will inhibit the file copy process." gstrMsgTitle = "Permission Denied" gintMsgType = vbExclamation + vbOKOnly GlobalMsg WriteOneLineToFile gstrOutputFile, "A permission denied error occured for " & Chr(34) & lstrArtistName & " - " & lstrAlbumName & Chr(34) & "." Case 76 gstrMsgText = "A path was not found. Check the following artist and album information." & vbcrlf & vbcrlf & "Artist - " & lstrArtistName & vbcrlf & "Album - " & lstrAlbumName & vbcrlf & vbcrlf & "The most likely cause of the error is that the folder representing the" & vbcrlf & "album name exists on the device but does not exist on the computer." & vbcrlf & "Check the music path on the computer:" & vbcrlf & vbcrlf & lstrMusicFolder & vbcrlf & vbcrlf & "for the artist name and see if the album name exists as a folder." gstrMsgTitle = "Path Not Found" gintMsgType = vbExclamation + vbOKOnly GlobalMsg WriteOneLineToFile gstrOutputFile, "The album (folder) " & Chr(34) & lstrAlbumName & Chr(34) & " wasn't found on the computer at " & Chr(34) & lstrMusicFolder & "\" & lstrArtistName & Chr(34) Case Else gstrMsgText = "An undefined error was encountered. Here is the error information." & vbcrlf & vbcrlf & "Error number: " & lstrErrNum & vbCrLf & lstrErrDesc & vbcrlf & vbcrlf & "The error occured while attempting to copy album art for:" & vbCrLf & vbCrLf & "Artist - " & lstrArtistName & vbcrlf & "Album - " & lstrAlbumName & vbcrlf & vbcrlf & "Click OK to continue processing." gstrMsgTitle = "Undefined Error" gintMsgType = vbExclamation + vbOKOnly GlobalMsg WriteOneLineToFile gstrOutputFile, "A non-specific error occurred for: " & Chr(34) & lstrMusicFolder & "\" & lstrArtistName & "\" & lstrAlbumName & Chr(34) End Select End Sub Sub PutFiles() On Error Resume Next Dim lstrDriveLetter, lstrDeviceFolder, lstrFolderName, lstrMusicFolder Dim lstrAlbumName, lstrArtistName, lstrAlbumArtName, lstrSourceFile Dim lobjDeviceArtists, lobjArtistAlbums, lobjArtist, lobjAlbum, lobjTargetAttribs Dim lcolArtists, lcolAlbums Dim lblnCopyJPGErrors, lblnCopyBMPErrors, lblnCopyErrors lblnCopyJPGErrors = False lblnCopyBMPErrors = False lblnCopyErrors = False lstrDriveLetter = GetDriveLetter(DEVICE_LABEL) If lstrDriveLetter = "Failed" Then gstrMsgText = "Could not find a " & DEVICE_LABEL & " device connected!" & vbCrLf & "If this is a Sansa device, make sure it is in MSC mode." & vbCrLf & vbCrLf & "This utility will now exit." gstrMsgTitle = "No Device Found" gintMsgType = vbInformation + vbOKOnly GlobalMsg() WScript.Quit End If gstrUserDesk = gobjWshShell.SpecialFolders("Desktop") RockboxQuery lstrDriveLetter AskForAll CreateLogFile gstrUserDocs = gobjWshShell.SpecialFolders("MyDocuments") lstrFolderName = gobjFSO.GetParentFolderName(gstrUserDocs) lstrMusicFolder = lstrFolderName & "\" & MUSIC_PATH lstrDeviceFolder = lstrDriveLetter & "\" & DEVICE_PATH Set lobjDeviceArtists = gobjFSO.GetFolder(lstrDeviceFolder) Set lcolArtists = lobjDeviceArtists.SubFolders For Each lobjArtist In lcolArtists lstrArtistName = lstrDeviceFolder & "\" & lobjArtist.Name Set lobjArtistAlbums = gobjFSO.GetFolder(lstrArtistName) Set lcolAlbums = lobjArtistAlbums.SubFolders For Each lobjAlbum In lcolAlbums If gblnReplaceAllFiles = False Then lstrAlbumName = lstrArtistName & "\" & lobjAlbum.Name lstrAlbumArtName = lstrAlbumName & "\album art.jpg" lstrSourceFile = lstrMusicFolder & "\" & lobjArtist.Name & "\" & lobjAlbum.Name & "\folder.jpg" lblnCopyJPGErrors = CopyArtFiles("folder.jpg", lstrSourceFile,lstrAlbumArtName, lobjArtist.Name, lobjAlbum.Name, lstrMusicFolder) If lblnCopyJPGErrors = True Then lblnCopyErrors = True End If lstrAlbumArtName = lstrAlbumName & "\cover.bmp" lstrSourceFile = lstrMusicFolder & "\" & lobjArtist.Name & "\" & lobjAlbum.Name & "\cover.bmp" lblnCopyBMPErrors = CopyArtFiles("cover.bmp", lstrSourceFile,lstrAlbumArtName, lobjArtist.Name, lobjAlbum.Name, lstrMusicFolder) If lblnCopyBMPErrors = True Then lblnCopyErrors = True End If Else lstrAlbumName = lstrArtistName & "\" & lobjAlbum.Name lstrAlbumArtName = lstrAlbumName & "\album art.jpg" lstrSourceFile = lstrMusicFolder & "\" & lobjArtist.Name & "\" & lobjAlbum.Name & "\folder.jpg" lblnCopyJPGErrors = ReplaceArtFiles("folder.jpg", lstrSourceFile,lstrAlbumArtName, lobjArtist.Name, lobjAlbum.Name, lstrMusicFolder) If lblnCopyJPGErrors = True Then lblnCopyErrors = True End If lstrAlbumArtName = lstrAlbumName & "\cover.bmp" lstrSourceFile = lstrMusicFolder & "\" & lobjArtist.Name & "\" & lobjAlbum.Name & "\cover.bmp" lblnCopyBMPErrors = ReplaceArtFiles("cover.bmp", lstrSourceFile,lstrAlbumArtName, lobjArtist.Name, lobjAlbum.Name, lstrMusicFolder) If lblnCopyBMPErrors = True Then lblnCopyErrors = True End If End If Next Next If lblnCopyErrors = False Then WriteOneLineToFile gstrOutputFile, "All album art files were copied without error." End If RunIt "notepad " & gstrOutputFile, 3, False End Sub Function CopyArtFiles(lstrSourceName, lstrSourceFile, lstrAlbumArtName, lstrArtistName, lstrAlbumName, lstrMusicFolder) On Error Resume Next Dim lobjTargetAttribs CopyArtFiles = False If Not (gobjFSO.FileExists(lstrAlbumArtName)) Then If (gobjFSO.FileExists(lstrSourceFile)) Then Err.Clear gobjFSO.CopyFile lstrSourceFile, lstrAlbumArtName If Err Then HandleErrors Err.Number, Err.Description, lstrArtistName, lstrAlbumName, lstrMusicFolder CopyArtFiles = True WriteOneLineToFile gstrOutputFile, lstrArtistName & " - " & lstrAlbumName End If Else WriteOneLineToFile gstrOutputFile, "Could not find a " & UCase(lstrSourceName) & " file for " & Chr(34) & lstrArtistName & " - " & lstrAlbumName & Chr(34) & "." CopyArtFiles = True End If Err.Clear Set lobjTargetAttribs = gobjFSO.GetFile(lstrAlbumArtName) If Err Then Exit Function lobjTargetAttribs.Attributes = 7 Set lobjTargetAttribs = Nothing End If End Function Function ReplaceArtFiles(lstrSourceName, lstrSourceFile, lstrAlbumArtName, lstrArtistName, lstrAlbumName, lstrMusicFolder) On Error Resume Next Dim lobjTargetAttribs ReplaceArtFiles = False If (gobjFSO.FileExists(lstrSourceFile)) Then Set lobjTargetAttribs = gobjFSO.GetFile(lstrAlbumArtName) lobjTargetAttribs.Attributes = 0 Set lobjTargetAttribs = Nothing Err.Clear gobjFSO.CopyFile lstrSourceFile, lstrAlbumArtName, True If Err Then HandleErrors Err.Number, Err.Description, lstrArtistName, lstrAlbumName, lstrMusicFolder ReplaceArtFiles = True WriteOneLineToFile gstrOutputFile, lstrArtistName & " - " & lstrAlbumName End If Err.Clear Set lobjTargetAttribs = gobjFSO.GetFile(lstrAlbumArtName) If Err Then Exit Function lobjTargetAttribs.Attributes = 7 Set lobjTargetAttribs = Nothing Else ReplaceArtFiles = True WriteOneLineToFile gstrOutputFile, "Could not find a " & UCase(lstrSourceName) & " file for " & Chr(34) & lstrArtistName & " - " & lstrAlbumName & Chr(34) & "." End If End Function