thanks in advance for your help.
New to Applescript.
Trying to open in Preview all files in folder and save them.
The problem is that saving pops up a dialog half the time, which requires me to sit there hitting enter.
Code:
tell application "Finder"
set fl to files of folder POSIX file "/Users/myname/Desktop/myfolder/" as alias list
end tell
repeat with f in fl
tell application "Preview"
activate
open f
# Trying to save before the window has appeared will fail.
# Note: - This assumes that NO window was initially open.
# - The code should be made more robust to eventually time out.
repeat until (count of windows) > 0
delay 0.3
end repeat
save front document
close front document
end tell
end repeat
Thank you for the help
I made several PDF files and download from different sites and I get sample of version 1.3, 1.4, 1.5, 1.7, ..but no 1.6 ! For all of them no issue.
Anyway, because I have not been able to reproduce what you have, I took different approach.
1) I have added at top of the script, a list of encoding/version list which may required special treatment (like hit return key). You can of course amend these 2 lists to manage other cases you may have.
2) I changed your script to allow the script to get encoding and version values of the pdf. This is done by using spotlight data base via shell command 'mdls'. I use it 2 times to get version and encoding characteristics. The shell command returns characters before and after the value we want to get, so I use text x thru Y to extract the encoding and the version itself.
3) if PDF version/encoding are in the list predefined which requires special treatment, then I set OKReturn to true.
4) Just after the save instruction, the script now test if OKReturn is true. then I ask the script to hit return key for you. you may have to adjust this part, for instance, it could be not only 1 return, but 2 or something else. this is something I have not been able to test, because all my pdf are working. please keep in mind that because I simulate return key, you should not use the keyboard during the script run.
based on my test, I don't think the encoding is the blocking criteria. I think the version 1.6 is.Here is the script. It includes comment to make you able to adjust it:
set CodingReturn to {"Mac OS X 10.7.3 Quartz PDFContext"}
set VersionReturn to {"1.6"}
set myFolder to choose folder
tell application "Finder"
set fl to files of myFolder as alias list
end tell
repeat with f in fl
set FVersion to do shell script "mdls -name kMDItemVersion " & quoted form of POSIX path of f
set FEncoding to do shell script "mdls -name kMDItemEncodingApplications " & quoted form of POSIX path of f
if (length of FVersion) > 21 then set FVersion to text 19 thru -2 of FVersion -- extract only version number
if (length of FEncoding) > 42 then set FEncoding to text 38 thru -4 of FEncoding -- extract only the coding
set OKReturn to ((FVersion is in VersionReturn) and (FEncoding is in CodingReturn)) -- special treatment true/false
tell application "Preview"
activate
open f
repeat until (count of windows) > 0
delay 0.3
end repeat
save front document
if OKReturn then -- we need special key to be pressed
tell application "System Events" to keystroke return
end if
close front document
end tell
end repeat
I would be very interested to get your feedback about this version.
To save without the "save as" dialog popping up, add "in f". Here "f" was the filename. You could also put in a different path.
save front document in f
Related
I work in media production at a university, we work on Mac systems, but our servers are windows based.
Illegal characters & long file names are causing us problems when transferring our production files to the server.
To prevent file transfers failing & being sent to a holding pen in our DAM system i'm looking to create a simple Automator App that can be used by the production team to do the following;
Accept source folder as input for the app.
Scan contents & replace the following characters ()\/[]"*?<>|+ with an underscore.
Scan contents & for file names longer than 100 characters
Log / report on the affected files for our producers to amend.
Within Automator I have had success with replacing the illegal characters using a find & replace rule for each, but I'm not sure of the apple script that would be required to check the file name lengths & reporting all changes.
I'll be eternally grateful if anyone would be able to suggest a route forwards!
Obviously, I have no clue what you might be passing along, nor how you might be replacing the text in filenames, nor exactly what you would like to report, as you don't really provide any of those details. However, here is a straightforward way to test for filenames longer than a given length within automator.
To provide the initial file list to test, I begin with three actions:
Get Selected Finder Items
Get Folder Contents ('repeat for each subfolder found' is checked)
Filter Finder Items ('kind is document')
This will pass along a list of alias file objects to the fourth 'run applescript' action, as input.
on run {input, parameters}
set fList to input
set nList to {} -- becomes list of filenames
set cList to {} -- becomes list of filename lengths
tell application "Finder"
repeat with ff in fList -- list of file aliases
set nn to name of ff
set end of nList to nn
set end of cList to length of nn
end repeat
end tell
set longList to {}
repeat with cc from 1 to length of cList
if item cc of cList is greater than 100 then
set end of longList to item cc of nList -- names with more than 100 characters
end if
end repeat
return longList
end run
This should be run when a folder is selected in the Finder.
Essentially, what this does is take the input (i.e. list of file aliases) and create corresponding lists of filenames and filename lengths. The script then loops through the list of lengths looking for items > 100 and and returns a list of matching filenames. If instead, you set end of longList… to items from fList then it will return a list of file aliases.
If this isn't what you're looking for, please advise. The above works under Sierra.
PreNote: I am open and hungry for any information, advice, tip etc.
Hello Everyone!
I am trying to create automation with applescript. This is my first personal applescript task but I have some valuable questions. Basically I am trying to catch live notifications from a website and display them in mac os notification.
I am trying to build process for a few days but I don't want to give a mess to you :) so I have roughly explained my process below.
(* Variables used in whole process
set $webToCheck > This is Safari webpage which I want to run my script on it. It won't be front window, script should be run with its name or other property.
set $theClass > This is class name of DOM element to check if it is exist or not. This class is not always exist on DOM of $webpage. It comes with notifications so when use it in "do Javascript" I got error "variable is not defined"
set $num > number of class to use in "do Javascript"
set $input > variable to assign HTML text
set $modifiedInput > Text of input seperated from HTML tags
*)
-- Step 1
tell application "Safari"
work on $webToCheck
-- Step 2
repeat until $input is not empty
set input do Javascript
document.getElementsByClassName > $theClass, $num of $webToCheck
end repeat
-- Step 3
modify text of $input to seperate from RAW HTML -- For example: <a class="" value=""> TEXT to be seperated </a>
Display notification $modifiedInput
-- Step 4
Go back to step 1 or 2 to check and display notification again
First of all, here are some general tips though:
Applescript won't accept $ at the start of variable names.
The variable assignment you are looking for is set {variable} to {value}. You can optionally at the end of it clarify the variable's class using as {class} at the end of the assignment.
Focusing a certain website does not happen with work on {URL} but as with most object oriented things in Applescript with the tell-statement. It will be shown in the full solution.
Text concatenation in Applescript happens with &. So something like "Hello " & "World" is the standard way to do it.
Modification of most things in Applescript happens with set.
It is easier to use innerText instead of innerHTML as splitting text in Applescript is a bit of a pain.
There is no goto but you could wrap the first few steps into a function, which are declared with on or to in Applescript.
Here is the full code with some documentation sprinkled in there:
global webToCheck, theClass, num, input --This says that all variables can be used even in functions.
set webToCheck to "youtube.com" --Strings can only use double quotes.
set theClass to "style-scope yt-alert-with-actions-renderer" --I will use an actual demo to prove that it is working
set num to 0 as integer -- This is the type declaration I was talking about. For numbers we have integer, real(float) and number.
set input to "" -- You don't have define everything at the top, but I will do so for this.
on displayNotification()
tell application "Safari"
tell window 1 -- This will target only the first window. For multiple windows you would have to write a repeat with-loop(for-loop), which I'm not going to do, for the sake of simplicity.
tell (first tab whose URL contains webToCheck) -- This targets just the first tab which contains the webToCheck variable.
set input to do JavaScript "document.getElementsByClassName('" & theClass & "')[" & num & "].innerText" -- This is the way I would go about writing the Javascript. I think you had something different in mind, but this works for my example.
display notification (paragraph 1 of input) with title webToCheck -- This displays the first line of my input since that is the relevant part. I also set a title so I doesn't just say "Script Editor"
end tell
end tell
end tell
end displayNotification
repeat 4 times -- I think this is quite obvious. Adjust this to your needs.
displayNotification()
delay 4
end repeat
Running this while having not used youtube on Safari in a while it displays this:
Note that this isn't the most elegant solution, but I think it is readable and it (hopefully) works for your needs.
I'm working on a project that involves using Applescript to make a list of open URLs within the users Google Chrome Browser, in order to save them for when I eventually want to re-open Chrome. Finding that I needed to have a way to determine which tabs were present in which windows, I decided to try and make a nested list in Applescript, in which each window is it's own sublist of tab URLs, and then return it in the variable declared before the subshell.
The way I'm doing this is via the following code
tabs=$(/usr/bin/osascript << EOT
tell application "Google Chrome"
# save a variable to the number of windows open
set windowCount to number of windows
set myWindows to {}
repeat with x from 1 to windowCount
# count the tabs in the window we are iterated upon
set tabcount to number of tabs in window x
# this list will hold the URLs, delimited by commas
set myURLs to {}
# secondary loop, this time iterating tabs
repeat with y from 1 to tabcount
# grab URL from current tab
set tabURL to URL of tab y of window x
# append URL to end of list
copy tabURL to the end of myURLs
end repeat
# this means our end result will be a list of lists
# containing the URLs of all the tabs of all the windows
copy myURLs to the end of myWindows
end repeat
return myWindows
end tell
EOT)
The issue I'm running into is that, although Applescript is building the nested list properly, i.e.
{{"https://stackoverflow.com/questions/ask"}, {"https://twitter.com", "https://facebook.com"}}
Bash seems to flatten the list when I reference $tabs later into something like
https://stackoverflow.com/questions/ask, https://twitter.com, https://facebook.com
which leads me to believe Applescript and Bash aren't getting along when passing complex variables. Is this the case and is Bash not able to read multi-dimensional lists from Applescript? Or am I simply programming this incorrectly?
Thank you!
Here's a basic, barebones script that contains two handlers: storeURLs() and restoreURLs().
storeURLs() retrieves a nested list of currently-open Chrome tabs (grouped by window) and writes their URLs out to file. restoreURLs() reads this file and opens the URLs in Chrome, restoring the arrangement of tabs and windows.
Running the script in its current form will store the list of URLs in the file ~/.chrometabs. To get the script to restore the saved URLs, comment out the first occurrence of "storeURLs()" (line 6) by prepending it with two hyphens (--) or a hash (#); and uncomment the line below that, by deleting the two hyphens before "restoreURLs()".
property home : system attribute "HOME"
property file : home & "/.chrometabs" --> /Users/%YOU%/.chrometabs
on run
storeURLs()
--restoreURLs()
end run
on storeURLs()
close access (open for access my file)
tell application id "com.google.chrome" to set ¬
URLs to the URL of every tab in every window
write the URLs to my file
return the URLs
end storeURLs
to restoreURLs()
close access (open for access my file)
if (get eof of my file) = 0 then return false
set URLs to read my file as list
tell application id "com.google.chrome"
repeat with URLgroup in the reverse of URLs
tell (make new window)
set the active tab's URL to the URLgroup's 1st item
repeat with |URL| in the rest of the URLgroup
make new tab with properties {URL:|URL|}
end repeat
end tell
end repeat
activate
end tell
return the URLs
end restoreURLs
The script doesn't contain anything more than the most basic error-prevention, and as such, will benefit from additional error-handling. It was written and tested using AppleScript version 2.5 in macOS 10.12.6. The only potential problem I anticipate in more recent versions of macOS (Mojave, Catalina) would be security bollocks that could prevent the script creating and/or writing to the file path ~/.chrometabs, either due to its location, or due to the leading "." in the file name which denotes an invisible file in macOS.
I have an filemaker Pro 13 database with around 120 records (it's for a conference). I want to team it up with BBEdit to create individual files for each abstract, thus applescript. Much to my surprise (and despite a lot of web tips on scripting) '[tag:current record]' is not recognised in the script.
The relevant bit is this:
FM Script:
Loop
Perform Applescript
tell application "FileMaker Pro"
activate
set MyFileName to cell "WebAbstractFileName" of table "SelectionProcess"
set MyWebAbstract to cell "WebAbstract" of table "SelectionProcess" as text
end tell
-- (BBEdit bit, which works fine in testing)
Go to Next Record (exit after last)
End Loop
This works fine if I only want to retrieve the first record!
This applescript is set within a filemaker script which loops through the records but the script doesn't care which record it's in.
I've tried adding 'of current record' before the table reference but it then gives me errors (eg error "FileMaker Pro got an error: Object not found." number -1728 from cell "WebAbstractFileName" of current record of table "SelectionProcess") Without 'current record' it works fine, but only gives me the first record.
Here's (roughly) how you could do this in a Filemaker script:
Go to Layout [ “YourTable” ]
# FIND THE RECORDS OF INTEREST
Perform Find [ Restore ]
Go to Record/Request/Page [ First ]
Loop
New Window [ ]
# ISOLATE THE CURRENT RECORD
Show All Records
Omit Record
Show Omitted Only
Set Variable [ $path; Value:Get ( DocumentsPath ) & "someFolder/" & YourTable::Somefield & ".html" ]
Export Records [ No dialog; “$path” ]
Close Window [ Current Window ]
Go to Record/Request/Page [ Next; Exit after last ]
End Loop
This will export every record in the found set as an individual file into the folder "someFolder" located in the user's Documents folder, using the contents of the YourTable::Somefield field as the filename.
If, as you say, you don't need the separate files, then of course this can be much simpler.
More tinkering solved this. The crucial bit was to change the syntax. The script now reads:
tell application "FileMaker Pro"
activate
tell current record to set MyFileName to cell "WebAbstractFileName"
tell current record to set MyWebAbstract to cell "WebAbstract"
end tell
What seems to happen is that the fields must be visible (yet I had that not be a problem at one point...go figure. If they're visible, you can drop the table specification). This script, wrapped in a Loop block, will act on the found set and (if instructed) exit after the last record.
I append the bbedit script to create a new file and save it with a variable taken from another field in case it's of interest.
tell application "BBEdit"
set notesPath to ":Users:ophiochos:Dropbox:TL Conference Admin:Webpage materials:Abstracts:"
set newFilePath to notesPath & MyFileName & ".html"
set newDoc to make new text document with properties {contents:MyWebAbstract}
tell newDoc
set source language to "HTML"
save to newFilePath
close window
end tell
end tell
Or you could simply create a calculated field that contains the contents of the desired export file for each record, loop through the records one by one, and just use an Export Field Contents ['YourCalculatedField_c'] script step.
You can also use FM to preview the html output by using a web viewer to display your html. This, along with exporting individually, you can get all this functionality without the need for an external program.
If you need to change the text encoding for output files, you can also specify those in an xslt for outputting files:
http://filemakerhacks.com/2012/09/23/export-field-contents-as-utf-8/
Also, if performing applescript from within FileMaker, the "tell application" line is not needed since it is implied.
I'm trying to get the filename without the extension of the current document file in Omnigraffle Professional 5.
tell application "OmniGraffle Professional 5"
set _document to front document
set _path to path of _document
-- Get filename without extension
tell application "Finder"
set {_filename, _extension, _ishidden} to the
{displayed_name, name_extension, extension_hidden} of the _path
end tell
end tell
This gives me the following error: error "Can’t get displayed_name of \"/Users/ca/Downloads/Feb 8.graffle\"." number -1728 from displayed_name of "/Users/ca/Downloads/Feb 8.graffle".
I found some related questions and pages, but I'm a bit lost and really can't understand why it does not work.
Applescript: Get filenames in folder without extension
Applescript Help...Just the File Name
Thanks for your help!
You'd need to change it to the following:
tell application "OmniGraffle Professional 5"
set _document to front document
set _path to path of _document
-- Get filename without extension
tell application "Finder"
set {_filename, _extension, _ishidden} to the ¬
{displayed name, name extension, extension hidden} ¬
of ((the _path as POSIX file) as alias)
end tell
if (_extension ≠ missing value) then
set baseName to text 1 thru -((length of _extension) + 2) of _filename
end if
end tell
"path of front document" returns the POSIX path of a file, which is just a plain string. To be able to get information on an item the Finder will want an alias reference to the file in question. When you pass a plain string it gets an error because a plain string won't have those properties. To get an alias, you need to coerce the plain path first to a POSIX file and then coerce the POSIX file to an alias.
Unless you have defined these variables elsewhere, you need to remove the underscores in {displayed_name, name_extension, extension_hidden}. When you look at the "compiled" code with those underscores left in, it looks like in the following image:
So, the AppleScript is interpreting displayed_name to be a variable, not a property. Now, that's fine if you've defined those variables elsewhere, such as at the top of your script in properties. But if not, you need to remove the underscores, as the property names of Finder items don't have underscores in them. When you remove the underscores, the coloring appears correct (properties are purple with the variables being green).
Note that that still won't give you the filename without an extension. To get that, you'd need to do something like I did in the added line using text n thru m
if (_extension ≠ missing value) then
set baseName to text 1 thru -((length of _extension) + 2) of _filename
end if
First, you need to use the correct labels for the properties of whatever application you are targeting - these can be found in the application scripting dictionary. The next problem is that the Finder doesn't know anything about POSIX paths, which is apparently what OmniGraffle is returning for the document path, so you need to coerce the path into something that the Finder does know about, such as an alias.
tell application "Finder"
set {_filename, _extension, _ishidden} to the {displayed name, name extension, extension hidden} of (_path as POSIX file as alias)
end tell