Archive for February, 2007

Well Rounded Images for Rails with acts_as_attachment

Tuesday, February 13th, 2007

In today’s world of Web 2.0, with rounded corners on everything, it seems a shame to have tacky square corner images uploaded by your customers. Luckily, those of us in the rails community have acts_as_attachment to assist with the upload. It’s really extensible, and allows you to have access to (most of) the ImageMagick functions underneath.

A recent personal project of mine required image upload, and creation of thumbnails, etc. acts_as_attachment fit the bill nicely, with the exception of square corners. I conjured up a snippet of code to trim the corners with RMagick, and voila! Round Corners on my images. Code follows. Note: due to MSIE braindamaged handling of PNG, this code creates GIF images (recently unencumbered by patents).


require 'RMagick'
include Magick
 
class SessionImage < ActiveRecord::Base
 
  belongs_to :user
 
  acts_as_attachment (:storage => :file_system,
                      :thumbnails => {'large' => '320',
                                      'medium' =>  '120',
                                      'thumb' => '90'},
                      :max_size => 5.megabytes,
                      :content_type => :image)
  before_thumbnail_saved do |record, thumb|
    img = Magick::Image::from_blob(thumb.attachment_data).first
    cols = img.columns
    rows = img.rows
    # Make the background green, so we know if something went wrong
    draw = Draw.new {self.background_color = 'green'}
    # Draw a round rectangle into the "Draw" object
    draw.roundrectangle(0, 0, cols-1, rows-1, 10, 10)
    # Draw the image froim before into the Draw Object
    draw.composite(0,0,0, 0,img,InCompositeOp)
    # Have to create a new image for some reason - GIF it for MSIE
    newimg = Magick::Image.new(cols,rows)
        {background_color = 'none', self.format = 'gif'}
    # This is the money line - puts the round corner image into our new image
    draw.draw(newimg)
    newimg['comment'] = 'Round Corners'
    # Replace the data that was sent to us.
    thumb.attachment_data = newimg
  end
 
  validates_as_attachment
 
 
# This is required, because we change whatever image type
# that was sent in to GIF
  def thumbnail_name_for(thumbnail = nil)
    return filename unless thumbnail
    basename, ext = filename.split '.'
    "#{basename}_#{thumbnail}.gif"
  end
 
end

Enjoy!

dhw

Review: Linux on the IBM z60t

Monday, February 12th, 2007

I’m a software developer, both professionally, and as a hobby. So, at any one time, I’ve got at least two laptops on my person, and at least one runs Linux. Those that don’t run Linux had the OS pre-installed by the client that insists that I use only their hardware. Whatever.

When I decided to buy a laptop for personal use, I had a few years of experience to pull from. I’ve run Linux on laptops from most of the major vendors:

  • Dell (Several models)
  • Toshiba
  • E-Machines
  • Gateway
  • IBM

All with limited success, especially with early versions of Linux. I started Linux on Slackware, then switched to Redhat, and more recently to Fedora. All of my laptop experiences have been with Redhat derivative distributions of Linux.

A good friend of mine is an IBM Territory Partner Manager, and he offered me his IBM discount. That, coupled with IBM’s stellar support of Linux, sealed the deal - I’m getting an IBM.

My criteria were:

  • Modestly powerful
  • Epic Battery Life
  • Somewhat svelte
  • Rugged

All of which were more than satisfied by the IBM lineup. After seeing a z60t, I decieded that would be the machine for me. The hardware specs are (shamelesly pulled from ThinkWiki.org):

My Configuration

(~$1300)

  • Intel Pentium M (Dothan) 1.73, 1.86 or 2.0GHz
  • Intel Graphics Media Accelerator 900 video controller
  • 14.0″ wide-screen TFT display with 1280×768 resolution
  • 1GB PC2-4200
  • 40GB 5400RPM SATA HDD
  • AD1981HD HD Audio 1.0 controller
  • Intel_82801FB_HDA Intel High Definition Audio Controller
  • UltraBay Slim with DVD±RW (dual layer)
  • Broadcom 10/100/1000 Ethernet
  • CDC slot (1) with a ThinkPad 56K Modem (MDC-1.5)
  • ThinkPad 11a/b/g Wireless LAN Mini Express Adapter
  • IBM Embedded Security Subsystem 2.0
  • Integrated Fingerprint Reader on select systems
  • UltraNav
  • IEEE1394 (Firewire) on select systems
  • CardBus slot (Type 2)
  • SD Card Slot

Weight and Dimensions

  • Weight: 2.2432 kg
  • Travel weight: 2.053 kg
  • Height: 26.6 mm
  • Width: 334 mm
  • Depth: 228 mm

So, once I finally took delivery of this laptop, I immediately dd‘d the Windows partition (just in case), and put Fedora Core 5 on it. Now, everything on the laptop did not work “out-of-the-box”, but, after a little configuration, a few downloads, and a kernel update or two, it’s all working! No ndiswrapper needed, sound works, USB, firewire, screen, monitor output, DVD, SD Card slot (whoopee!), fingerprint reader, hibernate / suspend, etc.

The best site on the web for IBM+Linux foo is ThinkWiki.org. Those guys have all the part numbers, links to all the drivers, postings from folks with similar hardware - everything for the new IBM owner. Many thanks to a well-run community site!

What I like about this machine:

Small
It’s a widescreen model, so the keyboard is plenty large, but the machine is thin and light. It’s exactly what I wanted as far as size and weight goes
Touchpad
Lots of IBM machines have shipped without a touchpad, but, I can’t function without it. Works like a charm.
Atheros Wireless
All the other laptops I’ve loaded Linux on have had Broadcom chipsets. The Atheros chipset based wireless was a big selling point for me. I’m using the madwifi-ng drivers, and I’m pretty sure I needed that to get WPA support working with NetworkManager. I’m using the Subversion build, and have been for a while. I’ve never had one bit of trouble out of the tip of the Subversion trunk
Battery
I got the extended battery, even though it added a little weight. I’ve never been disappointed.
Suspend
How did we ever live without Suspend? I’ve only used Hibernate (to disk) a few times, but it works too.
Keyboard
The most important part of a laptop (in my world) is the keyboard, and this one rocks. My hands are large, and I don’t feel cramped at all. Everything is there, and in the correct place. I really notice it when I use any other brand of laptop.

What’s not-so-hot about this machine

CPU
It seems I bought this machine just days before all respectable machines went dual-core. I’ll admit I had a bit of CPU-Envy towards a couple of guys that got a t60 a month after I bought mine. After a good bit of soul-searching, I’ve realized that my machine stays clocked down at 800mhz most of the time. I don’t write C++ or Java on this machine (Ruby and Perl, mostly), so I don’t have long compile cycles to worry about. Bottom line - It’s just what I need
Screen resolution
I’m an XEmacs user, so I can slice and dice the screen as I see fit. Also, I’m a virtual desktop power user, so I’ve got lots of real-estate for full-screen apps. If I used Eclipse, or just about any IDE, this screen would be too low-res. Again, just what I need, probably not for everyone.
Windows Key
This IBM has a Windows key - go figure. I don’t use it, but I think that it works.

So, this machine, warts and all, is my personal coding machine. I only have to reboot when there’s a new kernel, I authenticate with the fingerprint reader (one finger is me, one finger is root), and generally love every minute of coding on it. I keep trying to convince my wife she needs one, but she’s wedded to the Microsoft Natural keyboard, for some reason.

dhw

Subversion Configuration on a Virtual Host

Sunday, February 11th, 2007

Subversion rocks! I’ve been a fan of Subversion for the past 4 years or so. Recently, I needed to give Subversion access to a small team, and my constraints were:

  • Available to the users over the Internet
  • *Not* hosted over my DSL/Cable
  • Using Apache 1.3
  • Secure
  • SSL not available

Given these constraints, I couldn’t have a traditional Apache 2.0+https installation of Subversion, rather I needed svnserve. Since I didn’t want to host it at home (my home machines frequently donate vital organs to science), I decided to host it on a virtual server. I’d previously discounted svnserve as a minor footnote, not something that was useful or interesting. Without Apache 2.0 and a dedicated server this imposed a couple more constraints:

  • Only one user account
  • No access to arbitrary ports for svnserve to listen on

From the Subversion Book, svnserve is:

A lightweight serve(sic) process which can run either as a persistent daemon, or as something automatically launched by inetd when necessary. Clients authenticate via CRAM-MD5 algorithm and speak a custom network protocol.

That’s all fine, but a little further down in the Subversion Book, we find svnserve over SSH, which fits the bill nicely.

The basic premise of svnserve over SSH, is that the client connects via SSH to a host, which spawns an svnserve process to serve the repository data. The Subversion designers built in a bit of *nix synergy here, so that svnserve could handle the repository, and ignore the authentication and encryption, via the -t option (tunnel mode). Tunnel mode assumes that the svnserve process communicates over STDIN/STDOUT with the client.

General Requirements

Subversion command line client
Although this will work with TortoiseSVN, I use the command line client.
*nix server
My virtual host is Linux, but this should work on just about any *nix host. On Windows, your mileage may vary
SSH Access to your virtual host
If your virtual host doesn’t allow SSH, then this will not work

Server SSH Configuration

First of all, your server needs to have Subversion installed. Whether it’s installed by your hosting service, or you install it right to your user account, it really doesn’t matter. Installation to a user account is a little tricky, since you may need to compile Subversion (lots of binaries exist, though).

All that’s really required is editing your .ssh/authorized_keys2 (on Linux) Here’s the line I added to mine:
(Line breaks added for readability) From “Controlling the invoked command” in the Subversion Book


command="svnserve -r /home/jkeyfrom/repo -t --tunnel-user=dwilkins",
no-port-forwarding,
no-agent-forwarding,
no-X11-forwarding,no-pty
ssh-rsa AAAAB3NzaC1yc2EA<snip....snip>DGLSKTFLPzUA9J8xJr1p/w== dwilkins@z60t

This command instructs ssh to run the svnserve command when the specified key is encountered. The Subversion Book suggests the additional ssh options to limit the rights of your Subversion users. If you’ve got users that will be using both shell access and Subversion access, they’ll need two public/private key pairs, one for shell, and one for Subversion.

The options to the svnserve command are:

  • -r <repository path>
  • -t (instructs svnserve to tunnel)
  • --tunnel-user <subversion user>

The <Subversion User> doesn’t have to bear any resemblance to your virtual host user.

Subversion Client Configuration

Your Subversion configuration is in ~/.subversion/config. This file is a pretty standard INI-style file, and in there, you’ll find a [tunnels] section. In the [tunnels] section, add / edit the ssh = line to read something like:

ssh = $SVN_SSH ssh -l jkeyfrom -i /home/dwilkins/.ssh/identity.svn

The options to the ssh command are:

  • -l <username> (this is the username of your virtual host account)
  • -i <location of your ssh private key for Subversion>

And that’s all there is to it! You can get Subversion SSH keys from each of your team members, and put them in the ~/.ssh/authorized_keys2 file, and they’ll have secure access to your archive, with full accountability of checkins.

Your urls will be of the form:
svn+ssh://example.com/directory

Again, I’m a big fan of Subversion, and I’ll probably be blogging more about it later. All of the information in this article came from the Subversion Book - a must-read for Subversion administrators. Subversion users can generally skip it, and just follow their noses in their Subversion client.

dhw

Valid XHTML 1.0 Transitional

Hello world!

Saturday, February 10th, 2007

Hello Blogosphere!  I’m David H. Wilkins, and this is my blog.

Well, I’ve finally done it - started blogging.  I’ve wanted to for a while, but never thought that I could generate enough content to keep others engaged - I guess we’ll see about that.

This blog will be decidedly technical - that’s what I do best.  I’ll probably digress into some other subjects, but mostly this will be code and algorithm based.

I hope you enjoy - send plenty of feedback!

dhw