Autotest and Me

Today, Mark and I were talking about some of the open source projects we've been working on. During our conversation, he mentioned how David's recent post about using Autotest on OSX was the catalyst for him to start using it on his projects. I decided that I would do the same, so I went about using it on a Ruby gem that I'm developing.

From the original post, using it on Rails is pretty straightforward, but getting it to work on a vanilla Ruby project requires a bit of tweaking. There's some outdated information out there, but I was able to find a solution that worked for me. My resulting .autotest file:

require 'autotest/growl'
require 'autotest/fsevent'

Autotest.add_hook :initialize do |at|
  at.clear_mappings

  at.add_mapping %r%/^lib/(.*).rb$% do |_, m|
    possible = File.basename(m[1])
    files_matching %r%^test/.*(#{possible}_test|test_#{possible}).rb$%
  end

  at.add_mapping(%r%^test/.*.rb$%) {|filename, _| filename }
end

With that patch in place, I get the results I want.

Access The Etsy API in Ruby

Long ago, my wife found a love for Etsy. When I recently discovered their public API, I figured that it was meant to be that I begin working on a clean implementation of the Etsy API in Ruby. So I did.

I'm releasing the first version to the public tonight that includes support for retrieving users, their shops, and associated listings.

Installation

A simple gem installation is all you need:

sudo gem install etsy

If you prefer to bleed:

sudo gem install reagent-etsy --source=http://gems.github.com

Usage

Once installed, set up your API key and you're ready to go:

require 'rubygems'
require 'etsy'

Etsy.api_key = 'snipsnap'

At the time of this post, all API calls are read-only so that's all you need to do. Let's get started by finding a user's shop:

user = Etsy.user('littletjane') # => #<Etsy::User:0x1057624 ... >
user.seller?                    # => true
user.shop.name                  # => "littletjane"

A shop can have multiple listings:

user.shop.listings  # => [#<Etsy::Listing:0x1001788 ... >, ... ]

listing = user.shop.listings.first

listing.title       # => "hanging with the bad boys matchbox"
listing.description # => "standard size matchbox, approx. 1.5 x 2 ... "

Each listing, in turn, can have one or more images:

image = listing.images.first

image.small_square # => "http://ny-image2.etsy.com/il_25x25.67765346.jpg"
image.large        # => "http://ny-image2.etsy.com/il_430xN.67765346.jpg"

For more information and usage examples, check out the documentation on Rubyforge. If you have feature requests or comments, open an issue on Github or send me an email.

SVN Cleansweep

Due to a very specific setup we have here at the office, I sometimes have to fix people's SVN working copies directly on the server. Sometimes I can run svn cleanup from the top-level directory, sometimes I can't.

With Kevin's help, I came up with this script to start at the deepest directories and clean all the way to the current directory:

Grab Flickr Tags and Comments With Fleakr

I just pushed out version 0.4.3 of the Fleakr gem that provides support for retrieving tags and comments for users, photos, and photosets. These are non-authenticated methods, so all you need is your API key:

Fleakr.api_key = 'your_api_key'

Once that's set, you can retrieve tags for users and photos:

user = Fleakr.user('teamviget')
user.tags.first.value
user.sets.first.photos.first.tags.first.value

Given a single tag, you can also retrieve a list of related tags:

user.tags.first.related.first

Tags associated with a photo have more information associated to them - see the documentation for what's available. Comments have no such limitation and are available for both sets and individual photos:

user = Fleakr.user('the decapitator')
user.sets.first.comments
user.photos.first.comments

Give it a try for yourself - check out the docs or send me an email if you get stuck. Enjoy

Am I Ruby 1.9?

Kevin and I were chatting about how to tell if your locally installed gems were compatible with Ruby 1.9. He was looking for a tool that would scan the list and figure out which ones worked. I pointed him to Is It Ruby 1.9?, he found the API and whipped up a gem that would tell you which of your gems would likely work (or not work) with the latest version of Ruby. Check it out:

$ sudo gem install n3bulous-amiruby19 --source=http://gems.github.com

Then let it loose on your system:

$ amiruby19

Oh, and it was built with simple-gem (shameless plug).

Hacking With GitJour

I finally figured out how to use gitjour effectively during "hack night" pairing sessions. The benefit of gitjour over git-daemon is discovery over Bonjour - from there on out, simple git commands are all you need. The secret is a setting in your project's .git/config:

[daemon]
  receivepack = true

The full post is over on the Viget developer blog. Enjoy.

Taming Your Feeds

I while back I was inspired by a talk that Clinton gave about maximizing developer efficiency, so I set out to find ways of improving my own efficiency. As part of that process, I ended up changing how I go about reading all the RSS feeds that I track. It's a simple approach that's worked for me for some time, so I thought it worth sharing.

In the beginning, there was categorization

Once I started using a Macbook, I ditched my NetVibes account and picked up a free copy of NetNewsWire since I no longer needed to read my feeds online. As part of this switchover, I spent a bit of time categorizing all the feeds that I had at the time. I dropped feeds into well-named buckets like "Programming" or "Contacts", etc..

While this was a very organized way of keeping track of feeds, it wasn't quite efficient when it came time to actually read them.

Then came prioritization

After spending some time analyzing my habits, I discovered that there were certain blogs that I wanted to devote more attention to and others that I could just safely skim. The thought occurred to me: why not just have 2 groups, one for reading and one for (gasp!) skimming? So, that's what I did:

read / skim

As I add new feeds I can quickly drop them into the appropriate bucket, and I can also promote or demote feeds into either bucket depending on the value I derive from the content. Each day, I can focus on the important content in my "Read" list and then burn through the items I need to skim.

Fleakr In The Wild: Flittr

James just launched a Twitter / Flickr mashup that matches tweets with relevant photos from Flickr and he's using Fleakr to make it happen:

Flittr Announcement

Very cool. Check out the app and vote for your favorite combos:

Flittr

Upload Images to Flickr With The Fleakr Gem

I just released version 0.4.2 of the Fleakr gem which includes better support for options when uploading files. To get started, install the gem from RubyForge:

$ sudo gem install fleakr

Then make sure that you have an API key, shared secret, and auth token for the Flickr API. You can find instructions on how to do this in the Fleakr documentation (see the "Authenticated Calls" section). Once you have that data, you can configure the gem pretty quickly:

Fleakr.api_key       = 'ABC123'
Fleakr.shared_secret = 'sekrit'
Fleakr.auth_token    = 'DEADBEEF'

Now, let's start uploading.

Single Files

The simplest way to upload is using a single file:

photos = Fleakr.upload('/path/to/my/image.jpg')

Once uploaded, you now have a reference to the new file through the photos array. By default, this image has a title based on the filename and is only viewable to you. Let's change that:

photos = Fleakr.upload('image.jpg', :title => 'My Mug', 
                                    :viewable_by => :everyone)

This new image is available to anyone and has a customized title.

Multiple Files

In addition to specifying a path to a single file, the upload method accepts a fileglob. This way, you can push out a full directory of images in a single call:

photos = Fleakr.upload('/party/images/*.jpg', :title => 'Party Photo',
                                              :viewable_by => :everyone)

Once the upload finishes, photos will contain a collection of the newly-uploaded images.

Additional Options

We saw how to set titles and permissions, but here are the full options that are available:

  • :title - Duh.
  • :description - The description of the image / photo.
  • :tags - A list of tags. This should be supplied as a single string value or an array of strings.
  • :viewable_by - A list of who can view this photo. Can be either :everyone or a combination of :friends and :family (e.g. :viewable_by => [:friends, :family]).
  • :level - The "safety level" of the photo. Can be one of :safe, :moderate, or :restricted
  • :type - What does this image represent? Can be one of :photo, :screenshot, or :other
  • :hide? - Should we hide this image from public searches? Set to true or false.

This list is also available in the documentation for Photo#upload.

Replacing Files

Remember when I said that the upload method returned a list of newly-uploaded photos? You can use that to replace the image if you'd like:

photos = Fleakr.upload('/path/to/image.jpg', :viewable_by => :everyone)
photos.first.replace_with '/path/to/other_image.jpg'

The same applies to any photo in your photoset. For example:

user = Fleakr.user('my_username')
photo = user.photos.first.replace_with('~/embarrassing_photo.jpg')

Enjoy!

Additional Resources

Srsly?

Skratchin'