Render Image Links Directly Inside Adium

Last night I delightfully discovered that Adium Message Styles are just html, css, and javascript rendered inside a webview. The next natural step was to write something in it, so I wrote a Message Style that tries to render any image link directly inline the conversation (campfire style).

The code was written at midnight after a long day, so its not best. Basically, it’s a setInterval that runs every 2.5 seconds that loops through all message elements, appending an img tag to the body of the message if an image link is detected. It also removes the processing class as to not reprocess the same messages.

Installation is simple, just download: 

http://dl.dropbox.com/u/42561/Stockholm.AdiumMessageStyle.zip

and extract into ~/Library/Adium 2.0/Message Styles (create if necessary). Then choose the TOP Stockholm theme (no idea why there are two entries), and close your chat window. It should be activated next time a chat window opens.

Don’t Pee in the Pool

A rich man builds a pool containing only bottled water and invites a few friends over. He gathers everyone around and says, “Guys, I know it’s tempting and convenient to pee in the pool, but this pool is 100% Evian, let’s all try to use the bathroom next to the pool instead.” So everyone listens and enjoys a urine-free, delicious pool for the rest of the day. Until, of course, one of them breaks the rule, ruining it for everyone.

That pool is your commit history and the merge commits are the pee in the pool. So please, keep your pee out of the pool and rebase instead.

Disclaimer: I don’t really care if you do or do not pee in regular pools. This is all made up to illustrate a point.

Sane Lion Gestures

Here’s how you disable lion’s dumb default gestures that break front/back on browsing and next/prev in emacs:

My Cloud Experiment

Lately I’ve been thinking about the best way to store and backup large amounts of personal data. It irked me that I’ve never been able to keep a collection of photos past 2-3 years. Either it’s a machine swap or a misplaced backup, something always happens. 

When the idea of storing or backing up everything offsite comes up, people usually throw out objections like “What if they lose all my stuff or go out of business?” or “I don’t like the idea of my files on someone else’s computers”. However, based on my past performance, I concluded that any solution is better than my current one.

The ideal situation was to have my entire home directory on Dropbox. This is feasible only if you have about 50-100gbs you care about. For most people, including myself, this is not the case. So how do you reduce your total data footprint to 50gbs?

  • No more local mp3 storage. I went and uploaded my current mp3 collection (15 gbs or so) to Amazon Cloud Player. I also deleted anything rdio already had in its collection. 

  • I deleted the random assortment of movies and tv shows I’ve acrued over the years, since 98% of them they are already on Netflix and Hulu Plus.

  • Pictures were the last remaining swath of disk space. I wrote a script using the (awesome) smugmug api, and uploaded all my photos to smugmug.

After these changes I’m going to put my entire home directory up on Dropbox, since it will fit now. Admittedly, all these services cost money, but it’s a small price to pay for never having to worry about backups or the location of your files (since they can be accessed anywhere).

Im curious as to how others have solved this problem or how Apple will solve it with their supposed ”iCloud”.

 

MigrationFor: Write Migrations Right From the Command Line!

As someone who mostly stays in the rails console, I’ve always hated forgetting a field, creating a migration, finding it among your other 500 migration files, then adding the one line you need to add, then running it. This is probably the most annoying part of the Rails experience. I’ve always wanted to write a better migration generator that could take a list of commands/fields and write the migration for you, since most of the time what you name a migration has all the info it needs (add_index_to_post_id). Thanks to the heavily refactored plugin/generator API in Rails 3, I was able to do just that.

Let’s take a look at how it works:

First, install it (only works for Rails 3)

rails plugin install git://github.com/capotej/migration_for.git

Then, you can create migrations like so:

rails g migration_for add_index:posts:posts_id

It would generate db/migrate/20110103182654_add_index_posts_posts_id.rb):

1
2
3
4
5
6
7
8
9
10
11
class AddIndexPostsPostsId < ActiveRecord::Migration

  def self.up
    add_index 'posts','posts_id'
  end

  def self.down
    #waiting for reversible migrations in rails 3.1!
  end

end

Which you can then run normally with rake db:migrate

Let’s look at a more complex example:

$ rails g migration_for create_table:posts add_column:posts:title:string add_column:posts:user_id:integer

Would generate:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CreateTablePostsaddColumnPostsTitleStringaddColumnPostsUserIdIntegeraddIndexPostsUserId < ActiveRecord::Migration

  def self.up
    create_table 'posts'
    add_column 'posts','title','string'
    add_column 'posts','user_id','integer'
    add_index 'posts','user_id'
  end

  def self.down
    #waiting for reversible migrations in rails 3.1!
  end

end

It uses a lookup table with all the activerecord transformations and will only insert an expression into a migration if the method name is valid and it has the right number of arguments, so botched commands wont mess up the migration. Hope you enjoy it as much as I have!

Source available here: https://github.com/capotej/migration_for

What I Released in 2010

Here’s a recap of what I’ve worked on and released in 2010:

Youtube Fraiche

I couldn’t find a youtube downloader that worked on github, so I wrote my own one evening

Uploadd and paperclip_uploadd

I wanted to upload and store images off-site (using paperclip/rails) on an server which has cheaper bandwidth rates than S3. Using rainbows, this tiny rack script has handled over a 1.5 million uploads at a peak of 10-15 uploads/sec. Also, it’s been running for about 6 months now without a single crash. Thank you Eric Wong! There is also a plugin for the popular paperclip gem to use uploadd as a storage backend transparently.

mrskinner

Tiny javascript for making the site gutters clickable based on a fixed width layout

existential

Completely inspired by Nick Kallen’s post on authorization, I wanted to extract that pattern into a rails plugin that I could use for all my projects. I use devise/existential for all my projects now.

has_opengraph

Easy way to participate in opengraph and draw facebook like buttons. Just annotate your models with meta data, and draw it in your view easily.

chewbacca

I kinda feel bad that I took a cool name for such a lame script. Anyway it’s a set of rake tasks that provide a hair of abstraction above scp. Useful when you have a set of files locally that map to a different set of files remotely.

I already have tons of stuff in the works for 2011!

Using Rack Applications Inside GWT Hosted Mode

This guide will show you how you can use JRuby to run any Rack application inside Google Web Toolkit’s (GWT) hosted mode server so your interface and your backend are of the Same Origin.

BackgroundGWT has two ways of interacting with a server: GWT Remote Procedure Call (RPC) and plain HTTP (XHR). GWT-RPC is a high level library designed for interacting with server-side Java code. GWT-RPC implements the GWT Remote Service interface allowing you to call those methods from the user interface. Essentially, GWT handles the dirty work for you. However, it only works on Java backends that can implement that interface. Since most of my backends are Sinatra/Rack applications, I’ll be using the plain HTTP library.

The problemDue to the restriction of the Same Origin policy, the interface served out of GWT’s development, or Hosted Mode server can only make requests back to itself. If you were using real servlets or GWT’s RemoteService this wouldn’t be an issue; but since Rack applications listen on their own port, you cannot make requests from GWT to our application without resorting to something like JSONP or server-side proxying. This leaves you having to compile our interface to HTML/JS/CSS, which is lengthy process, and serve it from the origin of the Rack application to see our changes.

The solutionSince I wanted to develop using GWT’s development environment with a Rack backend, I devised a way to use jruby-rack to load arbitrary Rack applications alongside our interface.

First let’s setup our environment:

Download and unpack the latest GWT for your platform (mine’s being linux)

1
2
wget http://google-web-toolkit.googlecode.com/files/gwt-linux-1.7.0.tar.bz2
tar -xvjpf gwt-linux-1.7.0.tar.bz2cd gwt-linux-1.7.0

Download the latest jruby-complete.jar

1
2
wget http://repository.codehaus.org/org/jruby/jruby-complete/1.3.1/jruby-complete-1.3.1.jar
mv jruby-complete-1.3.1.jar jruby-complete.jar

Download the latest jruby-rack.jar

1
2
wget http://repository.codehaus.org/org/jruby/rack/jruby-rack/0.9.4/jruby-rack-0.9.4.jar
mv jruby-rack-0.9.4.jar jruby-rack.jar

Create an app with webAppCreator

1
2
./webAppCreator -out MySinatra com.example.MySinatra
cd MySinatra

Package gem dependencies

In order for this to work you have to package any gem dependencies your backend needs (sinatra, in our case) as jars within your application. For Sinatra it looks like this:

1
2
java -jar jruby-complete.jar -S gem install -i ./sinatra sinatra --no-rdoc --no-ri
jar cf sinatra.jar -C sinatra .

Add jruby-complete.jar, jruby-rack.jar, sinatra.jar (and any other jars you’ve created) to the libs target of your build.xml

1
2
3
4
5
6
7
8
<target name="libs" description="Copy libs to WEB-INF/lib">
  <mkdir dir="war/WEB-INF/lib" />
  <copy todir="war/WEB-INF/lib" file="${gwt.sdk}/gwt-servlet.jar" />
  <!-- Add any additional server libs that need to be copied -->
  <copy todir="war/WEB-INF/lib" file="${gwt.sdk}/jruby-complete.jar" />
  <copy todir="war/WEB-INF/lib" file="${gwt.sdk}/jruby-rack.jar" />
  <copy todir="war/WEB-INF/lib" file="${gwt.sdk}/sinatra.jar" />
</target>

Add these lines right after in war/WEB-INF/web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<context-param>
  <param-name>rackup</param-name>
  <param-value>
    require 'rubygems'
    require './lib/sinatra_app'
    map '/api' do
      run MyApp 
    end
  </param-value>
</context-param>
<filter>
  <filter-name>RackFilter</filter-name>
  <filter-class>org.jruby.rack.RackFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>RackFilter</filter-name>
  <url-pattern>/api/*</url-pattern>
</filter-mapping>
<listener>
  <listener-class>org.jruby.rack.RackServletContextListener</listener-class>
</listener>

Note: All you’re doing here is passing the contents of a config.ru file into the <param-value> element for the <context-param> (make sure this is HTML encoded!). This states that any request to /api is to be handled by your Sinatra application and not GWT’s Hosted mode servlet.

Create your Sinatra backend and place it in war/WEB-INF/lib/sinatra_app.rb

1
2
3
4
5
6
7
8
9
10
11
require 'sinatra'
require 'open-uri'
class MyApp < Sinatra::Base
  get '/showpage' do
    open('http://www.yahoo.com').read
  end

  get '/helloworld' do
    'hello world'
  end
end

Run your new awesome setup

ant hosted

Now when navigate to http://localhost:8888/api/helloworld or http://localhost:8888/api/showpage you should see the Sinatra application being served via GWT.

Useful Rails Routing Tips

Even though I have been using Rails for fun and profit for about 2 years now, I felt I never really used it’s routing engine to its full potential. So I checked out new Rails Routing from the outside in guide and discovered bunch of useful tricks that I (and maybe you) had no idea you could do. Here they are:

Multiple resource definitions on a single line

1
map.resources :photos, :books, :videos

Impose a certain format for resource identifiers

1
map.resources :photos, :requirements => { :id => /[A-Z][A-Z][0-9]+/ }

This way, /photos/3 would not work, but /photos/DA321 would.

Friendlier action names

Say for your application ‘create’ and ‘change’ make more sense than the default ‘new’ and ‘edit’ you can do

1
map.resources :photos, :path_names => { :new => 'make', :edit => 'change' }

You can also do this site-wide also, in your environment.rb

1
config.action_controller.resources_path_names = { :new => 'make', :edit => 'change' }

Trim the fat off resources with :only and :except

When you use map.resources, rails generates 7 restful routes for that resource; But what if that resource only needed to be seen and listed, never edited or created?

1
map.resources :photos, :only => [:index, :show]

If your application uses a lot of map.resources calls but not neccesarily all its generated routes, you can save memory this way.

Adding extra routes to your resources

Instead of fighting the map.resources generator by placing a horror like this atop your routes.rb

1
map.connect '/photos/:id/preview', { :controller => 'photos', :action => 'preview' }

You can do this to your already mapped resource

1
map.resources :photos, :member => { :preview => :get }

This will map all GET’s to /photos/3 to the preview action of your photos controller

This can also be  used in collections instead of singular members, just change :member to :collection

1
map.resources :photos, :collection => { :search => :get }

This will give you /photos/search and hit the search action within the photos controller

So You Want to Click That Button?

I stumbled uponhttp://clickthatbutton.com during my routine lurking ofhacker news . After being amused for about 10 seconds,  I decided to take it to the next level; I wanted to click on it really, really fast. After going through a few solutions (simple js while loop in firebug, then curl/wget) and failing, the idea of using selenium popped into my head. So I went off to theirsite and installed the extension. I figured a simple recording of the mouse event, then wrapping it around a loop in selenium would do the trick, but I quickly found that selenium doesn’t support loops. Not to be stopped, I searched google and ended up withthis . After installing the plugin for selenium (a plugin for a plugin!?) and restarting firefox, I tried it again and to my surprise it worked! The click counter was going up steadily on its own (18k clicks and counting). Here is my selenium test case for those of you following along:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="http://clickthatbutton.com/" />
<title>haha</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">haha</td></tr>
</thead><tbody>
<tr>
    <td>open</td>
    <td>/</td>
    <td></td>
</tr>
<tr>
    <td>store</td>
    <td>x</td>
    <td>1</td>
</tr>
<tr>
    <td>while</td>
    <td>storedVars['x'] == storedVars['x']</td>
    <td></td>
</tr>
<tr>
    <td>click</td>
    <td>submit</td>
    <td></td>
</tr>
<tr>
    <td>endWhile</td>
    <td></td>
    <td></td>
</tr>

</tbody></table>
</body>
</html>

Just paste that into a file, open it with selenium ide, hit play and you should be good to go.

Arrow Key Navigation for Text Fields

Here is a class for enabling the use of arrow keys to navigate through a grid of input fields: (using mootools)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
var FocusMover = new Class({

        initialize: function(sel, col_num){

                this.sel = sel
                this.col_num = col_num
                this.inputs = $$(this.sel)
                this.current_focus = 0

                var self = this

                this.inputs.each(function(item, index){
                        item.addEvent('keydown',function(key){
                                $try(function(){
                                        self[key.key]()
                                })
                        })
                        item.addEvent('focus',function(e){
                                self.refresh(e)
                        })

                        item.set('myid', index)
                })

                this.inputs[0].focus()

        },


        refresh: function(e){
                this.current_focus = e.target.get('myid')
        },

        down: function(){
                i = parseInt(this.current_focus) + parseInt(this.col_num)
                this.inputs[i].focus()
        },

        up: function(){
                i = parseInt(this.current_focus) - parseInt(this.col_num)
                this.inputs[i].focus()
        },

        left: function(){
                i = parseInt(this.current_focus) - 1
                this.inputs[i].focus()
        },

        right: function(){
                i = parseInt(this.current_focus) + 1
                this.inputs[i].focus()
        }

})

As you can see, the constructor takes two arguments: a selector (which should return a list of all your input fields), and the number of input field columns. So for a 4x2 table, you would set it up like this:

1
var FM = new FocusMover('#mytable input', 4)