Play sound with AppleScript using afplay and relative file path - macos

I'm trying to create an AppleScript that uses afplay (as suggested here) to play a random sound file that's located in a directory within the same directory as the script.
folder
-- applescript.scpt
-- sounds
----- sound-x.aiff
I found this comment regarding relative paths to be potentially useful:
(POSIX path of (path to me))
However, I keep receiving errors when I try mashing it up with this approach for randomness...
set theNumber to 3
set theFiles to {}
repeat
set file_path to quoted form of (POSIX path of (path to me))
tell application "Finder" to set aFile to (some file of file_path & "/sounds_dir") as text
if aFile is not in theFiles then
set end of theFiles to aFile
tell application "Finder" to open file aFile
do shell script ("afplay " & file_path & " > /dev/null 2>&1 &")
end if
if (count of theFiles) is equal to theNumber then exit repeat
end repeat

In a script, path to me returns the path to the script file but we need its parent path to add a sub path.
To compose the correct path, we can use the subroutine composeFilePath(fileName).
The main action is in the repeat loop. I also added a delay so it's easier to test. Save the script before using since path to me will return a wrong path when its unsaved.
set LOOPS to 3
set soundFolderName to "sounds_dir"
# ---------------------
# SETUP
# ---------------------
set soundFolderFullPath to my composeFilePath(soundFolderName)
tell application "Finder"
if folder soundFolderFullPath exists then
set soundFolder to (folder soundFolderFullPath)
else
set soundFolder to ""
# Customize action when folder does not exist
beep
log "*** Error: folder " & quoted form of soundFolderFullPath & " missing!"
return
end if
if (count files in soundFolder) is 0 then
# Customize action when folder has no items in it
beep
log "*** Error: No items in " & quoted form of soundFolderFullPath & " !"
return
end if
end tell
# -------------------------------------------
# We have "soundFolder" and it has items in it
# -------------------------------------------
repeat LOOPS times
# PLAY RANDOM FILE
# As ONE LINER:
## do shell script "/usr/bin/afplay " & quoted form of (POSIX path of ((some file of soundFolder) as text)) & " > /dev/null 2>&1 &"
# Step By Step
set aRandomFile to some file of soundFolder
set aRandomFile to POSIX path of (aRandomFile as text)
set shellScript to "/usr/bin/afplay " & quoted form of aRandomFile & " > /dev/null 2>&1 &"
do shell script shellScript
delay 1
end repeat
on composeFilePath(fileName)
if fileName is "" then return ""
set pathToMe to path to me -- this is the full path to this script
-- get the folder this script is in:
set thisScriptsFolder to ""
tell application "Finder"
try
set thisScriptsFolder to (get container of pathToMe) as text
end try
end tell
if thisScriptsFolder is "" then
return ""
end if
return thisScriptsFolder & fileName -- full path
end composeFilePath

You have your paths all messed up. Applescript doesn't use "posix paths" so you can't pass that type of path to applications such as the Finder. Shell scripts do use posix paths and you have to quote them.
In addition for applescript, whenever your path is in string format you must put the word "file" or "folder" in front of the path before you use it so that applescript can understand it's an object to be acted upon otherwise applescript just treats it like a string. Also string paths in applescript should be colon delimited (:) rather than slash delimited (/). Finally applescript paths start with the name of your hard drive such as "Macintosh HD".
You can see you must treat paths in applescript much differently than you do with the shell. Anyway, I didn't test this code but using those basic rules this should work. Good luck.
set theNumber to 3
set theFiles to {}
repeat
set file_path to (path to me) as text
set file_dir to file_path & ":sounds_dir:"
tell application "Finder" to set aFile to (some file of folder file_dir) as text
if aFile is not in theFiles then
set end of theFiles to aFile
tell application "Finder" to open file aFile
do shell script "afplay " & quoted form of POSIX path of aFile & " > /dev/null 2>&1 &"
end if
if (count of theFiles) is equal to theNumber then exit repeat
end repeat

Related

How do I get the properties or the info of a file using AppleScript?

I need to write the properties or at least the info of a file I have only the name of (here: "text2.txt") to a textfile.
I tried various ways but each time I just get the properties of the Desktop folder but not the file.
What am I doing wrong here?
try
tell application "Finder"
set this_folder to path of (folder of the front Finder window) as alias
end tell
on error
-- no open folder windows
set this_folder to path to desktop folder as alias
set is_desktop to true
end try
tell application "System Events"
set file_list to the name of every file of this_folder
end tell
tell application "Finder"
set theFile to path to desktop folder
set myList to {}
repeat with n from 1 to count of file_list
set currentFile to item n of file_list
set the_filePath to this_folder
set the_filename to currentFile
if currentFile contains "text2.txt" then
set {creation date:creaDate, modification date:modDate, name:fName, displayed name:dName, name extension:nExt, description:descript, URL:fPath} to properties of the_filePath
set theText to creaDate & "#" & modDate & "#" & fName & "#" & dName & "#" & nExt & "#" & descript & "#" & fPath
do shell script "echo " & theText & ">> $HOME/Desktop/FileProperties.txt"
end if
end repeat
end tell
I think you mostly have it right already.
Finder windows have a 'target', which is the folder that the window looks at. You can get and set the target normally. Everything below the try statement is unchanged.
try
tell application "Finder" to set this_folder to target of front window as alias
on error
set this_folder to (path to desktop) as alias
set is_desktop to true
end try
As alternatives, the script could use TextEdit or its own 'write' command to create the text document. If you're curious, let me know and I'll add those options.
Okay… here is a script you can try that should handle the writing within applescript. I've made a few other tweaks, all of which are commented (which unfortunately, make the script appear longer than it really is).
Applescript has a built-in 'File Read/Write suite' which you can read about each command in the Language Guide here, but in a nutshell, you use these commands to write to a new file, replace or append text to an existing file.
p.s. I changed some of your variable names
-- Make front window specifier a global var. Unnecessary if you integrate System Events block into Finder block (see below)
global fw
tell application "Finder"
try
set targFol to target of front window as alias
set fw to front window
on error
set targFol to (path to desktop) as alias
set fw to make Finder window to targFol
end try
end tell
The system events block below could also be handled by the Finder. If the folders you're rooting through don't typically have thousands of files in them (or if the alternative line is sufficient), you should consider doing so, as the primary advantage of using System Events is performance with high file counts. I don't think any changes would be required beyond removing the appropriate 'tell/end' statements.
tell application "System Events"
-- Some filtering options as an alternative to the repeat loop
set txFiles1 to files of targFol whose kind is "Plain Text Document"
set txFiles2 to files of targFol whose kind is "Plain Text Document" and name is "text2.txt"
set txFile to item 1 of txFiles2
-- Alternatively, you can just use the file itself, without any of the rigmarole.
set txFile to file "text2.txt" of targFol
end tell
tell application "Finder"
set {creation date:creaDate, modification date:modDate, name:fName, displayed name:dName, name extension:nExt, description:descript, URL:fPath} to properties of targFol
set newText to creaDate & "#" & modDate & "#" & fName & "#" & dName & "#" & nExt & "#" & descript & "#" & fPath as text
end tell
-- Write the properties as text to a text file -- requires the 'class furl' bit to work
set tf to (path to desktop as text) & "FileProperties.txt" as «class furl»
-- Alternatively, you could create the text file in the target folder
-- set tf to (targFol as text) & "FileProperties.txt" as «class furl»
close access (open for access tf)
write newText to tf as text
-- And some obvious things you can do with your new text file
tell application "TextEdit" to open tf
tell application "Finder" to select tf
set rtext to read tf
I made a few adjustments to your code. Maybe something like this will help you out.
property theFile : "text2.txt"
tell application "Finder"
try
-- Gets The Name Of The Front Finder Window If There Is One Opened
set containerName to name of front Finder window as POSIX file as text
-- Checks If The File "text2.txt" Exists In That Folder
-- fileExists Will Be Set To True Or False Depending On The Results
set fileExists to (containerName & theFile) as alias exists
on error errMsg number errNum
-- If Either Of The Previous Commands Throws An Error
-- This Will Give You An Option To Choose A Folder Where You Think
-- The File "text2.txt" Is Located
activate
set containerName to my (choose folder with prompt "Choose A Folder") as text
end try
try
-- Checks If The File "text2.txt" Exists In The New Chosen Folder
set fileExists to (containerName & theFile) as alias exists
on error errMsg number errNum
-- If "text2.txt" Does Not Exist In This Folder Either, Script Stops Here
return
end try
delay 0.1
-- If fileExists Is Set To True From Previous Commands
if fileExists then
set fullFilePath to (containerName & theFile) as alias
set {creation date:creaDate, modification date:modDate, name:fName, displayed name:dName, name extension:nExt, description:descript, URL:fPath} to properties of fullFilePath
set theText to creaDate & "#" & modDate & "#" & fName & "#" & ¬
dName & "#" & nExt & "#" & descript & "#" & fPath
tell current application to (do shell script "echo " & theText & ¬
">> $HOME/Desktop/FileProperties.txt")
end if
end tell

AppleScript: Download URL from file and keep the names

I want to create a simple AppleScript:
define a folder (that will get all the images, docs etc.)
read a file (.txt for example)
download all the URLs into the folder with their original name
Currently, my file has one URL by line, no separator.
I found several scripts but they always do something I don't want, don't need or doesn't work.
I found one that is very close to what I want, but it's editing the names in the loop.
I didn't succeed to split the URL and keep the last part.
Here it is:
property desktopPath : path to desktop as string
set n to 1
repeat with urlLine in paragraphs of (read alias (desktopPath & "filename.txt"))
set qURL to quoted form of urlLine
if qURL ≠ "''" then
set dest to quoted form of ¬
(POSIX path of desktopPath & "URLs/" & n & ".jpg")
do shell script "curl " & quoted form of urlLine & " > " & dest
set n to n + 1
end if
end repeat
If you have any other solution, I take.
Thanks in advance
I found a script that is working fine.
You just need to be sure about the txt file: the list inside should not have any text format.
Weirdly I have to do a copy/paste through a text editor to remove every text format.
1/ Put the txt file on your desktop, 2/ Create a "download" folder on your desktop, 3/ Start the script
set theList to (path to desktop as text) & "Download.txt" -- File name with the URLs
set theFolder to (path to desktop as text) & "download" -- Folder name between quotes
set theFolder to quoted form of POSIX path of theFolder
set theImages to read alias theList as list using delimiter linefeed
repeat with i from 1 to count of theImages
set thisItem to item i of theImages
do shell script "cd " & theFolder & "; " & "curl -O " & quoted form of thisItem
end repeat

(Automator/AppleScript) Rename files to a folder name, save to different folder & add prefix

I really need you help and will be very grateful for it.
I think this should be no problem for you.
So I have folder with different subfolders in it. In subfolders are images.
What I need is:
Change each image name to it’s subfolder name + 001 and so on («1stSubfolder001, 1stSubfolder002, …», «2ndSubfolder001, 2ndSubfolder002, …»)
Move all images from all subfolders to one folder (or at least to root folder)
Add random prefix number to names.
I have script to third task:
tell application "Finder"
repeat with this_item in (get items of window 1)
set name of this_item to ((random number from 0 to 99999) & name of this_item) as string
end repeat
end tell
But it only works with opened folder on the foreground. Maybe there is a way to make one script to run it on the background?
Huge thank you in advance.
I found cool automator app here, but I need to correct it a little bit.
How do I use the current folder name without a path as a variable in automator in Mac?
This script does everything I need BUT it renames all files to ONE folder name, not each different.
Here is another applescript that does rename files to folders, but it uses 2 folders name (folder + subfolder), and I need only subfolder prefix.
set myFolder to do shell script "sed 's/\\/$//' <<< " & quoted form of POSIX path of (choose folder)
set myFiles to paragraphs of (do shell script "find " & quoted form of myFolder & " \\! -name \".*\" -type f -maxdepth 2 -mindepth 2")
repeat with aFile in myFiles
tell application "System Events" to set file aFile's name to (do shell script "sed 's/.*\\/\\([^/]*\\)\\/\\([^/]*\\)\\/\\([^/]*$\\)/\\1_\\2_\\3/' <<< " & quoted form of aFile)
end repeat
(MacBook Pro Late 2013, OS X Yosemite 10.10.1)
This accomplishes what you want. You should be able to adjust from here. There are no checks to ignore non-image files.
property top_folder : alias "Macintosh HD:Users:MyName:Downloads:Images:"
property save_folder : ""
set save_folder to choose folder with prompt "Select the folder to save the images in."
process_folder(top_folder)
on process_folder(this_folder)
set these_items to list folder this_folder without invisibles
set container_name to name of (info for this_folder)
repeat with i from 1 to the count of these_items
set this_item to alias ((this_folder as Unicode text) & (item i of these_items))
if folder of (info for this_item) is true then
process_folder(this_item)
else
process_item(this_item, container_name, i)
end if
end repeat
end process_folder
-- this sub-routine processes files
on process_item(this_item, c, i)
-- make the integer a 3 digit string
if i < 10 then
set i to "00" & i
else if i < 100 then
set i to "0" & i
end if
-- set a random number
set r to (random number from 0 to 99999) as string
tell application "System Events"
-- get file extension so not overwritten
set e to name extension of this_item
set new_name to "" & r & "_" & c & "_" & i & "." & e
set name of this_item to new_name
move this_item to save_folder
end tell
end process_item

Open Finder alias

I'm relatively new to Applescript, I was hoping someone can help me resolve this one...
I have a script that does a spotlight search and returns the found items as founditems. The result will either be a folder or an alias to a folder. I'd like to open the found item and it works if the result is a folder but I can't figure how to handle an alias. With an alias I get the error incorporated in the code
try
set theapp to default application of (get info for (POSIX file founditems)) as string
tell application theapp to open (POSIX file founditems as string)
activate application theapp
on error e
display dialog "An error has occured trying to open your file:" & return & return & e buttons {"OK"} default button 1
end try
I get 10665 error code. My guess is that incorporating original path may resolve the alias issue but I'm not sure how to plug it in... Thanks much
founditems is created this way:
set input_var to "12345"
set spotlightquery to "\"kMDItemFinderComment == '" & input_var & "'\""
set thefolders to {POSIX file "/Volumes/RAIDvolume"}
set founditems to {}
repeat with i in thefolders
set thepath to quoted form of POSIX path of i
if exists thepath then
set command to "mdfind -onlyin " & thepath & " " & spotlightquery
set founditems to founditems & (paragraphs of (do shell script command))
end if
end repeat
So it was a list because you used "paragraphs of" and I can see now that founditems is a list of posix paths. As such the following will open it with the default application regardless if the path is to a file, folder or alias.
set founditems to {"/Users/hmcshane/Desktop/aaa alias"}
set macPath to POSIX file (item 1 of founditems)
tell application "Finder" to open macPath

Copy multiple files to a folder in newbie appelscript

I'm trying to make an Applescript that takes a list of names and makes a set of folders from it. And then copies files from a choosen folder into each of these newly created folders.
I have search for the answer, but didn't understand them. So if you could be so kind to explaine what and why I should change the code, it would be a great learning experience for me.
set destinationFolder to choose folder
set {text returned:textReturned} to display dialog "enter folder names" default answer return & return & return
if textReturned is "" then return
set folderWithFiles to (choose folder with prompt "Where are the files at?")
repeat with aLine in (get paragraphs of textReturned)
if contents of aLine is not "" then
do shell script "/bin/mkdir -p " & quoted form of (POSIX path of dest inationFolder & aLine)
set folderNew to aLine & ":" as alias
set dest to folderNew on destinationFolder -- as alias
tell application "Finder"
duplicate every file of folderWithFiles to dest
end tell
end if
end repeat
Thanks in advance
Updated: posted answer to myself
Got help from StefanK at macscripter.net
Here is the complete code:
set destinationFolder to choose folder
set {text returned:textReturned} to display dialog "enter folder names" default answer return & return & return
if textReturned is "" then return
try
set theFiles to (choose file with prompt "Where are the files at?" with multiple selections allowed)
end try
repeat with aLine in (get paragraphs of textReturned)
if contents of aLine is not "" then
set newFolder to (destinationFolder as text) & aLine
do shell script "/bin/mkdir -p " & quoted form of POSIX path of newFolder
try
tell application "Finder" to duplicate theFiles to folder newFolder
end try
end if
end repeat

Resources