Ary Borenszweig

Ary Borenszweig

Ary is a software craftsman, he is our guru in all code-related problems. Always teaching how to develop the best code with simplicity in mind, he makes everything seem easy no matter how difficult, to the point that nothing seems impossible with him on the team. Very optimistic (sometimes too much), he has the ability to put any idea into code in almost no time.

Rails Rumble is over: welcome GithubDamper!

This past weekend, together with Emmanuel Oga, we’ve been coding a Ruby on Rails application for this year’s Rails Rumble.

The idea: in github you can watch some repositories, but later you can’t make a search over those watches. The only search github provides is one over all repositories. When your watches reaches a big number it’s defeats its purpose. So we decided to let users tag their watches and then be able to search them by tags.

(Well, actually the original idea was a lot bigger: github generates a big feed for your watches, including commits, comments and gists, and we wanted to filter that feed in a smart way, but in just 48 hours, having to install a server from scratch it was a little ambitious)

What we wanted is the tags to be a community effort: if I tag a project with “java”, let that tag be shown to other users. On the other side, we also wanted the users to have personal tags. But we didn’t want the user to choose, when tagging, wheter it’s personal or global, because that’s a burden on him. So we came up with the following idea: if more than five users put the same tag on a give repository, that tag becomes automatically available to all users.

We also wanted to start out with some tags, like for programming languages or common software terms, so when a user logs in she starts with some tags on her repositories. So we have a background process that imports a user’s watches and put tags on them if their description contains one of those common words. That list gets expanded as tags become automatically available to all users, as described in the previous paragraph. For instance, if the initial tags list didn’t contains “orm” as a tag, but more than five users tagged the same repository as “orm”, all repositories whose description contain “orm” will now contain that tag. That makes the community effort a lot easier.

On the other hand, the automatic tagging might not be perfect and a repository might get tagged with an incorrect word. So, if more than five users remove the same tag from a repository, that tag gets automatically removed from that repository to all users.

Unfortunately, we forgot to put this behavior on our web site so users might think they must tag their watches without the system ever helping them. We hope to spread that knowledge with blogs and tweets, since we will get disqualified if we make changes after those 48 hours.

It was a really fun experience. I couldn’t install the necessary software to deploy it on my computer so I used Emmanuel’s one, with Arch Linux and using gvim. I learned a lot!

Emmanuel’s brother-in-law helped us out with the design and the logo, which we really like. It seems that octocat had some troubles keeping his watches organized and got tired of it. :-)

Finally, here’s the website: http://www.githubdamper.com. We hope you find it useful!

Even more powerful Goolge Visualizations for Ruby on Rails

Ok, now you can easily implement a Google Visualization API data source on rails. But… are you still using javascript to render them?

Well, you don’t need to do that anymore. Now rgviz-rails supports a pretty simple and powerful way to do it. In your views templates you now have an rgviz function. You use it like this:


<%= rgviz :id => 'my_visualization',
:kind => 'BarChart',
:url => '/some_endpoint',
:query => 'select country_name, sum(age) group by country_name',
'options' => {:width => 640, :height => 480, :is3D => true}
%>

Not a single line of javascript code.

Yes, I know. You have a combo box and when the users changes its value you need to refresh the visualization, right? You can do it with what I call “magic names”, hehe.

Read more about this. :-)

Powerful Google Visualizations for Ruby on Rails

So we have this project in Ruby on Rails where we keep track of several reports. Now we need to do some visualizations with all those reports.

We analyzed several solutions. One was using Google Fusion Tables but we soon realized it was not an easy task: we need to keep our records synchronized with Google. Well, maybe not very hard: have a background process that keeps track of the last date of synchronization and gets all the records whose updated_at date is greater then that, and synchronize. The problem is that some of our records can be deleted, so we would need to mark them as deleted or think of something else, which complicates the main logic of our application. Also our application is pretty simple and complicating it with background processes wasn’t our ideal solution.

Then we though about just using the Google Visualization API. It works by sending a query to an endpoint which returns some javascript code that includes, amongst other things, a table to be used in the visualization. The query can be anything that the end-point understands but Google has it’s own query language, which is used by Google Spreadsheets, for example.

So we started by making one endpoint that just ignores the query and sends what we needed for one of our visualizations. We basically issued an ActiveRecord query, with some sums, custom selects, groups by and joins, and transformed the results into the necessary javascript code. But then we needed another visualization and we had to write another endpoint with yet another query. Soon we realized it would really be nice to have just one endpoint that supports receiving a query, and much better if that query comes in Google’s query language syntax, since people should be familiar with it and we can give the documentation URL to our developers and tell them “This is how you can query our endpoint”.

This is how rgviz and rgviz-rails were born. The first one just implements a query language parser. The second one executes queries with ActiveRecord. So if you have a model named Person and you want to provide an endpoint to query Person data, you just need to write this in a method of your controller:

render :rgviz => Person

One of the nicest things about this is that you can also use associations in your query. So for example if a Person belongs to a City, you could write a query like:

select city_name, avg(age) group by city_name

Another nice thing is that the pivot clause is fully supported. And the endpoint will always execute your query in just one SQL query, and an efficient one.

Building an application to track expenses in one hour using GeoChat

Whenever one of our team member travels to another country we tell her to track expenses like food, transportation and accomodation so that later that money can be refunded. Each of us does it in a different way: we write it in a notes application in a cellphone, or in a text file in our computer, or maybe in a web application. The problem with the two first approaches is that the information might be lost: the machine might crash or be lost. The last approach is ok, but then you need to remember to connect to the internet to track the expense, and that can happen several hours after having paid, and our memory is not very good.

So I wanted to simply send an sms message to some number to track my expenses. I carry my cellphone all the time so I can send an sms immediately after paying something. Such an application seems very hard to do at first, specially because of the messaging component: receiving sms, configuring a number, etc. Doesn’t it?

Well, we have GeoChat! GeoChat is an application that lets you create groups of people to stay in touch with them. When a message is sent to a group it will be broadcasted to every member. And not necessarily to their mobile phone: each user can decide to receive emails, twitter updates, an instant message to their jabber client, etc. The original use case is for people in the field to report emergency and disaster situations to recover from them as quickly as possible. But that doesn’t mean we can use it for other purposes.

For example, one thing that you can do is configure a group in GeoChat to forward some or all of the messages to an external service. You can also configure GeoChat not to broadcast its messages.

So here’s the idea: we’ll create a group and we’ll configure it to send every message to an external service. This service will receive messages like “shopping $20″ or “accomodation $300″.

So I started coding it and in one hour I got it working! This new tool is called Xpenz.

That shows us how easy is to build some applications on top of GeoChat. In fact, here we are not using much of GeoChat’s power, mainly the messaging component. For this you could instead use Nuntium, but I decided to use GeoChat since a lot of messaging is already configured for me and I also had the authentication problem solved.

The code is in Google Code, so it’s open source. Let’s review the main logic:

class TrackController < ApplicationController
  def expense
    name = params[:sender]
    if name.blank?
      head 'bad_request'
    else
      User.track :user => name, :message => request.raw_post
      head 'ok'
    end
  end
end

So basically we are getting the sender query parameter, which is the GeoChat login name, and if it is present we track the expense by using the request raw post body. And here’s User#track:

def self.track(options)
    user = User.find_or_create_by_name options[:user]
    pieces = options[:message].split(' ')
    pieces.map!{|x| x.start_with?('$') ? x[1 .. -1] : x}

    numbers = pieces.select{|x| x.float?}
    texts = pieces.select{|x| !x.float?}
    text = texts.join(' ')

    if numbers.length == 0
      user.currency = text
      user.save!
    else
      if numbers.length == 1
        amount = numbers[0].to_f
      else
        amount = numbers.last
        numbers[0 .. -2].reverse.each{|n| text = "#{n} #{text}"}
      end
      Expense.create! :user => user, :amount => amount, :reason => text, :currency => user.currency
    end
  end

So the first line finds or create the user in xpenz for the GeoChat user. Then we split the message in spaces and do some logic do termine whether it’s a currency change or an expense track.

The main point here is that I just had to write about 20 lines of code to make it work. Well, maybe 50 because I tested it. ;-)