Posts Tagged ‘gem’

Gmail and OAuth, Ruby developers haz it

You’ve probably heard about Google launching OAuth to access Gmail and Google Apps Mail.

Developers can now grab emails thanks to the IMAP protocol, without asking for a password. It’s awesome to see an “old” technology, IMAP, meeting a new one, OAuth. And no need to use a new API.

To help other Ruby developers integrating Gmail+OAuth, we published a new gem, gmail_xoauth. Once installed, you get updated Net::IMAP and Net::SMTP libraries, ready to authenticate via XOAUTH. And of course, it works with Google Apps too.

To authorize on ‘imap.gmail.com’, instead of giving a string password, you give a hash of options so the SASL Initial Client Request will be generated and sent over the wires for you.

require 'gmail_xoauth'
imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
imap.authenticate('XOAUTH', 'roger.moore@gmail.com',
  :consumer_key => 'anonymous',
  :consumer_secret => 'anonymous',
  :token => '4/nM2QAaunKUINb4RrXPC55F-mix_k',
  :token_secret => '41r18IyXjIvuyabS/NDyW6+m'
)
messages_count = imap.status('INBOX', ['MESSAGES'])['MESSAGES']
puts "Seeing #{messages_count} messages in INBOX"

The principle is the same for SMTP:

require 'mail'
require 'gmail_xoauth'
 
mail = Mail.new do
     from 'roger.moore@gmail.com'
       to 'marcel@amont.com'
  subject 'This is a test email'
     body 'Hi!'
end
 
smtp = Net::SMTP.new('smtp.gmail.com', 587)
smtp.enable_starttls_auto
secret = {
  :consumer_key => 'anonymous',
  :consumer_secret => 'anonymous',
  :token => '4/nM2QAaunKUINb4RrXPC55F-mix_k',
  :token_secret => '41r18IyXjIvuyabS/NDyW6+m'
}
smtp.start('gmail.com', 'roger.moore@gmail.com', secret, :xoauth) do |session|
  session.send_message(mail.encoded, mail.from_addrs.first, mail.destinations)
end

Feel free to fork the public github repository and add new features !

Note: we just launched OAuth support for Gmail and Google Apps Mail on Silentale.

Everyone deserves a Face

FacesA pluggable avatar architecture for universal implementation of avatars from multiple/external sources.

Avatars have become a fundamental building block for any person-orientated web application. Avatars add a spark of life into your site and allow your users to relate to an otherwise faceless name. (Yeah, you liked that one didn’t you?)

As any developer who has worked with implementing an avatars system will know however, it can sometimes be a real pain in the derrière. Usually avatars start in a web application as a quick-fix solution with no thought for later expansion & scaling. This leaves the code isolated so that if you then decide to grow it out later, you’re going to hit some serious road bumps. This is sometimes down to bad planning by the developer and sometimes down to a lack of implementation consistency between multiple gems/plugins. The end result however is the same – it sucks.

I joined Silentale just at the start of January and one of my first tasks was to improve our current avatar architecture. When first starting out on the project I battled with many gems & plugins to try and achieve the result we wanted. When I completed my first build I sat back and looked at my code. The thought that came into my head was:

“What a big pile of dung!”

The reason for this was that to achieve the result we needed, I had to hack together 3 gems, some of our existing avatars architecture and some other messy bits and bobs to just get close to an okay implementation. This resulted in a big pile of slow and yucky code that when the next developer came to… well, I don’t like to think about that.

It was because of this I decided to create Faces. is an open-source gem that I built to rectify the problem we faced at Silentale. It allows developers to pull avatars from multiple external sources by simply providing an identifier and provider name like so:

avatar_url('someone@example.com', 'gravatar')

Pretty neat, huh? Faces can also:

  • Generate/manage a consistent HTML style with classes, ids, alts and sizes
  • Auto-calculate the closest possible size to an image size requested
  • Manage multiple default image sizes
  • A whole load more

Faces is crazily customizable – the entire purpose of the gem is to have a universal method for managing all your different types of avatars. I’d really advise reading the documentation to get the really juicy info on how it works and how far you can take it.

At the moment Faces supports by default the following providers:


Faces is built in such a way to allow developers to add their own providers with ease by either passing Faces a direct avatar URL or building their own provider.rb file (which is so simple that monkeys could do it).

At the moment Faces is only available as a Ruby gem/plugin however I will be releasing it in first PHP and then Python in the near future, so make sure to keep an eye out for that.

Make sure to check it out for implementing your next avatars system – we hope it makes your next project that little bit easier!

Leopard, where are those Ruby gems?

It’s always useful to check the code of those downloaded Ruby gems. You should try for at least two reasons: learning and submitting bugs. It’s always a good idea to give technical details about bugs you encounter. The community is small and responsive, get involved :)

You’re lucky, Leopard user, Apple made a great work embedding Ruby in Mac OS X 10.5. You have the latest version of Ruby, 1.8.6, and RubyGems installed.

Apple guys set a specific directory for all Ruby related things.

/Library/Ruby/Gems/1.8/

This directory contains exploded gems and their documentation. For example, you can examine the content of the ActiveRecord gem and its documentation with those two commands (I hope you use TextMate…).

mate /Library/Ruby/Gems/1.8/gems/activerecord-2.1.0/
open /Library/Ruby/Gems/1.8/doc/activerecord-2.1.0/rdoc/index.html

No need to google “activerecord”, everything’s on you hard drive.

Note: Rubygems has evolved since the release of Leopard. But hopefully, it’s simple to update it. Just download the last version and one simple command will do the work.