I have an AppleScript that works perfectly in finder. It creates a folder named with the days date and has a shortcut key connected to it.
But it does not work when in another app, in the save window. Can you please help.
Here is the code I have.
tell application "Finder"
try
if exists Finder window 1 then
set thisPath to (the target of the front window) as alias
else
set thisPath to (path to desktop)
end if
on error
return
end try
end tell
set x to my the_perfect_datestring()
if x is not "-ERROR" then
set fullPath to thisPath & x as text
tell application "Finder"
try
--activate
if not (exists fullPath) then
set y to make new folder at thisPath with properties {name:x}
end if
activate
end try
end tell
end if
on the_perfect_datestring()
try
set cd to (the current date)
set the_year to year of (cd) as number
set the_month to month of (cd) as number
set the_day to day of (cd) as number
if the_month < 10 then set the_month to "0" & the_month
if the_day < 10 then set the_day to "0" & the_day
return ((the_year & "-" & the_month & "-" & the_day) as string)
on error
return "-ERROR"
end try
You cannot access the settings in a Save dialog box with the Finder AppleScript terminology.
The only way with AppleScript is System Events and GUI scripting. The script syntax depends strongly on the particular UI.
To work with save dialogs in other applications, you would need to change your workflow a bit. The save dialog works with text (the file/folder name), so you can create a text service to paste in the desired string.
To create a service, start up the Automator application and select the Service (Quick Action) document - the workflow will have settings that determine what kind of input it will accept, for example:
Workflow receives current text in any application
Next, check the Output replaces selected text box - this will replace selected text with the output of your workflow.
Drag a Run AppleScript action into the workflow, and completely replace the default contents with a new Run handler and your date string handler, for example:
on run {input, parameters}
set x to the_perfect_datestring()
if x is not "-ERROR" then return x
end run
on the_perfect_datestring()
try
# do your filename stuff
tell (current date) as «class isot» as string
return text 1 thru 10
end tell -- or whatever
on error
return "-ERROR"
end try
end the_perfect_datestring
After you save the workflow, the service should be available any time you select some text (in the right-click context menu).
An equivalent to your original workflow with the Finder would then be to create a new folder, and use the service on the highlighted “untitled folder” name to change it.
Related
As you can see from my code below I am extremely new to this. My code just about works, but my major issue is that it hogs up Finder and sometimes it does not set the Desktop picture, but does most of the time!
The script just monitors a folder, and if an "***.jpg" is added then the Desktop picture set to it.
This is my very first script so I have a lot to learn,
set reset to ""
display notification "Alarm Front Active " & (current date) as string
tell application "Finder"
set path_to_sourceFull to ":photo:FRONT CAM 1:20190929:images" -- from nsa310 network drive
set path_to_source to ":photo:FRONT CAM 1:20190929:images" -- from nsa310 network drive
set directory1 to "/Volumes/photo/FRONT CAM 1/20190929/images" as text -- from nsa310 network drive
set path_to_destinationFull to "Macintosh HD:Users:rekordbox:Documents:temp folder 2"
set path_to_destination to ":Users:rekordbox:Documents:temp folder 2"
set directory2 to "/Users/rekordbox/Documents/temp folder 2" as text
repeat while reset = ""
set allok to ""
set filelist to name of every item in folder path_to_source --of startup disk
set listSizesaved to count of filelist
delay 1
repeat while allok = ""
set filelist to name of every item in folder path_to_source --of startup disk
set listSize to count of filelist
if listSize = listSizesaved then
else
set filelist to name of every item in folder path_to_source --of startup disk
set listSize to count of filelist
set LastAddedFile to item listSize of filelist
set allok to "ALARM"
set listSizesaved to listSize -- (save the updated) count
set activefile to (path_to_source & LastAddedFile)
set selectedpicture to (directory1 & "/" & LastAddedFile)
tell application "System Events" to tell every desktop to set picture to selectedpicture
delay 1
display notification "ALARM FRONT TRIGGERED...." & (current date) as string
delay 1
end if
end repeat
end repeat
end tell
The script you want, I think, is this:
on adding folder items to thisFolder after receiving filelist
set droppedFile to first item of filelist
tell application "System Events"
tell every desktop
set picture to droppedFile
end tell
end tell
end adding folder items to
(I've left out the 'Alarm' bit, since I wasn't sure what the point of it was.)
To use this script, copy it into Script Editor, save it in the folder ~/Library/Scripts/Folder Action Scripts/, then open the applet 'Folder Actions Setup'. Add the folder you want on the left-hand side, and choose the file you just saved on the right. It should look something like this:
...where the checkmark on the left shows that folder actions are enabled for the folder (which I called 'test folder') and the script (which I called 'FADtop.scpt') is attached.
Drop an image in the folder, and it should just work.
As a general rule, don't script the Finder unless you absolutely need to; always use System Events. The Finder is a busy app, and scripting it can gum up the system. And also try to avoid this design pattern:
(* Don't do this! *)
repeat
(* test for something *)
delay x
end
The delay command is not particularly resource-efficient. If you really want to use a polling system to test for some event, it's often better to create a stand-alone app with an on idle handler. That way you let the system wake and sleep the script, with significant performance improvements.
EDIT
Since folder actions don't seem to be working with ftp drops onto remote drives, here's a reasonably efficient folder-polling approach. Save the following script as a stay-open application (choose 'Application' as the file type, and click the 'stay open' checkbox). Then launch the application and leave it running in the background.
property dateOfLastFileChosen : missing value
property targetFolder : "/Volumes/photo/FRONT CAM 1/20190929/images"
property idleTime : 300 -- 300 seconds is five minutes
on run
end run
on idle
tell application "System Events"
if exists folder targetFolder then
if dateOfLastFileChosen is missing value then
set recentFiles to every file of folder targetFolder whose visible is true
else
set recentFiles to every file of folder targetFolder whose modification date > dateOfLastFileChosen and visible is true
end if
set newFile to my mostRecentFileOfList(recentFiles)
if newFile is not missing value then
set dateOfLastFileChosen to modification date of newFile
tell every desktop
set picture to (POSIX path of newFile)
end tell
end if
end if
end tell
return idleTime -- check every 5 minutes (300 seconds)
end idle
on mostRecentFileOfList(fileList)
set maxDateObj to missing value
repeat with thisFile in fileList
if maxDateObj is missing value then
set maxDateObj to contents of thisFile
else if modification date of thisFile is greater than modification date of maxDateObj then
set maxDateObj to thisFile
end if
end repeat
return maxDateObj
end mostRecentFileOfList
Without trying to steal the thunder from #Ted Wrigley, whose solution provided the AppleScript code for the folder action, I felt there were enough comments and items for me to add to post it as another answer to the OP's dilemma.
First I will address the tell every desktop set picture to droppedFile lines of code in the following AppleScript Folder Action. If the user has only one monitor/display attached to the computer, but has created several different "Spaces", the tell every desktop set picture to droppedFile lines of code will only change the Desktop Picture for the Desktop of the current active "Space" only. The other Desktop backgrounds will not be changed. However, if the user has several monitors/displays attached to the computer, the tell every desktop set picture to droppedFile lines of code will change the Desktop Pictures for the Desktops of the current active "Space" for each attached monitor/display. If the latter is not the desired result, then tell every desktop should be changed to tell current desktop.
After testing the AppleScript Folder Action code provided by #Ted Wrigley, I noticed the image file being downloaded from an FTP server, to the test folder where I have the folder action script attached to, looked like this before the image was actually finished transferring. Because the file was kind of there and not there, it did not trigger the Folder Action.
Next, I figured I would add a delay to be beginning of the Folder Action code to allow for the transfer of the image file from the FTP server, to complete. I added a delay of 180 seconds to allow for the transfer to complete and it worked. When the transfer was complete, the file look like this.
Depending on how many files you foresee being transferred at any given time along with factoring in for file sizes... It's possible you may need to significantly increase the Delay time.
on adding folder items to thisFolder after receiving theseFiles
delay 180
set newBackground to first item of theseFiles
tell application "System Events"
set picture of current desktop to newBackground -- Single Display Attached
--set picture of every desktop to newBackground -- Multiple Displays Attached
end tell
end adding folder items to
I'm using a code to format textedit files for lab data.
I currently am using AppleScript to create a document in TextEdit and adding text to it, but when I try to save it, TextEdit gives me the error "you do not have permission to save as blahblahblah." I have already tried changing the permission on the folder in which I'm saving it in, but I think it may have something to do with it being a file that AppleScript created.
The exact error output is a dialog box from TextEdit
The document “1.txt” could not be saved as “1”. You don’t have permission.
To view or change permissions, select the item in the Finder and choose File > Get Info.
The segments of my code that don't work are
tell application "TextEdit"
make new document with properties {name:("1.txt")}
end tell
--data formatting code here (n is set here)
tell application "TextEdit"
delay 1
close document 1 saving in ("/Users/bo/Desktop/Script Doc/" & (n as string))
set n to n + 1
make new document with properties {name:((n as string) & ".txt")}
delay 1
end tell
I have scoured other questions and I have found the code segments
open for access document 1
close access document 1
but I'm not sure how to implement these / if I even should, and if not, I'm not sure how to fix this issue.
Thanks in advance
Unfortunately, that error message isn't helping much. You are essentially trying to save into a string, which isn't going to work - you need to use a file specifier, for example:
close document 1 saving in POSIX file ("/Users/bo/Desktop/Script Doc/" & n & ".txt")
Note that not everything knows about POSIX paths, in which case you will need to coerce or specify it as in my example.
Saving directly to the Desktop works for me using the latest version of macOS Mojave
property outputPath : POSIX path of (((path to desktop as text) & "Script Doc") as alias)
property docNumber : 1
property docExtension : ".txt"
tell application "TextEdit"
set docName to (docNumber & docExtension) as text
set theText to "Your Desired Text Content"
set thisDoc to make new document with properties {name:docName, text:theText}
close thisDoc saving in POSIX file (outputPath & "/" & (name of thisDoc))
(* IF YOU WANT TO SAVE MULTIPLE FILES WITH CONSECUTIVE NAMES *)
set docNumber to docNumber + 1
set docName to (docNumber & docExtension) as text
set thisDoc2 to make new document with properties {name:docName} -- Removed Text Property This Time
close thisDoc2 saving in POSIX file (outputPath & "/" & (name of thisDoc2))
end tell
TextEdit is sandboxed. You cannot save documents in the standard desktop folder.
An alternative is to hard-code the path to the documents folder in the container of TextEdit.
tell application "TextEdit"
make new document with properties {name:"1.txt"}
end tell
set containerDocumentsFolder to (path to library folder from user domain as text) & "Containers:com.apple.TextEdit:Data:Documents:"
tell application "TextEdit"
close document 1 saving in containerDocumentsFolder & (n as string) & ".txt"
set n to n + 1
make new document with properties {name:(n as string) & ".txt"}
end tell
I'm making an applescript to help with school. You type the subject you wish to access, and then it opens that folder (inside the app). However, some subjects have ebooks, so I want there to be another dialog box asking you wether you want to open the ebook or the folder. Unfortunately, a display dialog can't branch off of another display dialog.
So far, the only way I've found around this is to direct the app to run off of another script (in the "Scripts" folder of the app). I've tried
tell application "Script Editor" to run script (path to me as sting) & "Contents:Resources:Scripts:Subject.scpt"`
But it didn't work. Sorry if I'm barking up the wrong tree and seem completely stupid. Thanks
As far as I understood what you're trying to achieve, the following script would work.
set listOfSubjects to {"Math", "Biology", "History", "Languages"}
set subjectsWithEbook to {"Biology", "History"}
choose from list listOfSubjects with prompt "Select the subject"
set subject to item 1 of result
set openEbook to false
repeat with subjectItem in subjectsWithEbook
if subjectItem contains subject then
choose from list {"Open folder", "Open Ebook"} with prompt "What to open?"
set openType to item 1 of result
if openType contains "Open Ebook" then
set openEbook to true
end if
exit repeat
end if
end repeat
if openEbook then
--Open ebook
else
--Open folder
end if
I am guessing that you want to type the subject name? Here is an example that uses dialog boxes.
set subjectFolderPath to (path to me as string) & "Contents:Resources:Subjects:"
set subjectsWithEbook to {"English", "Spanish"}
display dialog "What subject would you like to access?" default answer ""
set theSubject to text returned of the result
if theSubject is in subjectsWithEbook then
display dialog "Would you like to open the Folder or the Book?" buttons {"Folder", "Book"} default button 1
set toOpen to button returned of the result
if toOpen is "Book" then
-- tell app "Preview" to open ???
beep
else
tell application "Finder" to open folder (subjectFolderPath & theSubject & ":")
end if
else
tell application "Finder" to open folder (subjectFolderPath & theSubject & ":")
end if
You might also want to have a list of subjects that are allowed and error check for them.
Goal
I would like to use AppleScript to open Automator and add specific actions to a new Workflow, regardless of the localization settings (language). In other words, I would like to use AppleScript to open a new Automator workflow and add specific actions in a specific order (at indexes) using the bundle identifiers of each action (to avoid language issues) or some other way to avoid language issues.
The Problem
The problem is that I cannot get Automator to add anything to the workflow.
What is the syntax for the add command?
Can I use bundle ids to add actions?
So far, this is what I have:
tell application "Automator"
make new workflow with properties {name:"Merge PDF Files"} -- Skips Opening Dialog
add "Get Specified Finder Items" to workflow 1 at index 1 --("com.apple.Automator.SpecifiedFiles")
add "PDF-Seiten kombinieren" to workflow 1 at index 2 --("com.apple.action.joinpdf")
end tell
Complete Code for a Merge PDF Files Droplet
After bwaldie posted his answer, I would like to share my useful droplet. You can put it on any Mac running OS X (especially useful for people who aren't familiar with Automator). To use it, just paste the code into the AppleScript Editor and save it as an application.
See code for droplet:
on open the_Droppings
-- CONVERT INPUT LIST OF ALIASES TO POSIX PATHS
repeat with itemStep from 1 to count of the_Droppings
set item itemStep of the_Droppings to POSIX path of item itemStep of the_Droppings
end repeat
tell application "Automator"
activate
set theWorkflowName to "Merge PDF Files"
set msg to "no"
tell application "Finder" to if exists POSIX path of ((path to temporary items as string) & theWorkflowName & ".workflow" as string) as POSIX file then set msg to "yes"
if msg is "no" then
set myWorkflow to make new workflow with properties {name:theWorkflowName, path:POSIX path of ((path to temporary items as string) & theWorkflowName & ".workflow" as string)}
add (first Automator action where its id = "com.apple.Automator.SpecifiedFiles") to myWorkflow at index 1
add (first Automator action where its id = "com.apple.action.joinpdf") to myWorkflow at index 2 --("com.apple.Automator.SpecifiedFiles")
else
set myWorkflow to open POSIX path of ((path to temporary items as string) & theWorkflowName & ".workflow" as string)
end if
set actionsList to name of Automator action of myWorkflow
set firstAction to item 1 of actionsList
tell myWorkflow
set value of setting of Automator action firstAction to the_Droppings -- MUST BE LIST OF POSIX PATHS
end tell
end tell
end open
Try something along the lines of...
set theWorkflowName to "Merge PDF Files"
tell application "Automator"
set myWorkflow to make new workflow with properties {name:theWorkflowName, path:POSIX path of ((path to desktop folder as string) & theWorkflowName & ".workflow" as string)}
save myWorkflow
add (first Automator action where its id = "com.apple.Automator.SpecifiedFiles") to myWorkflow
end tell
I think the key is to create the workflow, then save it, and then add the action.
Hope this helps!
-Ben
If you want to use Automator, there is no need for scripting. This works for me:
start Automator;
create new Service or e.g. create new Workflow;
if you created a Service, select "Service receives PDF files in
Finder.app" at the top of the window; if you chose Workflow, select
Files & FOlders in the list of Actions on the left and drag Get
Selected Finder Items to the right and make sure that Appending Pages is selected;
Select PDFs in the Actions list and drag Combine PDF Pages to the right
Select Files and Folders in the Actions list and drag Copy Finder Items to the right and make sure that Desktop is selected
Drag "Make Finder Item Names Sequential" to the right, select Make Sequential" and "Add number to existing item name".
You may want to tweak and experiment with Automator a bit to make sure that it does exactly what you want.
Please excuse my less-than-elegant scripting ability, but the script is working fine when invoked within the script editor itself. When I save it as an application however, the icon doesn't show that it's a droplet and does not work as such. Any help is greatly appreciated!
try
set destinationFolder to "Mercury:F1_PropertyLogos:"
tell application "Finder" to set logoFileName to name of item 1 of (get selection)
end try
set file_name to logoFileName
set file_name to remove_extension(file_name)
on remove_extension(this_name)
if this_name contains "." then
set this_name to ¬
(the reverse of every character of this_name) as string
set x to the offset of "." in this_name
set this_name to (text (x + 1) thru -1 of this_name)
set this_name to (the reverse of every character of this_name) as string
end if
return this_name
end remove_extension
tell application "Finder"
set selected_items to selection
set theFolder to "Mercury:F1_PropertyLogos:"
repeat with x in selected_items
move x to theFolder
end repeat
end tell
tell application "QuarkXPress"
set mypath to "Mercury:F1_Layouts:"
set myfile to file_name
set extension to ".qxp"
set logoFolderPath to "Mercury:F1_PropertyLogos:"
set myLogoFile to file_name
set myLogoExtension to ".psd"
set myLogo to (logoFolderPath & myLogoFile & myLogoExtension)
open file (mypath & myfile & extension)
set selected of picture box "Logo" of spread 1 of document 1 to true
set image 1 of picture box "Logo" of spread 1 of document 1 to file myLogo
set bounds of image 1 of picture box "Logo" of spread 1 of document 1 to proportional fit
end tell
end
To deal with items dropped onto the application, you will need to add an open handler that receives a list of the dropped items (even if there is only one), for example:
on open theDroppedItems
-- whatever
end open
You should probably rearrange your code to place your main statements into a handler (or handlers) that can be called from multiple places, since double-clicking on the application will call the run handler instead.