I would like to modify the filesystem path for tracks on itunes programmatically, so that I can apply a string transformation to some of the tracks locations (which are now stored in a different places on the filesystem).
I've tried using AppleScript to update the location property of the relevant tracks but I get an end-of-file error when calling "set mytrack's location to ..."
I've seen various other hacks online that involve exporting the entire track db, modifying it in XML, and then reimporting it - but that seems to lose too much metadata (such as playlists).
It would really help to see more of your code. Of particular interest is the value you are using and how it is derived. It would also be useful to see the exact error message you get (you should be able to copy the text out of the AppleScript error dialog sheet if you are running the program from Script Editor/AppleScript Editor).
The dictionary entry for the file track class shows its location property being a writable alias value. The problem you are probably running into is that you are not using an alias for the value.
The following code shows how one might change a track's location using an interactive prompt from choose file (which returns an alias):
set m to path to music folder
tell application "iTunes"
set trk to first item of selection
set l to location of trk
if class of l is alias then
set m to l
end if
set {d, a, n} to {database ID, artist, name} of trk
choose file with prompt "Choose the file to use for " & d & ": " & a & "—" & n default location m
set location of trk to result
end tell
The choose file method is not what you want though, since you are doing some kind of automated, string based pathname translation.
When working with pathnames in AppleScript, there are two kinds that you might use: POSIX and HFS. POSIX pathnames have slash delimited components (and allow colons inside any component). HFS pathnames have have colon delimited components (and allow slashes inside any component), and they usually start with a volume name component.
To convert a POSIX pathname stored in a variable str to an AppleScript alias, use the following expression:
POSIX file str as alias
To convert an HFS pathname stored in a variable str to an AppleScript alias, use the following expression:
alias str
For example:
tell application "iTunes"
set trk to first item of selection
set l to location of trk
set newPath to my computeNewPath(POSIX path of l)
set location of trk to POSIX file newPath as alias
end tell
to computeNewPath(pp)
-- presumably something interesting happens here
return pp
end computeNewPath
How to move media files (that are not "organized" by iTunes) to a different location while keeping the iTunes library database (iTunes Library.itl) intact:
Move files to new location (e.g., mv ~/MyMusic /Volumes/Huge/)
Create symlink in old location pointing to new location
(ln -s /Volumes/Huge/MyMusic ~/MyMusic)
Start iTunes (if not already running)
Select all tracks that were moved.
Run this AppleScript:
-- Mark missing tracks (and update database with real path of existing
-- tracks) in iTunes
-- Instructions:
-- * symlink new file location to old location (old location points to
-- new location, file exists)
-- * select tracks to scan/update
-- * run the script
-- * missing tracks are marked with (!) and all other track paths have
-- been updated to the real path (symlinks eliminated) in iTunes
tell application "iTunes"
set fx to fixed indexing
set fixed indexing to true
set Sel to the selection
repeat with i from 1 to number of items in Sel
set trk to item i of Sel
set loc to (get location of trk as text)
end repeat
set fixed indexing to fx
end tell
All tracks should now point to the correct location, and the symlink(s) can be removed. This can be verified by selecting Get Info on a track that was moved and verify that the path points to the new location.
If you didn't get the symlink correct iTunes will display (!) beside each missing track. To fix the issue, simply create a symlink in the old location pointing to the new location and run the script again. Hint: the Get Info dialog can be used to determine the old location of a missing track.
This worked on iTunes 11.0.5
Adding to the previous answer by millerdev I updated the script to work with MacOS Catalina and the new Music app. Just create a $HOME/Library/Music/Scripts directory and place it there.
tell application "Music"
set fx to fixed indexing
set fixed indexing to true
set Sel to the selection
repeat with i from 1 to number of items in Sel
set trk to item i of Sel
set l to location of trk
set location of trk to l
end repeat
set fixed indexing to fx
end tell
Related
I've been struggling to try and figure out an Automator workflow or Applescript that can accomplish this task.
I want to:
Target a folder with hundreds of subfolders with numeric names (i.e. 00000001, 00000002, 00000003, etc.)
Filter to return only folders that DO NOT already contain files within them (either by size or by number of files, etc.)
Sort by name, Ascending
Select top result (lowest number folder name that doesn't already contain files) and set the folder path as a variable so it can be the next folder the workflow adds files to
Any ideas on how to accomplish this? Thanks!
Most of your requirements will be addressed automatically since you're dealing with file objects rather than text strings, e.g. sorting will occur naturally.
The script begins by designating the parent folder as an alias and then gets its items whose filenames begin with '00000' as a list. If the number of folders increases, eventually you may need to reduce that to four zeros. Needless to say, there shouldn't be non-folder items here with such a filename.
It then cycles through this list, getting the count of disk items within each folder. Based on that number, the name is added to either the empty or non-empty list, and optionally, the folder has its label colour changed to make it visibly obvious.
Finally, it grabs the first item from the list as the next folder up. Obviously, the next time you run it, that item will instead be added to the non-empty list.
tell application "System Events"
set pdk to (path to desktop) & "repo" as text as alias
set fList to disk items of pdk whose name begins with "00000"
set emptyList to {} -- empty folder list
set nonList to {} -- non-empty folder list
repeat with x in fList
set cx to contents of x
set acx to (get path of cx) as alias -- use to change label
if (count of (disk items of cx)) is greater than 0 then -- non-empty
set end of nonList to name of x
tell application "Finder" to set label index of acx to 3
else -- empty
set end of emptyList to name of x
tell application "Finder" to set label index of acx to 0
end if
end repeat
set nextUp to pdk & item 1 of emptyList as text
end tell
I work in media production at a university, we work on Mac systems, but our servers are windows based.
Illegal characters & long file names are causing us problems when transferring our production files to the server.
To prevent file transfers failing & being sent to a holding pen in our DAM system i'm looking to create a simple Automator App that can be used by the production team to do the following;
Accept source folder as input for the app.
Scan contents & replace the following characters ()\/[]"*?<>|+ with an underscore.
Scan contents & for file names longer than 100 characters
Log / report on the affected files for our producers to amend.
Within Automator I have had success with replacing the illegal characters using a find & replace rule for each, but I'm not sure of the apple script that would be required to check the file name lengths & reporting all changes.
I'll be eternally grateful if anyone would be able to suggest a route forwards!
Obviously, I have no clue what you might be passing along, nor how you might be replacing the text in filenames, nor exactly what you would like to report, as you don't really provide any of those details. However, here is a straightforward way to test for filenames longer than a given length within automator.
To provide the initial file list to test, I begin with three actions:
Get Selected Finder Items
Get Folder Contents ('repeat for each subfolder found' is checked)
Filter Finder Items ('kind is document')
This will pass along a list of alias file objects to the fourth 'run applescript' action, as input.
on run {input, parameters}
set fList to input
set nList to {} -- becomes list of filenames
set cList to {} -- becomes list of filename lengths
tell application "Finder"
repeat with ff in fList -- list of file aliases
set nn to name of ff
set end of nList to nn
set end of cList to length of nn
end repeat
end tell
set longList to {}
repeat with cc from 1 to length of cList
if item cc of cList is greater than 100 then
set end of longList to item cc of nList -- names with more than 100 characters
end if
end repeat
return longList
end run
This should be run when a folder is selected in the Finder.
Essentially, what this does is take the input (i.e. list of file aliases) and create corresponding lists of filenames and filename lengths. The script then loops through the list of lengths looking for items > 100 and and returns a list of matching filenames. If instead, you set end of longList… to items from fList then it will return a list of file aliases.
If this isn't what you're looking for, please advise. The above works under Sierra.
I want to create a new document in TexShop at a specific directory. The documentation says for the command make it has the option at location specifier. I have not been able to see anywhere in the documentation what actually qualifies as a "location specifier". I have tried alias [some path] but only gotten the results can't make into type location specifier or File alias X wasn't found (if it is a new filename I append to the end of the path). I have also tried it with just the path as text without alias, with the same results. What other kind of location specifier could there be? Or is there some strange rule that you have to create the file in the Finder first before calling TexShop's make new document command?
tell application "TeXShop"
make new document at alias "Users:jukhamil:Desktop:apples.tex"
end tell
Error message:
File alias Users:jukhamil:Desktop:apples.tex wasn’t found.
the at location specifier does not refer to the file system but to the list of the documents of the application like in
make new document at the beginning of documents
make new document at the end of documents
Instead you should set the path property and save eventually.
tell application "TeXShop"
log (count of documents) -- n
set p to (POSIX path of (path to desktop folder)) & "foo.tex"
set the_document to make new document with properties {path:p}
tell the_document to save
log (count of documents) -- n+2 whereas n+1 was expected
end tell
However, you should notice that until version 4.27 at least
1) TeXShop creates one window but 2 documents, meaning that iterating over the documents with AppleScript will loop twice as you can test by running
tell application "TeXShop"
set ds to documents
repeat with d in ds
log name of d as text
end repeat
end tell
2) TeXShop does not use the location specifier properly
I was wondering how to return just the file extension from a string. I've tried the 'set variable to name extension of...' detailed in this question, but that only seems to work for recognized extensions. The idea is to sort files with the extension '.meta' into their own collection.
What I have now looks like
tell application "Finder'
set everyName to name of every item in entire contents of this_folder
end tell
set metaFiles to {}
repeat with n from 1 to count of everyName
set currentName to item n of everyName
set currentExt to last word of currentName --this assignment fails
if currentExt is "meta" then
set end of metaFiles to currentExt
end if
end repeat
I'm brand new to applescript so I appreciate any and all help/direction. Thanks!
Edit: Hacky Solution
I solved this by using the split function described here to break up the filename after every period. I grabbed the last string, made sure it wasn't the same as the first string in case there were no period characters, and then stored the corresponding filename.
The name includes the file extension, whether the Finder recognizes it or not. So just sort on the name like this...
tell application "Finder"
set metaFiles to (every item in entire contents of this_folder whose name ends with "meta") as alias list
end tell
If you aren't getting a name extension, make sure there actually is one and that you aren't looking at the end of the name. If you are going to be moving files around, you will also need to get the path, and not just the name. I don't think that making a list of your extensions is what you are going for, either - several different characters are used for word boundaries, but a period isn't one of them.
Why not just ask Finder for your file items?
tell application "Finder"
set metaFiles to (every item in entire contents of this_folder whose name extension is "meta") as alias list
end tell
I am building a Applescript droplet to automate some stuff. I have the following line:
tell application "Finder" to duplicate dropped
Dropped being a reference to the file that was dropped on the droplet. The documentation says that this returns a reference to the duplicated object.
I want to set myVariable to the reference that is returned but I can't find in any of the documentation how to actually do that!
if it's a droplet, be aware that the parameter is a list of aliases (you can drag more than one file!), and that if you duplicate a single finder item you will get a finder item, whereas if you duplicate more than one finder item, you will get a list of finder items. i.e. the return value of duplicate depends on the parameters sent to it.
AND... finder items are not very useful outside the finder. You'd be better off with aliases or POSIX paths.
So you probably need something like
on open (dropped)
tell application "Finder"
set duplicate_Finder_items to duplicate dropped
end tell
-- convert the Finder reference for each duplicate item to an AppleScript alias
set duplicate_item_aliases to {}
if class of duplicate_Finder_items is list then
repeat with i from 1 to number of items of duplicate_Finder_items
set the end of duplicate_item_aliases to (item i of duplicate_Finder_items) as alias
end repeat
else -- result was a single Finder item, not a list
set duplicate_item_aliases to {duplicate_Finder_items as alias}
end if
repeat with f in duplicate_item_aliases
set inf to (info for (f as alias))
set n to name of inf
display dialog "You duplicated a file. The duplicate is now known as " & n
end repeat
end open
The duplicate command allows for a location to be specified:
set theResult to duplicate reference ¬
to insertion location ¬
replacing boolean ¬
routing suppressed boolean
Parameter, Required, Type, Description
direct parameter, required, reference, the object(s) to duplicate
replacing, optional, boolean, Specifies whether or not to replace items in the destination that have the same name as items being duplicated
routing suppressed, optional, boolean, Specifies whether or not to autoroute items (default is false). Only applies when copying to the system folder.
to, optional, insertion location, the new location for the object(s)