I need to write an AppleScript to open Safari and go to https://www.stats.govt.nz/large-datasets/csv-files-for-download/ to download the first csv file
Rather than doing your work for you by providing you with a code snippet to accomplish this task, I will instead provide you with a great resource. Cube MG has a bunch of tutorials that are really helpful for interacting with web page elements via Safari. Check it out here: http://www.cubemg.com/how-to-click-a-button-on-a-web-page-with-applescript/
There are other ways that you could approach something like this such as using the command line but that is a bit more advanced. Check out Cube MG and see what you can learn!
tell application "Safari"
make new document with properties ¬
{URL:"https://www.stats.govt.nz/large-datasets/csv-files-for-download/"}
repeat
if the front document's source contains "What are CSV files?" then ¬
exit repeat
delay 0.5
end repeat
tell the front document to set CSVfiles to ¬
do JavaScript "Array.from(document.links,
x=>x.href)
.filter(x=>x.indexOf('.csv')!=-1);"
end tell
This gets you the links to all the CSV files. To extract the first one, use item 1 of CSVfiles.
NB. Don't forget to enable Allow JavaScript from Apple Events in Developer menu (a hidden menu, made visible through Preferences > Advanced > Show Develop menu in menu bar)
Related
I am working with Selenium on macOS to automate sending images using WhatsApp web in Google Chrome. The task involves uploading the image, and for that a system(Finder) prompt comes up to select the file. It's done in Windows using AutoIt.
I tried looking up how to automate this task in macOS, and I believe AppleScript can be used for it. Since I have no experience in GUI scripting, any help would be appreciated.
Thanks.
I was able to find the answer on another post on Stack Overflow. I have added the answer for anyone who comes across the same problem.
tell application "System Events"
keystroke "G" using {command down, shift down}
delay 1
keystroke "/path/to/file"
delay 1
keystroke return
delay 1
keystroke return
delay 1
end tell
I don't advocate GUI scripting any more than the burning down of the Amazon, but it seems to be necessary for this task, and I wanted to provide you with an example of a GUI script that tries its best to minimise the unpleasantness of the user experience, and aim for fewer weak points in the code where GUI scripts are most likely to falter.
If you know the path to your file—which I assume you do in these sorts of situations, as your script keystrokes the filepath—then you might find the following technique saves a few steps, and feels a bit more graceful in how it gets executed:
set filepath to "/path/to/image.jpg"
-- Copy file object to clipboard
set the clipboard to filepath as «class furl»
-- Make sure Chrome is in focus and the
-- active tab is a WhatsApp tab
tell application id "com.google.Chrome"
activate
if the URL of the active tab in the front window ¬
does not contain "web.whatsapp.com" then return
end tell
-- Paste the clipboard contents
-- and hit return (send)
tell application id "com.apple.SystemEvents"
tell (process 1 where it is frontmost) to tell ¬
menu bar 1 to tell menu bar item "Edit" to tell ¬
menu 1 to tell menu item "Paste" to set Paste to it
if (click Paste) = Paste then keystroke return
end tell
The if (click Paste) = Paste check should negate the need for a delay, as it explicitly forces AppleScript to evaluate the click command before going on to issue a keystroke. However, I can't test this under all possible conditions, and if there are other factors, like CPU usage, or process freezes, that are likely to give the script a chance to jump ahead, then just insert a small delay after then and move keystroke return down onto its own line.
If you wish to remove the file object from the clipboard afterwards, then simply add as the final line set the clipboard to (and just leave it blank after the word "to", which will clear the clipboard's contents). Of course, this won't affect any clipboard history data you might have if you use a clipboard managing app, only the system clipboard's current item.
I open a lot of new documents in Textwrangler/BBedit and I would like them to always have the date printed at the top. I would like this to be automatic so that I don't have to remember to run a script each time.
I'm new to BBEdit but I really like Textwrangler and have used it for years. I read some of the documentation on BB and I think that attaching some Applescript to an event might be the way to go. However, none of the listed events seem quite right, and I don't really want to add dates to existing documents.
I found the following page which was a good starting point:
http://bbeditextras.org/wiki/index.php?title=Scripting_and_Automation
I also found these relevant hooks from the BB docs:
App attachment points
applicationDidFinishLaunching: called when the application has completed
startup.
applicationShouldQuit: called when you choose the Quit (or the application
receives a ‘quit’ event for any other reason).
applicationDidQuit: called when the application has finished shutting down and is about to exit.
applicationDidSwitchIn: called when BBEdit has been brought to the foreground.
applicationWillSwitchOut: called when BBEdit is being put into the background.
Document attachment points
documentDidOpen: called when a document has been opened and is ready for use. (Since BBEdit supports multiple types of documents, your script should allow for the argument to be a document of any type.)
documentShouldClose: called when the application is preparing to close a
document.
documentDidClose: called when the application has closed a document.
documentShouldSave: called when the application is trying to determine whether a given document should be saved.
documentWillSave: called when the application is about to begin saving a
document. (note that this will only be called after a successful return from a
‘documentShouldSave’.
documentDidSave: called after a document has been saved successfully.
documentWillUnlock: called when BBEdit is going to make a document writeable. (For example, when you click the pencil to unlock a document)
documentDidUnlock: called when BBEdit has successfully made a document
writeable.
documentWillLock: called when BBEdit is going to make a document read-only.
documentDidLock: called when BBEdit has successfully made a document readonly.
I don't know if any of those really fit, though. I could also try adding some scripts into the startup folder, but I'm not sure how I would go about say, adding a date to all open documents. I've never done applescript before so it's a little trial and error.
I have this code that I've tried running by itself, and it works fine:
tell application "BBEdit"
tell text window 1
select insertion point after (last character)
set selection to ((current date) as string)
end tell
end tell
I'm just a little lost as to how to get the above code to execute on file creation.
Open Script Editor and paste the following code in a new script document:
use BBEdit : application "BBEdit"
use scripting additions
on documentDidOpen(doc)
set n to the doc's name
set t to the doc's text as string
if n does not start with "untitled text" then return
if t's length > 0 then return
set the contents of the doc to (the (current date) as text) ¬
& linefeed & linefeed
end documentDidOpen
Save it as type script (extension .scpt), and name it Document.documentDidOpen.scpt. Either save it directly, or move it subsequently, to the folder ~/Library/Application Support/BBEdit/Attachment Scripts/; if the folder doesn't exist, create it.
Restarting BBEdit ought not to be necessary, but also couldn't hurt. Now, whenever you create a new document (of any type), it will be headed with the current date and time.
Try using BBEdit's 'Attaching Scripts to Menu Items' feature (p 295 of the v11 User Manual). In a nutshell, if you save a script to the Menu Scripts folder with a name based on the menu/command, then this script will run when that menu item is selected. So in your scenario:
Save the script below to BBEdit's Menu Scripts folder with the filename 'New•Text Document'.
tell application "BBEdit"
set cDate to ((current date) as text)
make new document with properties {contents:cDate}
end tell
As an aside, you can generally avoid using selection with the insertion point, for example:
tell document 1 of application "BBEdit" to set text of ¬
first insertion point of text 1 to ((current date) as text)
In your second 'question' scenario, you could probably cycle through all existing windows with that, for example:
tell application "BBEdit"
set tdCount to count of text documents
repeat with i from 1 to tdCount
set text of first insertion point of text 1 of ¬
text document i to ((current date) as text) & linefeed
end repeat
end tell
The following script will open a track in iTunes
use application "iTunes"
property trackURL : "itmss://itunes.apple.com/us/album/brahms-violin-concerto-in-d-major-op-77-iii-allegro/145533236?i=145533044&uo=4"
open location trackURL
Now, asking "iTunes" to play it does not work because the track is highlighted but not properly selected, i.e., it requires a manual mouse click to select it and play it.
How can I select the highlighted track? Or how could I ask "iTunes" to play the song?! Alternatively, is there a way to add a music to my library from an URL directly?
Disclaimer: I don't have the Apple Music subscription, so the UI on my end may not be exactly the same as yours. However, if I click the "Play" button, I get the little advertisement asking me to sign up for the service, which I assume would just play the music if you had the service. So, these are the steps I've been able to follow to get that box to pop up:
The first, and most convenient from AppleScript, thing to try is just to hit the space bar to start the music playing. This actually works great if I've selected the item manually by clicking on it. However, after open location, it doesn't work, and this appears to be because even though the row is highlighted in the viewer, the actual keyboard focus seems to be on the page itself (the iTunes Store and Apple Music appear to have their entire UI presented as web pages rendered by WebKit). You can verify this by tapping the up and down arrow keys on the keyboard; the page scrolls up and down instead of you switching to adjacent tracks.
My opinion is that this is actually a bug in iTunes; I'd consider the true solution to the problem to be to report this to Apple via the bug reporter. Using open location really should set the keyboard focus to the track you navigated to.
With that said, we can work around it in the short term by simulating a click on the "Play" button. Note that you'll probably need to add your app in System Preferences > Security and Privacy > Accessibility. Note also that this is incredibly fragile, and if Apple ever changes anything in the layout of the web pages they're serving, this whole thing will break. Finally, please note that this code is extremely ugly; the whole thing gives me hives just by looking at it, but it's the only thing I was able to get to work. Side effects of reading this code may include nausea, headaches, and suicidal thoughts. Do not read this code immediately after eating. Consult your doctor before reading this code if you have a history of depression or obsessive-compulsive disorder.
property trackURL : "itmss://itunes.apple.com/us/album/brahms-violin-concerto-in-d-major-op-77-iii-allegro/145533236?i=145533044&uo=4"
property trackTitle : "III. Allegro giocoso, ma non troppo vivace"
tell application "iTunes"
activate
open location trackURL
delay 1 -- give the page a second to load
end tell
tell application "System Events"
tell process "iTunes"
set theRows to the rows of table 1 of UI element 1 of scroll area 1 of group 1 of group 1 of front window
-- "repeat with eachRow in theRows" isn't working. I don't know why. Freaking AppleScript
repeat with i from 1 to the number of theRows
set eachRow to item i of theRows
if exists group 2 of UI element 2 of eachRow then
if value of static text 1 of group 1 of group 2 of UI element 2 of eachRow is trackTitle then
tell group 1 of UI element 2 of eachRow to click
end if
end if
end repeat
end tell
end tell
If Apple ever fixes the bug, of course, we should be able to just:
tell application "iTunes"
activate
open location trackURL
delay 1 -- give the page a second to load
end tell
tell application "System Events" to keystroke space
I would like to click on the Wi-Fi icon with the option key down to reveal extra options available on Mac. How can I automate it using AppleScript?
I tried using key down option and click menu item but no luck in revealing special options.
Is there any way I can achieve this?
It's currently not possible to click with a key held down using AppleScript. Key down actions only apply to other key press actions, since the AppleScript click action doesn't actually perform a ‘click’, but rather directly actions the element.
If you don't mind using a 3rd party utility, here's an example AppleScript script that uses cliclick:
tell application "System Events"
tell application process "SystemUIServer"
set theWiFiProperties to item 1 of (get properties of every menu bar item of menu bar 1 whose description starts with "Wi-Fi")
end tell
set theXpos to (item 1 of position in theWiFiProperties) + ((item 1 of size in theWiFiProperties) / 2) as integer
set theYpos to (item 2 of position in theWiFiProperties) + ((item 2 of size in theWiFiProperties) / 2) as integer
end tell
tell current application
do shell script "/path/to/cliclick kd:alt c:" & theXpos & "," & theYpos & " ku:alt"
end tell
Note: Change /path/to/cliclick to the actual pathname of the cliclick executable.
How it works:
The theWiFiProperties variable gets set to the properties of the Wi-Fi menu extra and then the variables theXpos and theYpos get set to a position that together is the center of the Wi-Fi menu extra on the menu bar.
This info is then used in a do shell script command using cliclick to press the option key down, click at the designated x,y coordinates and let the option key up.
You can use Automator and record the process using “Watch me do” and then save the automated workflow as an application or a dictation command.
In Automator, I saved the watch me do action as an application. I named this new application “Extended_Wifi.app”. Then I had to add this application in system preferences to be able to control my computer.
Personally, I prefer to use Scripteditor rather than Automator because a huge part of me feels like using Automator is cheating. But at the end of the day, I was able to save the Automator action as an application and it functions perfectly however in Scripteditor, I Could not get the AppleScript version of the action to function correctly.
Here is a quick .gif showing the Automator application working correctly.
I have a bulk amount of images, of which i need to remove alpha from each. This is doable from Preview application, but the sheer amount of times i would need to repeat that is way too time consuming.
I have heard about AppleScript and made some feeble attempts at automating the process, currently to no avail.
i am using something like this and then starting a repeat, but it only allows me to loop through one direct folder (also i'm having troubles with menu bar items)
set fl to files of folder POSIX file "/Users/user/Documents/" as alias list
But i have multiple folders within folders which i wish to change an amount of images. the folder structure is like this:
Users/user/folder/ImagesRoot/
in inside ImagesRoot are 3 folders and one txt file. I want to specifically select 2 of the folders called "Icons" and "Screenshots". In "Icons" is 5 images. However "Screenshots" contains 3 subfolders, each with their own 5 images. (can be referred to as "Screensub 1,2,3")
Once receiving the list of images inside such folder, the process would be something like
tell application "Preview"
open the image file
open the file menu
open export...
untick alpha
press save
press replace
close window
end tell
Loop to next one
when looped through all in Icons folder, do all 5 images of each subfolder of screenshot folder
I am told that AppleScript is a good way to do this, but also that bash is a possibility?
However, i have 2% experience with applescript and maybe 4% of bash, and don't know how to approach it.
Any advice or help would be greatly appreciated.
Thanks
As far as I can tell, Preview doesn’t have the ability to change the alpha of a document, even if you enable AppleScripting. In an application that does support it, such as GraphicConverter, this is a fairly simple task:
on open imageFile
tell application "GraphicConverter 9"
open imageFile
tell window 1
set alpha to false
end tell
--save image as needed
end tell
end open
You may find it easier to use Automator. The combination of Get Folder Contents with Repeat for each subfolder found and Alpha Channel set to Remove may be all you need. If you need to exclude some files, Filter Finder Items would do it.
If you want to use Preview, however, you may be able to use System Events. Something like:
on open imageFile
tell application "Preview"
open imageFile
activate
set filename to name of window 1
tell application "System Events"
tell process "Preview"
click menu item "Export…" of menu "File" of menu bar 1
tell sheet 1 of window 1
--rename file
set value of text field 1 to filename & " Alpha Removed"
--uncheck alpha channel
tell checkbox 1 of group 1
click
end tell
--save
click button "Save"
end tell
end tell
end tell
end tell
end open
If you choose the assistive access route, you may find Apple’s help on signing applications useful: http://support.apple.com/kb/HT5914