I was feeling somewhat unproductive last week. Although learning Clojure has been enjoyable, I missed my efficiency in Ruby. As a break from Clojure, I built Pagelapse, a Ruby gem to create time-lapses of websites. I spent half of Wednesday and Thursday coding it, just finishing it in time for Hacker School’s Thursday presentations.
Pagelapse uses PhantomJS to take screenshots of websites, and Sinatra to host a local time-lapse viewing server. Pagelapse comes with a command line tool for easy integration with your project’s foreman
Procfile. Pagelapse isn’t just for your own projects, though — you can use it with any website you’d like.
Installation & Usage
Installation is simple:
brew install phantomjs gem install pagelapse
If you’re not on OS X, you’ll have to install PhantomJS yourself.
Once that’s installed, create a
Lapsefile in the root directory of your project, or a folder where you want to keep the screenshots.
Lapsefiles are just Ruby with a tiny little DSL to tell Pagelapse which sites to record. (Why does Pagelapse need it’s own DSL? For fun!)
Here’s an example
record "lord", "http://www.lord.io/blog" record "metafilter", "http://www.metafilter.com"
The first argument to
record is the name of the time-lapse, and the second is the URL of the page to record. Start recording by running
pagelapse in your shell with the
Lapsefile in the current directory.
You can add as many
record statements as you’d like. You can also specify the interval between captures with a do block, as well as the size of the virtual browser window.
record "lord-mobile", "http://www.lord.io/blog" do |r| r.width = 300 # pixel width of the virtual window r.height = 500 # pixel height of the virtual window r.interval = 10 # time between captures, in seconds end
You can also run Capybara commands to take screenshots of pages that need signing in:
record "github", "http://github.com/login" do |r| r.interval = 10 r.before_capture do page.fill_in('login', :with => 'lord') page.fill_in('password', :with => 'my password here') page.click_button('Sign in') end end
There are several other parameters that you can set. Check out the readme for the complete list.
After you’ve captured a bunch of screenshots, you can view the files with the viewing server.
This command starts a server at http://localhost:4567. Just click the name of the time-lapse you want to view, and then move your mouse from left to right to play it.
I’ve never built a DSL in Ruby before, so this was an educational exercise in using
File.read. Let’s look briefly at a abridged version of
class Parser def initialize(file) puts "Starting Pagelapse" instance_eval(File.read(file), file, 1) end private def record(name, url) # do stuff end end
Now, when the command line tool runs
Parser class will run the contents of the file as though it were written directly into the class’s
initialize method, with full access to the
Parser‘s public and private methods. If we used
require instead of this method, the file would not be scoped in the instance, and so the
Lapsefile would have to call
parser.record (or something like that) instead of
record. Not quite as clean.
Also, for the curious, the second and third arguments of
instance_eval are for errors. Since the
Lapsefile contents are passed to
instance_eval as a string, if there’s an error, Ruby has no idea where to say the error came from. Those arguments tell Ruby that the string passed to
instance_eval corresponds with line 1 of
file. That way, Ruby can display errors during the eval as coming from the
All in all, I’d call this a successful project. It was short, sweet, and I learned something. Plus, it’s a useful tool that I might use in the future.