Archive for the ‘Ruby’ Category

PNG Thumbnails for PDF files. Take two

Tuesday, October 7th, 2008

Updating my previous post, I finished up the work of extending attachment_fu to optionally create PNG thumbnails of updated PDF files. Check out the fork on github

Creating thumbnails of PDFs with attachment_fu

Tuesday, September 16th, 2008


We needed to create some thumbnails from uploading PDF files for a new site feature – We’re using attachment_fu which doesn’t support that (yet?), but we’re using RMagick as our processor and it understands PDF files.

I came up with the hack below (warning, first draft, only briefly tested) which works without having to modify the attachment_fu plugin itself. One day I’ll loop back and figure out a cleaner way to do this and see which of attachment_fu’s other image processors can even support pdfs.



There are three methods to override to make a go of this:

  1. self.image? : consider pdf files as an image so thumbnail process will happen

  2. thumbnail_name_for : change the extension of the saved thumbnail filename to png

  3. resize_image: override to change format via block passed to to_blob

Apologies for the crappy source formatting, I have to install a plugin to do that well one of these days


###Hacks to allow creation of png thumbnails for pdf uploads - depends on RMagic being the configured processor

## likely very fragile

def self.image?(content_type)
(content_types +  ['application/pdf']).include?(content_type)
end

alias_method :original_thumbnail_name_for, :thumbnail_name_for
def thumbnail_name_for(thumbnail=nil)
return original_thumbnail_name_for(thumbnail) unless (content_type 'application/pdf' && !thumbnail.blank?)
basename = filename.gsub /.w+$/ do |s|
ext = s; ''
end
"#{basename}_#{thumbnail}.png"
end

#copied from rmagick_processor with change in last few lines
def resize_image(img, size)
size = size.first if size.is_a?(Array) && size.length 1 && !size.first.is_a?(Fixnum)
if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum))
size = [size, size] if size.is_a?(Fixnum)
img.thumbnail!(*size)
else
img.change_geometry(size.to_s) { |cols, rows, image| image.resize!(cols<1 ? 1 : cols, rows<1 ? 1 : rows) }
end
img.strip! unless attachment_options[:keep_profile]
if content_type == ‘application/pdf’ # here force the output format to PNG if its a pdf
self.temp_path = write_to_temp_file(img.to_blob {self.format = ‘PNG’})
else
self.temp_path = write_to_temp_file(img.to_blob)
end
end

Ruby operator precedence (the ors and ands of it)

Friday, March 14th, 2008

I found out (by introducing a bug into the application I’ve been working on) that “or” and “||” do not have equal precedence in Ruby.

More importantly, the assignment operator “=” has higher precedence than “or” so that means that while the expression


>> foo = nil || 2
=> 2
>> foo
=> 2

results in foo being assigned the value 2 as you might expect, the following expression leaves foo assigned the value nil.


>> foo = nil or 2
=> 2
>> foo
=> nil

This is well covered ground online (see this post) but I was surprised that this oddity didn’t warrant an explicit mention in the operator precedence section of the Pickaxe book.

Boston Ruby User’s Group meeting

Tuesday, June 12th, 2007

I attended my first Boston Ruby User’s group meeting earlier tonight. I wasn’t sure what to expect exactly, but I was surprised how many people attended (in the neighborhood of a hundred I would guess).
Both of the speakers were quite interesting.

  • David Black gave an interesting talk on the way Ruby implements inheritance with a particular emphasis on giving objects that “spring from” the same class different behaviors without defining additional classes.

    Learned a lot from this exercise in meta programming because I’ve really only dabbled in Ruby so far.

  • Zed Shaw had a really energetic, engaging and entertaining presentation touching on his http server, Mongrel, its competitors, evildoers and anti-social behavior on the internet and how he aims to address that with his Utu project

The sessions were video taped so they’ll apparently be up on Google video sometime soon. You don’t really have to know or care about ruby to enjoy and learn from Zed’s talk.

One of the great things about living somewhere like the Boston area is that people I’ve heard of before show up at things like this – attendees of the meeting tonight included Martin Fowler and John Resig (wrote JQuery), along with many other folks much smarter than me.

Gas prices, state by state, with and without state taxes

Monday, May 7th, 2007

In the image below I’ve plotted the average gas price in each state for 4/25/07 (data from here) with and without state per-gallon taxes included. Without the taxes included, it becomes obvious that gas prices increase on the west coast, perhaps due to transportation costs? ( a quick search didn’t turn up any port-by-port oil import stats).

425composite-small.png

I created this using ruby-shapelib and rmagick as mentioned previously.

Loading and drawing maps with Ruby

Saturday, April 28th, 2007

Loading geographic map data and drawing maps is pretty easy to do with two Ruby tools – ruby-shapelib (to load the map data) and RImageMagick (to create the drawings).

I didn’t see any tutorials or sample code, so I’m posting this sample as is – it will draw every shape part of every shape in a given shape file. Note this code does not perform any geographic projections.

require 'rubygems'
require 'RMagick'
require 'rvg/rvg'
require 'shapelib'
include ShapeLib
include Magick

USSTATES_SHAPEFILE="/Users/jkk/projects/shapelib/statesp020/statesp020.shp"
OUTFILE="/Users/jkk/projects/shapelib/test.png"

def drawshape shape, canvas
  #each shape can have multiple shape parts...
  #iterate over each shape part in this shape -
    0.upto(shape.part_start.length-1) do |index|
       part_begin = shape.part_start[index]
      unless shape.part_start[index+1].nil? then
        part_end = shape.part_start[index+1]-1
      else
       part_end=-1
      end
    #NOTE we're assuming all the parts are polygons for now...
    #draw a polygon with the current subset of the xvals and yvals point arrays
    canvas.polygon(shape.xvals.slice(part_begin..part_end),shape.yvals.slice(part_begin..part_end)).styles(:fill =>"green",:stroke=>"black",:stroke_width=>0.01)
  end
end

#create a viewbox with lat/long coordinate space in the correct range
def create_canvas rvg, shapefile
    width = shapefile.maxbound[0] -shapefile.minbound[0]
    height = shapefile.maxbound[1] -shapefile.minbound[1]
    #puts "viewport #{shapefile.minbound[0]},#{shapefile.minbound[1]} - width= #{width} height= #{height}"
    #invert the y axis so "up" is bigger and map the coordinate space to the shape's bounding box
    canvas = rvg.translate(0,rvg.height).scale(1,-1).viewbox(shapefile.minbound[0],shapefile.minbound[1],width,height).preserve_aspect_ratio('xMinYMin', 'meet')
end


shapefile = ShapeFile.open(USSTATES_SHAPEFILE,"rb")
#create a new RVG object
rvg = RVG.new(1000,100)
rvg.background_fill='white'
canvas = create_canvas rvg, shapefile
shapefile.each { |shape| drawshape(shape,canvas) }
shapefile.close

rvg.draw.write(OUTFILE)




I’m using the US State boundary file from the national atlas website.

Recursive deletes

Friday, March 9th, 2007

Posting this little ruby snippet so i can reference it later. Need to recursively delete directories with a certain name in a large tree? The simplest example is scrubbing those pesky .svn directories in a subversion repository, which can be done like so:

require ‘fileutils’
Dir.glob(“**/.svn/”) {|fname| FileUtils.rm_r(fname) }

another use case I have here at work is to scrub extra maven generated versions of code out of each java project (so as to keep eclipse sane). In this case, we want to delete all directories (and their contents) named “target” except for the target directory at the root (because mvn clean is “too clean” in this instance):

require ‘fileutils’
Dir.glob(“**/target/”) {|fname| FileUtils.rm_r(fname) unless /^target.*/ =~ fname}

It gets a bit more complicated if you want to exclude list of directories from the operation. Here I found Ruby’s Enumerable module detect method quite handy to short circuit evaluate all the directories to exclude regex on each directory.


require 'fileutils'
@exclude= [/<sup>foo.*/ , /</sup>bar.*/ , /<sup>james.*/, /</sup>target.*/]
Dir.glob("**/target/") do |fname|
@erase = @exclude.detect{ |r| r =~ fname }.nil?

if @erase puts "erasing #{fname}"
FileUtils.rm_r(fname)
else
puts "skipping #{fname}"
end
end

Note: this code won’t copy and paste well because wordpress replaces quotes with smartquotes. I also really need to fix my stylesheet for code samples.

Rails Development - Tracks

Thursday, March 8th, 2007

I’ve resolved to learn Ruby on Rails this spring in lieu of the grad school class that I would normally be taking (rather than letting any free time slide by playing Wii Sports). I think the best way to learn is by doing, and since I don’t have any containable project ideas, I’ve been tinkering with an open source project called Tracks, which is a web based organization application in the mold of the getting things done philosophy.

Even though I’m still painfully slow as a ruby developer, I’m really amazed how easy to work with and powerful some of the frameworks in rails are compared to the (clunky and slow to work with by comparison) Java/JSP/Struts stack I’m accustomed to. One of the features I love so far is the ability to reuse page chunks (“partials”, which could roughly be compared to tag-files in JSP land) in rails javascript templates which make it really simple togenerate javascript that will update multiple sections of a web page (as opposed to one container, which is easy to do with prototype alone from the client). I figured out enough in no time at all to submit a patch to enhance the project pages. Pretty cool.