Is it possible to store a persistent value in an automator workflow (specifically for a service flow)?
It seems that regular automator variables are not persistent; for instance trying to use an applescript chunk which has a property (which normally persists) does not actually persist the property in Applescript either (works in testing, but when you run the service the value doesn't persist).
Any ideas?
You can use script objects to store your data in an out of the way place.
on run
-- Path of script which holds data
set thePath to (path to desktop as text) & "myData.scpt"
--set thePath to (path to preferences as text) & "myData.scpt" -- better
script theData
property xxx : missing value
end script
try
set theData to load script file thePath
on error
-- On first run, set the initial value of the variable
set theData's xxx to 5
end try
-- change the value of the variable
set theData's xxx to (theData's xxx) + 1
-- save your changes
store script theData in file thePath replacing yes
return theData's xxx
end run
Related
If I set a variable in AppleScript to the path to an AppleScript applet or droplet, the applet or droplet is launched and the run() handler is executed. For example, I have
set thePath to path to application "HS Extract"
and this launches the droplet "HS Extract". I have also tried setting a variable to the application as alias and then setting a variable to the path to the alias and a few other possibilities that all failed.
How can I set a variable to the path to a droplet or applet without launching that droplet or applet?
Another way to find things is using mdfind from the shell and metadata properties. This is like doing a spotlight search and this method shouldn't launch any applications.
For example applications have the kMDItemContentType property of com.apple.application-bundle. If we combine this with the name of an application we can create something like the following to get a posix path and then convert it into an alias.
set appDisplayName to "HS Extract"
set posixPath to item 1 of paragraphs of (do shell script "mdfind \"kMDItemContentType == 'com.apple.application-bundle' && kMDItemDisplayName == " & quoted form of appDisplayName & "\"")
set thePath to (POSIX file posixPath) as alias
NOTE: you mention the bundle id is common in your comment to jackjr300's post. The bundle identifier has the kMDItemCFBundleIdentifier metadata property. So if the combination of kMDItemContentType and kMDItemDisplayName doesn't work (as in my example code) then you can try kMDItemCFBundleIdentifier and kMDItemDisplayName instead.
To not open an application : use the Finder to get the path, this need the bundle identifier of the application.
set bundlId to id of application "HS Extract"
tell application "Finder" to set thePath to (application file id bundlId) as alias
Or you can use a NSWorkspace method to get the path, this doesn't need an identifier
do shell script "/usr/bin/python -c 'from AppKit import NSWorkspace; print NSWorkspace.sharedWorkspace().fullPathForApplication_(\"HS Extract\")'"
set thePath to the result as POSIX file as alias
What about setting it as a string, then, if you need to launch it, coercing to alias.
Set thePath to (choose file as string)
--gives you path string
you can use that string in a variable, but use
alias thePath
if you need to.
I prefer #jackjr300's answer, but if this script is for private use, a property seems to work:
property appPath : path to application "HS Extract"
display dialog appPath as string
The application is only launched when the script is compiled. Note that the property is an alias.
The script will track the original HS Extract, even if it's later renamed to something else.
I've created two droplets, one to rename files, another to print files. They are more complicated than that, but this is the essence. Sometimes we need to just rename them, sometimes just print them, and on occasion do both. I'd prefer to keep the two droplets separate because of extensive customization required for each user.
Desired workflow: drag file to RenameMe droplet, if command key is held down then pass the renamed file to the PrintMe droplet.
With the help of the checkModifierKeys script (sorry, don't have the citation handy) I can check to see if the command key is pressed, so that part of the script is taken care of. The problem is how to trigger the second droplet from the first. I've tried the opening the file with the second droplet as the application (as in the code below) but get a communication error.
Any ideas?
--Alex
Sample code:
on open the_Droppings
set flPth to POSIX path of (path to me) & "Contents/MacOS/checkModifierKeys"
set cmdPressed to (do shell script (quoted form of flPth & " command")) as integer as boolean
repeat with i from 1 to (count of items in the_Droppings)
set file_name to "NEW NAME FROM SCRIPT" #actual script that generates name isn't relevant
tell application "Finder"
set name of file (item i of the_Droppings) to file_name
end tell
if cmdPressed is true then
#pass the file to the PrintMe droplet
tell application "PrintMe"
open (item i of the_Droppings)
end tell
end if
end repeat
end open
You can add an explicit run handler to PrintMe, which will allow you two different entry points into the script. Both of which take arguments. I've set it up here with one file being passed to the run handler, and a list being passed to the open handler, but if you wanted you could pass a list to the run handler and repeat the same way you do in open.
In RenameMe:
if cmdPressed is true then
#pass the file to the PrintMe droplet
run script (load script file "path:to:PrintMe.app") with parameters (item i of the_Droppings)
end if
In Print Me:
on open the_droppings
repeat with i from 1 to (count the_droppings)
process(item i of the_droppings)
end repeat
end open
on run the_file
process(the_file)
end run
on process(the_file)
// Code for printing files goes here
end process
How do I remove passwords from multiple PDF files using Applescript or by creating a Workflow in OS X?
My scenario is that I have multiple password protected PDF files in a folder. I know the passwords for all, which is same. I want to be able to run a Workflow on this folder so that all PDFs inside it are unlocked by the workflow.
OR run an Applescript shell code on all these files at once
I also preferably want to be able to create a way where putting / moving / pasting any PDF in the folder automatically unlocks it :)
Help appreciated !!
Update:
I have tried pdftk. The following code works awesome in Terminal, once pdftk is installed
pdftk secured.pdf input_pw foopass output unsecured.pdf
Now I want to be able to create a workflow that runs this command on selected files or on all the files in a folder
The AppleScript command to execute a shell script is do shell script...
So something like this:
do shell script "pdftk secured.pdf input_pw foopass output unsecured.pdf"
should work.
At this point I see 2 options:
write an AppleScript script that ask the user for the folder or get it from the Finder selection and then execute the command for each file in the folder;
write an Automator workflow that get the files from the folder using already available actions and then attach a new action that execute the AppleScript script.
For option 2 you can set an Automator workflow as in the following image.
Have you heard of "Folder Actions"? It's a way to attach an applescript to a folder so that whenever a new file is added to the folder the applescript is run. A quick google search turned up this which will give you directions on how to set it up. You can do more google searching if you still have questions.
Here's an applescript you can use with folder actions. I didn't test it but it should work (it's basic code). This will do its stuff on only pdf files. Other files you add to the folder will be left alone. NOTE: you have to put in your values for the first 4 variables of the script.
Good luck.
on adding folder items to theFolder after receiving theItems
-- enter your values here
set pdftkPosixPath to "/usr/bin/pdftk"
set pWord to "foopass"
set appendedName to "_unlocked" -- text to append to the file name
set shouldTrash to true -- true or false, move the locked file to the trash after unlocking?
set fContainer to theFolder as text
repeat with anItem in theItems
try
tell application "System Events"
set fName to name of anItem
set fExt to name extension of anItem
end tell
if fExt is "pdf" and fName does not contain appendedName then
set baseName to (text 1 thru -5 of fName) & appendedName & ".pdf"
set newPath to fContainer & baseName
do shell script (quoted form of pdftkPosixPath & space & quoted form of POSIX path of anItem & " input_pw " & quoted form of pWord & " output " & quoted form of POSIX path of newPath)
if shouldTrash then
tell application "Finder" to move anItem to trash
end if
end if
end try
end repeat
end adding folder items to
EDIT: here's how you can ask for a password. Note that if you want to see the text then remove "with hidden answer".
display dialog "Enter a password:" default answer "" with icon note with hidden answer
set theAnswer to text returned of the result
if theAnswer is not "" then set pWord to theAnswer
I have the following script (modified to remove any private information).
-- This line is for testing.
set the clipboard to "1234567890"
set loginName to "username"
-- Password is stored in KeyChain (you need to do manually).
-- Create Remote path
set folderNumber to the clipboard as string
set subdir1 to character 1 of folderNumber
set subdir2 to character 2 of folderNumber
set remotePath to "/files/" & subdir1 & "/" & subdir2 & "/" & folderNumber
-- Create Local path
set homeFolder to (path to home folder) as string
set localPath to homeFolder & "LOCALSTORAGE" as string
set localStorage to localPath & ":" & folderNumber & ":" as string
-- Create Local file
tell application "Finder"
try
make new folder at localPath with properties {name:folderNumber}
on error e number n
-- Do nothing.
end try
end tell
-- Connect to FTP
tell application "Fetch"
activate
set tWindow to make new transfer window at beginning with properties {hostname:"ftpServerAddress", username:loginName, initial folder:remotePath}
tell window tWindow
download every remote item to beginning of alias localStorage
close window
end tell
quit
end tell
-- Open folder
tell application "Finder"
open localStorage
end tell
When I run the script the following line fails.
download every remote item to beginning of alias localStorage
The error I get is as follows:
error "Fetch got an error: Can’t get every remote item of window (transfer window id 232280960)." number -1728 from every remote item of window (transfer window id 232280960)
Does anyone know what the error means or how to fix it? I've tried the Fetch website without much luck. "Fetch" btw is the Fetch FTP client.
First you should check that the remotePath that you're generating really exists (e.g. by adding a log statement such as log tWindow's remote items and looking up in the Script Editor's event log whether it was able to get those).
If the path is correct, I think the problem is that you're using the download command with a reference to a list object (every remote item...). In the documentation, the command expects a specifier of a single item:
download specifier : the remote file, remote folder, shortcut, or url to download
That's why you need to loop through the items. The snippet below works perfectly for me:
-- my settings for testing
set theHost to "ftp.fetchsoftworks.com"
set loginName to "anonymous"
set remotePath to "/example/"
set localStorage to ((path to home folder) as text) & "LOCALSTORAGE:1234567890:"
-- Connect to FTP
tell application "Fetch"
activate
set tWindow to make new transfer window at beginning with properties {hostname:theHost, username:loginName, initial folder:remotePath}
set localStorage to (localStorage as alias)
repeat with theItem in tWindow's remote items
try
download theItem to localStorage
end try
end repeat
close tWindow
quit
end tell
There's no problem passing a list to download. But there are two problems with the original code:
tell window tWindow
download every remote item to beginning of alias localStorage
close window
end tell
The tell block directs the enclosed commands to a generic window object, rather than a transfer window, and the generic window object does not contain remote items.
The download command's to parameter should be an alias, not an insertion location (e.g. beginning of ...).
This should work:
tell tWindow
download every remote item to alias localStorage
close
end tell
In Script editor i have written a command to boot the JAR.
do shell script "cd /Desktop/RunJar/; java -jar RunMyJar.jar"
and Saved as script file as a Application. When i click on script file jar get run.
My requirement
I would like get the name of file that has been dropped onto the script file and would like to pass the name of that dropped file as an argument to my jar.
I have implemented this in Windows but could not working similar on MAC O.S.
On Windows
I have placed a BAT file to Boot JAR along with the absolute file name, that has been dropped on the bat file on windows. #echo %* will give me the list of files that has been dropped onto Batch file.
#echo %*
#pause
java -jar RunMyJar.jar %*
Similar i would like to implement in MAC O.S.
Thanks.
I found the following example at: Ben's AppleScript Snippets:
on open of finderObjects -- "open" handler triggered by drag'n'drop launches
repeat with i in (finderObjects) -- in case multiple objects dropped on applet
displayName(i) -- show file/folder's info
if folder of (info for i) is true then -- process folder's contents too
tell application "Finder" to set temp to (entire contents of i)
repeat with j in (temp)
display dialog j as string -- example of doing something with each item
end repeat
end if
end repeat
end open
You can also easily modify my answer to a similar question:
on open of theFiles -- Executed when files are dropped on the script
set fileCount to (get count of items in theFiles)
repeat with thisFile from 1 to fileCount
set theFile to item thisFile of theFiles
set theFileAlias to theFile as alias
tell application "Finder"
set fileInfo to info for theFileAlias
set fileName to name of fileInfo
-- something to this effect, but now that you have the file name,
-- do what you will...
do shell script "cd /Desktop/RunJar/; java -jar " & fileName
end tell
end repeat
end open
To add to Paul's answer
on open of finderObjects
repeat with currFile in finderObjects
-- ok, we have our current item. But it's an "alias": a Mac OS path
-- not a POSIX path
set unixPath to POSIX path of currFile
set base to do shell script "dirname " & unixPat
set fname to do shell script "basename " & unixPath
-- you could ask the Finder to give this to you too -- I'll use this way because
-- I'm guessing it's more familiar to you
do shell script "cd '" & base & "';" & " java -jar " & fname
end repeat
end open