Server changes 0

Posted by andy

I’ve kinda changed the whole platform mibly.com is running on. I’ll outline here what’s changed and why.

Source control iPlayerlist and some other projects I’m involved with now use Git, rather than Subversion for source management. The Rails core team have also moved over. So being the Technology magpie I sometimes am I jumped on to the latest shinny thing. Github. My code is now stored at Github, and I deploy from there too. It’s such a nice interface and nice not to have to worry about setting up repositories and deal with user management.

Application server The old server used to run on Apache 2 front end with 3 mongrel instances in the background. 2 for iPlayerlist and one for this blog. It was a pain to set up and rather limited. Since then however, Phusion Passenger, a.k.a. mod_rails has come on leaps and bounds. Its fast, spawns new threads when needed and easier to use and to implement. I now Passenger along with apache2. yay.

Deployment The old install used Capistrano. So does this one, as its lovely. However, I’m now up and running with the latest (version 2 strain) of Capistrano with support for Git. A little bit code is added to help Passenger to gracefully restart after all my code is checked out from github.

Host I’ve moved from slicehost to get a larger 512mb slice at railsplayground. It was a bit of a bargain and to be honest, 256mb can be a bit limiting when it comes to RubyGems and passenger.

Custom validation with Paperclip

Posted by andy

In my rails apps I used to use attachment_fu for uploading files, but of late I have moved over to thoughtbots Paperclip plugin. Its perfect for most instances, and indeed simple to use. I required it to do a little more than it can do out of the box. In my case I needed to check that the uploaded document was a well formed XML document. The result was a nice little custom validation method levered into the plugin.

# lib/paperclip_mixin.rb
module Paperclip
  module ClassMethods
    def validates_attachment_valid_xml name
       require 'xml/libxml'
       @attachment_definitions[name][:validations] << lambda do |attachment, instance|
         if attachment.file.nil? || !File.exist?(attachment.file.path)
           "must be set" 
         else
         # check file is valid xml
           begin
             # use libxml-ruby gem to do basic check on the file
             parser = XML::Parser.new
             parser.string = File.open(attachment.file.path).read
             parser.parse
             return nil # i.e no exceptions equals validity
           rescue
             "must be a valid xml document" 
           end
         end
       end
     end
  end
end

Then initiallise this patch it in our initializers.

# config/initializers/custom_requires.rb
require 'paperclip_mixin'

Now we can just add this validation method to our model that is using paperclip

# app/models/asset.rb
class Asset < ActiveRecord::Base
  has_attached_file :config_file
  validates_attachment_valid_xml :config_file
end

And that worked fine. yay.

Time for a Wii

Posted by andy

I got hold of a Wii this weekend, mainly because of Mariokart but also so I could faff around with its browser. The result is iPlayerlist for the Wii (thank you BBC). Again, its work in progress and consider it to be my programming play thing rather than a fully fledged service.

iPlayerlist on the wii

Its a shame the little Wii cant handle anything more than Flash 7, as its a bit blocky and clunky for video playback, worth a try though. Just point your Wii at http://iplayerlist.mibly.com.

Update I’ve put a PS3 user agent look up in there too. So PS3 users can have a play, a la ps3iplayer.com

A little about BBC iPlayer, youtube and playing 3

Posted by andy

Its nice to have a project that you dabble with as a hobby. A project that even if it fails, you won’t lose cash, job, respect or pets over and can only really gain through lessons learned. Currently, my hobby project is iPlayerlist.

I started to build iPlayerlist as I wasn’t a fan of the original bbc.co.uk/iplayer site. It didn’t group episodes by series, rather graphics heavy and required too much clicking about for my liking. So over a Christmas, I began writing some code that would give me something I would use, but also as a vehicle to play around with some APIs that are about.

I’m happy with the result in that I use it and have learned stuff through developing. If anybody else uses it, its a bonus.

Anyhow, “Whats in the pot?” I hear you ask. Well here are the services the site uses.

These services all contribute in a way. The BBC iPlayer site is screen scraped (yeah I know, I know, but there are no RSS feeds or API yet so I had to). We grab a little more information from /programmes relating to each episode such as descriptions and broadcast dates. Then for each series we search youtube via its API for related videos. We then get some related blog posts via Google Blog Search. These blog results are passed through Akismet to reduce the spam, then moderated by myself.

For all this to happen Rails 2.0.2 handles the donkey work with the following

There is loads more I could ramble on about here, but I’ll leave that for another post.

Slicehost

Posted by andy

This blog and iplayerlist (which I will go into more detail in a later post) are hosted at Slicehost. I think its wise just to go through how everything is set up over here.

This is on the cheapo slice with 256mb of memory. Thats enough for me.

I used deprec to set up everything over here. It didn’t work straight off the bat and required a little tweaking but the resulting server setup is pretty much ideal for my needs.

  • Ubuntu Gutsy
  • Ruby on Rails 2.0
  • Mysql
  • Apache2 with mod_proxy
  • mongrel cluster application servers. (one for the blog and 2 for iplayerlist)
  • subversion source management
  • capistrano deployment (this end)
  • mephisto blogging system

I went with slicehost after I finally got annoyed at dreamhost. Now dreamhost is awesome and very cheap but for Rails apps it really doesn’t cut the mustard. Its FastCGI was slow and rails apps were a pain to set up. Slicehost offered a blank canvas which I could install what I wanted and can only blame myself if something goes horribly wrong, hurray! :)

jQuery and Ajax in Rails 2.0

Posted by andy

I'm having loads of fun with jQuery of late. Its small size and increasing collection of plugins has made me want to throw it in any app that has a need for javascript and ajax controls. So I thought I would just put down the basics for anybody wanting to give it a bash.

In this example I will be avoiding RJS and helper methods, sticking to writing pure Javascript. Plus as jQuery and jQuery UI is, in my opinion, rather cleaner and easier to read than Prototype and script.acul.us, RJS and helper methods would just gets in the way.

First thing is first, load up your javascripts including jQuery in your layout.

<%= javascript_include_tag 'jquery-1.2.1.min.js' %>
<%= javascript_include_tag 'application.js' %>
Lets make a standard link in a view that we are going to attach our jQuery magic to.
<%= link_to 'What do little foxes like to eat?', 
                    { :controller => 'foods',  :action => 'fox' }, 
                    { :class => 'ajaxLink' } 
%>

In our application.js we are going to convert this regular joe soap html link into an ajax one unobtrusively. Here is a good place to start having a read through the jQuery docs.

$(function() {
  $(".ajaxLink").click( function() {
      $.ajax({
          url: this.href,
          dataType: "script",
          beforeSend: function(xhr) {xhr.setRequestHeader("Accept", "text/javascript");}
      });
      return false;
  });
});

Create our action in our foods controller that will spit out the food that foxes love to eat.

def fox
    @food = 'foxes love chunky Bacon'    
    respond_to do |format|
        format.js {}  # renders fox.js.html
        format.html { render :text => @food }
    end
end

This method will respond to an Ajax request by rendering fox.js.erb, however, if the user’s browser doesn't have javascript enabled we will just render the food string, this could easily be fox.html.erb.

Create our javascript ‚view‚ called fox.js.erb. We will just have an alert box for now, but this could easily be any other javascript method.

alert('<%= @food %>');
As you can see this is a fairly trivial example, but works rather well. Now if I wanted to Ajaxify any link, all I need do is give it the class .ajaxLink in the html. Much much cleaner than the onclick links the link_to_remote produced.