SmugMug

Posted by Jason Terk on Friday, December 25

Up until now to post photos from SmugMug I've crafted the link and image markup by hand, which is pretty tedious and prone to error. Today I ginned up an extension to Markdown (RDiscount, really) that allows automatic generation of the markup from the image title and URL. Here's how it works:

The first step is to create a new Hobix entry class (located in BLOG_ROOT/lib/local.rb):

module Hobix
  # Entries that use Markdown for formatting and automatically handle SmugMug
  # photos.
  class SmugMugEntry < Entry
    # Use SmugMug
    def self.text_processor
      SmugMug
    end

    # The YAML type for this entry class.
    def to_yaml_type
      "!goterkyourself.com,2009/SmugMugEntry"
    end

    # Register with the YAML engine.
    YAML::add_domain_type('goterkyourself.com,2009', 'SmugMugEntry') do |type, val|
      self.maker(val)
    end
  end
end

Now, any Hobix entry created with the type goterkyourself.com,2009/SmugMugEntry will use the SmugMug photo processor. All that remains now is to define the SmugMug class, which does the heavy lifting. This class is nested inside Hobix::SmugMugEntry:

# A SmugMug text processor that wraps Markdown with SmugMug specific
# capabilities.
#
# The syntax is:
#
#   $[Image Caption](Image URL)
#
#   i.e.: $[Bob Swimming](http://account.smugmug.com/Some/Category/1234567_abc12#123456789_AaBbC)
#
# Note that, for simplicity's sake, a SmugMug image blob must be on its
# own line
#
class SmugMug < RDiscount
  def to_html
    # Create a temporary string for the replacement so @text doesn't get
    # mangled.
    text = @text

    # Replace
    if text and not text.empty?
      text.gsub!(/^\s*\$\[(.*)\]\((.*)\)\s*$/) do |match|
        begin
          caption = $1
          image_url = $2
          image_id = image_url.split("#")[1]
          image_uri = URI.parse(image_url)

          raise "Missing image ID" if image_id.nil? or image_id.empty?

          "<a href=\"#{image_url}\">" +
            "<img src=\"http://#{image_uri.host}/photos/#{image_id}-640x640.jpg\" "+
                 "alt=\"#{caption}\" " +
                 "title=\"#{caption}\" " +
                 "class=\"photo\"/>" +
          "</a>"
        rescue
          # Just return the match on poorly formatted image blobs.
          $stderr.puts "Bad SmugMug blob: #{match}"
          match
        end
      end
    end

    m = RDiscount.new(text)
    m.to_html
  end
end

Once this is in place $[Amelie in her sheep hat!](http://gty.smugmug.com/Children/Amelie/7135981_oYtj9#705169136_SeMGC) becomes: Amelie in her sheep hat!

0 comments

Old Is New

Posted by Jason Terk on Friday, November 27

I switched the blog to a different back end and a slightly different style. I'm using Hobix (again, I used it back in... 2007?) and have made a bunch of modifications to support what I want to do. I have a fork of (a fork of) the original Hobix project at Github. I also have a bunch of local modifications (for things like Markdown support and permalink preservation - real exciting, I know). I'll probably publish these at some point. Here's to blogging more...

0 comments

Cap upgrade:revisions problem (and solution)

Posted by Jason Terk on Sunday, April 29

I just upgraded to version 1.99 of Capistrano, the remote deployment tool most commonly used for Rails projects. This is a prerelease of Capistrano 2.0 and installed easily with the following commands:

sudo gem install highline
sudo gem install -s http://gems.rubyonrails.com capistrano

Highline is a new (at least on my machine) dependency for Capistrano and needs to be installed separately because it isn't present in the gems.rubyonrails.org repository. Following the upgrade instructions I ran capify . in my local working copy to upgrade my recipe setup. I then ran cap -f upgrade upgrade:revisions to upgrade the remote revision tracking files. Sadly, that didn't work very well and I was greeted with a mostly unhelpful little error:

* executing `upgrade:revisions'
/usr/local/lib/ruby/gems/1.8/gems/capistrano-1.99.0/lib/capistrano/configuration/namespaces.rb:175:in `method_missing': undefined local variable or method `deploy_to' for #<Capistrano::Configuration::Namespaces::Namespace:0x69e8a8> (NameError)

It took a little looking about, but I figured out how to fix it: just run this command:

cap -f upgrade -f Capfile upgrade:revisions

All better.

0 comments

Capazon

Posted by Jason Terk on Tuesday, March 27

Now, this is interesting.

0 comments

Capistrano

Posted by Jason Terk on Tuesday, March 27

I had a chance to play around with Capistrano this weekend. It's a cool little tool and it works very well.

0 comments

ZenTest

Posted by Jason Terk on Friday, March 02

Discovered via. Dr. Nic: ZenTest.

ZenTest scans your target and unit-test code and writes your missing code based on simple naming rules, enabling XP at a much quicker pace. ZenTest only works with Ruby and Test::Unit.

autotest is a continous testing facility meant to be used during development. As soon as you save a file, autotest will run the corresponding dependent tests.

0 comments

rcov

Posted by Jason Terk on Wednesday, February 28

I really should start using Mauricio Fernandez' rcov code coverage tool for ruby.

0 comments

Test Driven Development

Posted by Jason Terk on Tuesday, February 06

Over the past, oh, year and a half or so, I've followed the rapid ascension of Ruby on Rails to the top of the web development heap. In the process I read a lot of blog entries, a lot of "Hello World!" introductory articles and a lot of best practice documents. A big part of the thinking behind Rails is Test Driven Development (TDD) - the idea that you should write automated tests before writing code to make sure that a) you know what the code is supposed to do before you write it and b) once the code is working there is a quick, easy way to make sure it keeps working as you further develop your application.

I never really had a chance to try TDD until recently. I started working on a project at work that isn't part of any of our old projects - I got to start something brand new. So I set out to use TDD from the start and I must say that it's going quite well. Writing the tests is forcing me to think carefully about the interfaces of my classes and to separate the project into more atomic parts than I might otherwise.

I'm using JUnit and have an Ant build file set up so that the default target depends on my unit tests. I can see very quickly if a change I make to the code makes things work or not. I don't have to mash together a driver program to exercise my work and then throw it away once it finally works. Sure, I write code to test, and that's analogous to a driver program, but the key is that the test will stick around after I'm finished with it for the time being and the work that I do to test my work for correctness won't need to be repeated by someone else when the program needs to evolve. The tests make nice example usages too.

I'm a convert.

0 comments

http-access2

Posted by Jason Terk on Saturday, January 27

I’m playing with http-access2, a Ruby library for programatically accessing web pages. I want to write a web app that sits between people and a privileged admin interface and this seems like it will do the trick. It’s a little slow but I think that’s the SSL talking.

0 comments