Saturday, February 19, 2011

Let facebook connect to your pc using reverse ssh tunnel from free Amazon AWS EC2

Developing facebook app (or facebook connect/login/register) on developing workstation requires a callback URL where facebook will forward a user after user approval. Amazon.com is offering a cloud EC2 micro instance to any new user free for one year. And since each EC2 instance has a real IPv4 IP, we can easily utilize that for facebook's required callback url. Well, its not that easy to upload development code to EC2 instance every time that I need to test. The solution is reverse ssh tunnel from EC2 instance to my local pc behind NAT or firewall.

Reverse ssh tunnel allows you use an encrypted tunnel for forwarding a connection to a remote host to your local workstation. To use reverse ssh tunnel one need to open a port from EC2 firewall configuration. I am running Ubuntu 10.04 LTS ami but this should work on all Linux instances.

Say I want to open 9000 port on my EC2 instance. I assume that I am using the 'default' security group (each security group consists of set of firewall rules). To do so, run the following from ec2 command line tool -

ec2-authorize default -p 9000


Also authorize ssl port 22 if done yet.

ec2-authorize default -p 22


Now log in to your ec2 instance and check if the following options exist in /etc/sshd_config file or not. If not, append the the lines to file.

AllowTcpForwarding yes
GatewayPorts yes

Now make the reverse ssh tunnel -

ssh -nNT -R0.0.0.0:9000:localhost:3000 <username>@<ec2_public_dns_or_ip> -i <your_private_key_file_that_ends_with_pem>


(Thanks to Vincent Danen for his tutorial Setting up a reverse SSH tunnel where he shows how to do reverse ssh without opening a terminal). Here is description of the parameters:

-n prevents reading from standard in
-N just set up a tunnel, without opening a console for executing command
-T disable pseudo tty allocation
-R reverse ssh tunnel. This parameter option must be followed by [bind_address:]port:host:hostport
-i your identity file (private key)


Thats it! Now point your browser to
http://<ec2_public_dns_or_ip>:9000

enjoy :)

Saturday, December 6, 2008

Some months with RSpec


For several months, I have been writing test-case ahead of any implementation. But the joy multiplied when we started thinking BDD. To me using RSpec as BDD tool is not much different than Rails default test mechanism other than the representation, unless you try the Story.

Test first development has a big advantage that you consider all possible scenarios before writing code. Yet sometimes you may miss some lines covered. An wonderful gem you require to check test coverage in Ruby is rcov. And no wonder RSpec has built-in support for rcov :) To test you code coverage, run
rake spec:rcov

This will create a folder named "coverage" on your rails root. Open the index.html from that folder in your browser to see how much your code is covered by test case. The screenshot is a polling script I just started.

Monday, December 1, 2008

Show numeric digit in your language

My previous post was about a Ruby on Rails plugin I wrote to convert any numeric digit to other languages' representations. Here is the internals; how that works.

That plugin converts a whole string character by character. To add any language, just add that language's digits to "NUMERIC_LOCALIZE_MAP" hash.


NUMERIC_LOCALIZE_MAP = {
'bn' => ["","","","","","","","","",""],
'hi' => ["","","","","","","","","",""],
'ar' => ["٠", "١","٢","٣","٤","٥","٦","٧","٨","٩"]
}

def localize_numeric(source, locale_code = nil)
string_representation = source
result_string = nil

if locale_code && NUMERIC_LOCALIZE_MAP.include?(locale_code)
result_string = string_representation.gsub(/\d/){|digit|
NUMERIC_LOCALIZE_MAP[locale_code][digit.to_i]
}
else
result_string = string_representation
end
result_string
end

Tuesday, November 25, 2008

Ruby on Rails plugin to localize numeric digits (translate to any language)

Probably somewhere in... is the first company to build Bangla web2.0 solutions using rails. The first problem we faced is the lack of support for Unicode in Ruby. But fortunately we rarely needed to use string funtions and thus avoid the consequence. Secondly, we needed a stable and efficient il8n library(plugin) for Ruby on Rails to translate the interface (we had planned to roll out with support for two language initially). The rescue came from globalize plugin. Its pretty old and no update for quite a while, yet this robust plugin suits the best to our need. The translation list is backed by database. So, you can easily create admin panel to manage translation list.

Then we felt the need for another feature; representing numeric digits to local language. And its better if that can work seamlessly with our existing code written using globalize plugin. The plugin globalize_numeric, with globalize, can translate your digits to any language (currently have Banga, Hindi, and Arabic) with minimal change in code that uses globalize for localization.

To add other language, add the language digits to NUMERIC_LOCALIZE_MAP in 'lib/core_ext.rb' file.

Plugin's github repository

Monday, November 24, 2008

Converting Bangla (Bengali) digits to ascii ones

ruby 1.8 doesn't support unicode. This creates problem when I need to parse Bangla digits in a text where each Bangla digit is represented as three bytes in utf-8.

I used a simple approach to satisfiy my need - 1. take the the last byte of each bangla digit, and 2. subtract by last byte of bangla digit '0'. Converting the whole number is even simpler. Here is my code -

  def self.translate_number_from_bangla(p_bn_number)
en_number = 0
length = p_bn_number.length
for i in 1..length/3 do
cur_digit = p_bn_number[3*i-1].to_i - 166
if cur_digit >= 0 && cur_digit <= 9
en_number *= 10
en_number += cur_digit
end
end
return en_number
end

Tips: Update your rubygems (with special case)

The most suggested updating technique is
$ sudo gem update --system


But this technique may not work with rubygems version 1.1 and 1.2. run
$gem -v

to know your rubygems version.

For those having these two versions, install rubygems-update gem and then run update_rubygems command (as sudo if necessary)

$ sudo gem install rubygems-update
$ sudo update_rubygems

Tuesday, April 15, 2008

View offline documentation of installed ruby gems

From command line, just run this -
$ gem server

This will start ruby documentation server on port 8088

previously it was
$ gem_server

which is now deprecated and may not work in your system