Applescript Traversing Directory - applescript

I have a script that add or update files in a folder. What I want to do is for an applescript to add these files to iTunes. But I can't seem to loop through the directory.
tell application "iTunes"
if playlist myPlaylist exists then delete playlist myPlaylist
set newPlaylist to (make new user playlist with properties {name:myPlaylist})
repeat with theFile in myPath as list
add theFile to playlist myPlaylist
end repeat
end tell
For every repeat, the value of theFile is the individual character of myPath, not the actual file in myPath. theFile will be M, a, c, i, n, ... instead of file1.mov, file2.mov, ...
Thank you.

If myPath is a string, as list converts it to an array of characters.
You can tell Finder to get a list of aliases:
tell application "Finder"
set l to items of (POSIX file "/Users/username/Music/folder" as alias) as alias list
end tell
tell application "iTunes"
if playlist "test" exists then
delete tracks of playlist "test"
else
set p to make new user playlist with properties {name:"test"}
end if
add l to p
end tell
This would add the selected files to the currently shown playlist:
tell application "Finder"
set l to selection as alias list
end tell
tell application "iTunes"
add l to view of browser window 1
end tell

Related

Apple Script: how do I watch for new download file with specific name to trigger a script?

I have a script that downloads a report from an online service, waits a specified amount of time e.g. 30secs for the file to actually download and then renames the file. The script then repeats
What I would like to do is instead of putting a static delay in the script, to create a trigger that looks for the new file and once it appears triggers the renaming portion of the script.
The downloaded file name is constant.
The current portion of the script looks like this
`
tell application "Finder" to activate
tell application "System Events"
delay Wait_Time
key code 125
tell application "Finder"
set name of (selection as alias) to (the clipboard)
end tell
end tell
ultimately what I would like is to replace the delay Wait_Time with a something like:
repeat until file name found
Search Folder for "file name"
end repeat
select new file
rename new file to clipboard
obviously this wont work but it kind of captures my logic.
I have also tried a few other possible solutions but Im new to AppleScript and not overly confident that these approaches are suitable for my application.
The below is an example of a solution I have tried. This is just an example and im not sure if this particular code can even get me to where I need to be. I thought I would include it to show just how lost I am.
set excludes to {"Folder", "Application"}
tell application "Finder"
set search_folder to folder "Macintosh HD:Users:XXXXXXXX:Library:CloudStorage:OneDrive-Flinders:Flinders Connect Stats:Source Stats:Cisco Finesse:Agent State Summary by Interval Report"
set foundItems to (every item in search_folder whose name contains "Agent State Summary by Interval Report" and kind is not in excludes) as alias list
if foundItems is {} then return
repeat with once from 1 to 100
try
if (count of foundItems) = 1 then
tell application "Finder" to activate
tell application "System Events"
key code 125
tell application "Finder"
set name of (selection as alias) to (the clipboard)
end tell
end tell
exit repeat
end if
end try
end repeat
return
end tell
Im sure you can see I have no idea what im doing.
Anyway any help would be awesome!
I have found a solution... if anyone has ideas for improvement please let me know.
tell application "Finder" to activate
tell application "System Events"
repeat until (exists (files of folder folderPath whose name contains "Agent State Summary by Interval Report"))
delay 1
end repeat
end tell
tell application "System Events"
key code 125
tell application "Finder"
set name of (selection as alias) to (the clipboard)
end tell
end tell
end repeat
say "Finished!"
display dialog "Completed"
The original solution was found here AppleScript: How to repeat a search for a file until it is found?

How do get last downloaded image to insert into object placeholder of current keynote slide?

Images are key to my work.
I am trying to find a quick way to automate image insertion to keynote. The script I am drafting is to get the last created/downloaded image, and insert it into the current slide on Keynote as a replacement of the master's object placeholder.
Error from applescript:
"Keynote got an error: Can’t set file name of slide 2 of document id \"B1054797-9A07-4642-AE79-166D1DE72674\" to alias." number -10006 from file name of slide 2 of document id "B1054797-9A07-4642-AE79-166D1DE72674" to alias
set myFolder to "/Users/Mingyu/Desktop/UpperEchelon"
tell application "Finder" to set latestFile to item 1 of (sort files of (POSIX file myFolder as alias) by creation date) as alias
tell application "Keynote"
activate
tell the front document
tell the current slide
set thisPlaceholderImageItem to item 1
set file name of thisPlaceholderImageItem to ¬
alias
end tell
end tell
end tell
I expect the script will insert last download image in the folder "UpperEchelon" to a current open slide in Keynote
Two issues:
You have to set thisPlaceholderImageItem to image 1 rather than to item 1
You have to set the file name to latestFile rather than just to alias. That's what the error is telling you.
And if the folder is a subfolder of the desktop there is a much shorter syntax
set myFolder to "UpperEchelon"
tell application "Finder" to set latestFile to item 1 of (sort files of folder myFolder by creation date) as alias
tell application "Keynote"
activate
tell the front document
tell the current slide
set thisPlaceholderImageItem to image 1
set file name of thisPlaceholderImageItem to latestFile
end tell
end tell
end tell

Using converted tracks in iTunes applescript

I have a script that iterates through tracks in a playlist. If they are already mp3 it adds them to my iPod (duplicate currentTrack to ipod_lib) and removes them from the playlist - this part works fine. If they are lossless however, I want to convert them to mp3 and add them to my iPod instead of add the lossless files themselves since they are too large. The line duplicate convertedTrack to ipod_lib throws the following error...
error "iTunes got an error: Can’t set library playlist id 270897 of source id 235166 to {file track id 322339 of library playlist id 38702 of source id 68}." number -10006 from library playlist id 270897 of source id 235166
the locateiPods code is pulled from a script on http://dougscripts.com/
Really not sure what I'm doing wrong here...
on locateiPods()
set the volumes_directory to "/Volumes/" as POSIX file as alias
set the volume_names to list folder volumes_directory without invisibles
set mounted_iPods to {}
repeat with i from 1 to the count of volume_names
try
set this_name to item i of volume_names
set this_disk to ("/Volumes/" & this_name & "/") as POSIX file as alias
set these_items to list folder this_disk
if "iPod_Control" is in these_items then
set the end of the mounted_iPods to this_disk
end if
end try
end repeat
-- check for iPod count
if the mounted_iPods is {} then
--
try
display dialog "iPod is not mounted." buttons {"Cancel"} with icon 0 giving up after 15
on error
error number -128
end try
else if the (count of the mounted_iPods) is greater than 1 then
-- choose iPod
set the ipod_names to {}
repeat with i from 1 to the count of the mounted_iPods
set this_iPod to item i of the mounted_iPods
tell application "Finder"
set the end of the ipod_names to the name of this_iPod
end tell
end repeat
tell application "iTunes"
activate
set this_name to (choose from list ipod_names with prompt "Pick the iPod to use:") as string
end tell
if this_name is "false" then error number -128
repeat with i from 1 to the count of the ipod_names
if item i of the ipod_names is this_name then
set this_iPod to item i of the mounted_iPods
exit repeat
end if
end repeat
else
set this_iPod to item 1 of the mounted_iPods
end if
return this_iPod
end locateiPods
tell application "iTunes"
set allTracks to every track in user playlist "TEST"
set the_iPod to my locateiPods() -- this is a path
set the_iPod_name to text 1 thru -2 of (the_iPod as string)
set ipod_src to some source whose name is the_iPod_name
set ipod_lib to library playlist 1 of ipod_src
repeat with i from 1 to count of allTracks
set currentTrack to item i of allTracks
set fileType to kind of currentTrack as string
if fileType is "MPEG audio file" then
duplicate currentTrack to ipod_lib
tell playlist "TEST" to delete contents of currentTrack
end if
if fileType is "Apple Lossless audio file" then
set convertedTrack to convert currentTrack
duplicate convertedTrack to ipod_lib
end if
end repeat
end tell
It seems doing the following makes it work, which suggests that convertedTrack is not of type track???
set convertedTrack to convert currentTrack
repeat with theTrack in convertedTrack
duplicate theTrack to ipod_lib
end repeat
I always used "convert" for list of tracks and then result is list of tracks. by the way it is much faster to convert list of tracks instead of doing loop to convert each track. May be you should do first a select of all tracks whose kind is lossless.
About convert, also keep in mind that convert does the conversion to the format set in your iTunes preferences. Then your scrip will depend of these preferences. I suggest, to be more safe, to save current preference, set the convert mode to format you want MP3, and then reset preferences to what they were before. You can use bellow script:
-- get & save current encoder
tell application "iTunes" to set Encoder_Base to name of current encoder
-- change encoder to MP3
tell application "iTunes" to set current encoder to (get first encoder whose name contains "MP3")
Also, may be you can optimise your iPod subroutine using Source method instead of looking for volumes mounted. iTunes kind of source provides an efficient way:
-- kind of source could be : library, iPod, audio CD, MP3 CD, radio tuner, shared library, iTunes Store
tell application "iTunes"
set myList to every source whose kind is iPod
if myList is {} then
display alert "no ipod connected"
return
else -- I assume if one iPod found, there is only 1 connected !!
set SourceName to name of first item of myList
set SourceID to id of first item of myList
end if
end tell
I hope it helps.

Can AppleScript determine the default mail app?

I'd like to know if there's a way to use AppleScript to determine what the current default email app is. Ideally it would return the path to the program, such as /Applications/Mail.app or /Applications/Outlook.app.
You can identify the default email client from the launch services preference file.
In El Capitan the file is located in ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist. In system versions prior to 10.11 the file might be directly in the Preferences folder.
set bundleIdentifier to missing value
set LSPrefFilePath to (path to preferences folder as text) & "com.apple.LaunchServices:com.apple.launchservices.secure.plist"
tell application "System Events"
set LSPrefFile to property list file LSPrefFilePath
tell property list item 1 of contents of LSPrefFile
repeat with anItem in (get property list items)
if exists property list item "LSHandlerURLScheme" of anItem then
if value of property list item "LSHandlerURLScheme" of anItem is "mailto" then
set bundleIdentifier to value of property list item "LSHandlerRoleAll" of anItem
exit repeat
end if
end if
end repeat
end tell
end tell
if bundleIdentifier is missing value then
set defaultMailClient to "/Applications/Mail.app"
else
tell application "Finder" to set defaultMailClient to POSIX path of (application file id bundleIdentifier as text)
end if

Applescript: Get absolute path of item in a File > Open window

I'm trying to automate JPEGmini which is not entirely scriptable - the only way to control it is via the "Open" dialog.
Repeatedly calling it once per image is extremely slow.
Instead I'm trying to to perform a search for .jpg or .jpeg files in the "Open" dialog, so that within that result set I can select the batch of files I want to process and open them in a single pass.
(More detail after the code example)
-- later within the search results list I get, I want to select these
set filesToSelect to {"/Users/me/Desktop/photo.jpg", "/Users/me/Documents/image.jpeg"}
-- the actual app is JPEGmini but the same principle applies to Preview
tell application "Preview"
-- start the app
activate
-- let it boot up
delay 3
-- ensure it still has focus
activate
end tell
tell application "System Events"
tell process "Preview"
-- spawn "Open" window
keystroke "o" using {command down}
delay 1
-- spawn "Go to" window
keystroke "g" using {command down, shift down}
delay 1
-- Go to root of hard drive
keystroke "/"
keystroke return
delay 1
-- Perform search
keystroke "f" using {command down}
delay 1
keystroke ".jpg OR .jpeg"
keystroke return
end tell
end tell
Having done the above, how do I access the list of search results, repeat over each item and get it's absolute file path?
I've tried a few variations but am getting nowhere.
Thanks for your time.
You could simplify this by using cross between the shell command line and applescript.
set jpegSearch to paragraphs of (do shell script "mdfind -onlyin / 'kMDItemContentType == \"public.jpeg\" '")
The mdfind command
consults the central metadata store and returns a list
of files that match the given metadata query. The query can be a string
or a query expression.
AFAIK this is what spotlight uses.
mdfind documents will give you an idea of how this command works. But ths script searches only in "/" and looks for content type attribute that is public.jpeg
The return is text. A list of POSIX Paths of the matching files. This text is like a text document each path on a new line but in effect one item as far as Applescript is concerned.
They need to be broken up in a applescript list. So I do this by asking for the paragraphs of the result.
Also if you want to open a new finder window:
try something like:
tell application "Finder"
activate
set myWindow to make new Finder window to startup disk
end tell
To answer why you are getting your error in trying to get the POSIX paths of the target of the files.
If you look at the properties of one of the files returned in your Search Window.
tell application "Finder" to set fileList to properties of first file of front window
You will see the file properties have a property named original item
If you really want to do it the way you are doing it then one way is to get the original item. Coerce the result into alias form then get the posix path.
tell application "Finder" to set aFile to POSIX path of (original item of first file of front window as alias)
In a normal finder window you can use.
tell application "Finder" to set fileList to POSIX path of (first file of front window as alias)
These are just examples to show you whats going on.
The difference in the type of finder window results is because in a Search window what is being displayed is alias files (class:alias file) to the original files, hence the original item property.
Update 2.
To go through your items in your list and check them against another list is simple.
Apple have some tools that will help you with the code.
When in your script.
crtl + Mouse Click the Variable that will hold the jpg result as a list.
This will give you a contextual menu that contains helper code.
Go to the Repeat routines folder in the menu.
Then to its 'Process Every Item'
This will add a repeat routine to your code.
And from there you can use it to check each item against your other list.
set yourOtherList to {"/Library/Desktop Pictures/Abstract/Abstract 2.jpg", "/Library/Desktop Pictures/Abstract/Abstract 1.jpg"}
set jpegSearch to paragraphs of (do shell script "mdfind -onlyin / 'kMDItemContentType == \"public.jpeg\" '")
repeat with i from 1 to number of items in jpegSearch
set this_item to item i of jpegSearch
if this_item is in yourOtherList then
-- do something
log this_item
end if
end repeat
The repeat routine works like this.
It loops over each item in the given list
It will iterate from item 1 to the count of the items in the list.
The i variable holds the loop iteration number. I.e it will be 1 on the first loop and 300 on the 300th loop.
so on the first loop set this_item to item i of jpegSearch is equivalent to writing set this_item to item 1 of jpegSearch
But apple saves you having to write each number of each item with the Repeat with i..
The variable i can be any word or letter you choose that conforms to the normal allowed Variable naming syntax.
Something you can do is build a new list from the matched items. by copying them into a previously declared list. You can then work on that list after the repeat loop has completed.
Here bigList is declared as a empty list {}
The matched items are copied to the bigList. Each new item it receives is added to the end of the list.
set bigList to {}
set yourOtherList to {"/Library/Desktop Pictures/Abstract/Abstract 2.jpg", "/Library/Desktop Pictures/Abstract/Abstract 1.jpg"}
set jpegSearch to paragraphs of (do shell script "mdfind -onlyin / 'kMDItemContentType == \"public.jpeg\" '")
repeat with i from 1 to number of items in jpegSearch
set this_item to item i of jpegSearch
if this_item is in yourOtherList then
copy this_item to end of bigList
end if
end repeat
bigList

Resources