Sunday, October 22, 2017

#51 2017-04-20 05:24:58 am

squigee90
Member
Registered: 2017-03-26
Posts: 26

Re: Applescript to read mp3 metatags and sort file into folder

how do you get the long script to handle folders?

Applescript:


error "Can’t get alias \"Untitled:_Production Drive backup 13/3/17:iTunes Media Folder:\"." number -1728 from alias "Untitled:_Production Drive backup 13/3/17:iTunes Media Folder:"

Applescript:



(*
rename & move mp3 ASObjC - 2

Written for [url]http://macscripter.net/viewtopic.php?id=45629[/url]

by Nigel GARVEY, Shane STANLEY & Yvan KOENIG

2017/04/15

Tested under 10.12.4 public version
# Edited on 2017/04/18 : report the list of files which weren't moved
# Edited on 2017/04/19 : at Nigel GARVEY's request, removed some instructions


CAUTION. THE SCRIPT IS SUPPOSED TO RENAME AND MOVE SOME FILES.
IF YOU ARE NOT SURE OF WHAT IT DOES, EDIT THE PROPERTY NAMED testIt SETTING IT THE VALUE : true
*)




use AppleScript version "2.4" # requires at least Yosemite
use scripting additions
use framework "Foundation"

property copyString : " #" -- added to file names for copies; edit to suit your language

property destinationRootPath : "/Volumes/Production/test/" # I assume that it's the one you need


property testIt : false
#################### true = log some metadatas and DON'T MOVE the files
#################### false = don't log these metadatas and MOVE the files

on run -- For when testing.
   set theFiles to choose folder with prompt "Please select folder"
   mainBusiness(theFiles)
end run

on adding folder items to thisFolder after receiving addedItems -- For when run as a folder action.
   mainBusiness(addedItems)
end adding folder items to

on mainBusiness(theFiles)
   -- Get the root path in a convenient form for use with ASObjC.
   local destinationRootPath, |⌘|
   
   # Instructions useful to get a script running flawlessly on my machine!
   set run4YK to (path to home folder as text) starts with "SSD 500"
   if run4YK then
       set my destinationRootPath to "/Volumes/Production/test3"
       set my testIt to true
   end if
   
   set |⌘| to current application
   set newArray to |⌘|'s NSMutableArray's arrayWithArray:{}
   set destinationRootPath to |⌘|'s class "NSString"'s stringWithString:(my destinationRootPath)
   repeat with thisFile in theFiles
       set thePath to POSIX path of thisFile
       set thePath to (|⌘|'s NSString's stringWithString:thePath)
       set theExtension to thePath's pathExtension()
       set theName to thePath's lastPathComponent()
       set theContainer to thePath's stringByDeletingLastPathComponent()
       set thePred to |⌘|'s NSPredicate's predicateWithFormat_("kMDItemFSName == %@", theName)
       -- build and start query
       set theQuery to |⌘|'s NSMetadataQuery's new()
       (theQuery's setPredicate:thePred)
       (theQuery's setSearchScopes:{theContainer})
       theQuery's startQuery()
       -- loop until it's stopped gathering
       repeat while theQuery's isGathering() as boolean
           delay 0.1
       end repeat
       -- stop and get the first NSMetadataItem (there can only be one in this case)
       theQuery's stopQuery()
       set metaItem to (theQuery's resultAtIndex:0)
       
       -- get the required attribute values, or default alternatives where the attributes weren't found.
       -- Firstly the artist ("authors") and genre values.
       set theArtist to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemAuthorsKey))
       set moveItArtist to (theArtist is not missing value)
       if (theArtist is missing value) then
           set theArtist to "(no artist)"
       else
           set theArtist to (theArtist's componentsJoinedByString:(","))
           set theArtist to my decodeText(theArtist)
       end if
       
       set theGenre to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemMusicalGenreKey))
       set moveItGenre to (theGenre is not missing value) # MOVED
       if (theGenre is missing value) then set theGenre to "(no genre)"
       
       -- Get the key, tempo, and title values.
       set theKey to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemKeySignatureKey))
       set moveItKey to (theKey is not missing value) # MOVED
       if (theKey is missing value) then set theKey to "(no key signature)"
       
       set theTempo to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemTempoKey))
       set moveItTempo to (theTempo is not missing value)
       
       
       # Instructions useful to get a script running flawlessly on my machine!
       if run4YK then
           # Here theKey metadata is NEVER defined so this instruction forbid every move.
           --set moveForbidden to (moveItArtist is false) or (moveItGenre is false) or (moveItKey is false)
           # With this one move is often allowed
           set moveForbidden to (moveItArtist is false) or (moveItGenre is false)
       else
           # The test below matches what you asked in the thread
           # If one of the four flags is false we don't move the file.
           set moveForbidden to (moveItArtist is false) or (moveItGenre is false) or (moveItKey is false) or (moveItTempo is false)
       end if
       
       if moveForbidden then
           log "Don't move : " & thePath & linefeed & "because at least one of these flags is false --> moveItArtist = " & moveItArtist & ", moveItGenre = " & moveItGenre & ", moveItKey = " & moveItKey & ", moveItTempo = " & moveItTempo # don't move the file
           (newArray's addObject:thePath)
       else
           -- Derive a path to the destination folder from the root path, genre, and artist.
           set destinationFolderPath to destinationRootPath's stringByAppendingFormat_("%@/%@", theGenre, theArtist)
           -- Create the folder, if necessary.
           
           my createFolder(destinationFolderPath) -- as text)
           
           set theTitle to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemTitleKey))
           if (theTitle is missing value) then
               --set theTitle to "(no title)"
               -- Derive a destination path for the file with a new name made up from these details.
               # but replace theTtle by the original fileName
               set destinationFileName to (|⌘|'s NSString's stringWithFormat_("%@-%@ %@", theTempo, theKey, theName))
           else
               # CAUTION, if the original title contained underscores they are replaced by slashes in theTitle.
               # We must revert that
               set theTitle to (theTitle's stringByReplacingOccurrencesOfString:"/" withString:"_")
               -- Derive a destination path for the file with a new name made up from these details.
               set destinationFileName to (|⌘|'s NSString's stringWithFormat_("%@-%@ %@.%@", theTempo, theKey, theTitle, theExtension))
           end if
           
           if not testIt then
               # Move the file to the new destination. It'll be renamed in the process.
               # DISABLED DURING TESTS
               (my moveThisFile:thePath uniquelyToPath:destinationFolderPath newName:destinationFileName)
           else
               log (get destinationFolderPath as text) & ", " & destinationFileName
               log "theArtist (Authors) : " & theArtist
               log "theTitle : " & theTitle
               log "theGenre : " & theGenre
               if theKey is not missing value then log "theKey : " & theKey
           end if # not testIt
       end if # (moveItTitle …
   end repeat
   
   if (newArray's |count|()) as integer > 0 then
       set outDoc to (newArray's componentsJoinedByString:linefeed)
       set outPath to (path to desktop as text) & "report Mp3_3pMtroper.txt"
       set outPath to (|⌘|'s NSString's stringWithString:(POSIX path of outPath))
       set theResult to outDoc's writeToFile:outPath atomically:true encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
   end if
end mainBusiness

#=====

-- Creates a new folder. There is no error if the folder already exists, and it will also create intermediate folders if required
on createFolder(POSIXPath)
   log "PosixPath : " & POSIXPath
   set |⌘| to current application
   set theFolderURL to |⌘|'s |NSURL|'s fileURLWithPath:POSIXPath
   set theFileManager to |⌘|'s NSFileManager's defaultManager()
   set {theResult, theError} to theFileManager's createDirectoryAtURL:theFolderURL withIntermediateDirectories:true attributes:(missing value) |error|:(reference)
   if not (theResult as boolean) then error (theError's |localizedDescription|() as text)
end createFolder

# Called with sourceString defined as NSString
on replaceSeveralStrings:sourceString existingStrings:listOfExistingStrings newStrings:listOfNewStrings
   if (count listOfExistingStrings) > (count listOfNewStrings) then error "The first list of strings is longer than the second one !" number 1789
   --set sourceString to current application's NSString's stringWithString:sourceString
   repeat with i from 1 to count listOfExistingStrings
       set sourceString to (sourceString's stringByReplacingOccurrencesOfString:(listOfExistingStrings's item i) withString:(listOfNewStrings's item i))
   end repeat
   return sourceString as text
end replaceSeveralStrings:existingStrings:newStrings:

# Called with sourceString defined as NSString
on decodeText(theText) # Handler written by Nigel GARVEY
   set |⌘| to current application
   
   --set theText to |⌘|'s class "NSString"'s stringWithString:(theText)
   -- If the string contains at least two consecutive 8+bit characters, assume it's a mangled result.
   if ((theText's rangeOfString:("[\\u0080-\\U0010ffff]{2}") options:(|⌘|'s NSRegularExpressionSearch))'s |length|() > 0) then
       set dataObj to (theText's dataUsingEncoding:(|⌘|'s NSISOLatin1StringEncoding))
       set theText to (|⌘|'s class "NSString"'s alloc()'s initWithData:(dataObj) encoding:(|⌘|'s NSUTF8StringEncoding))
   end if
   return theText as text
end decodeText

# Modified version of a Shane STANLEY's handler borrowed from File Manager.scptd
on moveThisFile:aFileOrPath uniquelyToPath:folderOrPath newName:destName
   # makes a NSURL from aFileOrPath
   set theSourceURL to my makeURLFromFileOrPath:aFileOrPath
   # makes a NSURL from folderOrPath
   set theFolderURL to my makeURLFromFileOrPath:folderOrPath
   # Drops the name extension from the proposed name
   set destNameLessExt to destName's |stringByDeletingPathExtension|()
   set theExtension to theSourceURL's |pathExtension|()
   # Builds the URL pointing to the final file
   set theDestURL to theFolderURL's URLByAppendingPathComponent:destName
   set theFileManager to current application's NSFileManager's |defaultManager|()
   set i to 2
   repeat
       set {theResult, theError} to (theFileManager's moveItemAtURL:theSourceURL toURL:theDestURL |error|:(reference))
       if theResult as boolean then exit repeat
       if (theError's code() as integer = current application's NSFileWriteFileExistsError as integer) then -- it already exists, so change name
           set proposedName to (destNameLessExt's stringByAppendingString:(copyString & i))'s stringByAppendingPathExtension:theExtension
           set theDestURL to theFolderURL's URLByAppendingPathComponent:proposedName
           set i to i + 1
       else -- an error other than file already exists, so return error
           error (theError's |localizedDescription|() as text)
       end if
   end repeat
   -- return theDestURL's |path|() as text
end moveThisFile:uniquelyToPath:newName:

# Shane STANLEY's handler borrowed from File Manager.scptd
-- This handler is called by moveItem
on makeURLFromFileOrPath:theFileOrPathInput
   set |⌘| to current application
   -- make it into a Cocoa object for easier comparison
   set theFileOrPath to item 1 of (|⌘|'s NSArray's arrayWithObject:theFileOrPathInput)
   if (theFileOrPath's isKindOfClass:(|⌘|'s NSString)) as boolean then
       if (theFileOrPath's hasPrefix:"/") as boolean then -- full POSIX path
           return |⌘|'s class "NSURL"'s fileURLWithPath:theFileOrPath
       else if (theFileOrPath's hasPrefix:"~") as boolean then -- POSIX path needing ~ expansion
           return |⌘|'s class "NSURL"'s fileURLWithPath:(theFileOrPath's |stringByExpandingTildeInPath|())
       else -- must be HFS path
           return |⌘|'s class "NSURL"'s fileURLWithPath:(POSIX path of theFileOrPathInput)
       end if
   else if (theFileOrPath's isKindOfClass:(|⌘|'s class "NSURL")) as boolean then -- happens with files and aliases in 10.11
       return theFileOrPath
   else -- must be a file or alias
       return |⌘|'s class "NSURL"'s fileURLWithPath:(POSIX path of theFileOrPathInput)
   end if
end makeURLFromFileOrPath:


Offline

 

#52 2017-04-20 07:26:29 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

Since the beginning every scripts were using choose file. Now you ask for choose folder.

As you made the change without knowing what you do, it's not surprising that you get a wrong behavior.

As with your code, theFiles is not a list of aliases but an alias, it's logical that the instruction

Applescript:

repeat with thisFile in theFiles

issue an error number -1728 !

Edit the run handler this way:

Applescript:

on run -- For when testing.
   set theFolder to choose folder with prompt "Please select folder"
   tell application "Finder"
       set theFiles to (files of theFolder) as alias list
   end tell
   mainBusiness(theFiles)
end run

May I know why you modified :

Applescript:

if run4YK then
set my destinationRootPath to "/Volumes/Macintosh HD/Users/Important/Test/"
set my testIt to true
end if

as

Applescript:

if run4YK then
set my destinationRootPath to "/Volumes/Production/test3"
set my testIt to true
end if

This piece of code was designed to allow the script to behave correctly on my machine where there is no device named "Production".

On your machine it's the instruction

Applescript:

property destinationRootPath : "/Volumes/Production/test/" # I assume that it's the one you need

which defines the destination location.

Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) jeudi 20 avril 2017 14:26:25

Last edited by Yvan Koenig (2017-04-20 07:45:05 am)

Offline

 

#53 2017-04-20 12:21:01 pm

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

Oops

Now that you want to use choose folder I forgot to add instructions accepting only the mp3 and/or aiff files.
I'm forced to post the complete script.

Applescript:

(*
rename & move mp3 ASObjC - Æ’

Written for [url]http://macscripter.net/viewtopic.php?id=45629[/url]

by Nigel GARVEY, Shane STANLEY & Yvan KOENIG

2017/04/15

Tested under 10.12.4 public version
# Edited on 2017/04/18 : report the list of files which weren't moved
# Edited on 2017/04/19 : at Nigel GARVEY's request, removed some instructions
# Edited on 2017/04/20 : now in the run handler choose file is replaced by choose folder + code getting the content of the selected folder
# Edited on 2017/04/21 : insert theArtist in the new fileNames. Write the count of moved files and the count of not moved files in the report : "report Mp3_3pMtroper.txt"
# Edited on 2017/04/29 : now write info about a not saved file one by one. Inserted numerous log instructions.
# Edited on 2017/04/30 : added a complementary transcoder handler named decodeText2 to treat an "unknown" encoding applied to theArtist
# Edited on 2017/05/01 : enhanced the handler decodeText2
# Edited on 2017/05/03 : disabled decodeText2 and try to filter the reported odd error
# Edited on 2017/05/11 : removed the log instruction and the decodeText2 handler

CAUTION. THE SCRIPT IS SUPPOSED TO RENAME AND MOVE SOME FILES.
IF YOU ARE NOT SURE OF WHAT IT DOES, EDIT THE PROPERTY NAMED testIt SETTING IT TO THE VALUE : true
*)


use AppleScript version "2.4" # requires at least Yosemite
use scripting additions
use framework "Foundation"

property copyString : " #" -- added to file names for copies; edit to suit your language

property destinationRootPath : "/Volumes/Production/test/" # I assume that it's the one you need # Is silently changed when the script run on my machine


property testIt : false
#################### true = log some metadatas and DON'T MOVE the files
#################### false = don't log these metadatas and MOVE the files

script o
   # These properties are available for the handlers but aren't saved on disk
   property filesMoved : 0
   property filesNotMoved : 0
end script

on run -- For when testing.
   set theFolder to choose folder with prompt "Please select folder"
   set theFiles to its listFolder:(POSIX path of theFolder) # ADDED to get the list of mp3 and/or aiff files
   mainBusiness(theFiles)
end run

on adding folder items to thisFolder after receiving addedItems -- For when run as a folder action.
   # CAUTION : this entry doesn't check that the files are mp3 and/or aiff ones !
   mainBusiness(addedItems)
end adding folder items to

on mainBusiness(theFiles)
   -- Get the root path in a convenient form for use with ASObjC.
   local filesMoved, filesNotMoved, newPath, blank, forYvanKoenig, |⌘|, newArray, destinationRootPath, thisFile, thePath, theExtension
   local theName, theContainer, thePred, theQuery, metaItem, theArtist, moveItArtist, theGenre, moveItGenre, theKey, moveItKey
   local theTempo, moveItTempo, moveForbidden, needComma, wrongMessage, destinationFolderPath, theTitle, destinationFileName
   
   # Prepare the counters of treated files
   set {filesMoved, filesNotMoved} to {0, 0}
   set newPath to POSIX path of ((path to desktop as text) & "report Mp3_3pMtroper.txt")
   # create a blank text file
   set blank to current application's NSString's stringWithString:("")
   set blank to blank's dataUsingEncoding:(current application's NSUTF8StringEncoding)
   (blank's writeToFile:newPath atomically:true) -- as boolean # clears the report
   # Instructions useful to get a script running flawlessly on MY machine!
   set forYvanKoenig to (path to home folder as text) starts with "SSD 500"
   if forYvanKoenig then
       set my destinationRootPath to "/Volumes/Macintosh HD/Users/Important/Test/"
       set my testIt to false --true
   end if
   
   set |⌘| to current application
   set newArray to |⌘|'s NSMutableArray's arrayWithArray:{}
   set destinationRootPath to |⌘|'s class "NSString"'s stringWithString:(my destinationRootPath)
   
   repeat with thisFile in theFiles
       set thePath to (|⌘|'s NSString's stringWithString:(POSIX path of thisFile))
       set theExtension to thePath's pathExtension()
       set theName to thePath's lastPathComponent()
       set theContainer to thePath's stringByDeletingLastPathComponent()
       set thePred to |⌘|'s NSPredicate's predicateWithFormat_("kMDItemFSName == %@", theName)
       -- build and start query
       set theQuery to |⌘|'s NSMetadataQuery's new()
       (theQuery's setPredicate:thePred)
       (theQuery's setSearchScopes:{theContainer})
       theQuery's startQuery()
       -- loop until it's stopped gathering
       repeat while theQuery's isGathering() as boolean
           delay 0.1
       end repeat
       
       -- stop and get the first NSMetadataItem (there can only be one in this case)
       theQuery's stopQuery()
       try
           set metaItem to (theQuery's resultAtIndex:0)
           
           -- get the required attribute values, or default alternatives where the attributes weren't found.
           -- Firstly the artist ("authors") and genre values.
           set theArtist to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemAuthorsKey))
           set moveItArtist to (theArtist is not missing value)
           if (theArtist is missing value) then
               set theArtist to "(no artist)"
           else
               set theArtist to (theArtist's componentsJoinedByString:",")
               set theArtist to my decodeText(theArtist)
           end if
           
           set theGenre to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemMusicalGenreKey))
           set moveItGenre to (theGenre is not missing value)
           if (theGenre is missing value) then set theGenre to "(no genre)"
           
           -- Get the key, tempo, and title values.
           set theKey to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemKeySignatureKey))
           set moveItKey to (theKey is not missing value)
           if (theKey is missing value) then set theKey to "(no key signature)"
           
           set theTempo to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemTempoKey))
           set moveItTempo to (theTempo is not missing value)
           if (theTempo is missing value) then set theKey to "(no tempo)"
           
           # Instructions useful to get a script running flawlessly on MY machine!
           if forYvanKoenig then
               # Here theKey metadata is NEVER defined so this instruction forbid every move.
               --set moveForbidden to (moveItArtist is false) or (moveItGenre is false) or (moveItKey is false)
               # With this one move is often allowed
               set moveForbidden to (moveItArtist is false) or (moveItGenre is false)
           else
               # The test below matches what you asked in the thread. If one of the four flags is false we don't move the file.
               set moveForbidden to (moveItArtist is false) or (moveItGenre is false) or (moveItKey is false) or (moveItTempo is false)
           end if
           
           if moveForbidden then
               set needComma to false
               set wrongMessage to "Not moved : " & thePath & linefeed & " because these flags are false --> "
               if moveItArtist is false then
                   set wrongMessage to wrongMessage & "moveItArtist"
                   set needComma to true
               end if # moveItArtist
               if moveItGenre is false then
                   if needComma then set wrongMessage to wrongMessage & ", "
                   set wrongMessage to wrongMessage & "moveItGenre"
                   set needComma to true
               end if # moveItGenre
               if moveItKey is false then
                   if needComma then set wrongMessage to wrongMessage & ", "
                   set wrongMessage to wrongMessage & "moveItKey"
                   set needComma to true
               end if # moveItKey
               if moveItTempo is false then
                   if needComma then set wrongMessage to wrongMessage & ", "
                   set wrongMessage to wrongMessage & "moveItTempo"
                   set needComma to true
               end if # moveItTempo
               set wrongMessage to wrongMessage & linefeed
               my writeTo(newPath, wrongMessage)
               set filesNotMoved to filesNotMoved + 1
           else
               -- Derive a path to the destination folder from the root path, genre, and artist.
               set destinationFolderPath to destinationRootPath's stringByAppendingFormat_("%@/%@", theGenre, theArtist)
               
               -- Create the folder, if necessary.
               my createFolder(destinationFolderPath) -- as text)
               
               set theTitle to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemTitleKey))
               if (theTitle is missing value) then
                   --set theTitle to "(no title)"
                   -- Derive a destination path for the file with a new name made up from these details.
                   # but replace theTitle by the original fileName
                   set destinationFileName to (|⌘|'s NSString's stringWithFormat_("{%@-%@} %@ - %@", theTempo, theKey, theArtist, theName))
               else
                   # CAUTION, if the original title contained underscores they are replaced by slashes in theTitle.
                   # We must revert that
                   set theTitle to (theTitle's stringByReplacingOccurrencesOfString:"/" withString:"_")
                   -- Derive a destination path for the file with a new name made up from these details.
                   set destinationFileName to (|⌘|'s NSString's stringWithFormat_("{%@-%@} %@ - %@.%@", theTempo, theKey, theArtist, theTitle, theExtension))
               end if
               if not my testIt then
                   # Move the file to the new destination. It'll be renamed in the process.
                   # DISABLED DURING TESTS
                   (my moveThisFile:thePath uniquelyToPath:destinationFolderPath newName:destinationFileName)
                   set filesMoved to filesMoved + 1
               else
                   if theKey is not missing value then log "theKey : " & theKey
                   set filesMoved to filesMoved + 1 # ADDED on 2017/04/25
               end if # not testIt
           end if # (moveItTitle …
           
       on error errMsg number errNbr
           # report the file as not moved
           set wrongMessage to "Not moved : " & thePath & linefeed & " Error " & "number #" & errNbr & linefeed & " " & errMsg & linefeed
           my writeTo(thePath, wrongMessage)
           set filesNotMoved to filesNotMoved + 1
       end try
   end repeat
   my writeTo(newPath, (linefeed & filesMoved & " were moved." & linefeed & filesNotMoved & " were not moved !" & linefeed))
end mainBusiness

#=====

-- Creates a new folder. There is no error if the folder already exists, and it will also create intermediate folders if required
on createFolder(POSIXPath)
   set |⌘| to current application
   set theFolderURL to |⌘|'s |NSURL|'s fileURLWithPath:POSIXPath
   set theFileManager to |⌘|'s NSFileManager's defaultManager()
   set {theResult, theError} to theFileManager's createDirectoryAtURL:theFolderURL withIntermediateDirectories:true attributes:(missing value) |error|:(reference)
   if not (theResult as boolean) then error (theError's |localizedDescription|() as text)
end createFolder

# Called with sourceString defined as NSString
on replaceSeveralStrings:sourceString existingStrings:listOfExistingStrings newStrings:listOfNewStrings
   if (count listOfExistingStrings) > (count listOfNewStrings) then error "The first list of strings is longer than the second one !" number 1789
   --set sourceString to current application's NSString's stringWithString:sourceString
   repeat with i from 1 to count listOfExistingStrings
       set sourceString to (sourceString's stringByReplacingOccurrencesOfString:(listOfExistingStrings's item i) withString:(listOfNewStrings's item i))
   end repeat
   return sourceString as text
end replaceSeveralStrings:existingStrings:newStrings:

# Called with sourceString defined as NSString
on decodeText(theText) # Handler written by Nigel GARVEY
   set |⌘| to current application
   --set theText to |⌘|'s class "NSString"'s stringWithString:(theText)
   -- If the string contains at least two consecutive 8+bit characters, assume it's a mangled result.
   if ((theText's rangeOfString:("[\\u0080-\\U0010ffff]{2}") options:(|⌘|'s NSRegularExpressionSearch))'s |length|() > 0) then
       set dataObj to (theText's dataUsingEncoding:(|⌘|'s NSISOLatin1StringEncoding))
       set theText to (|⌘|'s class "NSString"'s alloc()'s initWithData:(dataObj) encoding:(|⌘|'s NSUTF8StringEncoding))
   end if
   return theText as text
end decodeText

# Modified version of a Shane STANLEY's handler borrowed from File Manager.scptd
on moveThisFile:aFileOrPath uniquelyToPath:folderOrPath newName:destName
   # makes a NSURL from aFileOrPath
   set theSourceURL to my makeURLFromFileOrPath:aFileOrPath
   # makes a NSURL from folderOrPath
   set theFolderURL to my makeURLFromFileOrPath:folderOrPath
   # Drops the name extension from the proposed name
   set destNameLessExt to destName's |stringByDeletingPathExtension|()
   set theExtension to theSourceURL's |pathExtension|()
   # Builds the URL pointing to the final file
   set theDestURL to theFolderURL's URLByAppendingPathComponent:destName
   set theFileManager to current application's NSFileManager's |defaultManager|()
   set i to 2
   repeat
       set {theResult, theError} to (theFileManager's moveItemAtURL:theSourceURL toURL:theDestURL |error|:(reference))
       if theResult as boolean then exit repeat
       if (theError's code() as integer = current application's NSFileWriteFileExistsError as integer) then -- it already exists, so change name
           set proposedName to (destNameLessExt's stringByAppendingString:(copyString & i))'s stringByAppendingPathExtension:theExtension
           set theDestURL to theFolderURL's URLByAppendingPathComponent:proposedName
           set i to i + 1
       else -- an error other than file already exists, so return error
           error (theError's |localizedDescription|() as text)
       end if
   end repeat
   -- return theDestURL's |path|() as text
end moveThisFile:uniquelyToPath:newName:

# Shane STANLEY's handler borrowed from File Manager.scptd
-- This handler is called by moveItem
on makeURLFromFileOrPath:theFileOrPathInput
   set |⌘| to current application
   -- make it into a Cocoa object for easier comparison
   set theFileOrPath to item 1 of (|⌘|'s NSArray's arrayWithObject:theFileOrPathInput)
   if (theFileOrPath's isKindOfClass:(|⌘|'s NSString)) as boolean then
       if (theFileOrPath's hasPrefix:"/") as boolean then -- full POSIX path
           return |⌘|'s class "NSURL"'s fileURLWithPath:theFileOrPath
       else if (theFileOrPath's hasPrefix:"~") as boolean then -- POSIX path needing ~ expansion
           return |⌘|'s class "NSURL"'s fileURLWithPath:(theFileOrPath's |stringByExpandingTildeInPath|())
       else -- must be HFS path
           return |⌘|'s class "NSURL"'s fileURLWithPath:(POSIX path of theFileOrPathInput)
       end if
   else if (theFileOrPath's isKindOfClass:(|⌘|'s class "NSURL")) as boolean then -- happens with files and aliases in 10.11
       return theFileOrPath
   else -- must be a file or alias
       return |⌘|'s class "NSURL"'s fileURLWithPath:(POSIX path of theFileOrPathInput)
   end if
end makeURLFromFileOrPath:

on listFolder:POSIXPath # handler using ASObjC ADDED
   set fileManager to current application's NSFileManager's defaultManager()
   set aURL to current application's |NSURL|'s fileURLWithPath:POSIXPath
   set theOptions to (current application's NSDirectoryEnumerationSkipsPackageDescendants as integer) + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)
   set theEnumerator to fileManager's enumeratorAtURL:aURL includingPropertiesForKeys:{} options:theOptions errorHandler:(missing value)
   set theFiles to theEnumerator's allObjects()
   set theFiles to theFiles's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:"(lastPathComponent ENDSWITH '.mp3') OR (lastPathComponent ENDSWITH '.aiff')")
   return theFiles as list # if we work upon files
   --return (theFiles's valueForKey:"path") as list # if we work upon POSIX paths
end listFolder:

#=====

on writeTo(newPath, theString)
   set fileAccess to current application's NSFileHandle's fileHandleForWritingAtPath:newPath
   try
       tell fileAccess to seekToEndOfFile()
       set theString to current application's NSString's stringWithString:theString
       set stringData to theString's dataUsingEncoding:(current application's NSUTF8StringEncoding)
       tell fileAccess to writeData:stringData
       set theResult to true
   end try
   tell fileAccess to closeFile()
end writeTo

#=====

# Edited on 2017/04/21 : insert theArtist in the new fileNames. Write the count of moved files and the count of not moved files in the report : "report Mp3_3pMtroper.txt"

# Edited on 2017/04/30 : added a complementary transcoder handler named decodeText2 to treat an "unknown" encoding applied to theArtist

# Edited on 2017/05/01 : enhanced the handler decodeText2

# Edited on 2017/05/03 : disabled decodeText2 and try to filter the reported odd error

# Edited on 2017/05/11 : removed the log instruction and the decodeText2 handler

I was far from home so I was unable to edit this message before my return.

Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) jeudi 20 avril 2017 19:20:56

Last edited by Yvan Koenig (2017-05-11 01:57:14 pm)

Offline

 

#54 2017-04-20 12:50:39 pm

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

Here is the "short old-fashioned" SLOW version.

Applescript:

use AppleScript version "2.4" # requires at least Yosemite
use scripting additions
use framework "Foundation"

script o
   property targetFile : missing value
   property filesMoved : 0
   property filesNotMoved : 0
end script

# The main code

set theFolder to choose folder with prompt "Please select a folder containing MP3/AIFF files" # ADDED

set theFiles to its listFolder:(POSIX path of theFolder) # ADDED

set o's targetFile to ((path to desktop as text) & "report Mp3_3pMtroper.txt") as «class furl»

# Creates the file reporting files not moved
my writeto(o's targetFile, "", «class utf8», false)

repeat with aFile in theFiles
   my treatThisFile(aFile)
end repeat

# Write the count of moved and not moved files in the text file "report Mp3_3pMtroper.txt"
my writeto(o's targetFile, linefeed & o's filesMoved & " were moved." & linefeed & o's filesNotMoved & " were not moved !", «class utf8», true)

#===== Below are the handlers

on treatThisFile(theFile)
   set posixFilePath to the quoted form of (POSIX path of theFile)
   
   set genreTag to (do shell script "mdls " & posixFilePath & " -name kMDItemMusicalGenre")
   set artistTag to (do shell script "mdls " & posixFilePath & " -name kMDItemAuthors")
   set tempoTag to (do shell script "mdls " & posixFilePath & " -name kMDItemTempo")
   set keyTag to (do shell script "mdls " & posixFilePath & " -name kMDItemKeySignature")
   
   set theGenre to text ((offset of "= " in genreTag) + 3) through -2 of genreTag
   set theArtist to text ((offset of "= " in artistTag) + 9) through -4 of artistTag
   set theTempo to text ((offset of "= " in tempoTag) + 2) through -1 of tempoTag
   set theKey to text ((offset of "= " in keyTag) + 3) through -2 of keyTag
   
   #SOME MP3 TAGS ARE NOT PROPERLY FILLED OUT- THIS BELOW PART DOESNT WORK AS SCRIPT PROCEEDS??????. # problem solved below
   if ((count theGenre) ≤ (count "(null)") and theGenre contains "null") or ((count theArtist) ≤ (count "(null)") and theArtist contains "null") or ((count theTempo) ≤ (count "(null)") and theTempo contains "null") or ((count theKey) ≤ (count "(null)") and theKey contains "null") then
       
       # The file can't be moved. Write it's path in the dedicated text file
       my writeto(o's targetFile, theFile as text, «class utf8», true)
       set o's filesNotMoved to (o's filesNotMoved) + 1
   else
       # There was no need to extract this info if one of the four other ones is null
       set titleTag to (do shell script "mdls " & posixFilePath & " -name kMDItemTitle")
       set theTitle to text ((offset of "= " in titleTag) + 3) through -2 of titleTag
       
       # For some files, theTitle is returned as "null" or "(null)" so it may generate duplicates # Edited
       # I choose to use the original name deprieved of the extension
       
       if (count theTitle) ≤ (count "(null)") and theTitle contains "null" then # EDITED
           tell application "System Events" # ADDED
               set theTitle to text 1 thru -5 of (get name of file (theFile as text))
           end tell
       end if
       
       set renamedTitle to ("{" & theTempo & "-" & theKey & "} " & theArtist & " - " & theTitle)
       
       set DestFolder to ("/Volumes/Production/test/" & theGenre & "/" & theArtist)
       --set DestFolder to ("/Volumes/Macintosh HD/Users/Important/Test/" & theGenre & "/" & theArtist)
       
       my createFolder:DestFolder
       
       set DestFolder to POSIX file DestFolder
       
       set theFile to (theFile as text) as alias # ADDED. Finder refuse to get extension or rename the object returned by the ASObjC handler
       tell application "Finder"
           set theExtension to name extension of theFile
           set name of theFile to renamedTitle & "." & theExtension #AS MAYBE AIFF OR MP3
           try
               move theFile to DestFolder
               set o's filesMoved to (o's filesMoved) + 1
               -- log ">>>>> " & theFile & linefeed & DestFolder
           on error errMsg
               -- display dialog renamedTitle & errMsg # IF ALREADY EXISTS WILL PROMPT
               my writeto(o's targetFile, (theFile as text) & errMsg, «class utf8», true)
               set o's filesNotMoved to (o's filesNotMoved) + 1
           end try
           
       end tell
   end if # (moveitGenre is false) or…
end treatThisFile

#=====

on listFolder:POSIXPath # handler using ASObjC
   set fileManager to current application's NSFileManager's defaultManager()
   set aURL to current application's |NSURL|'s fileURLWithPath:POSIXPath
   set theOptions to (current application's NSDirectoryEnumerationSkipsPackageDescendants as integer) + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)
   set theEnumerator to fileManager's enumeratorAtURL:aURL includingPropertiesForKeys:{} options:theOptions errorHandler:(missing value)
   set theFiles to theEnumerator's allObjects()
   set theFiles to theFiles's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:"(lastPathComponent ENDSWITH '.mp3') OR (lastPathComponent ENDSWITH '.aiff')")
   return theFiles as list # if we work upon files
   --return (theFiles's valueForKey:"path") as list # if we work upon POSIX paths
end listFolder:


-- Creates a new folder. There is no error if the folder already exists, and it will also create intermediate folders if required
on createFolder:POSIXPath
   set |⌘| to current application
   set theFolderURL to |⌘|'s |NSURL|'s fileURLWithPath:POSIXPath
   set theFileManager to |⌘|'s NSFileManager's defaultManager()
   set {theResult, theError} to theFileManager's createDirectoryAtURL:theFolderURL withIntermediateDirectories:true attributes:(missing value) |error|:(reference)
   if not (theResult as boolean) then error (theError's |localizedDescription|() as text)
end createFolder:

#=====
(*
Handler borrowed to Regulus6633 - [url]http://macscripter.net/viewtopic.php?id=36861[/url]
*)

on writeto(targetFile, theData, dataType, apendData)
   -- targetFile is the path to the file you want to write
   -- theData is the data you want in the file.
   -- dataType is the data type of theData and it can be text, list, record etc.
   -- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
   try
       --set targetFile to targetFile as «class furl» # no need, the calling instructions pass a «class furl» object
       set openFile to open for access targetFile with write permission
       if not apendData then set eof of openFile to 0
       write (theData & linefeed) to openFile starting at eof as dataType
       close access openFile
       return true
   on error
       try
           close access targetFile
       end try
       return false
   end try
end writeto

#=====

I hope that I didn't forgot a change to match your settings after testing it with mines.

Added code writing the count of moved and the count of not-moved files in the file : "report Mp3_3pMtroper.txt"

Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) jeudi 20 avril 2017 19:49:29

Last edited by Yvan Koenig (2017-04-21 09:29:32 am)

Offline

 

#55 2017-04-21 06:30:19 am

squigee90
Member
Registered: 2017-03-26
Posts: 26

Re: Applescript to read mp3 metatags and sort file into folder

thanks Yvan

I'm looking to change the renaming format to: {118-Gmaj}  Elton John - Tiny Dancer

In the script I found where it does it, however not sure how to script it (the older script I could do it)

Also would it be hard to script how many mp3/aiff files were moved after completing?

Applescript:


           set theTitle to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemTitleKey)) --SET THE NEW FILE NAME
           if (theTitle is missing value) then
               --set theTitle to "(no title)"
               -- Derive a destination path for the file with a new name made up from these details.
               # but replace theTtle by the original fileName
               set destinationFileName to (|⌘|'s NSString's stringWithFormat_("%@-%@ %@", theTempo, theKey, theName))
           else
               # CAUTION, if the original title contained underscores they are replaced by slashes in theTitle.
               # We must revert that
               set theTitle to (theTitle's stringByReplacingOccurrencesOfString:"/" withString:"_")
               -- Derive a destination path for the file with a new name made up from these details.
               set destinationFileName to (|⌘|'s NSString's stringWithFormat_("%@-%@ %@.%@", theTempo, theKey, theTitle, theExtension))
           end if

Offline

 

#56 2017-04-21 07:51:04 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

My physical Internet connexion is down. So I use a WiFi hotSpot whose performance are far from good.
Don't worry if responses don't come quickly.

As far as I know, If I understand well, at this time you get

118-Gmaj Tiny Dancer.mp3

I ask because the metadatas tempo and key are never defined here.

If it's really what you get, edit the instructions as :

Applescript:

           if (theTitle is missing value) then
               --set theTitle to "(no title)"
               -- Derive a destination path for the file with a new name made up from these details.
               # but replace theTtle by the original fileName
               set destinationFileName to (|⌘|'s NSString's stringWithFormat_("{%@-%@} %@ - %@", theTempo, theKey, theArtist, theName))
           else
               # CAUTION, if the original title contained underscores they are replaced by slashes in theTitle.
               # We must revert that
               set theTitle to (theTitle's stringByReplacingOccurrencesOfString:"/" withString:"_")
               -- Derive a destination path for the file with a new name made up from these details.
               set destinationFileName to (|⌘|'s NSString's stringWithFormat_("{%@-%@} %@ - %@.%@", theTempo, theKey, theArtist, theTitle, theExtension))
           end if

The newly required feature is available in messages #53 and #54


Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) vendredi 21 avril 2017 14:50:14

Last edited by Yvan Koenig (2017-04-21 09:31:10 am)

Offline

 

#57 2017-04-24 09:18:33 am

squigee90
Member
Registered: 2017-03-26
Posts: 26

Re: Applescript to read mp3 metatags and sort file into folder

awesome that worked. Would it be hard to put a couple lines of script in, so that at the end I know how many files were moved?

Like a prompt saying "412 Files were successfully move to /test/test"

Offline

 

#58 2017-04-24 11:24:07 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

I carefully wrote :

Applescript:

# Edited on 2017/04/21 : insert theArtist in the new fileNames. Write the count of moved files and the count of not moved files in the report : "report Mp3_3pMtroper.txt"

at the beginning of the script using ASObjC.

At the beginning of the old fashioned one everybody may read :

Applescript:

use AppleScript version "2.4" # requires at least Yosemite
use scripting additions
use framework "Foundation"

script o
   property targetFile : missing value
   property filesMoved : 0
   property filesNotMoved : 0
end script

# The main code

set theFolder to choose folder with prompt "Please select a folder containing MP3/AIFF files" # ADDED

set theFiles to its listFolder:(POSIX path of theFolder) # ADDED

set o's targetFile to ((path to desktop as text) & "report Mp3_3pMtroper.txt") as «class furl»

# Creates the file reporting files not moved
my writeto(o's targetFile, "", «class utf8», false)

repeat with aFile in theFiles
   my treatThisFile(aFile)
end repeat

# Write the count of moved and not moved files in the text file "report Mp3_3pMtroper.txt"
my writeto(o's targetFile, linefeed & o's filesMoved & " were moved." & linefeed & o's filesNotMoved & " were not moved !", «class utf8», true)

Isn't it clear enough ?


Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) lundi 24 avril 2017 18:22:46

Offline

 

#59 2017-04-24 10:32:31 pm

squigee90
Member
Registered: 2017-03-26
Posts: 26

Re: Applescript to read mp3 metatags and sort file into folder

its clear looking at the script. But I need it in the newer script because with the old fashion script it has a few problems- which I have come to realise...such as doing bulk files creates strange artist name folders.

So I'm trying to incorporate the below into the "newer" script but I'm getting unrecognized handler sent to object at the line:

my writeto(o's targetFile, "", «class utf8», false)

error

Applescript:


error "*** -[BAGenericObjectNoDeleteOSAID writeto]: unrecognized selector sent to object <BAGenericObjectNoDeleteOSAID @0x7fe15e85fa70: OSAID(1) ComponentInstance(0x840007)>" number -10000

Applescript:


script o
property targetFile : missing value
property filesMoved : 0
property filesNotMoved : 0
end script

set o's targetFile to ((path to desktop as text) & "report Mp3_3pMtroper.txt") as «class furl»

my writeto(o's targetFile, "", «class utf8», false)

my writeto(o's targetFile, linefeed & o's filesMoved & " were moved." & linefeed & o's filesNotMoved & " were not moved !", «class utf8», true)

Offline

 

#60 2017-04-25 07:42:35 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

Oops

One instruction was missing.
I added it.

I'm back while the Wifi Hotspot is active.

The script using ASObjC doesn't use the handler Writeto.
It rely upon ASObjC instructions which were available in the script.

Applescript:

   
   set theCounts to (|⌘|'s NSString's stringWithString:(linefeed & filesMoved & " were moved." & linefeed & filesNotMoved & " were not moved !"))
   (newArray's addObject:theCounts)
   set outDoc to (newArray's componentsJoinedByString:linefeed)
   set outPath to (path to desktop as text) & "report Mp3_3pMtroper.txt"
   set outPath to (|⌘|'s NSString's stringWithString:(POSIX path of outPath))
   set theResult to outDoc's writeToFile:outPath atomically:true encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)

Due to the missing instruction, the counter was not incremented so your "report Mp3_3pMtroper.txt" file was displaying something like :

0 were moved.
xx were not moved !


Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) mardi 25 avril 2017 14:42:33

Last edited by Yvan Koenig (2017-04-25 08:07:10 am)

Offline

 

#61 2017-04-26 05:11:48 am

squigee90
Member
Registered: 2017-03-26
Posts: 26

Re: Applescript to read mp3 metatags and sort file into folder

It seems now that it doesn't create the txt file. I have added the missing instruction down the bottom of mainbusiness??

Yet the script still moves the file to the destination. I also tried taking away the defined properties (targetfile, filesmoved, filesnotmoved) but it does the same thing.

Last edited by squigee90 (2017-05-05 08:38:38 pm)

Offline

 

#62 2017-04-26 05:15:53 am

squigee90
Member
Registered: 2017-03-26
Posts: 26

Re: Applescript to read mp3 metatags and sort file into folder

the other issue I get is when I select a folder that has "multiple" files within, I get a error at line:
       

Applescript:


       -- stop and get the first NSMetadataItem (there can only be one in this case)
       theQuery's stopQuery()
       set metaItem to (theQuery's resultAtIndex:0)

Error

Applescript:


error "*** -[NSMetadataQuery resultAtIndex:]: index (0) out of bounds (0)" number -10000

Offline

 

#63 2017-04-27 04:56:07 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

When I apply the script of message #53 on a folder containing 15 mp3 files,
as I posted in my late message, 11 are moved, 4 aren't.

I compared the content of your last message to the one in message #53.

Below is the list of oddities available:

Applescript:

# Prepare the counters of treated files # YOU DROPPED IT
set filesMoved to 0 # YOU DROPPED IT
set filesNotMoved to 0 # YOU DROPPED IT

# You have.
set my destinationRootPath to "/Volumes/Production/test6" --YOU NEED TO CHANGE DESTINATION PATH
# the comment is incorrect since several days.
# The instruction is designed to define the path used on MY machine.
# it MUST be:
set my destinationRootPath to "/Volumes/Macintosh HD/Users/Important/Test/" --"/Volumes/Production/test3"

set filesNotMoved to filesNotMoved + 1 # YOU DROPPED IT

# The comment to the instruction below is WRONG. It's not mine. The variable theTitle is not set to the file name !!!!
set theTitle to (metaItem's valueForAttribute:(|⌘|'s NSMetadataItemTitleKey)) --SET THE NEW FILE NAME


set filesMoved to filesMoved + 1 # YOU DROPPED IT


set filesMoved to filesMoved + 1 # ADDED on 2017/04/25 -- YOU DROPPED IT

--if (newArray's |count|()) as integer > 0 then # WAS REMOVED WHEN I ADDED THE COUNTERS


-- end if # WAS REMOVED WHEN I ADDED THE COUNTERS

Please use the script in message #53 without changing anything except the path used on your machine defined by the instruction :

property destinationRootPath : "/Volumes/Production/test/" # I assume that it's the one you need # Is silently changed when the script run on my machine

If you want to work upon Test6, it's this instruction and only this one which must be edited.



Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) jeudi 27 avril 2017 11:56:01

Offline

 

#64 2017-04-27 08:51:35 am

squigee90
Member
Registered: 2017-03-26
Posts: 26

Re: Applescript to read mp3 metatags and sort file into folder

ok, I ran the script from #53 WITHOUT editing anything. It worked for one folder! which was the first time I ran the script.

However the second time I ran the script I selected another folder, and got the same error again.


Applescript:


error "*** -[NSMetadataQuery resultAtIndex:]: index (0) out of bounds (0)" number -10000

At line:
-- stop and get the first NSMetadataItem (there can only be one in this case)
        theQuery's stopQuery()
        set metaItem to (theQuery's resultAtIndex:0)     <<<<got error at this line.

Offline

 

#65 2017-04-27 09:10:31 am

squigee90
Member
Registered: 2017-03-26
Posts: 26

Re: Applescript to read mp3 metatags and sort file into folder

ok now it didn't error this time, but only moved one file? which is strange.

The source folder is located on my desktop not on the Production drive- but that shouldn't matter.

Also the source folder is a already sorted mp3/aiff folder structure with the genre>artist from the script. Inside some artist folders are mp3s, so It should find them and move them, but instead throws this error.

Offline

 

#66 2017-04-27 09:25:16 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

When  the script moved only one file, what is reported in the text file ?
You are supposed to see the list of the files which were not moved.
More,the script is carefully designed so that the history displayed in the dedicated window is supposed to report something like :

	(*Don't move : /Users/??????????/Desktop/111 autre/Ah ! Vous dirai-je maman.mp3
because at least one of these flags is false --> moveItArtist = false, moveItGenre = false, moveItKey = false, moveItTempo = false*)
	(*Don't move : /Users/??????????/Desktop/111 autre/Aldo Romano, Louis Sclavis, Henri Texier - live 2005 - 3-3.mp3
because at least one of these flags is false --> moveItArtist = false, moveItGenre = false, moveItKey = false, moveItTempo = false*)
	(*Don't move : /Users/??????????/Desktop/111 autre/Ancient_Beijing.mp3
because at least one of these flags is false --> moveItArtist = false, moveItGenre = true, moveItKey = false, moveItTempo = false*)
	(*Don't move : /Users/??????????/Desktop/111 autre/Anne Sylvestre - Une sorcière comme les autres .mp3
because at least one of these flags is false --> moveItArtist = false, moveItGenre = false, moveItKey = false, moveItTempo = false*)
	(*Don't move : /Users/??????????/Desktop/111 autre/Bach_Two_Part_Invention_in_C_Major.mp3
because at least one of these flags is false --> moveItArtist = false, moveItGenre = false, moveItKey = false, moveItTempo = false*)
	(*Don't move : /Users/??????????/Desktop/111 autre/Barbara (1962) les boutons dorés.mp3
because at least one of these flags is false --> moveItArtist = false, moveItGenre = false, moveItKey = false, moveItTempo = false*)

According to what you asked, a file is not moved if at least ONE of the 4 flags is set to false because the related metadata is unavailable.

No idea about what you get.

With the folder "1dossier" I got:

/Users/??????????/Desktop/1 dossier/Anne Sylvestre - Mes amis d'autrefois (Live).mp3
/Users/??????????/Desktop/1 dossier/Anne Sylvestre en studio _ Des calamars à l'harmonica 2.mp3
/Users/??????????/Desktop/1 dossier/Anne Sylvestre en studio _ Des calamars à l'harmonica.mp3
/Users/??????????/Desktop/1 dossier/Jolie bouteille Sacrée bouteille.mp3
/Users/??????????/Desktop/1 dossier/Mouloudji chante Boris Vian le politique.mp3
/Users/??????????/Desktop/1 dossier/MOUSTAKI Maman Papa.mp4.mp3
/Users/??????????/Desktop/1 dossier/Romano-Sclavis-Texier - live 2005 - 33.mp3
/Users/??????????/Desktop/1 dossier/Serge Reggiani - Ma fille (Lyrics).mp3
/Users/??????????/Desktop/1 dossier/Serge Reggiani -Le Petit Garçon.mp3
/Users/??????????/Desktop/1 dossier/Serge Reggiani _Le petit garçon_.mp3
/Users/??????????/Desktop/1 dossier/Supplique pour être enterré sur une plage de Sète.mp3
/Users/??????????/Desktop/1 dossier/The Future of Jazz_ Billy Taylor_George Russell_Bill Evans.mp3
/Users/??????????/Desktop/1 dossier/Un été.mp3

11 were moved.
13 were not moved !

With the folder "111 autre"  containing 89 files in 4 subfolders I got :

89 were moved.
0 were not moved !

Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) jeudi 27 avril 2017 16:25:04

Last edited by Yvan Koenig (2017-04-27 09:34:43 am)

Offline

 

#67 2017-04-29 08:23:58 am

squigee90
Member
Registered: 2017-03-26
Posts: 26

Re: Applescript to read mp3 metatags and sort file into folder

ok I've uploaded a screen capture video showing the issue. You will get a idea of the source folder structure and files I'm trying to move.


https://youtu.be/z75mEF-ivUY


I just tried a artist folder from within that "Deep House" folder and it worked fine. Got the text file with the following text.

2 were moved.
0 were not moved !


However when I get this error, it doesn't create a text file.

Last edited by squigee90 (2017-04-29 08:28:48 am)

Offline

 

#68 2017-04-29 11:15:00 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

I apologize but your video doesn't help.
With my 73 years old eyes I'm quite unable to read what is displayed.

I'm always unable to guess what fails on your machine.
I made new tests with a folder containing 21 folders and didn't got the described error.

It would have been more useful to reproduce what is displayed in the history window.

I replaced the content of message #53 by an edited version.
This time it write infos about not saved file one by one like the old fashioned script.
I inserted a lot of log instructions.
When you will get the infamous error, looking in the history window will tell you which is the last instruction correctly executed.
If you pass this info it would be easier to try to understand what failed.


Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) samedi 29 avril 2017 18:14:03

Offline

 

#69 2017-04-30 07:42:10 am

squigee90
Member
Registered: 2017-03-26
Posts: 26

Re: Applescript to read mp3 metatags and sort file into folder

ok I ran the script from #53
Got the error again, seems to be stopping at point 27. A text file was created on the desktop but nothing in it.


This is from log history window - replies -

Applescript:


tell application "Script Editor"
   choose folder with prompt "Please select folder"
       --> alias "Macintosh HD:Users:mattsquires:Desktop:SOURCE:Deep House:"
end tell
(*point 000*)
tell current application
   path to desktop as text
       --> "Macintosh HD:Users:mattsquires:Desktop:"
   (*point 010*)
   path to home folder as text
       --> "Macintosh HD:Users:mattsquires:"
   (*point 014*)
   (*point 015*)
   (*point 016*)
   (*point 017*)
   (*point 018*)
   (*point 019*)
   (*point 020*)
   (*point 021*)
   (*point 022*)
   (*point 023*)
   (*point 024*)
   (*point 025*)
   (*point 026*)
   (*point 027*)
Result:
error "*** -[NSMetadataQuery resultAtIndex:]: index (0) out of bounds (0)" number -10000

Offline

 

#70 2017-04-30 08:04:17 am

squigee90
Member
Registered: 2017-03-26
Posts: 26

Re: Applescript to read mp3 metatags and sort file into folder

ok I've found the issue, it was a mp3 file with some odd characters in its names.

Once I took that out of the folder it worked fine.

When the script sorted it previously, it put some weird stuff in the title.

I've uploaded the original and sorted mp3 here, so you can try & see why it would stop the script from working.

https://www.dropbox.com/sh/twxdfvgxm4em … 5dt7a?dl=0

The sorted problematic file name was:

{125-Bbm}  A.Squared \U00bb download-techno.com - Third Eye (Original Mix) » download-techno.com.mp3



Is there anyway to prevent this? Without having to go through hundreds looking to change any long filenames.

Last edited by squigee90 (2017-04-30 08:18:49 am)

Offline

 

#71 2017-04-30 11:04:52 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

Would be fine to report which is the last point logged when you treat the infamous file.
This would help to know where a change would be welcome.
According to the given string, I may know that
theTempo is 125
theKey is Bbm
theArtist is A.Squared \\U00bb download-techno.com
theTitle is Third Eye (Original Mix) » download-techno.com

It appears that theArtist isn't encoded the same way than theTitle.
Alas, it's not the encoding which I encountered on my side, encoding treated by the handler

Applescript:

# Called with sourceString defined as NSString
on decodeText(theText) # Handler written by Nigel GARVEY
set |⌘| to current application
--set theText to |⌘|'s class "NSString"'s stringWithString:(theText)
-- If the string contains at least two consecutive 8+bit characters, assume it's a mangled result.
if ((theText's rangeOfString:("[\\u0080-\\U0010ffff]{2}") options:(|⌘|'s NSRegularExpressionSearch))'s |length|() > 0) then
set dataObj to (theText's dataUsingEncoding:(|⌘|'s NSISOLatin1StringEncoding))
set theText to (|⌘|'s class "NSString"'s alloc()'s initWithData:(dataObj) encoding:(|⌘|'s NSUTF8StringEncoding))
end if
return theText as text
end decodeText

Alas I'm unable to create a general modified version of this handler.
If Nigel GARVEY see this thread maybe he would build such handler.
At this time I created one able to treat two characters

Applescript:

on decodeText2(theText) # Temporary transcoder handler
   set theText to current application's class "NSString"'s stringWithString:(theText)
   set theText to my replaceSeveralStrings:theText existingStrings:{"\\U00ab", "\\U00bb"} newStrings:{"«", "»"}
   return theText
end decodeText2

I inserted the enhanced script in message #53.


Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) dimanche 30 avril 2017 18:02:44

Browser: Safari 601.7.7
Operating System: Mac OS X (10.10)

Offline

 

#72 2017-05-01 07:12:18 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

I enhanced the handler decodeText2


Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) lundi 1 mai 2017 14:12:13

Offline

 

#73 2017-05-01 05:01:39 pm

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 4412

Re: Applescript to read mp3 metatags and sort file into folder

Yvan Koenig wrote:

Alas I'm unable to create a general modified version of this handler.
If Nigel GARVEY see this thread maybe he would build such handler.
At this time I created one able to treat two characters

Applescript:

on decodeText2(theText) # Temporary transcoder handler
   set theText to current application's class "NSString"'s stringWithString:(theText)
   set theText to my replaceSeveralStrings:theText existingStrings:{"\\U00ab", "\\U00bb"} newStrings:{"«", "»"}
   return theText
end decodeText2

I inserted the enhanced script in message #53.


Hi Yvan.

I only noticed this earlier this evening just before I had to go out.

I don't understand the problem it's supposed to cure. The MP3 in squigee90's "Original" folder has these metadata, as noted by my own 'log' commands in the post #53 script:

(*raw artist = A.Squared » download-techno.com*)
(*decoded artist = A.Squared » download-techno.com*)
(*genre = Deep House*)
(*key = Bbm*)
(*tempo = 125*)


Even with decodeText2() switched out, the script relocates the file as "{125-Bbm} A.Squared » download-techno.com - Third Eye (Original Mix) » download-techno.com.mp3" in a folder called "A.Squared » download-techno.com" in a folder called "Deep House" in the destination folder set near the top of the code. It does not "put some weird stuff in the title" and change the first chevron to "\\U00bb".

There's no file in squigee90's "Problem" folder. However, renaming the good file in the manner described and putting it back does lead to the error when the script tries to access the metadata query's resultAtIndex:0. Basically, the query returns an empty array. The strange file name stops it from returning any results at all, so there's no point in having a special handler to massage the Artist result.

I don't know why the file name causes the metadata query to fail. When the \U00bb is manually changed back to », everything works again — on my system, anyway.


NG

Offline

 

#74 2017-05-01 07:07:16 pm

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

Thanks Nigel.

I get the same result than you but my understanding is that the problem is related to a locale setting on the asker's machine.

I got the same kind of problem with a file when I exchanged with Shane about one of the files which I used for tests.

With a bit of luck, the asker will tell us which are his local settings.

I'm running in french.
On his side, Shane was running English but I don't know which one. As you know Apple define several variants of English.
When it will be more logical to be awake I will try to retrieve which is the file which behaved differently for Shane and for me.


Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) mardi 2 mai 2017 02:07:09

Offline

 

#75 2017-05-02 09:44:59 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3200

Re: Applescript to read mp3 metatags and sort file into folder

I think that I am on the track.

In the files which I had to treat during these weeks, the metadatas are encoded in Utf8. They use one byte for a character. Some characters are using 2 or more bytes.
When we extract the author,we need to use the decoder handler designed by Nigel.
No need for that for the other extracted values.

In the asker's file, the metadatas are encoded in Utf16 with the BOM FF FE.
In thisfile, there is a character "»" in the author string. Here with the french system it's perfectly treated.
If I understand well it's also correctly treated on Nigel's English system.
The infos given by the asker let me think that the version of macOS which he use fails to treat this character encoded in  Utf16.

Interesting enough, exactly as it does here, the system doesn't treat the same way the author and the title so, the title is correctly deciphered but the author isn't.

I'm curious to read what is the behavior of the old fashioned script - using do shell script - when it's asked to treat this infamous file.


Yvan KOENIG running Sierra 10.12.4 in French (VALLAURIS, France) mardi 2 mai 2017 16:44:53

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)