A simple Drafts work diary

Topics for posts are piling up and I don’t have time to write them up. I’ve recently plotted out posts on

  1. The dangers of stored strain energy and how I avoided shooting my older son with the head of a screw when he helped me run some load tests a couple of months ago. This topic was inspired by the May 4 episode of the Generational podcast, in which Erik Hess and Gabe Weatherhead discussed the dangers of their former workplaces and Gabe’s propensity for setting himself on fire.
  2. Thermal stresses and why Katie Floyd’s glass baking dish blew up on Mother’s Day. This one would harken back to Dan Rutter’s post on Pyrex, which I read through a link from Marco Arment.
  3. The alleged design and craftsmanship in this artisanal bottle opener which Justin Blanton made the unforgivable mistake of ordering.
  4. How revisiting the comic books I loved as a teen has left me disappointed in both the writing and the artwork. The one exception is the early Conan series by Roy Thomas and Barry Windsor-Smith, and that’s probably because I’ve always seen myself as a latter-day Conan—black-haired, sullen-eyed, sword in hand, a thief, a reaver, a slayer, with gigantic melancholies and gigantic mirth.

And that doesn’t include more topical posts that I’ve given up on writing because their time has passed.

So tonight I’m taking the easy way out, with a short post about the iOS Drafts app inspired by David and Katie’s recent iOS Automation episode of Mac Power Users and by the Generational episode with Greg Pierce,1 the developer of Drafts.

Last night I asked a stupid question about Drafts on Twitter:

Y’know what’d be great? If @draftsapp could append to a Dropbox file named according to the date, creating the file if necessary.
Dr. Drang (@drdrang) Mon May 13 2013 8:16 PM CDT

It was stupid because Drafts can already do what I was asking for, as several kind people told me without snickering. Here’s the Dropbox action I came up with:

Drafts work diary

In my defense, the reason I didn’t realize I could use a date tag (the thing inside the doubled square brackets) in the name of the file is the name of the option that must be chosen with it: Predefined. It just didn’t seem right to me that a file with a predefined name could have its name defined on the fly. Also, it seemed superfluous to have a Timestamp option for the file name if a timestamp could be provided through tags. Still, the ability to use tags in file names goes back to version 2.5.3—I should have known about it.

Anyway,2 this action is intended to help me keep track of what I’m doing at work, what the action described at the end of this post should’ve been. The idea is to launch Drafts when I switch from one task to another, tap in (or dictate) what I’m about to start working on, and invoke this action. Each time, a pair of lines will be added to a diary file for that day, one with the timestamp and the other with the note I wrote for it. Like this:

1:14 PM
Started 200° test

1:45 PM
Ended 200° test

1:54 PM
Started 300° test

The improvement over the old system is that now I’ll have a separate file for each day, all in the same Diary folder in Dropbox. To me, this is a more natural way to organize diary entries, rather than having them all with time and date stamps in a single big file. Each day’s file will have a name like 2013-05-14.txt.

This is, in many ways, the same sort of thing Katie Floyd is doing with Day One. I like Day One, but I prefer using plain text files in case there comes a time when I want to run some script over my diary files to extract information. I have no plans to do that, but I want leave open the possibility.

Of course the real trick isn’t coming up with a Drafts action, it’s developing and maintaining the discipline to make an entry every time I switch contexts. I’m working on that.


  1. Gabe and Erik have been killing it on Generational. You really should make room for it in your listening schedule. 

  2. Have I ever mentioned how much I hate the non-word “anyways”? Once limited to the sort of people who say “irregardless,” it’s now everywhere, tormenting me. 


Cleaning out Clean My Mac

I just got a notification on my computer from Clean My Mac 2, a utility I bought as part of the recent MacHeist nanoBundle. I have nothing against CMM2—it does a fine job of scanning my disk and finding files that might be good to delete—but I don’t want it nagging me to do so. So I went searching for how that notification was sent.

I didn’t have to look far. The natural place for scheduled, periodic tasks to live is in your ~/Library/LaunchAgents folder. And that’s exactly where I found a couple of Launch Agent plist files from CMM2.

Clean My Mac Launch Agents

A quick review of the plist file shows that the scheduled scan is set to run on the 12th and 19th of the month. I installed CMM2 late last month, so it’s not surprising that today was the first day I saw the notification.

I didn’t want to delete the plist files (they might be useful later), but I did want to stop them, so I ran

launchctl unload -w ~/Library/LaunchAgents/com.macpaw.CleanMyMac2Helper.scheduledScan.plist

and

launchctl unload -w ~/Library/LaunchAgents/com.macpaw.CleanMyMac2Helper.trashWatcher.plist

from the Terminal. Running the launchctl command to look for other MacPaw processes

launchctl list | grep macpaw

showed that there was still a CMM2 Helper process running, so I opened Activity Monitor and killed it.

Activity Monitor with CMM2 Helper

I suppose I could’ve edited the plist files to add a Disabled key, but I find running launchctl easier. I’m always worried that I’ll add an item at the wrong nesting level when I edit XML files.

I’m not going to rant against MacPaw for installing processes without telling me, because it’s entirely possible it did tell me and I didn’t pay attention. Either way, I shouldn’t get that unwanted notification again.


Bite me

Earlier today, Gabe Weatherhead recommended a very powerful compact flashlight. It’s a nice product, I’m sure, but it’s missing one feature that I’ve come to find very important in a flashlight: biteability.

You know what I mean. You’re working in the dark and need both hands free. Where does your flashlight go? In your mouth, of course. And to keep it pointed in the right direction, you need to be able to grip it between your teeth, so a metal barrel is out of the question. For several years now, I’ve been using a Brinkmann 3-watt LED Armor Max flashlight that runs on 3 AAA batteries. It has a plastic body with a rubbery grip around the barrel that makes it very tooth-friendly. It’s nowhere near as bright as Gabe’s, but it’s always been more than bright enough for my needs.

Brinkmann 3 watt flashlight

Yes, you can buy headband-mounted flashlights, but the great thing about this Brinkman is that it works perfectly well as a regular flashlight, and under normal circumstances you won’t look like a dork using it. And while you will look like a dork when you put it in your mouth, you only need to do that when there’s no one around to hold the flashlight for you and, therefore, no one around to see how dorky you look. Self-correcting!

I didn’t set out to find a biteable flashlight. I just happened to buy a Brinkmann because it was bright, compact, and water-resistant (O-rings seal the screw-on caps at either end) and learned later how helpful it was to have a flashlight I could hold comfortably in my teeth.


TextExpander date snippets via bash

You have, presumably seen this post by David Sparks, in which he provides a bunch of TextExpander snippets for showing dates and times in different formats, some of which involve calendrical calculations. That’s a combination of topics I simply cannot resist commenting on.

First, if you download his snippet collection and double-click on the file, it’ll be imported into its own folder in TextExpander. If you already have some date snippets—and I suspect most of you do—you don’t have to worry that David’s will overwrite or get mixed in with the ones you already have.

MacSparky date snippets

Second, you’ll notice that most of David’s abbreviations start with x. He uses that the same way I use the semicolon: as a signal character that makes it easy to come up with meaningful abbreviations that don’t conflict with real words. By using a letter instead of a punctuation character, David can sync his snippets between his Mac and his iOS devices and not have to worry about his abbreviations requiring a trip to a secondary iOS keyboard. I’d use this except for the fact that I often use variable names that start with x,1 and my fear of conflicts is greater than my desire for snippet harmony.

Finally, and most interestingly, David has a few snippets for inserting dates that are for some date in the future. I’ve made similar snippets, but mine have always been for a fixed number of days from today. David’s are more subtle. As you can see from the screenshot, he has snippets for things like “next Monday” and “next Friday.” TextExpander’s built-in date calculation commands can’t handle things like that, so David’s snippets use AppleScript (written by Ben Waldie).

I wrote a post about these kinds of calculations last fall, discussing both AppleScript and Python solutions. In the comments to that post, David Cross (@roguemonk) pointed out a clever use of the date command that blew me away. It manages to do these same calculations in way that’s both more compact and easier to understand at a glance. The technique relies on the use of date’s -v option.

Let’s say you want to replicate the “Next Monday” snippet shown above. The date invocation that’ll do it is

bash:
date -v +1d -v +mon +"%Y-%m-%d"

Like the AppleScript in the screenshot, this gives you the next Monday (-v +mon) after (-v +1d) today.2 3 The formatting of the date is done through the familiar strftime library used by lots of Unix utilities and programming languages.

To make this command work in TextExpander, you need to add the shebang line for bash and you probably want to use echo -n to suppress the linefeed that date adds to the end. Your final snippet would look like this:

bash:
#!/bin/bash
echo -n `date -v +1d -v +mon +"%Y-%m-%d"`

Next Friday would look like this:

bash:
#!/bin/bash
echo -n `date -v +1d -v +fri +"%Y-%m-%d"`

And so on. The great advantage of this approach is that the strftime format is much more flexible than what you can get out of AppleScript. Just look at the contortions poor Ben had to go through to get a simple year-month-date format. If you wanted a format like “8 May 2013,” the date specifier would be easy to change:

bash:
#!/bin/bash
echo -n `date -v +1d -v +mon +"%-d %b %Y"`

I realize that writing this post so close on the heels last week’s gentle poke at Merlin Mann makes it look like I’m taking on the role of TextExpander policeman. But if I could control my obsessions they wouldn’t be obsessions, would they?


  1. Contrary to popular opinion, variable names that start with x aren’t necessarily a recipe for obscure code. I write scripts that do coordinate calculations, and the variables that represent the x-, y-, and z-coordinates of points often start with those letters. 

  2. The order of the -v options is important, as they’re applied sequentially. In this case, we start by moving forward a day and then look for the “next” Monday. If the order of the -v’s were reversed, we’d go to the next Monday and then step forward a day, landing on a Tuesday. 

  3. If tomorrow is a Monday, that’s the date that’ll be returned. The + sign for day-of-week searches works more like than >


Sidebar affiliate links

If you’re reading this on the site rather than through an RSS reader, you’ll see that the sidebar over on the right has changed. Gone are the Flickr photos, which I hadn’t updated since the fall, and the tag cloud, which I doubt that anyone used. In their place are affiliate links to Amazon, the Mac App Store, and the iOS App Store.

As I mentioned a few months ago, I’m not entirely comfortable with conventional web ads on the site, but I have no problem with affiliate links. I’ve been using them in my posts for quite a while when I recommend an application or book or pen or whatever. Now they’ll be in the sidebar.

I’ll certainly be tweaking the format, but what you see now is—in broad terms, if not in detail—the way I expect it to stay: an Amazon product, a Mac application, and an iOS app. A decent-sized image of each, with a sentence or two from me explaining why I recommend it. At present, the text appears when you hover over the image via the title attribute. That was easy to implement, but isn’t a permanent solution because hovering isn’t a concept that applies to touch devices. A popup system that works just as well on mobile and the desktop will be one of my first changes.1

At present, I expect to switch the recommendations every week or two, but we’ll see how that works out. I’m notoriously lazy2 and may leave some links up for longer.

I have, of course, written a couple of scripts to make it easier to add the link code to my WordPress template. Here’s the script that generates the Amazon link:

python:
 1:  #!/usr/bin/python
 2:  
 3:  from amazonproduct import API
 4:  import sys
 5:  import re
 6:  
 7:  # Get the item's ID from the URL on the command line.
 8:  itemID = re.search(r'dp/([^/?%]+)', sys.argv[1]).group(1)
 9:  # print itemID
10:  # sys.exit()
11:  
12:  # Login.
13:  api = API('myaccesskey', 'mysecretkey', 'us', 'myassociateID')
14:  
15:  # Lookup the item.
16:  node = api.item_lookup(itemID, ResponseGroup="Images,Small")
17:  itemURL = node.Items.Item.DetailPageURL
18:  imageURL = node.Items.Item.LargeImage.URL
19:  author = node.Items.Item.ItemAttributes.Author
20:  title = node.Items.Item.ItemAttributes.Title
21:  
22:  # Print the HTML to be added to the sidebar
23:  print '''<p>
24:    <a href="{0}"><img src="{1}" alt="{2} by {3}" title="" /></a>
25:  </p>'''.format(itemURL, imageURL, title, author)

This takes the URL of an Amazon product as its command-line argument and returns the HTML link code. To use it requires an Amazon Associates account, a Product Advertising API account, and the python-amazon-product-api library.

The comments in the script pretty much tell you what’s going on. You’ll want to edit Line 8 to use your own API access and secret keys and your own Associate ID. Lines 17-20 show how deeply nested the return values are; figuring out how to extract the fields I needed was the most difficult part of this script.

The script is called this way:

amazon-sidebar-link 'http://www.amazon.com/Idiot-America-Stupidity-Became-Virtue/dp/0767926153/ref=la_B001IQXNKY_1_1?ie=UTF8&qid=1367898622&sr=1-1' | pbcopy

The URL is put in single quotes to keep the ampersands (and any other special characters) from being interpreted by the shell. I typically use my ;furl TextExpander snippet to insert the URL of the page I’m browsing so I don’t have to jump back and forth between the Terminal and the browser. Piping the output through pbcopy puts the HTML output into the clipboard, ready for pasting into the template.

A similar script uses the python-itunes library to access the iTunes Search API:

python:
 1:  #!/usr/bin/python
 2:  
 3:  import itunes
 4:  import re
 5:  import sys
 6:  
 7:  # Get the item ID from the URL on the command line.
 8:  itemID = re.search(r'/id([^/?%]+)', sys.argv[1]).group(1)
 9:  # print itemID
10:  # sys.exit()
11:  
12:  # Lookup the item.
13:  item = itunes.lookup(itemID)
14:  itemURL = item.get_url() + "&uo=4&partnerId=30&siteID=mysiteID"
15:  imageURL = item.get_artwork()['512']
16:  name = item.get_name()
17:  publisher = item.get_artist()
18:  
19:  # Print the HTML to be added to the sidebar
20:  print '''<p>
21:    <a href="{0}"><img src="{1}" alt="{2} by {3}" title="" /></a>
22:  </p>'''.format(itemURL, imageURL, name, publisher)

Here, the only things you’ll need to edit are the siteID item and (possibly) the uo and partnerID items3 in Line 14. You’ll need to be a member of Apple’s Affiliate program to get those items. This script is called exactly the same way as the Amazon script above. The argument is the URL of the itunes.apple.com web page for the product.

To help me find the right web page quickly, I use Google’s site-specific searching restriction. For example, a search on

bbedit site:itunes.apple.com

brings me immediately to the page I want. Of course, I have a TextExpander snippet that expands to site:itunes.apple.com.

It’d be nice to get the product ID number directly from iTunes or the App Store application, but I don’t know how.

You’ll notice that in each script, I leave the title attribute of the <img> blank. That’s where I add my comment on the item after pasting the output into my blog template.

This site doesn’t get enough traffic for the earnings on affiliate links amount to much, but they should allow the site to pay for itself. Actually, only iTunes/App Store earnings come to me. Earnings from the Amazon account go to my daughter who, unlike many her age, didn’t come back to sponge off live with her parents after college. It’s not enough to pay for her coffee habit, but it helps.

Update 5/7/13
I should’ve mentioned that the images used in the links—which are served directly from Amazon and Apple—are larger than what you see in the sidebar. That’s because the CSS for the sidebar has max-width and max-height settings that tell the browser to scale the images down. This wastes a little bandwidth, but I don’t have to redesign the sidebar to match the size of the images Amazon and Apple deliver.


  1. And I should probably apply that solution—whatever it turns out to be—to footnotes, too. 

  2. See Flickr comment above. 

  3. I confess I’ve forgotten whether those items are generic or specific to your account, and I just don’t feel like looking it up (see earlier comment on laziness). If your affiliate links use different values, then they must be account-specific.