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.
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.
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.
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 wwwThat 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::startNow 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 includesconf/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!