url2png is a service for generating screenshots of websites. Pass in a URL and some dimensions and it spits back a high quality png capture of that site.

Unlike some competing services I've tried, it even does a decent job handling sites that require client-side rendering.

Someone has already built a ruby gem for working with url2png. It provides a rails helper for hot-linking url2png images in your views. Perhaps a better name for that gem would be url2png-rails.

Though useful, this is not what I was looking for. Instead, I wanted the ability to save a local copy of the screenshots on my own server. Since I was already using Paperclip for saving attachments, this turned out to be easy.

An API wrapper The url2png API is quite simple. Using it requires building the URL of the image by generating a token. The following uses v3 of their API. As of writing, this is the version they use in their guide. require 'digest/md5' class ScreenShot KEY = 'your key' SECRET = 'your secret' def initialize ( url , bounds ) @url = url @bounds = bounds end def token Digest :: MD5 . hexdigest ( " #{ SECRET } + #{ @url } " ) end def img_url "http://api.url2png.com/v3/ #{ KEY } / #{ token } / #{ @bounds } / #{ @url } " end end Using this, we can easily get the URL of a screenshot of the front page of reddit >> shot = ScreenShot . new ( 'http://reddit.com' , '200x200' ) >> shot . img_url ... http : //u rl2png .../ reddit . png

Saving it with Paperclip Paperclip is a popular gem for managing file attachments in rails applications. Until now, I'd only used it to save files that were passed in through a form. But, it is not restricted to handling POST data or files already on disk. Pass in any IO and it will take care of the rest. Given a Website model with a url attribute, we can fetch an image for that URL and save an associated screenshot. class Website has_attached_file :screenshot , :styles => { :thumb => '50x50' , :square => '200x200' } def gen_screenshot! shot = ScreenShot . new ( url , '200x200' ) self . screenshot = open ( shot . img_url ) save! end end Notice that we can pass the IO returned by open directly to Paperclip without having to bother saving it to disk ourselves. If the image is small enough, behind the scenes open will use a StringIO and hold the image data in memory. This avoids the filesystem overhead of writing an extra TempFile . We can attach the image to our Website model like this: >> site = Website . new ( url : 'http://reddit.com' ) >> site . gen_screenshot! Paperclip will handle the messy details of thumbnail generation. When it's done, it will move the files to the proper location on disk.