Blog Home  Home Add to any service  
Beckshome.com: Thomas Beck's Blog - Wednesday, December 19, 2007
Musings about technology and things tangentially related
 
 Sunday, October 07, 2007

Another in the installment of Rails on Windows “gotchas”, there are some things to be wary of when working with the Simple_Captcha plugin in the Windows environment. In terms of basic background, the Simple_Captcha plugin facilitates the integration of CAPTCHA (Computer Automated Public Turing test to tell Computers and Humans Apart) image recognition tests, like the example below, into a Rails application. Facilitates is perhaps not a strong enough term. The plugin makes CAPTCHA integration dirt simple.


The Simple_Captcha plugin uses RMagick for generation of the CAPTCHA recognition images, allowing for various image styles and distortion levels. The CAPTCHA can be integrated via the controller (this one is dirt simple) or via the model (this one is just silly simple). You can find out more about these and various other integration options on the plugin’s page.  

If you’re doing Rails development on the Windows platform and are not feeling especially masochistic, the rmagick-win32 gem, which is bundled with a copy of the ImageMagick Windows installer, is really the only way to use RMagick. For a long while, the 1.13.0 rmagick-win32 gem was the standard. However, this gem is likely to cause you issues and you should really upgrade your gem to the 1.14.1 gem or greater. These gems are fixed to work with RubyGems 0.9.4, which is the most recent version of this gem as of this blog post. If you don’t perform this update, you’re likely to see ImageMagick issues bubble up at runtime.

On Windows, these runtime errors frequently manifest themselves as ‘cur_image’ issues. Several of these issues have been reported on the plugin’s page. My post on 10/6 covered fixing these issues by upgrading your RMagick gem. Please don’t downgrade other gems, as suggested in some other posts; this will only make your life more miserable in the future.

All-in-all, the RMagick Windows gem is an excellent way to make powerful image processing capabilities available to all, including those unfortunate enough to be stuck on a Rails on Windows development platform. The plugins built on top of RMagick such as Simple_Captcha and Attachment_Fu are incredibly powerful and remain very simple by leveraging RMagick’s capabilities. Just beware if you’re developing on Windows, a little bit of tweaking and debugging may be necessary to get these plugins to work as advertised.

Sunday, October 07, 2007 3:29:01 PM (Eastern Standard Time, UTC-05:00)  #    Comments    |   |  Trackback
 Monday, October 01, 2007

I’ve posted about how impressed I was with NetBeans as a Java IDE and the incredible progress this product has made in the last couple of years. I knew for a while that Ruby on Rails and JRuby support was coming for the next major Netbeans release (v 6.0), but I hesitated moving from RadRails to NetBeans until the feature set had stabilized. Last week, the Netbeans 6.0 beta was released and, with RadRails stagnating somewhat under the Aptana brand, I caved in and made the switch.

 

George Cook does an excellent Job of running through the new features with lots of nice pretty screenshots. If you’re looking at moving to Netbeans as a Rails IDE, it’s the first place I suggest that you go. Some of my favorite features of Netbeans (with screens shamelessly stolen from George’s site) include code completion

 

 

 

…and debugging

 

 

There are several features from RadRails that I miss and that I hope the NetBeans team will consider integrating over time. These include the ability to import a project directly from Subversion and the test window that allows you to visually check the status of your tests and select particular tests to run. Those features aside, I don’t plan on going back to RadRails. NetBeans has made so much progress so quickly, I can only imagine that it’s going to put significant distance between itself and RadRails in the near future.

 

You can get Netbeans 6.0 here, available as a skinnied-down Ruby only version if you want. Finally, since Netbeans uses JRuby as the default interpreter and expects the Derby Java database, this article on wiring NetBeans for InstantRails should get you up and moving with the standard Ruby interpreter and MySQL database configuration, regardless of whether you’re using InstantRails or not.

 

Final note if you're brand new to Ruby on Rails and reading this post. Skip right to Rails 2.0, which is now in preview mode, to avoid dealing with Rails 1.2.x deprecations and to benefit from some of the new defaults. Enjoy!

Monday, October 01, 2007 5:21:36 AM (Eastern Standard Time, UTC-05:00)  #    Comments    |  |   |  Trackback
 Saturday, September 29, 2007

During a discussion the other day, I found myself repeatedly asking the question of how many organizations could make the leap from an organization dabbling in services (SOA believers) to an organization living SOA and benefiting from services (SOA achievers). I kept referring to the SOA chasm, this nearly insurmountable gap that needs to be crossed to move from an SOA believer to an SOA achiever. The image below is my visualization of this gap.

 

 

Why is it so hard to make it from one side to the other? It’s because this leap requires an organization to rethink everything; fundamentally changing the way they fund, govern, build, and host their applications. If you’re wondering what an SOA achiever looks like, check out this article on the Amazon.com architecture. Note the stat near the top of the page – between 100 and 150 services are accessed to build a page. These guys have made the leap.

 

I’ve heard a lot of contentions that the move to an SOA represents an evolution, not a revolution. I think this is true for only so long. An organization can incrementally improve their capabilities as an SOA believer but once they reach the end of the SOA believer cliff, it’s an all-or-nothing proposition. When an organization has completed the construction of their utility services and the time comes to tackle the core business entities, functions, and processes, it’s the SOA moment of truth. That quote from the Matrix before Neo tries to jump the chasm between two buildings rings in my head, “You have to let it all go, Neo; fear, doubt, disbelief. Free your mind!"

Saturday, September 29, 2007 6:23:57 AM (Eastern Standard Time, UTC-05:00)  #    Comments    |  Trackback
 Friday, July 27, 2007

Tad Anderson posted about the release of an SOA-related e-book from Microsoft concerning Service Oriented Architecture (SOA). This is one area in which Microsoft has remained notably quiet compared with competing enterprise software vendors such as IBM and Sun. As Tad points out in his post, Microsoft has made some forays into SOA publications and they have been pretty readable.

Their most recent publication, SOA in the Real World (mirrored here), is one of the better pieces of SOA writing that I’ve encountered, vendor-specific or otherwise. It uses Microsoft technologies to illustrate certain principles but it manages to maintain a largely implementation-agnostic viewpoint. The e-book has multiple authors but it was edited together in a very seamless way, which is not always the easiest thing to pull off.

The e-book appears to have been pulled together by Microsoft’s Architectural Resource Center (ARC). No authors are listed specifically and the ARC branding is new, somewhat resembling the branding used for Microsoft’s Architecture Journal. The publication includes a pretty sound enterprise SOA approach, detailed explanations of how some of the major pieces of a SOA come together and a description of how Microsoft’s technologies fit in the mix. Whether one architect’s opinion or the Microsoft party line, there are some insightful and succinct explanations provided, such as the differences between Workflow Foundation and BizTalk when it comes to implementing workflow.

This book is a great read for anyone looking for a solid introduction to SOA and could well be the definitive read for anyone dealing with SOA and Microsoft technologies.

Friday, July 27, 2007 3:34:19 PM (Eastern Standard Time, UTC-05:00)  #    Comments    |  |   |  Trackback
 Saturday, July 21, 2007
I was performing functional tests on my models that employed Attachment_Fu this morning and thought it would be worthwhile to share the code since it was a bit of a hassle pulling it together. Kudos to Mike Subelsky for his introduction to functional testing Attachment_Fu. It got me going in the right direction. What proved difficult once again was the multi-model controller. Once I got over that hump, I was on my way. As you can see from all the detail in the HTTP POST below, that was not an entirely easy task.

class ProductsControllerTest < Test::Unit::TestCase
...
def test_create_with_user
    num_products = Product.count
    imgdata = fixture_file_upload('/files/image.png', 'image/png')
    audiodata = fixture_file_upload('/files/sound.mp3', 'audio/mpeg')
    post :create, {:product => {
            :name => "Widget",
            :description => "A small tool-like item",
            :weight => "3",
            :price => "19.99",
            :language_id => "1"
                   },
            :image => {:uploaded_data => imgdata},
            :audio => {:uploaded_data => audiodata} ,
            :html => { :multipart => true }
          },
          {:user_id => users(:valid_active_user).id}
    assert_response :redirect
    assert_redirected_to :action => 'show'
    assert_equal num_products + 1, Product.count
  end
  ...
  end

Saturday, July 21, 2007 6:41:26 AM (Eastern Standard Time, UTC-05:00)  #    Comments    |  Trackback
 Thursday, July 19, 2007

Continuing my Rails on Windows thread, I’m going to spend a bit of time on something that’s brought me both some substantial gains and some minor woes lately, running the Attachment_Fu plugin on Windows. I’ll start off with some general Attachment_Fu information and then get into some of the quirks, which are, as expected, mostly specific to the Windows environment.

First, for those not in the know, Attachment_Fu is a Rails plugin that allows you to store binary data (e.g. images, video, documents) and associate it with other models in your Rails application. Metadata (content type, size, height, width) about the attachment is stored in a separate model. Attachment_Fu’s sweet spot is handling images. It can handle automatic image conversion and thumbnailing using a number of popular image processors such as ImageScience, RMagick, or minmagick. Although not provided, you can imagine that Attachment_Fu might be extended to handle other types of binary processing utilities such as PDF converters or audio/video transcoding software. The other very cool thing about Attachment_Fu is that it provides support for pluggable persistence mechanisms. Out of the box, it allows for storage on the file system, as binary information in a database or on Amazon’s S3 storage service.

There is an abundance of information already written about Attachment_Fu so to avoid re-inventing the wheel, I’ll provide what I found to be the best sources of information to start.

  • Mike Clark’s tutorial is the gold standard introduction to using Attachment_Fu. The code is simplistic but rock solid. It covers using both the file system and S3 for storage and will get you up and running on Attachment_Fu in no time.
  • This post on the Attachment_Fu message board provides a solution to associating the attachment model with another model (i.e. making it an attachment to something). The post provides both the controller and the view code for uploading the initial attachment and rendering it. Handling the attachment relationship in your MVC is going to be a fairly common requirement and most Attachment_Fu users will benefit from this post.

For my part, I’m going to provide some controller source code for updating the attachment when you have a relationship with another model (an extension of the second item above) since this is one area that wasn’t covered well anywhere else and might save you some time in your travels. In the code below, my main model is the product and the image is the model where a photo and thumbnail are stored using Attachment_Fu.

class ProductController < ApplicationController

  def update
    @product = Product.find(params[:id])
    # Load up product categories for the view
    @all_categories = Category.find(:all, :order=>"name_en")
    if @product.update_attributes(params[:product])
      if !params[:image][:uploaded_data].blank?
        # My product only has one image / thumbnail, I'll destroy 'each'
        # wait 3 # See quirk no.1 below

        @product.images.each {|img| img.destroy}
        @image = @product.images ||= Image.new
        @image = @product.images.build(params[:image])
        @image.save
      end
      flash[:notice] = 'Product was successfully updated.'
      redirect_to :action => 'show', :id => @product
    else
      render :action => 'edit'
    end
  end
 
end


The links above, in combination with my snippet, should get you through creating an attachment and handling CRUD for an attachment and its parent model from a single view. Now comes the Windows quirkiness. Not knowing to expect these Attachment_Fu quirks and then having to root out the cause of the behavior took up a lot of time. It turns out that most of I found that most of the quirks are documented in some way, shape, or form. I’ve pulled together a list of the quirks as well as some best practice workarounds.

  • When running Attachment_Fu on Windows, the most commonly accounted problem is the “Size Is Not Included In List” validation error. This post goes into some details and speculation around the cause of the issue. It appears that no amount of fixing in the Ruby code is going to help here since it appears to be a Windows file system issue. The workaround is really simple, just add a wait x statement before your attachment processing and things will be golden. The x (which denotes seconds) time will vary based upon the size of the attachments you are processing. Bigger attachments require more of a wait. Also, be sure to comment this code out in production since this is a Windows only issue.
7/19/2007 Update - Rick suggested using RUBY_PLATFORM to determine if the wait should be invoked. I tested this and it worked as suggested
  • When you invoke the destroy method on your attachment using Attachment_Fu on Windows, your models reference to the attachment will be deleted but the physical attachments themselves will not be deleted if you have persisted them to the file system. If you look at the Attachment_Fu source code or your log files, you’ll see that Attachment_Fu assumes that you are using a UNIX-based system and executes UNIX commands like rm to remove these files. These commands will obviously not work in a Windows environment, leaving you with a bunch of zombie files. This should not be a problem if you use a database or S3 persistence mechanism since these mechanisms are independent of the operating system.
7/19/2007 Update - Rick corrected me. He is indeed calling the OS safe FileUtils.rm in the file system backend. It still isn't working though - at least on my machine.
  • My last Windows specific quirk is actually an Internet Explorer issue. If your attachments are images, you may have problems with uploading JPEG’s using the default Attachment_Fu plugin. From what I’ve been able to determine, if you upload a JPEG from IE with a file extension of .JPEG, IE will set the MIME type to image/pjpeg for a progressive JPEG. However, if the image extension is simply .jpg, IE will set the MIME type to image/jpg. This MIME type, however, is not included in the default list of content types accepted by Attachment_Fu. My suggestion is to add this type to the list in the source code until Rick can get around to modifying the source.
7/19/2007 Update - The MIME type was added to source. For reference, Rick suggested that this could have been done without changing the source simply by adding
    Technoweenie::AttachmentFu.content_types << 'image/jpg

The last quirk for my post should be meaningful to all of those using Capistrano, the Rails migration utility. Capistrano manages versions of the application for rollforward / rollback by creating symlinks to previous versions of an application and deploying the most recent version of your entire application tree from your version control system (e.g. Subversion). However, since it’s very unlikely that you are storing all of the attachments for your application under version control, the attachments will be unlinked and no longer available when you migrate a new version of your application to production. To get around this issue, the solution proposed here creates a separate physical directory for the attachments outside of your application’s directory and then updates a symlink from your application’s attachment directory to the separate physical directory every time you migrate.

Thursday, July 19, 2007 1:22:16 PM (Eastern Standard Time, UTC-05:00)  #    Comments    |  Trackback
 Tuesday, July 17, 2007

I’ve had some really good experiences with some of the iTunes Original collections, which include a mix of pre-existing songs, original versions of hits and artist narrations. I’ve especially enjoyed the iTunes Originals with Rob Thomas. This weekend, I picked up my first iTunes Exclusive Live Sessions mix. The Live Sessions series at 5 or 6 songs per collection offers only about half the music of your average Original collection but, as the title indicates, it’s all live music.

Since I’ve downloaded the Five for Fighting Live Session from iTunes, I have not been able to get the music off of my mind. I’ve been listening to Five for Fighting since their first CD, which accompanied my wife and I on a memorable trip down the US West Coast. Even if you can’t associate the Five for Fighting name with a particular song, it’s fairly likely that you’ve heard their music since it gets a good amount of radio play and has found favor with a number of TV commercial producers.

Granted, you are not going to get any original music here but what you do get is Five for Fighting’s best material done live in a pure acoustic (piano and guitar) format. The album is tight and the recording quality is superb. Artist narration, storytelling, and interludes are edited out except for one story about the writing of the song Two Lights which really accentuates that piece. At about $5 for the collection, you really can’t go wrong with this one whether you are an old fan or someone simply looking to pick up some great music to listen to.

Tuesday, July 17, 2007 7:53:57 AM (Eastern Standard Time, UTC-05:00)  #    Comments    |  Trackback
 Sunday, July 08, 2007

I’ve been putting a good deal of time recently into converting GeoGlue from .NET to Rails. One of the things that I’m looking to get into the alpha release is the dynamic creation of podcasts. This is really nothing special since a podcast is little more than a special case of an RSS feed that points at external media files (i.e. audio or video).

I plan on covering the audio/video entry in an upcoming post about the nuances of the Attachment_Fu plugin on Windows. In this post, I’m going to just lay out the code for the podcast creation, since this is nothing more that a simple rxml file. I’ve sprinkled in comments liberally but most of the code should be fairly self explanatory to those familiar with Ruby and RSS feeds.

xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
xml.rss('version' => '2.0') do
  xml.channel do
    xml.title @podcast.name
    # Self-referencing link
    xml.link url_for(:only_path => false)
    # Important --> RFC-822 compliant datetime
    xml.pubDate(Time.now.strftime("%a, %d %b %Y %H:%M:%S %Z"))
    xml.language "en-us"
    xml.ttl "40"
    # User who caused the feed to be generated
    xml.generator User.find(:first, session[:user_id]).name
    xml.description @podcast.description
    # 'public_filename' is a method from the Attachment_Fu plugin
    xml.image do
        xml.url url_for(:controller => @podcast.images[0].public_filename, :only_path => false)
        xml.link url_for(:only_path => false)
        xml.title @podcast.name
        xml.width @podcast.images[0].width
        xml.height @podcast.images[0].height
    end
    @podcast.entries.each do |entry|
      xml.item do
        xml.title(entry.title)
        xml.link(url_for(:controller => entry.audios[0].public_filename, :only_path => false))
        # User who actually generated the media (i.e. audio)
        xml.author(entry.user.name)
        xml.category "Uncategorized"
        xml.guid(url_for(:controller => entry.audios[0].public_filename, :only_path => false))
        xml.description(entry.description)
        # Simplification, you should pull from updated_at/updated_on
        xml.pubDate(Time.now.strftime("%a, %d %b %Y %H:%M:%S %Z"))
        # The enclosure is very important!!
        # If you use Attachment_Fu, everything you need is included in the model

        xml.enclosure(:type=>entry.audios[0].content_type,
                :length=>entry.audios[0].size.to_s,
                :url=>url_for(:controller => entry.audios[0].public_filename, :only_path => false)
          )
      end
    end
  end
end


A couple of lessons learned from my experience. Firstly, Apple provides some good resources on generating podcasts. This is especially important since the iTunes crowd is a large and important contingent of the feed consuming world. There are iTunes-specific tags (and a schema) available. These tags are not mandatory (I didn’t use them here) but they will help you produce a richer feed for consumption within iTunes. Secondly, since the RXML file is just another view, make sure to turn off any default layouts that you might have applied to your other views. I’ve included a snippet below to demonstrate how to do this. Check your version of Rails, mileage may vary with exempt_from_layout based upon your release.

class ApplicationController < ActionController::Base

  # Pick a unique cookie name to distinguish our session data from others'
  session :session_key => '_trunk_session_id'
  layout 'default'
  exempt_from_layout :rxml
  ...

end

My final caveat is not to apply forms-based authentication to your podcast (RXML view). Either make the view public or, if you wish to protect it, do so using HTTP Basic authentication instead. If you’re using both forms-based and HTTP Basic authentication, you’ll probably need to sync the two by using a single LDAP repository. That’s fodder for a completely different post.

Sunday, July 08, 2007 6:46:34 AM (Eastern Standard Time, UTC-05:00)  #    Comments    |  |   |  Trackback
Copyright © 2008 Thomas Beck. Some rights reserved.

Creative Commons License