AppleScript: Download URL from file and keep the names - applescript

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

Related

How to print out to a text file folder names within folder names (AppleScript)

I have a script that partially works. I need to print out a list of folder names which is working. But then I need to go inside of each of those folders into a specific path and then also print out those specific folder names. Whenever I try and do this my text file comes out blank. I have separated the text files to try and find the issue and I get the same result no matter what I try. The first text file works but the second one is always blank. I would ideally like the second text file o work with that format specified in the script. Any guidance would be greatly appreciated.
tell application "Finder"
with timeout of 3600 seconds
set src to (path to me) as string
set multiPath to (src & "Contents:Resources:Fixed multiSteps")
set zipFiles to {".zip"}
set allPlugins to get name of every folder in folder ("" & multiPath & "") whose name extension is not in zipFiles
set outputFile to ((path to desktop as text) & "pluginNames.txt")
set typeFile to ((path to desktop as text) & "types.txt")
set fileReference to open for access file outputFile with write permission
set filetypeReference to open for access file typeFile with write permission
try
repeat with a in allPlugins
write a & return to fileReference
set innerPath to (a & "Double Click to Install.app:Contents:Resources")
set innerFolders to get name of every folder in folder ("" & innerPath & "")
repeat with b in innerFolders
write a & " - " & b & return to filetypeReference
end repeat
end repeat
end try
end timeout
end tell
Okay So I figured it out.
tell application "Finder"
with timeout of 3600 seconds
set src to (path to me) as string
set multiPath to (src & "Contents:Resources:Fixed multiSteps:")
set zipFiles to {".zip"}
set allPlugins to get name of every folder in folder ("" & multiPath & "") whose name extension is not in zipFiles
set ListFile to ((path to desktop as text) & "List.txt")
set filetypeReferenceList to open for access file ListFile with write permission
try
repeat with a in allPlugins
set innerPath to (multiPath & a & ":Double Click to Install.app:Contents:Resources")
set typesForList to get name of every folder in folder ("" & innerPath & "")
write a & " - " & typesForList & return to filetypeReferenceList
end repeat
end try
end timeout
end tell

Applescript, Automator - Find & Copy imgs in Dir/sub-dir

I am looking to make an automator workflow, or applescript (but I am not familiar with the language yet) that can use a list of names (spreadsheet or a .csv) to search a directory and its sub-directories for those specific file names (with varying extensions) and copy that image to a folder created for these images.
I've found a script that seems to be somewhat similar to what I need, but it doesn't search within sub-directories, so I've yet to actually find any images with it.
After extensive research, I've found 2 different scripts that seem to be what I need, but neither of them seem to search sub-directories. Below are the 2 scripts I've tried. If anyone could help me get these to search sub-directories, I would really appreciate it!
Script 1:
set thePhotos to paragraphs of (read (choose file with prompt "Choose a text file"))
set theSourceFolder to (choose folder with prompt "Choose source folder")
set theDestination to (choose folder with prompt "Choose destination folder")
set dupeList to {}
repeat with theName in thePhotos
try
set end of dupeList to alias ((theSourceFolder as text) & theName)
end try
end repeat
tell application "Finder" to duplicate dupeList to theDestination with replacing
set theCount1 to (count of dupeList) as text
set theCount2 to (count of thePhotos) as text
display dialog (theCount1 & " of " & theCount2 & " items copied to " & (theDestination as text)) buttons {"OK"}
Script 2
set fileContents to read (choose file with prompt "Choose a comma-delimited text file")
set theText to result
set AppleScript's text item delimiters to ","
set theTextItems to text items of theText
set AppleScript's text item delimiters to {""}
theTextItems
set theSourceFolder to (choose folder with prompt "Choose source folder") as string
set theDestination to (choose folder with prompt "Choose destination folder")
repeat with theEPSName in theTextItems
tell application "Finder"
set theEPSFile to theSourceFolder & theEPSName
move file theEPSFile to folder theDestination with replacing
end tell
end repeat
So it lets me choose the .csv to use, choose the directory to save and choose the directory to search. How can I get this script to search within sub-directories? And to someone who understands Applescript, does this look like it will function as needed?
Thank you in advance! I really appreciate any help on this, as it is my first Applescript experience, but I am excited to learn it!
This is a very fast solution using the shell and Spotlight searching.
The script creates a search criteria string
'kMDItemFSName == picture1.png || kMDItemFSName == picture2.jpg || ...'
then performs the search and copies all files by passing the found items to the cp command.
There might be a caveat if the name list is too long and exceeds the maximum length of shell parameters.
set theNames to paragraphs of (read (choose file with prompt "Choose a text file" of type "txt"))
set sourceFolder to quoted form of POSIX path of (choose folder with prompt "Choose source folder")
set destinationFolder to quoted form of POSIX path of (choose folder with prompt "Choose destination folder")
set nameList to {}
repeat with aName in theNames
set end of nameList to "kMDItemFSName == " & quoted form of aName
end repeat
set {TID, text item delimiters} to {text item delimiters, " || "}
set nameFilter to quoted form of (nameList as text)
set text item delimiters to TID
do shell script "mdfind -onlyin " & sourceFolder & " -0 " & nameFilter & " | xargs -0 -J {} cp {} " & destinationFolder

Play sound with AppleScript using afplay and relative file path

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

Creating nested folders with variable names using Applescript/mkdir

I'm trying to create an applescript that prompts for a job name, then a desired directory in which to create a folder with the job name. It then should create a series of subfolders within the initial folder with names such as "job name-Links" & "job name-PDFs" etc.
I've cobbled this script together from different sources & would like feedback on how to improve it, because I'm sure it's ugly as sin.
tell application "Finder"
activate
set jobNum to text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
set folderpath to POSIX path of (choose folder with prompt "Select client folder")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Links")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-PDFs")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Supplied")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Versions")
end tell
Any thoughts & comments would be greatly appreciated. This is my first attempt at a script. I thought I'd post this because I've hunted for this specific use case for ages and only found bits and pieces. Hopefully someone can help me out so other will find it useful too.
Another idea would be to create a template of the desired folder structure somewhere, then have the script copy that structure with the client prefix. A couple of benefits to this method are that you don't need to change the script if folders are added to the template (the handler will also add to existing structures), and you don't have to figure out how to script complex (or large) structures.
property template : "/path/to/template/folder" -- the folder structure to copy from
on run -- example
set jobNum to text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
set folderPath to (choose folder with prompt "Select a location for the client folder")
tell application "Finder" to try
set clientFolder to (make new folder at folderPath with properties {name:jobNum})
on error number -48 -- folder already exists
set clientFolder to (folderPath as text) & jobNum
end try
copyFolderStructure_toFolder_withPrefix_(template, clientFolder, jobNum)
end run
to copyFolderStructure_toFolder_withPrefix_(source, destination, additions) -- copy folder structure using mkdir
set {source, destination} to {source as text, destination as text}
if source begins with "/" then set source to POSIX file source
if destination begins with "/" then set destination to POSIX file destination
set {source, destination} to {source as alias, destination as alias}
set additions to additions as text
tell application "Finder" to set theFolders to (folders of entire contents of source) as alias list
set folderNames to ""
repeat with someFolder in theFolders -- set up the folder names parameter for the shell script
set {tempTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
set namePieces to text items of (text ((count (source as text)) + 1) thru -2 of (someFolder as text))
set AppleScript's text item delimiters to ("/" & additions)
set namePieces to space & quoted form of (additions & (namePieces as text))
set AppleScript's text item delimiters to tempTID
set folderNames to folderNames & namePieces
end repeat
do shell script "cd " & quoted form of POSIX path of destination & "; mkdir -p" & folderNames
end copyFolderStructure_toFolder_withPrefix_
You can do something like this:
set TID to AppleScript's text item delimiters
-- Ensure the answer is formatted properly
repeat
try
set theAnswer to text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
set AppleScript's text item delimiters to "-"
set {jobNum, jobDes} to {text item 1 of theAnswer, text item 2 of theAnswer}
exit repeat
on error
display dialog "Please enter your response in this format [JobNumber]-[Description]" buttons {"Cancel", "Try again"} default button "Try again"
end try
end repeat
set folderpath to POSIX path of (choose folder with prompt "Select client folder")
set folderNames to {"-Links", "-PDFs", "-Supplied", "-Versions"}
repeat with aName in folderNames
do shell script "mkdir -p " & quoted form of (folderpath & jobNum & "-" & jobDes & "/" & jobNum & "-" & jobDes & aName as text)
end repeat
set AppleScript's text item delimiters to TID
mkdir can create a hierarchy, just put these names in the {}
Example : '/destFolderPath/jobName/prefix'{"suffix1","suffix2","suffix3","suffix4"}
Here is the script.
set jName to my getJobNum()
set folderpath to POSIX path of (choose folder with prompt "Select client folder")
do shell script "mkdir -p " & (quoted form of (folderpath & jName & "/" & jName)) & "{\"-Links\",\"-PDFs\",\"-Supplied\",\"-Versions\"}"
on getJobNum()
activate
text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
tell the result to if it is not "" then return it
getJobNum() -- else text returned is empty
end getJobNum
Important, if you plan to have slashes in the name, you must replace them by the colon character, it's easy to add a handler in the script to replace them, otherwise it will create other subfolders.
I'm no scripter, but I was looking for the same kind of structured folder solution. After going over these other examples, I came up with a slightly modified version for setting up project folders for our group of designers.
set TID to AppleScript's text item delimiters
-- Ensure the answer is formatted properly
repeat
try
set theAnswer to text returned of (display dialog "Please create a job folder, with the name in this format:" default answer "JobNumber-JobCode-ClientDescription")
set AppleScript's text item delimiters to "-"
set {jobNum, JobCod, CliDes} to {text item 1 of theAnswer, text item 2 of theAnswer, text item 3 of theAnswer}
exit repeat
on error
display dialog "Please enter your job details in this format [JobNumber]-[JobCode]-[ClientDescription]" buttons {"Cancel", "Try again"} default button "Try again"
end try
end repeat
set folderpath to POSIX path of (choose folder with prompt "Where to create your project folder?")
set folderNames to {"Links", "Client_input", "SourceBuilds", "Review-Proofs"}
repeat with aName in folderNames
do shell script "mkdir -p " & quoted form of (folderpath & jobNum & "-" & JobCod & "-" & CliDes & "/" & aName as text)
end repeat
set AppleScript's text item delimiters to TID
I'm using a variant of jackjr300 script to generate a website folder template/
do shell script "mkdir -p " & (quoted form of (folderpath & jName & "/")) & "{\"codey\",\"js\",\"fonts\",\"images\"}"
Plus another run to generate the subfolders and populate those with an existing frameworks and scripts with a duplicate folder action.
Very handy Thanks ...!
The first thing you could do to improve your script is don’t use shell scripting. Shell scripting is like a jackhammer, but what you are doing only requires the tiniest hand-held hammer.
Here is your original script:
tell application "Finder"
activate
set jobNum to text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
set folderpath to POSIX path of (choose folder with prompt "Select client folder")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Links")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-PDFs")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Supplied")
do shell script "/bin/mkdir -p " & quoted form of folderpath & "/" & quoted form of (jobNum) & "/" & quoted form of (jobNum & "-Versions")
end tell
Compare to a “de-shelled” version, which is easier to read, write, and maintain:
tell application "Finder"
activate
set jobNum to text returned of (display dialog "Enter a job number:" default answer "[JobNumber]-[Description]")
set theClientFolder to (choose folder with prompt "Select client folder")
set theSubFolderNames to {"Links", "PDFs", "Supplied", "Versions"}
repeat with theSubFolderName in theSubFolderNames
make new folder at theClientFolder with properties {name:jobNum & "-" & theSubFolderName}
end repeat
end tell
Notice that the variable “folderpath” has changed to “theClientFolder” because choose folder does not return a path, it returns an alias object for the chosen folder. The command for telling Finder to make a new folder is “make new folder at [alias where you want the folder to be made]” so you don’t need to convert that alias into a path to make new folders inside of it.
Notice also that the names of the folders have been declared as variables in a list, which makes them easier to read or change later. Even somebody who does not know AppleScript could open this script and change the name of the “PDFs” folder to “Documents” or something like that.
Another improvement I could suggest would be to make the way that you’re gathering the input from the user a little more sophisticated. You seem to be asking for 2 items of information other than the client folder — job number and job description — so use 2 dialog boxes, because that will be easier for the user and less error-prone because you can give 2 actual examples of what you want them to input. You can also improve the appearance of those dialogs in a few ways. And you can add a little error handling — if the user cancels the dialogs you’re presenting, that generates errors. You can handle them gracefully by checking if the user clicked “OK” or not.
Here is a version of your script with the user input cleaned up a bit:
tell application "Finder"
activate
display dialog "Enter a job number:" default answer "100" buttons {"Cancel", "OK"} default button "OK" with title (the name as text) with icon note giving up after 180
if the button returned of the result is equal to "OK" then
set theJobNumber to the text returned of the result
display dialog "Enter a job description:" default answer "Photos" buttons {"Cancel", "OK"} default button "OK" with title (the name as text) with icon note giving up after 180
if the button returned of the result is equal to "OK" then
set theJobDescription to the text returned of the result
try
choose folder with prompt "Select client folder:" default location (the path to the desktop folder as alias) without multiple selections allowed, invisibles and showing package contents
set theClientFolder to the result
on error
set theClientFolder to ""
end try
if theClientFolder is not equal to "" then
set theSubFolderNames to {"Links", "PDFs", "Supplied", "Versions"}
repeat with theSubFolderName in theSubFolderNames
make new folder at theClientFolder with properties {name:theJobNumber & "-" & theJobDescription & "-" & theSubFolderName}
end repeat
end if
end if
end if
end tell
This will give you dialog boxes that say “Finder” at the top and include the Finder icon, which will give up after 180 seconds (to prevent at timeout error) and which, if the user presses “Cancel” at any point, will just die gracefully without generating any errors. You can tweak the default answers for the input dialogs so that they help the user put in the right input, for example, if job numbers are 4 digits, put a 4 digit number here. And the choose folder prompt will start by showing the Desktop — you can change that to another location if there is a disk or folder where you store all your client folders:
choose folder with prompt "Select client folder:" default location (disk "Clients" as alias) …
To be clear, shell scripting is awesome, but I recommend you only use “do shell script” to get at unique features of the UNIX layer, like PHP functions, Perl regex, and so on. Anything that is already available to you in the Mac layer is going to be easier and safer to use, and easier to read, write, and maintain in AppleScript. Especially really basic things like creating folders.
I have a solution that copies the folder from a template location. It also creates a shortcut that allows to email the design manager with the subject as the job number/project number
global jobNum
global newJobFolder
set jobNum to text returned of (display dialog "Enter a job number:" default answer "")
set jobName to text returned of (display dialog "Enter a job name:" default answer "")
set jobMgr to text returned of (display dialog "Enter account manager email:" default answer "")
set folderpath to (choose folder with prompt "Select client folder")
set newJobFolder to my newFold(jobNum, jobName, folderpath, jobMgr)
on newFold(theNumber, theName, thefolder, jobMgr)
set emailAddress to jobMgr
set emailSubject to theNumber & " -" & theName
set bodyText to ""
set emailLinkFileName to theNumber & " -" & theName
set subNameList to {"Designs", "Documents", "Received"}
set itemCount to count of subNameList
set linkBody to "mailto:" & emailAddress & "?subject=" & my
replace_chars(emailSubject, " ", "%20") & "&body=" & my
replace_chars(bodyText, " ", "%20")
tell application "Finder"
set newJobFolder to (make new folder at thefolder with properties ¬
{name:theNumber & " " & theName})
repeat with i from 1 to itemCount
set aSubFolder to make new folder at newJobFolder with properties {name:jobNum & " " & item i of subNameList}
set theMailto to make new internet location file to linkBody at aSubFolder with properties {name:emailLinkFileName, name extension:"mailloc"}
set the name extension of theMailto to "mailloc"
end repeat
duplicate file "Users:ace:Dropbox:Company:0000-1_E.xlsx" of startup disk to folder (jobNum & " Documents") of newJobFolder
set name of the result to jobNum & " E.xlsx"
set theMailto to make new internet location file to linkBody at newJobFolder with properties {name:emailLinkFileName, name extension:"mailloc"}
set the name extension of theMailto to "mailloc"
end tell
end newFold
-- Generic find and replace functionality
on replace_chars(this_text, search_string, replacement_string)
set AppleScript's text item delimiters to the search_string
set the item_list to every text item of this_text
set AppleScript's text item delimiters to the replacement_string
set this_text to the item_list as string
set AppleScript's text item delimiters to ""
return this_text
end replace_chars

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