RSS on FeedBurner

Update to Yahoo! Mail on Rails 4/7/2007

I got my upgrade to Yahoo! Mail Plus and so have added the ability to read messages to the plugin. For those of you just joining in, check out the original version. Here is what the inbox controller looks like now, detecting whether the user is a Mail Plus user or not and linking to messages as necessary:

class InboxController < ApplicationController
    before_filter :check
    def index
        y = YMail.new(session[:wssid], session[:ycookie])
        user = y.get_user_data
        begin
            if user['data']['userFeaturePref']['hasMailPlus']
                @base = '/message/'
            else
                @base = 'http://mrd.mail.yahoo.com/msg?fid=Inbox&mid='
            end
        rescue
            @base = 'http://mrd.mail.yahoo.com/msg?fid=Inbox&mid='
        end
        @inbox = y.list_messages
        @inbox = @inbox['messageInfo'] if @inbox
    end
end

Actually viewing the message is brainlessly easy, but a bit verbose here to keep the view nice:

class MessageController < ApplicationController
    before_filter :check
    def index
        y = YMail.new(session[:wssid], session[:ycookie])
        message = y.get_message(params[:id])
        if message
            message = message['message'][0]
            if message
                @ok = true
                @subject = message['subject']
                @timestamp = message['receivedDate']
                @from = message['from']
                @cc = message['cc']
                message['part'].each do |part|
                    @text = part['text'] if 'text' == part['type']
                end
            end
        end
    end
end

Download ymail-0.2.tar.bz2 or see it in action.

Comment Tags:

Yahoo! Mail on Rails 4/3/2007

Update: New version, but read this post first.

Update 4-4-2007 @ 10:24am: All’s well again.

Update 4-4-2007 @ 8:44am: My ISP decided last night was a good time to change my IP address. The sample app will be back online soon.

I set out Thursday to produce a sample Rails app using the new Yahoo! Mail API. As it came together I started learning about Rails plugins and have packaged this up for communal consumption. There are two pieces to this — authentication and mail access. This is a very basic starting point, not really a full-fledged app.

I found several attempts at plugins for using Yahoo! BBAuth for authentication, but none were to my liking, so I took a few pages from Erik Kastner and built a BBAuth controller specifically for Mail. This one has one important extra feature — it calls back to Yahoo! after authenticating to pick up a web services session ID (WSSID), which becomes necessary when using the Mail API. My BBAuth "plugin" is implemented as an extension to ActionController::Base and so can be used simply by extending it once again in your LoginController.

class LoginController < BBAuthController
end

The access to Yahoo! Mail is again not a true plugin because I couldn't get the mixin stuff to work. The class YMail is provided as a way to communicate with Yahoo! Mail using the JSON-RPC version of the API. Interestingly, Ruby's SOAP library can't (to my knowledge) send cookies with its SOAP requests, so its useless for the Mail API. I've only implemented a few of the calls currently, but you get the idea. I'll be updating with more as soon as I score a premium account. Using the YMail class is pretty simple, too.

class InboxController < ApplicationController
    before_filter :check
    def index
        y = YMail.new(session[:wssid], session[:ycookie])
        user = y.get_user_data
        if user
            @id = user['data']['userSendPref']['defaultID']
            @name = user['data']['userSendPref']['defaultFromName']
            @from = user['data']['userSendPref']['defaultFromAddress']
            @reply = user['data']['userSendPref']['defaultReplyToAddress']
        end
        @inbox = y.list_messages('Inbox')
        @inbox = @inbox['messageInfo'] if @inbox
    end
end

One headache I still have with this setup is that I can't find a way to pull the check function out of ApplicationController and into the plugin. Advice here from real Rails experts would be awesome. But for the time being, here's what you need to put in your app/controllers/application.rb file. Make sure this is all that's in that file, as the default does something strange to the session.

class ApplicationController < ActionController::Base
 
    # Check that someone is logged in and force them if they're not
    #   Use this in a before_filter where needed
    #   I could not figure out how to put this anywhere better
    def check
        redirect_to :controller => 'login' unless session[:token]
    end
 
end

The last thing is a configuration file to tweak it to your application, which you must register. Put this in config/ymail.yml. If you submit a URL to Yahoo! other than {Your domain}/login/cred, change the application entrypoint in the config file and update your routes accordingly.

application_id: {Your application ID from Yahoo!}
shared_secret: {Your shared secret from Yahoo!}
application_entrypoint: /login/cred

This should be it, all you need now is the actual plugin: Yahoo! Mail on Rails 0.1 Yahoo! Mail on Rails 0.2. See it in action.

See what’s new in 0.2.

2 Comments Tags:

Easier Rails in Ubuntu 7.04 beta 4/1/2007

With the upcoming release of Ubuntu 7, Apache 2.2 will be included in the standard package manager, meaning we no longer have to work in a hybrid managed and from-source environment to get a proper Rails stack up and running. Apache 2.2 added mod_proxy, giving us access to the ProxyBalancer directive that allows Apache to serve as a frontend to several Mongrel application servers.

Here is a quick-and-dirty guide to installing my application stack:

  • Ubuntu 7.04 beta
  • Apache 2.2 with mod_rewrite and mod_proxy
  • Mongrel 1.0.1
  • MySQL 5 (finally)
  • Ruby 1.8.5 and Rails 1.2.3

For starters, get yourself a copy of Ubuntu 7.04 beta and get it installed. No one should have to give you directions on that part. Once that's up and running, we need to turn it into a development environment, so fire up a terminal and bang out the following:

$ sudo apt-get install build-essential

Now open Synaptic Package Manager and select and install mysql-server, libmysqlclient15-dev, ruby, irb, rdoc, ruby1.8-dev, and rubygems. Accept all the dependencies it alerts you to, and move on. Its very important you get ruby1.8-dev installed, or rubygems will not work correctly. I believe this to be an error in Synaptic, but we have to deal.

Now get back to the command line. Using Ruby's Gem installer, its time to finish up the Rails side of our stack. This part is similar to my previous howto for Ubuntu 6.

$ sudo gem install rails --include-dependencies
$ sudo gem install mysql
$ sudo gem install daemons gem_plugin mongrel mongrel_cluster --include-dependencies

Again, accept the dependencies it asks you to build, and accept the highest-versioned, non-win32 option in the menus. At this point you have a fully-functioning Rails environment, so test it out. Start a new rails app and configure a cluster like this:

$ mkdir ~/rails ; cd ~/rails ; rails www
$ mongrel_rails cluster::configure -p 8001 -a 127.0.0.1 -N 3
$ mongrel_rails cluster::start

Test it out by browsing to http://127.0.0.1:8001/ and you should see the Rails welcome screen. If not, you've got something screwy happening and you should ask about it in the comments.

Now its time to get our Apache 2.2 frontend running. Start by using Synaptic to install apache2 (and its dependencies). If you like, include PHP or whatever else you think will be fun. After you've got it all installed, run these commands to enable mod_rewrite and mod_proxy:

$ sudo a2enmod rewrite
$ sudo a2enmod proxy
$ sudo a2enmod proxy_balancer
$ sudo /etc/init.d/apache2 restart

Now add a line to the bottom of /etc/apache2/apache2.conf that directs Apache to your configuration file, which I store in ~/conf/httpd.conf.

Include /home/rcrowley/conf/httpd.conf

In this new config file, wherever you put it, place the following code (replacing whatever you need with new values):

NameVirtualHost *:80
<VirtualHost *:80>
  ServerName richarddcrowley.org
  Include /home/rcrowley/conf/www.conf
</VirtualHost>
<VirtualHost *:80>
  ServerName www.richarddcrowley.org
  Include /home/rcrowley/conf/www.conf
</VirtualHost>

I choose to link out to another config file to keep from repeating myself when configuring both with-www and without-www versions of my sites. In the new file:

DocumentRoot /home/rcrowley/rails/www/public
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://www_mongrel%{REQUEST_URI} [P,QSA,L]
<Proxy balancer://www_mongrel>
  BalancerMember http://127.0.0.1:8001
  BalancerMember http://127.0.0.1:8002
  BalancerMember http://127.0.0.1:8003
</Proxy>

Now you’re pretty much done, but its likely throwing 403 errors at you for most any request. Since this is undesirable behavior, you need to edit /etc/apache2/mods-available/proxy.conf. I found this method to be less-than-helpful, so I commented every line in the file out, restarted Apache, and life became better.

The last thing necessary is making your Mongrel cluster start up with your machine. This is exactly like last time. Create /etc/init.d/mongrel and put this in it:

#! /bin/sh
do_start()
{
  echo "Starting Mongrel..."
  mongrel_rails cluster::start -C ~rcrowley/rails/www/config/mongrel_cluster.yml
}
do_stop()
{
  echo "Stopping Mongrel..."
  mongrel_rails cluster::stop -C ~rcrowley/rails/www/config/mongrel_cluster.yml
}
case "$1" in
  start)
    do_start
    ;;
  stop)
    do_stop
    ;;
  restart|force-reload)
    do_stop
    do_start
    ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
    exit 3
    ;;
esac

Now make it run on startup:

$ sudo update-rc.d mongrel defaults

Go forth and hack.

7 Comments Tags:

Ruby on Rails from source on Ubuntu 1/15/2007

Update: Now that Ubuntu 7.04 beta is out, I tackled this problem again: Easier Rails in Ubuntu 7.04 beta.

A few weeks back I started playing a lot with Rails and got hooked. Everything that I had hacked before was just part of the workflow in Rails. In a bit of good timing, I broke my webserver while trying to upgrade X11 on Gentoo. Clearly it was time to start from scratch and to try Ubuntu. What follows is my way of getting from a blank Ubuntu install to a solid LAMP stack plus Ruby on Rails.

Format notes: a backslash (\) indicates a long line that I wrapped, a $ is a regular terminal and a # is a superuser terminal.

Gathering the pieces

$ su
# cd ~
# apt-get install zlib1g-dev
# wget ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.5\
-p12.tar.gz
# tar xzf ruby-1.8.5-p12.tar.gz
# cd ruby-1.8.5-p12
# ./configure
# make && make install
# apt-get install postfix
# apt-get install mysql-server mysql-common \
mysql-client libmysqlclient15-dev libmysqlclient15off
# apt-get install libmysql-ruby1.8
# wget http://rubyforge.org/frs/download.php/\
11289/rubygems-0.9.0.tgz
# tar xzf rubygems-0.9.0.tgz
# cd rubygems-0.9.0
# ruby setup.rb
# cd ~
# gem install rails --include-dependencies
# gem install mysql
# gem install daemons gem_plugin mongrel \
mongrel_cluster --include-dependencies
# wget http://apache.mirror99.com/httpd/\
httpd-2.2.4.tar.bz2
# tar xjf httpd-2.2.4.tar.bz2
# cd httpd-2.2.4
# ./configure --enable-deflate --enable-proxy \
--enable-proxy-balancer --enable-http --enable-info \
--disable-cgi --enable-rewrite --enable-so
# make && make install

Apache startup script

# vi /etc/init.d/apache

The apache init script should look something like this:

#! /bin/sh
do_start()
{
  echo "Starting apache..."
  /usr/local/apache2/bin/apachectl start
}
do_stop()
{
  echo "Stopping apache..."
  /usr/local/apache2/bin/apachectl stop
}
case "$1" in
  start)
    do_start
    ;;
  stop)
    do_stop
    ;;
  restart|force-reload)
    do_stop
    do_start
    ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
    exit 3
    ;;
esac

Rails setup

As Steven pointed out in the comments, I missed a step. If you have previously built Rails apps, now is the time to copy them onto your Ubuntu system and remember where they are. If you're really starting from scratch, the following command will give you a fresh Rails app called "www" to play with.

$ mkdir ~/rails ; cd ~/rails ; rails www
That last command, rails www is where the magic happens. That generates the skeleton of a Rails app for you to fill in. See OnLamp for a good intro to building a Rails app.

Mongrel cluster wrangling

Before we can serve a Rails app properly, we need a Mongrel cluster. These steps are nearly verbatim what is prescribed by Coda Hale. I find it to be pretty tasty, myself.
$ cd ~/rails/www
$ mongrel_rails cluster::configure -p 8001 \
-a 127.0.0.1 -N 3
$ mongrel_rails cluster::start
Now would be a good time to test the URL http://127.0.0.1:8001/ in a browser to see your Rails app working properly. Once it is, stop the cluster so we can setup the script that will start it at boot. This is pretty much exactly like the apache script (which is pretty much exactly like the Ubuntu skeleton script).
$ mongrel_rails cluster::stop
# cp /etc/init.d/apache /etc/init.d/mongrel
# vi /etc/init.d/mongrel
4,5c4,5
<       echo "Starting apache..."
<       /usr/local/apache2/bin/apachectl start
---
>       echo "Starting mongrel cluster..."
>       mongrel_rails cluster::start -C ~rcrowley/\
rails/www/config/mongrel_cluster.yml
9,10c9,10
<       echo "Stopping apache..."
<       /usr/local/apache2/bin/apachectl stop
---
>       echo "Stopping mongrel cluster..."
>       mongrel_rails cluster::stop -C ~rcrowley/\
rails/www/config/mongrel_cluster.yml

Install the init scripts

# update-rc.d apache defaults
# update-rc.d mongrel defaults

Put the puzzle together

Again following the gospel according to Coda, this is how to beat the entire system together. First uncomment the line that includes conf/extra/httpd-vhosts.conf in the main apache conf/httpd.conf file. Then we can setup virtual hosts in that file. Something like
NameVirtualHost *:80
<VirtualHost *:80>
  ServerName richarddcrowley.org
  Include conf/extra/www.conf
</VirtualHost>
<VirtualHost *:80>
  ServerName www.richarddcrowley.org
  Include conf/extra/www.conf
</VirtualHost>

will do just fine. You'll notice that I left a lot out by including conf/extra/www.conf. Indeed. That is where we'll do all the fun stuff:

DocumentRoot /home/rcrowley/rails/www/public
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://www_mongrel\
%{REQUEST_URI} [P,QSA,L]
<Proxy balancer://www_mongrel>
  BalancerMember http://127.0.0.1:8001
  BalancerMember http://127.0.0.1:8002
  BalancerMember http://127.0.0.1:8003
</Proxy>

Now the Rails part of the config is done, so restart!

# /etc/init.d/apache restart

It works, right? Of course it does. I'll leave the "why" to experts but this is a fine "how" for making your Ubuntu box a sort of web server Swiss Army knife.

As a bonus, I have installed PHP 5.2 from source as well. PHP is better for hacking things together, so we have to keep it around. Before you run back to the command line, use Synaptic to make sure libcurl and libxml2 are installed, as any self-respecting PHP install will need those.

# wget http://us2.php.net/get/php-5.2.0.\
tar.bz2/from/this/mirror
# tar xjf php-5.2.0.tar.bz2
# cd php-5.2.0
# ./configure --disable-cgi --with-libxml-dir \
--with-apxs2=/usr/local/apache2/bin/apxs \
 --with-curl --with-mysql --with-mysqli \
--with-pdo-mysql --with-pear
# make && make install

We're really done now. You now have a LAMPR server!

7 Comments Tags: