Category Archives: AppleScript

Hack That Mac 1: Who’s who

Advertisements

applescript: file & folder handlers

Screen Shot 2016-07-26 at 17.06.40

Here’s a few of
the AppleScript handlers I use for getting contents of folders (examples 1 & 2), or for getting the text of a file (example 3).

In all three cases, you give the handler a path string in POSIX form, e.g, ~/Desktop or (for example 3), ~/Desktop/sometext.txt.

In example 1, what you get back is a list of the item names in the folder. It doesn’t include hidden or invisible files.

In example 2, what you get back is a record of all the items and their properties. This can be an immensely useful and powerful handler.

In example 3, what you get back is a text variable whose value is the complete text of the file.

Hope these come in as handy for you folks as they have for me!

Click here to get the handlers from my pastebin.

Enjoy! 🙂

Note: The getFileContents() handler requires OSX 10.10 or higher.

Using Handlers Pt1

Using Cocoa in AppleScript

applescript: easiest way to GUI script

 

Script Debugger is third-party software available from here.

Disclaimer: I have no financial or any other compensatory connection with the developers.

Script Debugger 6: the complete review

SD Shot 2



It feels like cheating. When you’ve spent pretty much your entire AppleScripting life behind the wheel of Apple’s austere Script Editor application, taking Script Debugger 6 out for a 20-day spin feels like someone’s let you in on a secret you’re not supposed to know. Hurdles you’ve taught yourself to clear – through considerable effort, frustration and no small amount of bloody-minded tenacity – are removed before you get to them; obstacles you’ve habitually steered around or avoided have disappeared, and dark holes of AppleScript mystery appear, in the light shone on them by SD6, to be not the menacing entities you once feared but new friends that offer ways to do things faster and more effectively. The secret that Script Debugger seems to lay bare is that AppleScripting doesn’t have to be as painful as we’ve been conditioned to believe. And that does feel like a cheat. Read the full review…


learning the Terminal: Part Three

Screen Shot 2016-07-02 at 15.24.53
It’s been a while since we last posted about Terminal tips and tricks, but a question popped up today about how to discover what tools are available on the command line.

Most of the tools you use in Terminal are located in /usr/bin, and we can use a nifty little tool from there to find out about all its friends. The whatis tool gives you a one-liner description of what a tool does. If it looks interesting, you can find out more about the tool by typing man and the tool’s name on the command line to see its help manual.

On my current machine, there’s over 1000 tools in /usr/bin, and life is just too short to go through them all doing whatis on each and every one, so we’ll combine a bit of command line power with some AppleScript magic, and produce a nice, easy-to-scroll output of all the summaries like the one in the screenshot above.

Copy the script below (or from my pastebin here) and paste it into the Script Editor (/Applications/Utilities/Script Editor.app). Click the ▶︎ button to run it.

This script took about 1m 30 seconds to run on my machine, but you only need to run it once then save the output. Browse or search through it at your own convenience. 🙂

The script will choose TextWrangler for display if you have it installed; if not, it’ll default to TextEdit. The display is much nicer in TextWrangler, but if you’re stuck with TextEdit, turning off ‘Check Spelling’ in TextEdit will aid readability.

# start 

(* 

This script produces a summary of all the CLI tools 

in /usr/bin and displays it in a text document 

*)

set noDocsList to {}

on extractDescription(aText)

repeat with i from 1 to count of items in aText

set this_item to item i of aText

if this_item contains "NNAAMMEE" then

set r to item (i + 1) of aText

try

set o to offset of "" in r

set short_r to text (o + 1) thru -1 of r

set r to short_r

end try

return r

end if

end repeat

end extractDescription

set theDescriptions to return & return & "**********************************" & return & "SUMMARY OF CLI TOOLS (Version 2)" & return & "**********************************" & return & return & return

tell application "System Events"

set theItems to name of every file of folder "bin" of folder "usr" of startup disk

end tell

repeat with i from 1 to count of theItems

set this_item to item i of theItems

set n_item to length of this_item

try

set what_is to do shell script "whatis " & this_item

if text 1 thru n_item of what_is is this_item and what_is does not contain "nothing appropriate" then

set theDescriptions to theDescriptions & return & what_is & return

else

try

set getMan to paragraphs of (do shell script "man " & this_item)

set desc to extractDescription(getMan)

set what_is to this_item & tab & tab & tab & tab & desc

set theDescriptions to theDescriptions & return & what_is & return

on error

set end of my noDocsList to this_item & return

end try

end if

end try

end repeat

set theApp to "TextEdit"

tell application "Finder"

if exists POSIX file "/Applications/TextWrangler.app" then

set theApp to "TextWrangler"

end if

end tell

set theDescriptions to theDescriptions & return & return & return & "The following tools do not have any documentation: " & return & return & noDocsList

tell application theApp

activate

make new document

set front document's text to my theDescriptions

end tell

# EOF 


how to turn off Maps’ location circle

circle of vagueness



If you’re finding that the large blue location circle is obscuring your view of your current location, here’s a quick script that will allow you to toggle it on and off. You could create a Service and then a hotkey for it, or save the script as an Application and add it to your Dock. That’ll give you a one-click method for toggling the circle on and off – you can also turn it back on (but not off!), just by clicking the usual Location button in Maps’ user interface.

Location script

how to create your own AppleScript commands

Screen Shot 2015-12-25 at 09.53.30
It being Christmas an’ all, we thought we’d contribute something special. What’s the one thing every AppleScripter wants for Christmas? Why “the missing command” of course.

You can bug report Apple all you like to add some command like “remove whitespace from a string” or “get substring” without having to mess around with offsets and so on, but there’s nothing better than helping your self. And that’s what we’re going to do today: learn how to add our own AppleScript commands with a bit of help from AppleScript-ObjectiveC and the use of Scripting libraries.

Put on your party hat and get ready to unwrap your gift. We’re going to learn how to add commands so we can write something like the script shown in the screenshot above.

That requires defining 3 new commands for AppleScript:

substring following  — get the rest of a string after a designated substring

substring preceding — get all the string before a designated substring

remove whitespace — remove all the extraneous spaces and new line characters at the beginning and end of a string.

In order to define your own commands (note to the unwary: beware name clashes!), you need to write an SDEF file and include it in a Library’s script bundle.

The steps are nicely laid out in this complete 26-minute video from OSXAutomation:

https://macosxautomation.com/mavericks/libraries/mda/libraries-with-terminology.m4v

(The video is interesting in it’s own right as it sounds like its entirely narrated by the one of the mac’s built in voices).

The library and the sdef file that I created are below, but you’ll need to watch the video to figure out how to put it all together.

A couple of ‘gotchas’ to watch out for:

i. the video doesn’t tell you that you need to include the ‘use framework “Foundation”’ line (you don’t on 10.9, but on 10.11 I couldn’t get it to compile otherwise);

ii. make sure the sdef file name, suite name and library script name all match or you might have trouble compiling.

iii. You’re going to need a heads-up on Objective-C and Cocoa if you don’t already know your way around Apple’s main programming language (Swift? Never heard of ya!) and APIs. Best place to get started with that is Shane Stanley’s intro guides to AppleScript-Objective-C.

If you get stuck, post a comment below and we’ll try to walk you past the obstacles. Once you get the bug, you’ll be writing your own commands left, right and centre!

After you’ve watched the video, you can either write your own commands or come back and copy our sdef file and library script.

If tackling AppleScript-ObjectiveC isn’t something you want to take on right now, let us know in the comments what kind of command you really want to add to your script library and we’ll see if we can’t cook up the code for you.

Alternatively, you can browse through some ready-made script libraries full of extra goodies from this collection.

Merry Christmas all, we’ll see you in the New Year!

🙂

 

Here’s our sdef file:

<?xml version=”1.0″ encoding=”UTF-8″?>

<!DOCTYPE dictionary SYSTEM “file://localhost/System/Library/DTDs/sdef.dtd“>

<dictionary>

<suite name=”ASTU” code=”ASTU” description=”Commands to edit text”>

<command name=”substring preceeding” code=”SQTXSUBB” description=””>

<direct-parameter type=”text” description=”Get the string up to a first occurrence of a substring”/>

<parameter name=”from” code=”FRoM” type=”text” description=”…”/>

<documentation>

<html>

<![CDATA[<p>set s to substring preceeding “world” from “hello world”</p>

<p>–> “hello “</p>]]>

</html>

</documentation>

</command>

<command name=”substring following” code=”SQTXSUBA” description=””>

<direct-parameter type=”text” description=”Get the rest of the string after the first occurence of a substring”/>

<parameter name=”from” code=”FRoM” type=”text” description=”…”/>

<documentation>

<html>

<![CDATA[<p>set s to substring following “hello ” from “hello world”</p><p>–> “world”</p>]]>

</html>

</documentation>

</command>

<command name=”remove whitespace” code=”SQTXRMWS” description=””>

<direct-parameter type=”text” description=”Remove extraneous whitespace and new line characters from beginning and end of a substring”/>

<documentation>

<html>

<![CDATA[<p>set s to remove whitespace ”  hello world  “</p><p>–> “hello world”</p>]]>

</html>

</documentation>

</command>

</suite>

</dictionary>

 

And here’s our library script, which we called “ASTU” (short for “AppleScript Text Utilities”).

 

use framework "Foundation"

on substring preceeding aSubstring from aParentString

set the sourceString to current application's NSString's stringWithString:aParentString

set the searchString to current application's NSString's stringWithString:aSubstring

set theRange to sourceString's rangeOfString:searchString

set theRest to sourceString's substringToIndex:(theRange's location)

return (theRest as Unicode text)

end substring preceeding

on substring following aSubstring from aParentString

set theLength to aSubstring's length

set the sourceString to current application's NSString's stringWithString:aParentString

set the searchString to current application's NSString's stringWithString:aSubstring

set theRange to sourceString's rangeOfString:searchString

set theRest to sourceString's substringFromIndex:((theRange's location) + (theLength))

return (theRest as Unicode text)

end substring following

on remove whitespace aString

set the sourceString to current application's NSString's stringWithString:aString

set trimmedString to sourceString's stringByTrimmingCharactersInSet:(current application's NSCharacterSet's whitespaceAndNewlineCharacterSet())

return (trimmedString as Unicode text)

end remove whitespace

 

how to see active internet connections

Screen Shot 2015-12-03 at 15.55.56.png

I was playing around with some ways of detecting active network connections to add as a function in one of my apps — didn’t really work out, so far — but as I was prototyping the code in AppleScript I came up with this little ditty which some of you might be able to make use of:

1. Open the Script Editor

2. Paste the code below into it and hit ‘Run’

#start of script

on getConnections()

set theCmd to "lsof +c 0 -i -n | grep -i established | cut -d \" \" -f 1 | awk '!_[$0]++'"

set theMsg to (do shell script theCmd)

display dialog "The following apps & processes are actively using your internet connection: " & return & return & theMsg with title "Net Tattler" buttons {"Refresh", "OK"} default button "OK"

set theRes to button returned of the result as string

if theRes = "Refresh" then

getConnections()

end if

end getConnections

getConnections()

#eof

 

If you need more information than just the names of the process, you can play around in Terminal with lsof -iHere’s a great little tutorial.

For something a bit more heavy-duty, check out either Little Snitch or Charles Web Debugging Proxy, both of which are paid-apps but offer free trials. If even those aren’t enough to satisfy your network monitoring desires, head on over to MurusFirewall.com and check out their packet filter GUI offerings for the Mac.

Enjoy 🙂

 

Acknowledgements

Thanks to the folks over at Etresoft for additional suggestions.

%d bloggers like this: