Semantic Tagging with Zemanta and Alfred

I’m struggling finding a satisfying taxonomy for tagging my posts here. There was even a time when I would enter them but hide from from display because of how unhappy I was with their ability to tie posts together or increasing discoverability for search engines.

That said, I was pretty intrigued when Brett recently blogged about his use of Zemanta to auto-tag posts on his Jekyll-based blog.

Since I’m not using Jekyll, however, I had to be a little more creative with adapting this workflow. I actually used it as an excuse to learn more about one of the headlining features in Alfred 2: Workflows.

Strictly speaking, Workflows in Alfred tie together triggers, inputs, actions, and outputs to automate common tasks. They operate on text, files, or even remote contents such as your GitHub repositories, like this incredible GitHub workflow does.1

As I despise PHP, I did not go down the route many others take when writing Alfred Workflows. I used Duane Johnson’s beginnings of an Alfred 2 Ruby Framework and implemented my Workflow based on that instead of using David Ferguson’s more sophisticated PHP class. Also, Dennis Paagman’s alfredo Rubygem was very helpful in generating the XML-based responses that the Alfred Workflows need to return to build up responses in the Alfred GUI.

Sadly, system Ruby on Mountain Lion is still 1.8 and the zemanta Rubygem Brett used to implement his auto-tagger is not compatible with Ruby 1.8. Fortunately, there is an alternative API implementation available: The term_extraction Rubygem by Alex Rabarts.

All keywords provided by the Zemanta Tagging Workflow

Armed with that gem and the Duane’s Ruby framework I started cobbling something together which works rather nicely. It will either take a complete folder of individual article files for you to pick from or, alternatively, take content you have previously put onto the clipboard and sends that to Zemanta for tagging.

The result of this operation is then put back onto the clipboard for you to paste into whatever editor you want.

It even has a built-in setup keyword zemapi to make providing the workflow with the necessary Zemanta API key a breeze.

The list of articles to select from when working directly with a folder

Apart from giving the Workflow an API key to use, you should provide the zemfile keyword a Search Scope to just the folder containing your articles. To do that, open up the Workflow in Alfred Preferences, double-click the zemfile keyword and select your desired folder in the “Search Scope” tab in the slide down panel. I keep my articles in ~/Dropbox/Articles/, for example.

As Brett mentions in his article, the terms returned by Zemanta are sometimes a little verbose and need a little manual tidy up. They’re also not replacing my manual tags any time soon. But one thing I will start using them for is meta tags.

Download

(The source code for the workflow is also available on GitHub.)

Happy Easter!

  1. Another handy list of workflows, which happen to be often buried in the bowels of the Alfred forums, comes from macminicolo, who blogged about Ten Alfred workflows for IT recently.

Automating Remote Downloads with Drafts and Hazel

One of my businesses uses Highrise as its CRM tool to document all of its sales activities.

As Highrise is a hosted application, I want to make sure that we have access to regular backups of our data. Luckily, Highrise offers a handy export feature for this purpose. Unfortunately, those exports do take a sweet while to generate.

I generate weekly backups using this method and usually trigger their creation when I leave the office on Fridays. When the export is done, Highrise will email me with a URL to download the final export. However, I'm usually on my commute back home at that point and I'm not willing to spend my mobile data allowance on a backup file that I have no use for on a mobile device anyway.

To trigger the download on my iMac back in the office remotely, I came up with a little workflow involving Hazel on the Mac and Drafts on my iPhone (or iPad for that matter) that I'd like to share with you today.

The Ingredients

The Concept

The basic setup consists of a Dropbox folder that is watched by Hazel. This folder is then populated with text files generated on an iOS device with Drafts (usually from the clipboard), containing the URLs to download. When Hazel finds a qualifying file, an Automator workflow is kicked off to start the download into a pre-defined folder and then it removes the text file that triggered the download.

Hazel can then be setup to further process the triggered downloads as those usually follow a pretty distinct filename pattern. In this specific case, I'm sorting those backup files into their own folder with a revised filename to include the date of the backup. These follow-up rules are applied to the main Downloads folder, so they're universally applicable whether you trigger the downloads from your Mac or, in this case, remotely.

The iOS Part

As I mentioned before, the URL I want to start downloading on my Mac is usually stored on the clipboard.

My first attempt at this workflow tried to solve the initial trigger through a bookmarklet on iOS. This, however, would require me to actually visit the download URL on my iPhone, starting the download itself in most cases. Since this is hardly desirable, I abandoned this tactic.

Instead, I will visit whatever page (or email) containing the download link and copy that link to the system clipboard using a tap-and-hold gesture. This will also work nicely in third-party browsers on iOS, some of which have very poor support for bookmarklets. (Chrome, I'm looking in your direction.)

Once the URL is on the clipboard, there are a variety of ways to get that URL into a file in Dropbox. I use Drafts, since it supports a nice way of timestamping those individual files. This way, the workflows don't trip each other up by, for example, removing entries from a file while you're already appending the next URL to download to the same file.

Here's the Dropbox Action I setup in Drafts.

Dropbox Action Setup in Drafts

In essence, it uses the contents of the current buffer ([[draft]]) to create a new file in Dropbox under the /Apps/Drafts/ path and names that file with the prefix download_urls (which we will pick up in Hazel later) and a timestamp suffix. An example filename would be download_urls-2013-03-10-16-46-10.txt.

Now, you could just open Drafts, paste in the clipboard contents, and then trigger the appropriate Dropbox action by manually selecting it from the Actions menu. But with the recent surge of support for and clever tricks involving URL schemes, we can do better than that.

The recent 1.1 update of Launch Center Pro brings with it support for passing on the clipboard contents to an action of your choosing. This way, with the press of a single button in Launch Center Pro we can trigger the remainder of the workflow in Drafts without any manual intervention.

Here's my trigger in Launch Center Pro:

drafts://x-callback-url/create?text=[clipboard]&action=Download%20Desktop
                

Using the drafts:// URL scheme, we tell Drafts to create a new note, the contents of which are provided by Launch Center Pro with the new [clipboard] placeholder, containing the contents of the, you guessed it, system clipboard. Lastly, we tell Drafts to trigger the action "Download Desktop", which we created before. (The name of the action needs to be URL-encoded.)

The Launch Center Pro Action

With this setup, after placing the URL on the clipboard, I can invoke Launch Center Pro from my iPhone's dock, tap the "Download to Desktop" icon, and the rest is handled behind the scenes.

Since that "rest" also involves the actual download, let's continue on the Mac.

The Mac Part

The first thing we need is a folder to hold the trigger files. As I mentioned in the section creating the Drafts Dropbox action, I picked /Apps/Drafts/ within my Dropbox folder in this example, as that is the default location where Drafts puts text files created in Dropbox. This folder is then handed to Hazel for surveillance.

In Hazel itself, the following rule takes care of feeding the right files into the Automator workflow that does all the heavy lifting.

Hazel Rule to feed the download URLs to Automator

When the Automator action is done performing its magic, we tell Hazel to remove the file it just finished processing, in order to not clutter up that folder over time.

The Automator workflow itself takes the textfile1 and uses OS X's built-in data detectors to make sure what we're feeding to the next action are actual URLs. This is just a safety measure and shouldn't be strictly necessary given that we're the only ones feeding this workflow, but you never know2.

The Automator Workflow to start the actual download

To handle the actual download, we use Automator's built-in "Download URLs" action. You need to be aware that this uses Safari behind the scenes. So if the URL you're trying to send it for download is only accessible to logged-in users, be sure to login using Safari beforehand.

I'm sending those downloads to the regular OS X "Downloads" folder, which, in turn, is guarded by Hazel. Once those Highrise backups land there, another Hazel rule is triggered to take those backups and sort them into their own folder after renaming the zip-file to include the current date.

An Alternative for iPad

Instead of Launch Center Pro, you can also trigger the Drafts Action through Pythonista, which comes in handy if you're using this from an iPad for example. (There is no Launch Center Pro for iPad, as of yet.) Since Pythonista scripts can be saved as icons to your homescreen, you could even save a tap by storing the icon directly on the homescreen.

Here's the Pythonista script to accomplish this:

                import webbrowser
                import urllib
                import clipboard
                
                base_url = 'drafts://x-callback-url/create?'
                url_text = clipboard.get()
                params = {
                          'text': url_text,
                          'action': 'Download_Desktop',
                         }
                
                webbrowser.open(base_url + urllib.urlencode(params))
                

Conclusion

So, there you have it. Downloads on your Mac, triggered remotely from your iOS device using Launch Center Pro (or Pythonista), Drafts, Hazel, and Automator.

Here's a video demonstrating the components working together.

Hit me up on Twitter as @patricklenz if you have additional tricks and automations up your sleeve that make the combination of Mac and iOS even more joyful.

  1. Don't get me started on the fact that Automator needs this Applescript crook to actually read a file that it clearly should know how to handle on its own.

  2. Maybe you're sleepwalking one day, manage to unlock your phone, and then start feeding cat pictures to this Automator action.

Protect Your Back

For a change, this post isn't about my beloved standing desk. It's about the DODOcase BOOKback, which I ordered for my iPhone 5 and iPad Mini late last year and have been using ever since.

TL;DR Summary: If you're typically a "no case" user but are occasionally worried about the back of your devices getting messed up, the BOOKback is definitely for you.

My iPhone 5 and iPad Mini, each with a BOOKback attached

The BOOKback is a very simple product. It consists of a thin layer of Moroccan leather that is applied to the back of your iDevice using an adhesive. Supposedly, it can even be peeled off and re-applied, which I, admittedly, haven't tested yet.

What's great about the BOOKback is that it really is just that very simple, low-profile back protection and not a full case. Thus, both iPhone and iPad remain fully compatible with the plethora of available accessories such as car cradles and the Elevation Dock, two things I put my iPhone in and out several times a day.

Of course, it also retains full compatibility with sleeves and the official Apple Smart Covers (and their many immitations), so that you can have a little protection for the front pane of glass as well.

It's an incredibly thin layer of Moroccan leather

Apart from scratch-proofing the back of your iDevice, it also removes the built-in slippery-factor that is inherent to almost all devices Apple ships these days. It feels great in your hand and you no longer need to hesitate when you put in on flat and slippery surfaces all around you, like tabletops, car roofs1, or Steve Ballmer's head.

One thing that I found it doesn't work too well with, though, is The Glif, which put a noticeable dent into my iPhone's back cover when I used the two together. But apart from that, I haven't found a single accessory that wasn't compatible with the BOOKback. It even still fits the confusingly similar-named BookBook with a little bit of persuasion.

The iPhone 5 camera hole

After using the BOOKback on two of my devices for close to 8 weeks I can attest that it ages very well. In fact, it may even get prettier the more it's used, as your own usage brings out a very own kind of personality. Yes, using my iPhone 5 with The Glif left the aforementioned marks in the leather, but it could be worse. And like a nice leather jacket or belt, things like these will tell a story over time.

I didn't have a problem with loose fabric or partially imperfect adhesive on any of my devices. The BOOKback sticks to the device just like on the first day. (And as the photographs in this article will unmistakenly document, I don't treat my devices like raw eggs. They're tools and they're being used day in and out.)

The embossed logo, also available in red

In summary, I can highly recommend anyone looking for a bit of minimalist protection for an iPhone or iPad to take a shot at the BOOKback. It's available in the DODOcase Online Store for $9.95 for iPhone, $19.95 for iPad mini, and $24.95 for iPad.

  1. Please don't leave it there.

Search Your Blog with SearchPath

Manton Reese’s newest venture is SearchPath, a hosted blog search engine.

Now, most blogging software, like the elephant in the room, already comes with a built-in search engine or at least has one readily available as a plugin.

If you, however, follow a recent trend of going with the a static site generator1, your only options would be a custom Google (or Duckduckgo) search or writing enough nerdy material to be invited to participate in NerdQuery, since the blog itself doesn't have any dynamic component to implement a search engine on your own.

Enter SearchPath.

SearchPath integrates into your site with a simple JavaScript snippet that you'll receive after a no-fuss signup process that just asks for your site URL and an email address. That's right, SearchPath doesn't even have passwords. If you need to login again, you provide your email address and a sign-in link is sent to you by email, signing you in with a long-living cookie.

After you integrate the snippet into your site's HTML code, SearchPath starts crawling your site. It does so the classic way of simply downloading the homepage of the site and then following every link it can find on that page, recursively. You can exclude certain URLs, too. Or just exclude whole folder structures by using robots.txt files. No need to mess with the generation of site maps at all.

One thing to watch out for is the validation of your site if you're trying to re-use an existing search input field, in which case you need to modify the JavaScript embed snippet. The verification process seems to expect the embed code unchanged and will not verify the site properly if it doesn't match character by character. As a workaround, simply verify your site ownership prior to mucking with the embed code.

The SearchPath dashboard provides simple stats such as the number of pages it has crawled, the date of the last crawl attempt, and popular search keywords users have searched for.

SearchPath comes with a trial limited to 2 search results and is $8 per month for a full account. Yearly subscriptions are 20% off.

Give it a try using the search form in the right sidebar on this site.

  1. And there are a lot of Internet-famous supporters like Brett Terpstra, who recently converted from WordPress to a custom install of Jekyll.

Cleartones Organic

While I use my iPhone with the ringer switch set to 'silent' 90% of the time, occasionally it helps to get audible alarms for incoming emails, calls, etc. The ringtones the iPhone ships with are decent, but haven't changed much since the original iPhone shipped in 2007.

Instead of being the umpteenth dude with the "Old Phone" ringtone at the dinner table, how about some minimalist, yet unobtrusive ringtones and notification tones, recorded using acoustic instruments? Cleartones Organic consists of 50 ringtones and 50 notification tones for $17.

(Via Tools and Toys.)