Sam Rayner

Hi, I’m Sam. I design and build apps for iOS and the web. I live in Sheffield, UK and play Ultimate far too much. You can reach me via email or on Twitter.

Alfred Lyrics Search Workflow

Ever had the lyrics of a song stuck in your head but can’t for the life of you remember the artist or title? I get it all the time so wrote this Alfred workflow to search my iTunes library and start playing the first match it finds.

Download Lyrics Search

Get Lyrical

To get it working with your music collection you’ll need to make sure all of your tracks have lyrics downloaded for them. Don’t panic though, a great little Mac app called Get Lyrical can automate the process, tagging songs you select or tagging in the background as you play them.

Once your library is tagged with lyrics, install the workflow and type sing followed by the lyrics.

Under The Hood

For those interested in the technical side, the Workflow is just an Applescript:

on normalize(theString)
  --trim everything but letters and numbers
  return do shell script "echo " & quoted form of theString & " | tr '\r' ' ' | sed 's/[^[:space:][:alnum:]]//g'"
end normalize

tell application "iTunes"
  set theQuery to my normalize("{query}")
  --playlist 1 should be your whole music library
  set theTracks to tracks of library playlist 1
  set match to ""
  
  repeat with i from 1 to number of items in theTracks
    set theTrack to item i of theTracks
    set theLyrics to my normalize(lyrics of theTrack)
    if theQuery is in theLyrics then
      set match to (artist of theTrack & " - " & name of theTrack)
      exit repeat
    end if
  end repeat
  
  if match is not "" then
    play theTrack
    get match
  else
    get "No match found"
  end if
end tell

You’ll notice that it runs through your entire library in alphabetical order. Unfortunately, if the song you’re looking for is by ZZ Top the search is going to be a hell of a lot slower than if it were by ABBA.

Also, lyrical clichés like “oh baby” or “tell me why” are likely to produce a match earlier than you expect so try to search for longer or less common phrases.1

If anyone has suggestions for improvements please let me know. I like the simplicity of the script so don’t plan to produce a playlist of search results or anything like that but feel free to use the Applescript as a starting point for your own script!

  1. It’s actually pretty fun to guess at lyrics and see what songs they appear in. If a search for “hands in the air” or “in da club” return in less than 10 seconds your iTunes may be due a clear-out.


Sprintly Workflow for Alfred 2

Since the first Alfred 2 beta was released, I’ve been building a workflow for Sprintly, the agile task management web app we use at Terracoding. The basic features are done so here it is for any other Mega Supporters who use Sprintly.

Download Sprintly for Alfred

Using the sly command, you can switch products, list, add and manage items. Full documentation is on Github.

NOTE: The workflow requires a system Ruby ≥ 1.9. If you haven’t upgraded to Mavericks yet version 1.0.1 will work with RVM.

To install, run sly setup {email} {api_key}.

Screenshots

Feel free to make a pull request on Github or let me know what features you would like to see on Twitter: @samrayner.

Hopefully in the future there’ll be an update mechanism for workflows, but until then keep an eye on the repo for changes. I’ll keep the download link above up-to-date.


Using Ruby 1.9 with Alfred

I’ve been building a Sprint.ly Workflow for Alfred 2 (currently in beta) and wanted to use it as an opportunity to brush up on my TDD and Ruby-foo.

Alfred 2 let’s you run PHP, Python, Perl and Ruby scripts but they run from usr/bin/lib and Mountain Lion ships with (a pretty outdated) Ruby 1.8.7.

If you have a newer version of Ruby installed with RVM or rbenv, here’s how to bootstrap Alfred to use it instead. In your Workflow, set up a Ruby script action as normal and fill it with:

SCRIPT_FILE = "example"

def ruby_exec_path(manager)
  begin
    ruby_path = `~/.#{manager}/bin/#{manager} which ruby`
    if $?.exitstatus == 127
      raise Errno::ENOENT
    end
  rescue Errno::ENOENT
    ruby_path = ""
  end
  return ruby_path.strip
end

ruby_path = ruby_exec_path("rvm")
ruby_path = ruby_exec_path("rbenv") unless ruby_path.length
ruby_path = "ruby" unless ruby_path.length

parent_dir = File.expand_path(File.dirname(__FILE__))
puts `#{ruby_path} "#{SCRIPT_FILE}.rb" "{query}"`

This fetches your active Ruby and runs the script example.rb, passing the Alfred query as an argument.

Create example.rb in your Workflow directory and you can grab the query string inside it:

QUERY = ARGV[0]

Anything your file puts into STDOUT will be passed back to Alfred to use in your Workflow!

As well as letting you use The New Ruby Hotness, this has the added benefit of moving code out of Alfred and into files that are more easily tested and version controlled. The only down-side is that your Workflow will require users to be running RVM or rbenv if you share it.


Update (Aug 4): Good news! OS X Mavericks is set to ship with Ruby 2.0 by default so you shouldn’t need to use this hack for much longer.


Handy Scripts

I have a bunch of Applescripts and shell scripts that live in Alfred and make my computing life a little easier. Here’s a collection of the the ones I’ve written. Most of them are pretty niche but hopefully they’ll prove useful to somebody.

Toggle Invisible Files

If invisibile files are hidden, show them, and vice versa. (Note: will restart Finder).

Top Google URL

Grab the URL of the top result for a search (using the Google Search API) and copy it to the clipboard.

Open Tab in Chrome

Opens the frontmost Safari tab in Google Chrome.

Obfuscator

Takes a chunk of text and converts everything to HTML character entities. Useful for encoding email addresses for spam-free publication on the web. The result is copied to your clipboard.

App Installer

Move any .app files from ~/Downloads to /Applications, overwriting existing apps.

5by5 Show Notes

Open the links list for the 5by5 show that is currently playing in iTunes.

Post Archive

2016

2015

July

2014

February