A Simple Way to Generate formatted PDF Documents
The Problem
Most of the applications we make are in aid of current manual systems. The whole reason clients come to us is because they want to streamline and automate parts of their processes but they still have to deal with the reality of the current, paper-based way of doing things. So it happens that recently I’ve gotten a sudden influx of requests to be able to generate printable pre-filled forms.
There are multiple ways to go about doing this. The easiest way would’ve been to just allow the user to click ‘print’ on their browser and serve them a formatted print.css page. However, a couple of projects back we ran into a problem using this approach – we could never get the same result across multiple computers. We tried restricting the browsers used to firefox but even that didn’t play nice with the differing operating systems. Using CSS to generate printable forms wasn’t an option.
The next ideal way would be to be able to generate a pdf using from an html output. This would be great because we could maybe use the existing templates and just generate the pdf from that. After looking around a while it seemed that PrinceXML was the way to go. Unfortunately for me, it didn’t come free. Alternatives such as HTML Doc just didn’t cut it.
Next in my quest was pdftk I thought maybe I could just design the templates by hand using Scribus and then just fill_form the values using pdftk. Again I hit a roadblock when I found that some of the forms had dynamic content (e.g. tables) that couldn’t be handled by this approach.
I was back to using PDF::Writer. The problem with pdf-writer is that it’s pretty raw. It allows you to do a lot of things with PDFs but you have to deal with lines, points, x/y coordinates, and all of the details. I didn’t have the time nor the patience to deal with all that for the amount of printables that were coming in.
The Solution?
So I decided to write my own little library that would fix all that. Introducing PDF::Cell – it’s a library based on PDF::Writer that allows you to layout documents in a straightforward manner without thinking about the nitty-gritty details about how exactly to position the elements. The model for laying out stuff is loosely based on Ruby Shoes’s concept of stacks and flows. Here’s an example:
pdf = PDF::Writer.new
biodata = PDF::Cell::Base.new(pdf)
biodata.build :width => 500, :font_size => 8 do
header "Crew File #245: Jack Black (2/M of MV Nautilus)", :shaded => true,
:font_size => 15
desc "The Content"
cell :width => 375 do
cell :width => 125 do
text "<b>Given Name</b>"
text "Jack"
end
cell :width => 125 do
text "<b>Middle Name</b>"
text "James"
end
cell :width => 125 do
text "<b>Family Name</b>"
text "Black"
end
cell :width => 250 do
text "<b>Address</b>"
text "#124 Main Street"
end
cell :width => 125 do
text "<b>Contact No</b>"
text "123-456-789"
end
end
cell :width => 125, :height => 125 do
text "Photo Here"
end
end
And here’s the result of the above code
Now for the explanation. The overall box is given a width of 500. (it uses pdf-writer’s measurements not mine) The width is strict – meaning everything else will adjust, just not the width. We add a cell to the box with 375 width – let’s call this the “Content” box. Within the Content box we add 3 cells each with a width of 125. These 3 boxes add up to exactly 375 – the limit of the Content box. Then we add another cell with a width of 250. Clearly this won’t fit into the Content box’s width so PDF::Cell automatically puts it below the previous 3 cells! And that’s basically it. Using that simple concept of cells you can potentially generate any layout your document needs.
I recently added support for tables within cells. Images within cells are coming up shortly although, if you know how to use pdf-writer, you can hack it yourself for now.
Installation
To install just copy/paste the following into your rails root directory:
ruby script/plugin install svn://svn.upstrat.com/plugins/pdf_cell/trunk
That’s it! You should be ready to go.
Speeding up Ruby with Lua
Everyone knows ruby is slow. That’s why I find that the ruby community is more obsessed with optimization than any other. One of the solutions tossed around to improve the performance of ruby programs is to forgo ruby in the complex computations and switch to C.
I don’t doubt this will work. In fact, based on all the stuff I’ve read, this is really a great way to speed up your app while still using the wonder (and joy) that is ruby. However I am loathe to go back to C. I mean, the whole reason I moved to ruby was because I wanted to use a high-level language and all the cool concepts not available to lower level languages.
Enter Lua. I’ve been reading about Lua for a while now. I know it’s fast ; it’s used in WoW and a whole lot of other stuff. It’s also a high level language which I find has a lot in common with lisp (something I’ve always wanted to learn). It’s also designed to be embedded into applications; much the same way ruby was initially designed as a tool for admins. It got me thinking that maybe Lua can help me speed up Ruby.
I found a nifty little library that allows lua to be called from within ruby called rubyluabridge. I installed it on my machine and decided to run the classic fibonacci benchmark test.
Code
fib.rb
t = Time.now
def fib(n)
if n == 1 or n == 2
return 1
else
return fib(n-1) + fib(n-2)
end
end
answer = fib(ARGV[0].to_i)
puts "Answer: #{answer}"
puts "Calculation Time: #{Time.now - t}"
new_fib.rb
t = Time.now
require 'rubyluabridge'
l = Lua::State.new
l.eval <<-LUA_END
function fib(n)
if n == 1 or n == 2 then
return 1
else
return fib(n-1) + fib(n-2)
end
end
LUA_END
l.eval "answer = fib(#{ARGV[0]})"
puts "Answer: #{l.answer.to_i}"
puts "Calculation Time: #{Time.now - t}"
Here are the results:
fib.rb 20Answer: 6765 Calculation Time: 0.071339new_fib.rb 20
Answer: 6765 Calculation Time: 0.034658fib.rb 33
Answer: 3524578 Calculation Time: 11.272733new_fib.rb 33
Answer: 3524578 Calculation Time: 2.103146
Conclusion
There is definitely an improvement in the processing time of the app with lua embedded. This is more apparent the more complex the calculation.
But the most striking thing is that there is very little change in the syntax of the code. If you’ll look at the embedded lua function fib(), it is almost identical to the ruby original. We got all that speed (around 500% in this example) for code that is essentially similar. I find it looks a lot better then lisp. (parentheses anyone?)
So there you have it, embedding lua into ruby for a quick performance boost.
Two-factor Authentication
Website authentication is usually done with using the username-password model: The user has a unique username and a password to prove that he owns that username. The programmer and the system administrator can put in all the encryption and security updates they can but if a hacker somehow manages to access a username and password (e.g. admin / password) then all the other measures become useless.
Enter multifactor-authentication. One-factor authentication is something you know – your username and password. The second factor is usually something you have – some form of key. On the web, it is not so easy to implement two-factor authentication. Usually, what passes for two-factor authentication doesn’t quite cut it.
There is an interesting idea out there though that aims to solve this called BeamAuth The idea is simpe – use bookmarks as a key. Using a little javascript, a bookmark, and the little-known fragment identifier, Ben Adida has developed a system that allows the user to securely send an encrypted key along with the login information. Seamless two-factor authentication!
BeamAuth is a new idea and I haven’t heard of any sites that use it yet. Unfortunately the demo app doesn’t work right now so I haven’t really seen it in action. However, the idea is simple and it looks easy enough to implement. I haven’t seen any holes in the idea yet maybe Bruce Schneier or Steve Gibson would know better but I don’t think they’ve heard of the idea yet. I might try it out myself soon and see if it’s as effective as it seems.
And...We're Back
Wow. Can’t believe it’s been months since we last updated the blog. We’ve been very busy. Well, I think we’ve got things more or less under control now and we can go back to blogging. Stay tuned!
Ruby Presentation in Malaysia
I recently went to Malaysia to do a quick workshop on Ruby on Rails for the Open Source Health Care Alliance. Presenting with me was Aizat. I think the workshop went well. Here’re the slides.
Trouble with RSpec Controller Specs
I had a lot of head scratching just moments ago. Basically it had something to do with controller specs and our in-house plugin ActiveCRUD.
What happens is when you do something like :
context "the Category create page" do
controller_name :categories
specify "should render new if parameters are invalid" do
post :create, :category => valid_category(:name => nil)
response.should render_template(:new)
end
end
You aren’t able to even reach response.should render since doing the post :create will raise the exception.
What happens in our plugin is the same with most of beast-inspired applications. You have code like
def create
@category.attributes = params[:category]
@category.save!
redirect_to category_path
end
private
def rescue_action(exception)
# render invalid model here, etc
end
end
But rSpec happily overrides the controller’s rescue_action method, which means all the expectations we have from our rescue_action are gone.
Right now I did some tweaks to our plugin, catching the exception manually and calling rescue_action_with_validation and then using alias_method_chain.
Hopefully I’ll have a more elegant solution in the future. But hey, they say that tests transform our code into more manageable pieces. I hope that’s what’s happening now.
Valid Model Parameters
While writing tests in rails, we frequently use the pattern :
@article = create_article(:title => nil)
@article.should have_at_least(1).error_on(:title)
and in the bottom of the test, we define a create_article. For the next model, say Project, you define also another one in the bottom.
Previously at our company, we’ve been extracting most of our valid model parameters into a module like so
module ValidParameters
def valid_article
{ :title => 'My Article' }
end
end
Which is very useful when you need to create a model, and the last thing we want is unnecessarily having DAMP code.
But what of combining the two approaches?
I just created a module, which I’ll extract to a plugin at a future date which does exactly that. Basically you add parameters with a DSL-like syntax :
module ValidParameters
valid :article, :title => 'My Article'
valid :project, :name => 'Hedgehog', :owner_id => 1
end
and in your tests you can then do either :
post :create, :article => valid_article
or
lamba { create_article }.should have_difference(Article, :count)
or finally with invalid parameters
lambda { create_article(:title => nil) }.should_not have_difference(Article, :count)
Neat huh?
Safari http-accept-language
Recently I’ve been working with a Globalized rails application. I’ve been testing the app heavily, and often bouncing back between internet explorer and Firefox in order to make sure things are working.
After my latest upload though, the client said that the application was throwing an application error. I asked which page. He said the homepage. That made me wonder a lot.
After some hours I suddenly realized that maybe he was using Safari or some other browser. So I tried safari. There it was. The application error.
It boiled down to the ff lines of code:
request_language = request.env['HTTP_ACCEPT_LANGUAGE']
request_language = request_language.nil? ? nil :
Locale.normalize(request_language[/[^,;]+/])
What happens is in Firefox the HTTP_ACCEPT_LANGUAGE is in the format
en-us,en;q=0.5
Whereas in safari, its just a plain en.
I added an additional case checking if the string matches two chars in the iso format. Hope this works for all browsers, will have to check Opera and Konqueror probably, which I’ve added somewhere in my personal todolist
Rethinking Deployment Strategy
Currently on one of the servers where we deploy rails, we use the Apache + Nginx + Mongrel setup, primarily for the following reasons :
- The Server has apache 1.3 already, and it’s really a pain to try updating it since it’s all tied up to cpanel
- Apache 1.3 proxying doesn’t support the ! directive, which basically is the strategy for skipping static images
- Because of the reason above, we use mongrel both for clustering and static file sending support.
- Mongrel, for obvious reasons, best of which is ease of use and deployment.
Now I’m thinking of just Apache + Mongrel, with no send file support. Basically the setup will rely on using rails’ asset host feature. Will post back if this works.
Also, im thinking of using pen as a load balancer, for ease of use and simplicity of getting it up and running (nginx config is a pain compared to pen)
Best Authorization Plugin for Rails
Ok, I think I’ve finally seen the authorization which fully satisfies my DSL taste.
Head on over to http://www.writertopia.com/developers/authorization to see what i mean.
Basically it allows you to define authorization
- Globally (throughout the entire app)
- For one model class (i.e. Group, Article)
- For an instance of the model class.
In addition, it features grammars!
(taken from the site : )
< checking out to read the source… >
Pretty Restful Resources
Have you ever questioned the rails way? We have.
http://mydomain.com/articles/1;edit
I’ve always had an itchy feeling when coding for this kind of URL ever since restful rails got out. Looking into resources.rb, we came up with a plugin that makes that URL look like this :
http://mydomain.com/articles/1:edit
So far, we haven’t had any problems yet. Nesting doesn’t also reveal any problems. We have declarations like :
map.resources :admin do |admin|
admin.resources :products, :name_prefix => 'admin_' do |product|
product.resources :sections, :name_prefix => 'admin_products'
end
end
Nothing seems to be broken as of now.
If you’re interested, check out the plugin @ svn://svn.upstrat.com/plugins/pretty_resources/trunk
Back to Nginx
After much head scratching, I just realized after re-reading the specs of mod_proxy in 1.3 spec that the mod_proxy version for apache 1.3.x doesn’t support the style
ProxyPass /images !
Looking closely at the spec
Syntax: ProxyPass path url
Default: None
vs this one (in the 2.0 spec)
Description: Maps remote servers into the local server URL-space
Syntax: ProxyPass [path] !|url
pretty much shows the unobvious difference that there is an exclamation point for v2.0 onwards.
With all that, I have opted to return to nginx (at least for now) with the new setup. Right now everything seems blazingly fast (and nginx has a new release, surprise surprise) so at long last, mongrel is no longer serving static files..
"Compiling" Ruby
- You cannot have the customer setup their own database on their computer
- You can’t have the customer install their own webserver
- You definitely cannot have the customer install the compiler/interpreter that you need to run your application.
- You cannot have the customer click more than one thing. (Anymore than one click, and things start to get really messy)
We’ve discovered the first steps to a solution to this dilemma for our rails apps thanks to a fascinating project on distrubuting ruby applications and another one for rails applciations. It’s not perfect but it’s good enough until we hear something from the JRuby, XRuby, Rite, or YARV projects along the lines of an actual compiler for ruby.
They’re pretty straightforward guides to “compiling” your ruby application here are a few lessons learned in our foray into this brave new world:- Make sure you use a portable database solution like SQLite. Everything is stored in one file and you can easily ship it with your app
- Take a second look at your applcation if it has file-upload features.
- Thank the man. It’s people like him that make the world a better place.
Lists!
People deal with a lot of things. Everyday, life make demands of us that sometimes just drive us crazy. But for some reason, We cannot escape it. It is ingrained in today’s society to handle many things at a time. in fact, productivity and efficiency have almost been synonymous with the ability to multitask.
I’m not going to write about doing less or simplifying life. Sometimes that’s just not possible. We want to make the best of everyday and so we have to tackle a lot of things. It’s the ability to do many things that make us such amazing beings.
Today’s little article is about lists. I’m a software developer and my life revolves around projects, feature requests, bugs, tasks, enhancements, and whatnot. You can begin to see that even my focused little nook of the world is riddled with its own barrage of todos and problems. It could literally drive programmers crazy. The only solution that I can think of is so simple that many don’t do it – make a list.
Lists are wonderful things.- They remind you of the stuff you need to do.
- They keep you focused on the things you really need to be doing.
- They help set your priorities as you constantly reorder and reorganize them as new information arises.
- Last, and my favorite, it feels oh so good when you cross-off an item from your list.
The important thing is to keep it organized and up to date as new issues arise. If you don’t believe me, take it from a battle-hardened software guru .
I’ll stop yapping now, (I’ve got some stuff to do) but I’ll leave you with a great (and old) anecdote concerning this particular topic:
A man approached JP Morgan, held up an envelope, and said, “Sir, in my hand I hold a guaranteed formula for success, which I will gladly sell you for $25,000.” “Sir,” JP Morgan replied, “I do not know what is in the envelope, however if you show me, and I like it, I give you my word as a gentleman that I will pay you what you ask.” The man agreed to the terms, and handed over the envelope. JP Morgan opened it, and extracted a single sheet of paper. He gave it one look, a mere glance, then handed the piece of paper back to the gent. And paid him the agreed-upon $25,000.
The Paper:- Every morning, write a list of the things that need to be done that day.
- Do them.
Ruby, Gtk, and Windows
I hate to admit it, but I’ll come clean. I have a Windows laptop. Hopefully that will change soon. In the meantime however I will have to make do with some problems of using Windows. One of these annoyances is getting ruby and gtk to work.
It’s not really a problem. You just have to dig a little to get it right, but just to make sure I don’t forget, here’s a little reminder for all those of you who want to run Ruby-Gtk in Windows.
First, go to the official ruby-gtk project and read a little.
Second make sure you read the bottom part concerning iconv.dll and it’s evil twin brother in your ruby_install_dir
Third, don’t forget the Gtk.init when you’re doing the third suggested test. You might be splitting hairs for no reason.