Control your Mac from iOS using Dropbox and Applescript
[day after posting UPDATE: this is just a start. I’m going to start working on a more intuitive way (than having to peck out all kinds of applescript in long hand on an iOS keyboard) to do this, and if anyone else is interested in working on it (probably a folder action script that can read some natural language commands) please email elasticthreads at gmail or twitter @elasticthreads]
So in the past few weeks a bunch of text editing apps for iOS have been released that use Dropbox to sync with your desktop computer. Here’s a good roundup of them. I’ve been really liking Plaintext, and was wondering what I could use it for besides just plain writing text…
And then I remembered Folder Actions, which are an OS X feature that lets you set an applescript to run whenever a file is added to a folder (or deleted). And since you can run one applescript file from another, I realized you could write an applescript in Plaintext and have your Mac run it. Which opens a pretty large window for controlling your Mac (as long as its running, and has Dropbox installed, and has a single Folder Action set up) from anywhere in the world just by writing some applescript in Plaintext. This should work with any Dropbox based text editor (Elements, Writer, Nebulous Notes, etc.), and might even work with Simplenote and Notational Velocity, but I’ve only tested this with Plaintext.
So that last night when I left my apartment with my stereo blasting from my Macbook Pro’s iTunes, to turn it off from miles away all I had to do was type this into a new file in Plaintext: tell application “iTunes” to quit
I came home late that night to a quiet apartment and no angry neighbors.
Here’s how to do it in case you’re interested:
First set up your Mac:
1. Download the Folder Action script here. Move that script to the following folder:
~/Library/Scripts/Folder Action Scripts/ (where “~” means your home folder). If you don’t have a “Scripts” folder in your library, or don’t have a “Folder Action Scripts” folder in the “Scripts” folder, or both, create them.
2. Go to the folder in your Dropbox where you sync your notes from Plaintext (or whatever app you use). The default for Plaintext is ~/Dropbox/Plaintext. Create a new folder inside of that folder and name it something useful like “dbScripts”.
3. Right-click on your new folder and look for a command in the contextual menu named “Folder Actions Setup…” and select it.

4. A list of available folder action scripts should pop up. Select the script we set up in step 1.

5. You should see a window with the name of your folder next to a checked checkbox, the name of your script next to a checked checkbox and “Enable Folder Actions” next to a checked checkbox.

We’re now done setting up your mac. Anytime you put a text file in that folder, your Mac will try and run it as an applescript.
Now a couple things to set up and consider in Plaintext:
1. So fire up Plaintext (or whatever app) on your iOS device and, after it loads up the contents of your notes folder, scroll around and find the folder we just created in Dropbox on your Mac. Select that folder.

2. Anytime you create a new file in that folder, or change the name of an existing file in that folder, after Dropbox works its magic, your Mac will try to run it as an applescript.
But first: there’s a key setting you need to check in Plaintext before testing this out. Hit that little cog in the lower left corner of Plaintext to bring up Settings. Select Dropbox settings:
Make sure that “Sync on Edit” is off.
if Plaintext syncs while your editing, then when you go to create a new file and then start typing your applescript, Plaintext will sync it over to your Mac when it just is an empty file and the folder action will run an empty script. Since Folder Actions only get run when a file is added (not changed), by the time you’re done with your script it will be too late. So turn this setting off.
So now, in Plaintext, you’ll navigate to your scripts folder, create a new file, name it, write the script, and then hit the back arrow to close that file, AND THEN Plaintext will sync it over to your Mac where it will get run.
An easier way to run a script if you have an existing file in your folder with a script that you want to run, or one that is close to what you want to run (for example, if you want to tell application “Safari” to quit instead of “iTunes” to hide that embarrassing page of NSFW), just open that existing file and, change whatever part of the script you might want to change and ALSO change its name. Changing the name of a file in Plaintext will cause Dropbox to delete the old named file and create a new file with the new name (which will then trigger the folder action).
Good scripting!
Update for Google Voice Quicksilver actions and OS X Services
One of my first posts I released applescript actions for Quicksilver that let you easily send a SMS or initiate a phone call thru Google Voice as well as OS X (10.6 only) services that let you right click on a phone number in any application and do the same.
Sometime in the last week the PHP script I used to work with GVoice broke. I fixed it. If you already use the QS actions and want to get them working again:
Go to “~/Library/Application Support/Quicksilver/” (“~” means your home folder) and delete “google-voice.php”. That’s it. The next time you use either the gvDialer or SMSgv actions they will automatically download the updated version.
If you already use the the OS X services you can find and delete the old “google-voice.php” file in “~/Library/Services/” folder. The next time they are run they’ll download the fixed php file.
If you’re just finding out about all of this and want in: read the original post here, the actions and services will just work.
Chrome 7 and OS X
If you’re a Google Chrome user, or considering it, on OS X: Go download and try out the dev channel build*. Yesterday the Chrome team updated its dev channel to Chrome 7, which includes big improvements to rendering speed and stability but also, shocker — better integration with OS X. This includes:
- The development of a real Applescript dictionary (something Firefox doesn’t have), adding one more way to script Chrome.
- Chrome now enables OS X Services, which in Snow Leopard are quite powerful ways of piping text and other data from one application to another or to a service.
- Chrome also lets you send selections to the system wide dictionary.app
* Safari has 2 basic “channels” of build, the official stable Safari releases, and the “Webkit Nightly” builds which are released every day and might be of questionable stability/reliablity.
Chrome on the other hand has 4 concurrent channels of builds you can use.
- The official “Stable”, or release, version of Google Chrome; the most stable, but also the most behind the features and development curve.
- The beta channel which is very stable and has newer features than the Stable channel; this build is actually suitable for most users (remember that Google kept gmail in beta for years. Beta is sort of the new release for Google), its just not certifiably solid.
- Then there’s the Dev channel, which contains a lot of new features, its kind of the testing ground for UI changes and features; some stay, some change, some come and go. You can get a good idea of the future of Chrome by trying out the dev channel, and it’s actually pretty stable; I use it day to day for a lot of browsing and almost never crash it.
- Finally, there’s Chromium, which is the open source base for Chrome, a lot of the development of Chrome happens there, lots of changes from day to day that might eventually come downstream to the other builds, not really for day to day browsing.
Applescript, Services, and Growl issues
One of Snow Leopard’s great evolutions was building up Automator’s ability to create a service, which you can access from your contextual menu, and to make powerful services using Applescript.
A lot of the services I’ve been making, like sending an article to instapaper, or shortening a URL with is.gd, do their business in the background; and I’ve found it useful to throw up a growl notification when their done. The challenge is then distributing the service to users who may or may not have Growl installed. In typical applescripting, outside of writing services, the way to handle this is to check if Growl is running,
tell application “System Events”
set isGrlRunning to (count of (every process whose name is “GrowlHelperApp”)) > 0
end tell
if isGrlRunning then
…
end if
and if it is running to Growl a notification.
The reason this works in applescripts and not services gets into the nerdy nitty-gritty of applescripting and will make this already nerdy post, nerdier. Apologies.
There are two conditions that are important to consider when you call an application from Applescript, given that a user may or may not have that application installed. One condition is during runtime, when the user runs the applescript, and the example with Growl above works great for that.
The other condition is when the applescript is compiled, turned from a mostly natural language script into code OS X and other applications can understand. When applescript gets compiled every call to every application gets checked, and so must be installed on the machine that compiles the script.
Non-service applescripts get compiled once, and can then be distributed and run by users without needing to be recompiled. So you can write an applescript on your machine calling all kinds of applications (as long as you use code like above which checks the machine running the script to see if the application is installed before sending it commands), and then send that applescript to users who may or may not have those applications installed, and they can run it, without compiling it, and be fine.
HOWEVER. For some reason, services compile their applescripts at runtime. Which means you can’t write rich services that call many applications without worrying what’s installed on a users machine, because each time the service is run it has to check every line of applescript against every application that it calls.
So a simple thing like Growling a notification becomes a dangerous prospect if you want to distribute your services… but I’ve figured out a way around it.
The thing to do is to isolate any bits of script that call extraneous applications, that might not be installed by a user, and run them as a shell script using “osascript”. When a service is run it does not go through and check any shell scripts, including ones run in applescript via “do shell script ‘osascript …”
So here’s a handler you can use in your Applescript services to growl, safely. It’s from my InstapaperIt service. The key here is that since you’re writing a shell script all quotes need to be escaped. Also note that I end the shell script with ” &> /dev/null &”, so that the shell script is run without waiting for a response. I’ll post it below, but you can also download an applescript of it here because posting escaped quotes on the web doesn’t come out right.
on triggerGrowl(currentStatus, currentTitle)
set myApp to “APPLICATIONNAME”
try
tell application “System Events”
set isGrlRunning to (count of (every process whose name is “GrowlHelperApp”)) > 0
end tell
if isGrlRunning then
set osaSc to “tell application "GrowlHelperApp"
set the allNotificationsList to {"Notification"}
set the enabledNotificationsList to {"Notification"}
register as application "” & myApp & “" all notifications allNotificationsList default notifications enabledNotificationsList icon of application "” & myApp & “"
notify with name "Notification" title "” & currentTitle & “" description "” & currentStatus & “" application name "” & myApp & “"
end tell”
set shSc to “osascript -e ” & quoted form of osaSc & ” &> /dev/null &”
ignoring application responses
do shell script shSc
end ignoring
end if
end try
end triggerGrowl
Big update to thermoCLine posted
the universal text field for OS X is now smarter, more accessible, and easier to use.
there’s also global keyboard shortcuts, and much more…
download it, or watch the demo video here.
Taskpaper syncing
The Taskpaper mac — Simpletext — Taskpaper iphone combo works alright in general.
The most problematic moment in the chain is when you’ve made changes to your Taskpaper doc on your iphone and the same Taskpaper doc is already open and running on your Mac.
The thing that works best is to run SimpleText sync from the Mac’s menubar and then, in Taskpaper, go to File “Revert To Saved”, which re-reads the file (which was just re-synced thru SimpleText) back into Taskpaper.
To speed this up and allow me to set up a keyboard shortcut for that to happen automated I wrote an applescript which does just this. First it tells Simpletext to sync, then it tells Taskpaper to revert the front most document to revert to saved, then it re-saves that document. Running this will effectively re-sync the front most Taskpaper document to whatever is in that same document in the Simpletext cloud.
Download the script here.
Unzip it so you have taskSync.scpt
then, open Taskpaper on your Mac, click on the script menu in the menubar and select “Open Scripts Folder”, which should bring up that folder in the Finder. Drag taskSync.scpt into it.
Now you can run the applescript directly from Taskpaper’s script menu.
Go to your Mac’s System Preferences —> Keyboard —> Keyboard Shortcuts Tab —> Application Shortcuts.
Click the plus symbol, select Taskpaper from the dropdown list.
Type “Revert to Saved” into the Menu Title field. Select the shortcut field and type command-2 (hold down the command key while typing “2”).
Type “taskSync” into the Menu Title field and whatever keyboard shortcut you like into the shortcut field (I use cmd-1).
enjoy
Snow Leopard Service, collect files into a new folder
Here’s a snow leopard service which lets you easily collect files into a new folder. Just select files in the Finder, right click on them and go to the service menu and choose folderCollect. The service will then pop up a dialog box asking what you want to name the folder. Then it will move all the files you had selected into that folder. Download folderCollect here. Install to ~/Library/Services. (“~” refers to your home folder).
if you don’t have a Services folder in ~/Library/, then make one Update 03/2010: Mike’s comment inspired a small change to the service.
Instead of “untitled folder” as the default name of your new folder, folderCollect now uses the name of the first file (alphabetically) you’ve selected to be collected. You’ll still get a dialog box, but this will be the default name in that box, so you can just hit enter to use it.
If you want the default name to always be the case, and no dialog box, you can double click on the service to open it with Automator. The first line of script is
property askName : true
change it to false and folderCollect will stop asking for your input…
Threshold has its own tumblr
thermoCLineThreshold has been taking over a lot of things lately. It no longer will be dominating this tumblr… it has its own: 
a new UI for thermoCLine is coming…
thermoCLine has been re-branded: it’s now Threshold
Download thermoCLine Threshold… here.

