Making Typo properly ping Technorati (and others...)

Posted by ryan
at 12:14 PM on Monday, November 28, 2005

With the trunk version of Typo you may or may not have noticed that your Technorati (or blo.gs etc…) pings aren’t getting recognized. This is because Typo doesn’t currently send the ping in the proper format. However, I just submitted this patch to the folks at typo that should remedy things.

When you add a new entry to your blog, most blogging software supports the weblogUpdates.ping ping specification that will notify blog aggregators and other services that your blog has been updated. This is done through a pretty simple SOAP call that just tells the service the blog that was updated and the root URL of the blog.

Typo seemed to support this functionality through its “settings -> General Settings -> URLs to ping automatically” section. However it was sending a POST request with a format that wasn’t quite the weblogUpdates.ping format. (Not to mention that it wasn’t a SOAP request). I noticed this and submitted this issue to the Typo guys. After sitting back and basking in my find for a day or two it dawned on me that I had every ability to fix the issue. So after toiling a bit and making a few passes, I did just that and submitted the above mentioned patch.

So why do I mention this? Because I’m egotistical and self-centered? Well, yes. But also because this announcement by scott made me a bit nervous that it might be awhile until the patch made it into the trunk and I thought a few people might want to get their posts recognized sooner by the very important ecosystem of blog aggregators and services. No knock on the Typo guys at all, just an opportunity to get the functionality in place sooner rather than later.

If you’re not up to doing the whole patch application process yourself, you can download these three files into your current Typo installation. (Make sure you’re on the most recent revision, though – 760 as of this writing)

app/models/ping.rb
app/controllers/application.rb
app/controllers/admin/content_controller.rb

Also let me know if you see a better way of doing things as I’m no Rails pro.

Creating weblogUpdates.ping SOAP web services with Rails

Posted by ryan
at 10:39 AM on Tuesday, November 22, 2005

I’ve recently had the occasion to work on both the client and server ends of implementing the weblogUpdates.ping SOAP call and thought it might be worthwhile to post the results here.

First, a little background. “weblogUpdates.ping” is a way for blogging software to notify aggregators that there’s been an update to the blog. If you use Technorati or blo.gs this is how your blogging package notifies the services when you post a new entry. The specification for this SOAP call is outlined here and here.

As you can see, it’s a pretty simple call. We need to make a SOAP call to the “weblogUpdates.ping” method with two string arguments, the title of the blog and the absolute URL of the blog – not the permalink of the new entry. (taken from technorati docs)

<?xml version="1.0"?>
<methodCall>
  <methodName>weblogUpdates.ping</methodName>
  <params>
    <param>
      <value>YOUR WEBLOG NAME HERE</value>
    </param>
    <param>
      <value>http://www.YOURWEBLOGURL.com/</value>
    </param>
  </params>
</methodCall>
So, on to implementing both sides of this in Ruby on Rails...

Let’s start with the client side, if you have a Rails app (such as a Rails blogger like Typo) that needs to send out a ping to Technorati or any other blog aggregator then you’ll need to send out this ping. This turns out to be quite simple, here’s the jist of the code (derived from Why’s example)

begin

  server = XMLRPC::Client.new2(URI.parse(endpoint_url).to_s)

  begin
    result = server.call("weblogUpdates.ping", blog_name,
                          blog_url)
  rescue XMLRPC::FaultException => e
    logger.error(e)
  end

rescue Exception => e
  logger.error(e)
end
Keep in mind this is a synchronous call – so if the aggregator is slow in responding it will hang your app. Some thought should be given to spawning the actual call in a new thread.

So what about when you’re writing a Rails app that serves as an aggregator that needs to receive these ping calls? It’s not as simple as sending the ping, but with Rails’ strong web services support it’s still quite easy. So here’s how you go about doing that:

  • Create the API class that defines what the call looks like:
    # In app/apis/blog_api.rb
    
    class BlogAPI < ActionWebService::API::Base
      inflect_names false
      api_method :ping,
                 :expects => [ {:name => :string}, {:url => :string} ]
    end
    
    Note that you have to set the “inflect_names” property to false since not doing so will cause the underlying SOAP method to be named “weblogUpdates.Ping”, which we don’t want. Also notice that we haven’t specified the full name of the call and have left off the “weblogUpdates” prefix. We’ll resolve this a few steps down by using the layered dispatching mode of Rails’ web services support which will bind a web service class to a specific name.
  • Next let’s create the actual web service class:
    # app/models/blog_api_service.rb
    
    class BlogAPIService < ActionWebService::Base
    
      web_service_api BlogAPI
    
      def ping(name, url)
        #Put your business logic here that handles incoming pings
      end
    end
    
    Pretty simple again, define a ping method that matches the BlogAPI method defined in the first step and add your business logic.
  • Now let’s wrap it all up with the controller that will handle the actual result:
    # app/controllers/blog_controller.rb
    
    class BlogController < ApplicationController
    
      web_service_scaffold :invoke
      web_service_dispatching_mode :layered
      web_service :weblogUpdates, BlogAPIService.new
    
    end
    
  • Now your SOAP weblogUpdates.ping service will be waiting at http://yourhostname/blog/api. To test it you can go to: http://yourhostname/blog/invoke.

And there you have it, sending and receiving the SOAP weblogUpdates.ping call. You can now write your own Rails version of Technorati and Moveable Type, so have at it.

Ruby on Rails and Postgres, Love at first sight

Posted by ryan
at 10:58 AM on Tuesday, November 15, 2005

With my recent selection of Planet Argon as my hosting provider for the rails app I’ve been working on I had two choices: use Postgresql or subject myself to ridicule and public humilition from the PA guys by sticking with MySQL. Fortunately I decided to take the opportunity to start learning about postgres, and I’m glad I have.

One of the unforeseen benefits I stumbled upon was using the inherits functionality of postgres to factor out some of the common columns that rails uses. For instance, everybody knows that adding the “lock_version”, “created_at” and “updated_at” columns gives you free optimistic locking and auto-timestamping, respectively. This is great, but adding these columns to every table definition in your SQL scripts is somewhat tedious. Enter “inherits”.

Instead of specifying these columns for every table like one would normally do:

create table users (
    id integer primary key default nextval('users_id_seq'),
    username varchar(255) not null unique,
    password varchar(255) not null,
    <b>created_at timestamp not null default now(),
    updated_at timestamp not null default now(),
    lock_version integer not null default 0</b>
);

create table documents (
    id integer primary key default nextval('documents_id_seq'),
    title varchar(255) not null unique,
    body text not null,
    <b>created_at timestamp not null default now(),
    updated_at timestamp not null default now(),
    lock_version integer not null default 0</b>
);
we can factor out the three common columns into their own table that the other tables can inherit from. For the purposes of this demo I’ve called this table “traceable”:
<b>create table traceable (
    created_at timestamp not null default now(),
    updated_at timestamp not null default now(),
    lock_version integer not null default 0
);</b>

create table users (
    id integer primary key default nextval('users_id_seq'),
    username varchar(255) not null unique,
    password varchar(255) not null
) <b>inherits(traceable);</b>

create table documents (
    id integer primary key default nextval('documents_id_seq'),
    title varchar(255) not null unique,
    body text not null
) <b>inherits(traceable);</b>
Just as we can factor out common attributes of an object model into an abstract or super class, postgres allows us to do the same with our table model.

I like it when architectural layers synch up like this, and postgres makes it easy to do so. The only question I have is if this structure will lead to a performance hit that negates its convenience. I would imagine it is similar to using a view, although that is a largely uneducated guess.

And Planet Argon it is

Posted by ryan
at 8:30 AM on Saturday, November 05, 2005

It was pretty clear after my last post that there are some good options when it comes to Rails hosting (and there are some having a few issues – hopefully all temporary). So after checking it all out, I’m going to start out with Planet Argon, which makes me an argonaut, er planetonian, er planaliscious argoharrian? Anyway, if you can get past their very 1995-ish sign-up process (snail mail or fax the hosting agreement and no way to enter a credit card into a web form), it’s all good. Great personal service and you can always find help on their IRC channel. Their startup documentation is still very much a work in progress (i.e. I can’t find any) which forces you to be somewhat intelligent and figure stuff out on your own. But when Robby (the techie-owner) is always a stone’s throw away on IRC, that’s not an issue. Thanks to all those who commented on the original post, it turned out to be quite an active discussion.

If you sign up yourself and want to throw me a bone, put me down as your referrer. It will make me happy, which makes me happy.

Textdrive vs. Planet Argon

Posted by ryan
at 12:09 PM on Thursday, November 03, 2005

I’ve been waiting for the fictitious Rails App Hosting to get off the ground for awhile now and have come to the realization that, in the name of expediency, I may need to look at some other options. Gauging by the amount of chatter and the “I just think your website looks legit” factor it certainly seems that Textdrive is the big daddy in town while Planet Argon is the smaller but still quite active player in the Rails hosting space.

So the question becomes, does anybody have any strong opinions between the two services, or even more ideally, has anybody hosted on both and can give their overall opinion? My main priorities are ease of setup and configuration, tech support and scaleability…