emporio armani,fake rolex for sale,rolex sea dweller,panerai,iwc,richard mille,replica watches,bell ross,a lange sohne,cheap replica watches,jaeger lecoultre,rolex explorer,corum,rolex milgauss,breguet,piaget,franck muller,chopard
Archives for category: Programación

I have a collection of users who store their favorite stuff id’s in an array, like this:

2.3-head :212 > User.each{ |u| puts u.inspect }
 => #<User _id: BSON::ObjectId('587356c45973747b77f1a35c'), favorite_ids: [1, 3, 5]>
 => #<User _id: BSON::ObjectId('587356c45973747b77f1a35d'), favorite_ids: [7, 3, 5, 2, 8]>
 => #<User _id: BSON::ObjectId('587356c45973747b77f1a35e'), favorite_ids: [3, 2, 7]>
 => #<User _id: BSON::ObjectId('587356c45973747b77f1a35f'), favorite_ids: [1, 10]>

I want to find those users who have favorited items 2, 3 and 8, and get them sorted by number of matchings.

class User
  def self.find_matches(array)
    User.collection.aggregate([
      { "$match" => { favorite_ids: { "$in" => array } } },
      { "$unwind" => "$favorite_ids" },
      { "$match" => { favorite_ids: { "$in" => array } } },
      { "$group" => { _id: "$_id", match_count: { "$sum" =>1 } } },
      { "$sort" => { match_count: -1 } }
    ])
  end
end

Finally:

2.3-head :228 >   User.find_matches([2,3,8]).entries
 => [{"_id"=>BSON::ObjectId('587356c45973747b77f1a35d'), "match_count"=>3}, {"_id"=>BSON::ObjectId('587356c45973747b77f1a35e'), "match_count"=>2}, {"_id"=>BSON::ObjectId('587356c45973747b77f1a35c'), "match_count"=>1}]

I’ve been trying to set up a Motion-JPEG streaming with ruby, for a webcam which uploads a picture per second to a server. I want new images to be served via streaming instead of making the browser call them every second via a javascript call.

I found many different solutions, some of them including EventMachine, which now is not necessary thanks to the new Sinatra 1.3 streaming feature.
The tricky part was related to the headers, the boundary, and the need to send the content type before each image.

For the test I first created a directory and stored some pictures inside

mkdir /tmp/images
# place some jpg pictures here

And the code. My little app looks like this:

# motion_stream.rb
require 'sinatra'
set :server, :thin

get '/' do |dir|
  boundary      = 'some_shit'
  source_dir    = '/tmp/images'

  headers \
    "Cache-Control" => "no-cache, private",
    "Pragma"        => "no-cache",
    "Content-type"  => "multipart/x-mixed-replace; boundary=#{boundary}"

  stream(:keep_open) do |out|
    while true
      file        = random_file(source_dir) # see also latest_file() below
      content     = File.open("#{source_dir}/#{file}", 'rb') { |f| f.read }

      out << "Content-type: image/jpeg\n\n"
      out << content
      out << "\n\n--#{boundary}\n\n"

      sleep 1
    end
  end
end

## get a random image from a directory
##
def random_file(dir)
  files = Dir.entries(dir).collect { |file| file }
  files -= ['.', '..']
  files[rand(files.size)]
end

## ... or get the newest image
## In this case I'm not taking the latest file
## uploaded by the camera, but the previous one.
## This is to avoid grabbing a currently uploading
## file, which may be shown as corrupt or incomplete.
##
def latest_file(dir)
  files = Dir.entries(dir).collect { |file| file }.sort { |file2,file1| File.mtime(dir+file1) <=> File.mtime(dir+file2) }
  files -= ['.', '..']
  files[1]
end

Then simply create a Gemfile including Sinatra and Thin, as WebRick is not evented and does not support this kind of stream.

# Gemfile
source :rubygems

gem 'sinatra'
gem 'thin'

And that’s all. Run the app and you’re done.

ruby motion_stream.rb

Just visit http://localhost:4567/ with your browser :-)

Have you ever written a Facebook application?
One of the most common problems for iframe apps is making canvas auto-resize. It’s solved this way:

    <div id="fb-root"></div>
    <script>
      window.fbAsyncInit = function() {
        FB.init({appId: 'YOUR_APP_ID_HERE', status: true, cookie: true, xfbml: true});
        FB.Canvas.setAutoResize();
      };

      (function() {
        var e = document.createElement('script'); e.async = true;
        e.src = document.location.protocol +
          '//connect.facebook.net/en_US/all.js';
          document.getElementById('fb-root').appendChild(e);
      }());
    </script>

Place this snippet after the body tag, and set your application (at facebook developers config center) to be auto-resizable. And that’s it!

Other common problem is how to make window scroll up when you click on a link. Usually the page renders but leaves you at the same vertical position you were before clicking.
If you are suffering this and you are using jquery, you can solve it this way:

    <script type="text/javascript">
      jQuery(document).ready(function($) {
        scrollTo(0,0);
        FB.Canvas.setSize({width: 760, height:$('body').height()+20});
      });
     
      function scrollTo(x,y){
        $("body").append('<iframe id="scrollTop" style="border:none;width:1px;height:1px;position:absolute;top:-10000px;left:-100px;" src="http://static.ak.facebook.com/xd_receiver_v0.4.php?r=1#%7B%22id%22%3A0%2C%22sc%22%3Anull%2C%22sf%22%3A%22%22%2C%22sr%22%3A2%2C%22h%22%3A%22iframeOuterServer%22%2C%22sid%22%3A%220.957%22%2C%22t%22%3A0%7D%5B0%2C%22iframeInnerClient%22%2C%22scrollTo%22%2C%7B%22x%22%3A'+x+'%2C%22y%22%3A'+y+'%7D%2Cfalse%5D" onload="$(\'#scrollTop\').remove();"></iframe>');
      }
    </script>

Same as before, place this snippet after the body tag and you’re done.

I don’t remember where I got these snippets. Just wanted to share them because they’re really useful, and because I usually forget them and have to rescue backups of older apps heheh

Hope it helps!

Those who know me also know that one thing I’m specially concerned about is the importance of writing good documentation on everything you do. Specially for technical projects. Maybe it is not important for coders or designers, but for a sysadmin I think it should be definilety mandatory. If you get cool things working together but you don’t write any documentation, you won’t be able to play that music again.

Also, I am working in Ruby on Rails development since about 2 years ago. One of the things I have to do usually is to set up servers for hosting projects. And sometimes I have to set up a server for project development and tracking. These are the steps you can follow to set up a Ruby on Rails based server for development tracking.

1. Get a server

There are plenty of choices around the internet, some of them come completelly installed and prepared for deploying your app. They usually work the same way traditional LAMP hostings used to do, but using ssh key authentication instead of FTP sessions… some of them have also web based backend panels for deploying, migrating and managing your app gems.

I prefer to set up an empty GNU/Linux vanilla server, so that I can host everything I need, my way, no worries if PHP, Ruby or whatever. I can set up a relay mailserver, netfilter routing, traffic shaping, services for monitoring and differential backups that I can periodically rsync to my office local server. This is the way a sysadmin thinks, something that coders not always understand.

If you want to set up a development server I recomment you to take a look at most basic Linode VPS. Their control panel will let you run and destroy any Linux distro, setup and resize partitions, add failover addresses, disk space, processor and memory. And of course you’ll have full SSH root access. So I find it very useful and flexible for my needs.

Some considerations:

  • You’ll have to set up a DNS name for the server IP, i.e: http://devel.somedomain.net
  • You’ll need root access on the server. I’ll suppose you are working on a local computer, remotely logged via SSH to your server
  • I usually build my servers using Debian (Lenny for now), but a basic knowledge of any other distro package system will let you adapt my guide to your preferred system
  • I’ll suppose you’ve set up a specific environment for running your app on the development server (I usually call it beta)

2. Install screen

You may partially lose your work if for any reason your local computer hangs during the process. So it’s recommendable to install and use screen for working on a detachable console terminal. This way, if your computer shuts down, you’ll be able to boot again, ssh into your server and recover your screen session.

apt-get install screen

You’ll maybe want to set up your screen sessions to look nicer than withe on black, and give you some additional information of the remote system. I use a copy of the screenrc configuration file from my friend r0sk, it’s simple and nice and works sweet.

wget -c http://ivanhq.net/stuff/_screenrc
mv _screenrc ~/.screenrc

Enter screen

screen

3. Base system

You’ll need an unprivileged user to host your web apps. I usually create a web user

mkdir /home/web
groupadd service
useradd -d /home/web -s /bin/bash -g service web
chown -R web:service /home/web/
passwd web        # type your preferred password here

Add contrib and non-free repositories to your Apt sources file (vim /etc/apt/sources.list)

deb http://ftp.us.debian.org/debian lenny main contrib non-free
deb-src http://ftp.us.debian.org/debian lenny main contrib non-free

Update your sources and then your system

apt-get update
apt-get upgrade

Edit your SSH server config file to disallow root login and enable SSH key authentication (vim /etc/ssh/sshd_config)

# change next line, swap "yes" for "no"
PermitRootLogin no
 
# uncomment next line
AuthorizedKeysFile      %h/.ssh/authorized_keys

Restart your SSH service

/etc/init.d/ssh restart

Install build-essentials for compiling and installing the environment dependencies

apt-get install build-essential

Install Postfix for using as MTA relay server, or MySQL Debian packages will install Exim (which I don’t really like)

apt-get install postfix

# select: internet site
# MTA's outgoing domain name: somedomain.net

4. Backports

Because of some software versions being old and deprecated on the APT sources, and some other not being present, an alternative repository can be set up for installing newer versions. The backports repository.

wget -O - http://backports.org/debian/archive.key | apt-key add -

Edit your APT sources file (vim /etc/apt/sources.list)

deb http://www.backports.org/debian lenny-backports main contrib non-free

Update your system again

apt-get update

5. MySQL

Install mysql service, and its ruby bindings package

apt-get install mysql-server mysql-client libmysqlclient15-dev libmysql-ruby

Create a database for your project (mysql -uroot -p)

mysql> CREATE DATABASE yourapp_beta;
mysql> GRANT ALL PRIVILEGES ON yourapp_beta.* TO yourapp_username@localhost IDENTIFIED BY 'your_superhacker_password123';

6. Ruby, Rubygems and Rails

Install the Ruby stuff, I prefer to use backports at this point to ensure latest versions.

apt-get -t lenny-backports install ruby1.8-dev ruby1.8 ri1.8 rdoc1.8 irb1.8 libreadline-ruby1.8 libruby1.8 libopenssl-ruby

Add unversioned links for the newly created binaries

ln -s /usr/bin/ruby1.8 /usr/local/bin/ruby
ln -s /usr/bin/ri1.8 /usr/local/bin/ri
ln -s /usr/bin/rdoc1.8 /usr/local/bin/rdoc
ln -s /usr/bin/irb1.8 /usr/local/bin/irb
ln -s /usr/bin/gem /usr/local/bin/gem

Install Rubygems from source, so you can update it directly whenever you want. Otherwise the system will update it for you, only when new packages for your distro are available.

cd /usr/local/src
wget -c http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz
tar zxvfp rubygems-1.3.7.tgz
cd rubygems-1.3.7
ruby setup.rb

Link gem binary to an unversioned name

ln -s /usr/bin/gem1.8 /usr/bin/gem

Update rubygems (not really needed, but just in case)

gem update
gem update --system

Install Rails

gem install rails

7. Image processing

Youll surelly want a plugin for cropping and thumbnailing images, maybe attachment_fu or paperclip. They both can work with Imagemagick.

apt-get install imagemagick

8. Apache

There are different web server layouts for hosting your application. Some people likes Nginx+Mongrel, some other prefer Apache+Passenger, others prefer Nginx+Passenger… I love Apache. Maybe because its syntax simplicity, its flexibility or maybe simply because as a sysadmin I’ve been working for years with it.

Install Apache

apt-get install apache2.2-common apache2-mpm-prefork apache2-prefork-dev libssl-dev

Rename default virtualhost

a2dissite default
mv /etc/apache2/sites-available/default /etc/apache2/sites-available/devel_somedomain_net

Edit that virtualhost (vim /etc/apache2/sites-available/devel_somedomain_net)and configure it with the minimum options to work. I’m adding a basic HTTP authentication so only people you give the password can see your project (it’s a development server heheh).

<VirtualHost *:80>
        ServerName devel.somedomain.net
        RailsEnv beta
        DocumentRoot /home/web/sites/devel.somedomain.net/current/public
 
        CustomLog /var/log/apache2/devel_somedomain_net/access.log combined
        ErrorLog /var/log/apache2/devel_somedomain_net/error.log
 
        <Directory /home/web/sites/devel_somedomain_net>
                AuthType Basic
                AuthName "Members Only"
                AuthUserFile /home/web/sites/.htpasswd_devel_somedomain_net
                <limit GET PUT POST>
                        require valid-user
                </limit>
        </Directory>
</VirtualHost>

Enable your new virtualhost

a2ensite devel_somedomain_net

As the unprivileged user running the service, create the application directory and the HTTP Auth passwords file

su - web
mkdir -p /home/web/sites/devel.somedomain.net
 
htpasswd -c /home/web/sites/.htpasswd_devel_somedomain_net username1
htpasswd /home/web/sites/.htpasswd_devel_somedomain_net username2
....

exit

Create the apache log directory for your app

mkdir -p /var/log/apache2/devel_somedomain_net

Install Passenger

gem install passenger
passenger-install-apache2-module

Create a file for loading passenger module into Apache (vim /etc/apache2/mods-available/passenger.load). Be careful with versions on the names as they may have changed.

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.15/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.15
PassengerRuby /usr/bin/ruby1.8

Enable passenger module

a2enmod passenger

Change the user and group executing Apache service to match your unprivileged user (vim /etc/apache2/envvars)

#export APACHE_RUN_USER=www-data
#export APACHE_RUN_GROUP=www-data
export APACHE_RUN_USER=web
export APACHE_RUN_GROUP=service

Restart Apache

/etc/init.d/apache2 restart

9. Git and Gitosis

If you don’t want to pay a Github account and you don’t want your source to be visible to everyone, you’ll want to host your own Git server. There are different choices for that, but I like Gitosis because it’s simple and I can manage it from my command line, only editing a config file.

Install Git

apt-get -t lenny-backports install git-arch

Gitosis is written in Python, so you need to install python’s setup-tools in order to install Gitosis

apt-get install python-setuptools

Clone and install Gitosis

cd /usr/local/src
git clone git://eagain.net/gitosis.git
cd gitosis
python setup.py install

Create a new unprivileged user for hosting Gitosis and its repositories. It does not need a password (so it can’t log in) but it needs a shell as all management occours using an SSH session.

adduser \
--system \
--shell /bin/sh \
--gecos 'git version control' \
--group \
--disabled-password \
--home /home/git \
git
 
usermod -g service git

Upload your ssh public key to the server, leave it in /tmp/ and call it user@host.pub being user@host the final string specified into the file itself (ivan@mbp-local, or something similar)

Initialize Gitosis using the SSH key you just uploaded, which will be the Gitosis admin

su - git
gitosis-init < /tmp/ivan\@ibelmonte-mbp.local.pub

In your local computer clone the Gitosis repository so you can manage it from now on

git clone git@devel.somedomain.net:gitosis-admin.git

Enter the gitosis-admin directory and check the contents. It has to show a filename called gitosis.conf and a directory called keydir.

10. Add a repository for your app

Edit the Gitosis config (vim gitosis.conf) and add a new group, formed with one user (or more, separated with spaces), and its repository

[group your_app_name]
members = user1@host1 user2@host2 ...
writable = your_repo_name

Make sure to put user’s keyfiles into the keydir directory, following the previously mentioned format. Upload your changes.

git add .
git commit -a -m "Added user2 to your_app group"
git push

In your local computer you can now create an application and add its files to the repo

rails your_app
cd your_app
git init
git remote add origin git@devel.somedomain.net:your_app.git
git add .
git commit -a -m "Initial import"
git push origin master:refs/heads/master

11. Capistrano

You’ll want to deploy your software to your newly configured server. Capistrano is the best choice I know, since it creates versioned directories to let you roll back and forth, remotely run tasks on the hosted version of your app, place a custom “under maintenance” page, etc…

Install Capistrano

gem install capistrano

Capify your application

cd /path/to/your/app
capify .

Create a recipe (vim config/deploy.rb)

# set a target name, so you can also use it to deploy to a production server

# set :targetname, 'www'
set :targetname, 'devel'
 
if targetname == 'devel'
  set :rails_env, 'beta'
end
 
set :application, "#{targetname}.somedomain.net"
set :deploy_to, "/home/web/sites/#{application}"
set :user, "web"
set :runner, "web"
set :repository, "git@devel.somedomain.net:your_app.git"
set :deploy_via, :remote_cache
set :copy_exclude, [".git", ".gitignore"]
set :scm, :git
set :use_sudo, false
 
# Master branch of course. If not, change
#
# set :branch, master
 
ssh_options[:forward_agent] = true
 
role :app, "#{targetname}.somedomain.net"
role :web, "#{targetname}.somedomain.net"
role :db,  "#{targetname}.somedomain.net", :primary => true
 
namespace :deploy do
  desc "Restarting passenger with restart.txt"
  task :restart, :roles => :app, :except => { :no_release => true } do
    run "touch #{current_path}/tmp/restart.txt"
  end
 
  [:start, :stop].each do |t|
    desc "#{t} task is a no-op with mod_rails"
    task t, :roles => :app do ; end
  end
end

12. SSH keys

In order to deploy your app without typing any password, you’ll have to set up a SSH key authentication between you and the unprivileged user of the server (web user).

Copy the content of your local ssh keyfile (commonly ~/.ssh/id_rsa.pub) and paste at the end of /home/web/.ssh/authorized_keys on the server. You’ll want to repeat this process for each developer so they can also deploy without typing a password.

You’ll also need to generate a SSH key for your web user on the server, and add it as a member of the repo in gitosis. Otherwise you won’t be able to deploy your app, because the server won’t let itself access to the repo for fetching.

13. Redmine

Redmine is one of those powerful tools that make your life easier when working with other developers, designers, webmasters and CEO’s… it helps you to keep tracking of issues, bugs, timings, files and documents, wikis and it also lets you graphically browse your repositories. If you’ve never tested it, now it’s your time.

NOTE: you’ll need to create a new entry on your DNS server. Set up a CNAME called redmine pointing to devel.somedomain.net

Redmine needs mod_rewrite support on Apache

a2enmod rewrite

You’ll need subversion to checkout the source code of Redmine

apt-get install subversion

Su to your unprivileged user

su - web

Checkout the code

cd sites
svn co http://redmine.rubyforge.org/svn/tags/1.0.1/ redmine.somedomain.net
cd redmine.somedomain.net

Create a database for redmine (mysql -uroot -p)

mysql> CREATE DATABASE redmine CHARACTER SET utf8;
mysql> GRANT ALL PRIVILEGES ON redmine.* TO redmine@localhost IDENTIFIED BY 'redmine123';

Edit Redmine’s database configuration file (vim config/database.yml)

production:
  adapter: mysql
  database: redmine
  host: localhost
  username: redmine
  password: redmine123
  encoding: utf8
  socket: /var/run/mysqld/mysqld.sock

Place a secret key for Redmine cookies on its environment file, inside the Initializer block (vim config/environment.rb)

config.action_controller.session = { :key => "_redmine_somedomain_com_session", :secret => "578359e95c3f2sj9enw10amkd81508ff" }

Migrate the database

env RAILS_ENV=production rake db:migrate

Edit the SMTP configuration for Redmine to be able to send notification emails (vim config/email.yml)

production:
  delivery_method: :smtp
  smtp_settings:
    address: "smtp.somedomain.net"
    port: '25'
    domain: "somedomain.net"
    authentication: :login
    user_name: "your_username"
    password: "your_password"

If you want to relay over Gmail or your domain’s email is hosted on Google apps, you’ll need to install a tls authentication plugin

ruby script/plugin install git://github.com/collectiveidea/action_mailer_optional_tls.git

Use this config for use with Gmail / Google apps

production:
  delivery_method: :smtp
  smtp_settings:
    tls: true
    address: "smtp.gmail.com"
    port: '587'
    domain: "gmail.com"   # use "somedomain.net" in case of Google Apps
    authentication: :plain
    user_name: "your_username"
    password: "your_password"

Exit su, and become root again

exit

Create a new Apache virtualhost (vim /etc/apache2/sites-available/redmine_somedomain_net)

<VirtualHost *:80>
        ServerName redmine.somedomain.net
        RailsEnv production
        DocumentRoot /home/web/sites/redmine.somedomain.net/public
 
        CustomLog /var/log/apache2/redmine_somedomain_net/access.log combined
        ErrorLog /var/log/apache2/redmine_somedomain_net/error.log
</VirtualHost>

Create an Apache log directory for redmine

mkdir /var/log/apache2/redmine_somedomain_net/

Enable your new virtualhost and restart Apache

a2ensite redmine.somedomain.net
/etc/init.d/apache2 restart

14. Start writing Ruby on Rails

Here comes the funny part. Enjoy! ;-)

I am generating an XML file for dumping some data from one application to another. Yes, I know it’s nicer to build a RESTful API, but it’s for a very custom scenario and the shorter way is to write an XML based interface. So I simply export some contents:

def show_some_content
  @content = Content.find(:all)

  respond_to do |format|
    format.xml
  end
end

For my view:

<%= @content.to_xml %>

The problem then is the resulting XML has not only escaped the HTML entities, but also latin characters (ie accents and tildes). After googling for an hour I’ve found some people blaming to_xs method (HTML escaped version of to_s, as its definition says) used for XML serialization.

Well, from the other app I need to parse this XML and get the original text. How the hell do I get latin chars unescaped again?

require 'cgi'
require 'iconv'

encoded_text = "ram&#243;n"
# some fucking encoded text coming from the XML

puts "#{Iconv.iconv('UTF-8', 'ISO-8859-1', CGI.unescapeHTML(encoded_text)).to_s}"
# => "ramón"

That’s it :-)

I love vim for editing everything, no matter if it’s code, config files, a note or a to-do list. I use it with a lot of plugins and config snips for doing things I need as file browsing, file searching, window splitting, tabbing etc… and I was trying to find a good plugin for folding code. After finding Simplefold and not being able to make it work, i found a config snippet Stackoverflow which works like a charm.

Once more I have to say: I’M LOVING VIM!!

Yesterday I did a talk at Xing offices in Barcelona. It was about some tips on how to send emails massively from a Ruby on Rails application without being tagged as a spammer by Hotmail, Gmail or Yahoo. I’m not a dedicated expert on this, but I’ve been learning these things while developing last internet site, and I thought it may be also interesting for other developers.
Here are the slides (in english) of the presentation, formerly named “Massive emailing with Linux, Postfix and Ruby on Rails“.

Here is the PDF for downloading.

DIOS!! esta es de las cosas más fuertes que he visto en internet en los últimos años… El dominio de Ruby On Rails (rubyonrails.org) está en parking!!

He mirado el registro del whois, y veo que el dominio ha caducado. Desde hoy mismo (23 de Abril 2009, día de Sant Jordi) pertenece a unos registradores masivos, de estos que te secuestran el dominio y luego te piden $15.000 por el.
Y desde luego la culpa no es de los bulk registers, sino del propietario anterior del dominio. Yo siempre me preocupo de renovar mis dominios antes de que caduquen.
Y es que en realidad el hecho de que se lo hayan quitado significa, no sólo que no se ha preocupado de renovarlo, sino que también se le ha pasado el periodo de redención (1 o 2 semanas, ahora no estoy seguro).

Bueno ahora la gran pregunta es dónde encontrar la documentación de la API, algo que uso a diario, y que ahora desde Gotapi no está disponible.

Qué es lo que ha pasado??? y ahora que????

EDIT: son las 20:31 y ya está funcionando again. No sé qué es lo que ha pasado, pero en 1 minuto se me ha venido el mundo encima. Se da uno cuenta de lo frágiles que somos, y lo delgada que es la cuerda sobre la que caminamos…

Pair programming es una técnica en la que dos programadores trabajan con una misma consola, sobre el mismo código. Normalmente uno hace la función de driver y el otro la de observer. El objetivo es evidente: crear un mejor código, a la vez que conseguir que ambos programadores lo conozcan con el mismo nivel de profundidad.

Hoy tenía un problema con el proyecto en el que estoy trabajando, y pedí a Mauro que me echase un cable a ver si entre los dos conseguíamos solucionarlo. Él estaba en su casa, y yo en la mía. Los ingredientes para cocinar un pair programming realmente fluído en remoto:

  • Port forwarding: un puerto para el acceso remoto por SSH y otro para el acceso al servidor de aplicaciones (acceso web)
  • screen: Usando una versión ligeramente modificada del screenrc de r0sk. Usamos tres consolas: [0] log del servidor, [1] vim con el código, [2] una bash para hacer accesos de mysql u otras cosas que necesitemos
  • vim: con los controles mapeados para trabajar con tabs, y el plugin de FuzzyFinderTextMate para buscar y abrir archivos… así se puede hacer todo en una sola consola
  • Skype: Para hablar todo el rato durante la sesión de programación

Los programadores maceros que usan TextMate suelen hacer el pair programming usando VNC, pero aunque no lo he probado pongo las dos manos en el fuego a que tiene que ser una cagada. La pareja screen+vim es brutal por lo lightweight y lo flexible, y consume muy poquito ancho de banda con lo que la comunicación del conjunto (ssh + skype) es perfecta.

La experiencia ha sido GENIAL, y hemos resuelto el problema en aproximadamente 1 hora. Es como trabajar en pair programming en local, tocando el mismo código y comentando todo el rato. Ha sido una pasada, y lo recomiendo a todos los programadores que trabajen separados físicamente del resto del equipo.

SPANISH: Al considerar este artículo de interés común y dado que no he encontrado la explicación en ningún otro sitio, voy a redactarlo en inglés por si puede servir a alguien en un futuro. Si hay algo que no se entienda bien, no dudéis preguntármelo.

I’m working on an online app about auctions. A lot of the users coming to register don’t complete the email confirmation process, although I advise it in a red huge font at the login form. Most of the time I’m getting emils of users saying they registered but can’t login. When I look into the database, they didn’t activate their accounts.

Well, finally our CEO’s decided to remove the activation process. And this is when I’ve been googling for hours without luck, nobody explains the way to do it. Well no problem, it hasn’t been difficult at all. This is the way: a user is active if its activation_code in the database is Null.

  • Edit models/user.rb and remove this filter
    before_create :make_activation_code
    
  • In the same models/user.rb file, remove the activate method (we’re not activating any more user)
  • In the same models/user.rb file, remove the make_activation_code method (it’s almost at the end of the file).
  • Now edit controllers/users_controller.rb, remove completelly the activate method
  • In the same controller/users_controller.rb file, in the create mehod, set the activated_at time before saving the user
    @user = User.new(params[:user])
    @user.activated_at = Time.now.utc  # <--- add this line
        if @user.save
        [...]
    
  • Edit models/user_mailer.rb and completelly remove the activation method
  • Remove the file views/user_mailer/activation.html.rb
  • Edit the file views/user_mailer/signup_notification.html.erb and set the message as you like (variables are coming from models/user_mailer.rb)
  • Restart your app and test

I'm sure there are better ways, and I'm not the best coder in the world, but this way works for me. Maybe it will help someone one day...