Initial Ubuntu 8.04 Linux Setup 1

Posted by John Sun, 11 May 2008 20:53:00 GMT

After grabbing and installing Ubuntu 8.04 I then had to put together and setup the baby, luckily I wrote down most of everything I did in case I’d have to do it again and to help out you guys.

What follows are my findings and what I did to fix them. The machine I used is an HP Pavillion dv2000 model dv2742 special edition. It’s got a built-in intel graphics card, 3gb memory, sata 250gb drive, wifi, bluetooth and an intel dual core 2 processor.

I installed the o/s using the 64-bit edition of Ubuntu 8.04 Hardy Heron, all what you see below are workable settings which provided the right setup; hope they help your situation if you go down this route.

Update System

First port of call, check for any new updates post-install,

sudo aptitude update
sudo aptitude upgrade

Dependencies / Software / Setup

Next, install Ruby, FlashPlayer, GCC Compiler, MySQL, JAVA, SqlLite,

sudo aptitude install mysql-server flashplugin-nonfree ruby-full libsqlite3-dev build-essential libmysqlclient15-dev sun-java6-jdk

Volume Mixer,

sudo aptitude install gnome-alsamixer

ImageMagick,

sudo aptitude install imagemagick

Ruby Gem Handler

I could get GEM from the repositories but because with each new update it breaks away from the in-built Linux installer it’s best to install it from source,

wget http://rubyforge.org/frs/download.php/34638/rubygems-1.1.0.tgz 
tar xzvf rubygems-1.1.0.tgz
cd rubygems-1.1.0
sudo ruby setup.rb
sudo ln -s /usr/bin/gem1.8 /usr/bin/gem

Had problems updating the GEM system initally, so logged in as root to finish it off,

su root 
sudo gem update --system

Now when you type gem –version you should see GEM ready to roll,

Gem Libraries

The slow bit, ran this as root just to make sure it worked,

gem install rails
gem install rake
gem install mongrel
gem install mongrel_cluster
gem install thin
gem install capistrano
gem install mysql
gem install termios
gem install sqlite3-ruby
gem install mini_magick

VLC + GIT

Next VLC to play videos,

sudo aptitude install vlc

Transmission for torrents, most important bit,

sudo aptitude install transmission

And GIT to handle code versioning,

sudo aptitude install git-core

Firefox + MS Fonts

Next I need Firebug for Firefox 3. Ubuntu 8.04 comes with Firefox 3 beta 5, the one available thru Tools / Add-ons won’t work with it; but thankfully it’s in the repositories

sudo aptitude install firebug

And you’ll probably need Microsoft Fonts later down the line,

sudo aptitude install msttcorefonts

Pimp GEDIT

The default Gnome Text Editor Isn’t bad but let’s add some extra’s to really kick it in gear,

sudo aptitude install gedit-plugins

And tweak it,

wget http://robzon.kapati.net/rails/rhtml.lang && sudo mv rhtml.lang /usr/share/gtksourceview-2.0/language-specs/
wget http://robzon.kapati.net/rails/rails.xml && sudo mv rails.xml /usr/share/mime/packages
sudo update-mime-database /usr/share/mime

Follow the guide here to get the TextMate look,

Now when you open rails source files they’ll actually look right, thanks Grigio.

PostGreSql + Thunderbird

Pretty easy to install the most powerful db system, and the better email handler

sudo aptitude install postgresql thunderbird

Wine for Windows

Thanks to Google for their support the Wine project is going great, to get Windows software running natively on your machine,

First add the key,

wget -q http://wine.budgetdedicated.com/apt/387EE263.gpg -O- | sudo apt-key add -

Then add the repository to your default repository list,

sudo wget http://wine.budgetdedicated.com/apt/sources.list.d/hardy.list -O /etc/apt/sources.list.d/winehq.list

And finally install it,

sudo apt-get install wine

Effects

To enable compiz effects make sure Appearance / Visual Effects is set to ‘Extra’, then install the Advanced Effects Manager,

sudo aptitude install compizconfig-settings-manager

This will give you access to the 3d cube, skydome effect and a host of other cool addons.

My desktop dpi is set to 100dpi, fonts set to ‘Bitstream Vera Sans Roman 8pt’, with ‘Bitstream Vera Sans Bold 8pt’ for Windows Title; and ‘Liberation Mono 8pt’ for fixed width font. Using subpixel smoothing for LCD.

Sound

For my laptop (hp pavillion dv2000 / dv2742se model), i had to use a different sound mixer to make sure the quickplay volume and mute buttons talked to the sound system.

So from the top menu bar, System / Preferences / Sounds, then set the Default Mixer Tracks hander device to: Conexant CX20561 (hermosa) (oss mixer).

Cleanup

To get any temp files carried on from the install, clean with,

sudo aptitude clean

Job done, however I had a problem with Hibernate & Suspend which was lucky fixed with some advice from here

Record Grouping

Posted by John Tue, 01 Apr 2008 22:05:00 GMT

Example to go thru your User model and return all the signups by month / year, doing conditionals on them and grouping,

@users = User.find(
  :all, 
  :select => "MONTH(created_at) as month, YEAR(created_at) as year, COUNT(*) AS records",
  :conditions => ["admin = 0'"], 
  :group => "year, month")

You can use this in your view like,

<% for @user in @users %>
  <%=@user.month%>
  <%=@user.year%>
  <%=@user.records%> signups
<% end %>

Ruby date_select conversion 2

Posted by John Wed, 19 Mar 2008 20:26:00 GMT

Had a bit of a pain with Ruby’s handling of Date/Time values coming from a Date_Select form element, managed to solve it though.

The problem was that in my form…

<%=date_select(:date,'',:start_year => 1950,:include_blank => false, :default => { :year => '1970' })%>

…the value I got back from the submitted field,

params[:date]

became…

'(3i)4(1i)1953(2i)5'

Bit of a mess, obviously I was expecting something a little more legible like 1953-5-4 (yyyy-mm-dd), so I bashed my head against a brick wall trying to work it out, I could have made my life easier with some select_date blocks but I’m a guy how likes to ask ‘why’ so I perceviered.

Turns out in my travels you can do this to break it into a usable DateTime object..

Time.mktime(params[:date]['(1i)'],params[:date]['(2i)'],params[:date]['(3i)'])

Which will return something much more legible…

Sun May 19 00:00:00 +0100 1968

Or whip it into a method to do exactly what you want…

def convert_date(obj)
  return "#{obj['(1i)']}-#{obj['(2i)']}-#{obj['(2i)']}"
end

<%=convert_date(params[:date])%>

But wait, it doesn’t end there, you could use Date.new or Date.civil to parse it into a real date object like…

def convert_date(obj)
  return Date.new(obj['(1i)'].to_i,obj['(2i)'].to_i,obj['(3i)'].to_i)    
end

Which will return…

1967-03-19

Much nicer, just remember to use .to_i otherwise you’ll get…

comparison of String with 0 failed

Enjoy!

Rails Sessions

Posted by John Sun, 09 Mar 2008 22:29:00 GMT

rails is love

To make a truly intelligent web application your gonna sooner or later have to play around with Sessions, which is basically a Cookie’s big brother.

Store in DB

Now Rails initally will store all it’s session data in a text file within the /tmp/sessions directory of your rails app, which is usually ok, but if you’re gonna build a production-ready app you’re gonna want to up the ante somewhat and store them in your DB.

This is simply done by opening up your environment.rb file and un-commenting the following line…

(within /config/environment.rb)
config.action_controller.session_store = :active_record_store

Then in the command-line generate a RAKE DB migration for your Session objects (so they’re stored in your db from now on).

rake db:sessions:create
rake db:migrate

Bingo, you now have a table within your database hooked up and ready to store your session data perfectly.

Storing Session Objects

Now that you’ve got your DB storing your session data, why don’t we start creating some session objects.

This is done by…

session[:order] = 'ASC'

Here, we’ve simply created a new session object, storing in it a text value of ‘ASC’; cool eh?

We can then check to see if our session is empty via…

if session[:order].blank?
   ..do stuff..

So if our session object contains nothing we can initialise it correctly.

Common Gotcha

Now one of the good things with switching sessions over to your db is that it’ll secure your app a little bit better and your performance will improve.

Plus if your building your app on your dev machine, then transfer it to your live box, but can’t find a reason why your sessions don’t work there it’s usually down to file permissions for the session file; by switching sessions over to a db you remove any future problem of this.

Good eh,

Rails : Exception Catching

Posted by John Thu, 06 Mar 2008 15:23:00 GMT

Global Error Catching

To handle errors globally in your application, add..

(within application.rb)
def rescue_action_in_public(exception)
    render :text => "<html><body><p>
    There was a global error processing your request.</p>
    <!--  #{exception}  --></body></html>"
end
def local_request?
    false
end

The final def def local_request? tells rails that it should act the same way in development mode.

Local Error Catching

To catch errors locally within your form submits do…

def update
    return unless request.post?
    begin
        User.update(self.current_user.id, params[:user])
        render :action => 'success'
    rescue ActiveRecord::RecordInvalid
        flash[:notice] = "Sorry, your profile was not saved"
        render :action => 'profile'      
    rescue
        flash[:notice] = "Sorry, something went wrong"
        render :action => 'profile'
    end
end

Simple process, here we’re basically saying if the user has submitted form data (done a POST), then process the code; if not redirect back to the sending page.

If yes then update the User object relevant to the specific user record (found by the id), updating the record with the parameters from the form. Save the record and render the ‘success’ page.

If we get a problem with saving the record (activerecord), display a message and goto the ‘profile’ page.

If we get some other error, display the second message and goto the ‘profile’ page.

Notify Me of Errors via Email

On top of this you can enhance it with flash messages and send off an email with the error code, here’s one such way.

(in application.rb)
protected  

def log_error(exception) 
    super(exception)

    begin
        Alert.deliver_errormail(
          exception, 
          clean_backtrace(exception), 
          @session.instance_variable_get("@data"), 
          @params, 
          @request.env)
    rescue => e
        logger.error(e)
    end
end

Adding this makes it send error emails in development mode..

def local_request?
    false
end

Now create an Mailer object with…

script/generate mailer Alert

And put this code in your generated alert.rb file

class Alert < ActionMailer::Base
def errormail(exception, trace, session, params, env, sent_on = Time.now)
    content_type "text/html" 
    @recipients         = 'john@gmail.com'
    @from               = 'admin@mysite.com'
    @subject            = "[Error] exception in #{env['REQUEST_URI']}" 
    @sent_on            = sent_on
    @body["exception"]  = exception
    @body["trace"]      = trace
    @body["session"]    = session
    @body["params"]     = params
    @body["env"]        = env
end
end

And create a appropriate alert/errormail.rhtml file in your view for the formatted error email…

<style>
    <!--
    * {    font-size:    9pt;    font-family:    verdana, helvetica, arial, sans-serif; line-height: 1.7em; }
    p { margin: 0 }
    -->
</style>

<h2>Error report from <%= Time.now %></h2>
<table border="0">
    <tr><td>Message</td><td><%= @exception.message %></td></tr>
    <tr><td>Location</td><td><%= @env['REQUEST_URI'] %></td></tr>
    <tr><td>Action</td><td><%= @params.delete('action') %></td></tr>
    <tr><td>Controller</td><td><%= @params.delete('controller') %></td></tr>
    <tr><td>Query</td><td><%= @env['QUERY_STRING'] %></td></tr>
    <tr><td>Method</td><td><%= @env['REQUEST_METHOD'] %></td></tr>
    <tr><td>SSL</td><td><%= @env['SERVER_PORT'].to_i == 443 ? "true" : "false"  %></td></tr>
    <tr><td>Agent</td><td><%= @env['HTTP_USER_AGENT']  %></td></tr>
    <% if @session['user'] -%>
    <tr><td>User id</td><td><%= @session['user'].id %></td></tr>
    <tr><td>User name</td><td><%= @session['user'].name %></td></tr>
    <tr><td>User email</td><td><%= @session['user'].email %></td></tr>
    <tr><td>Registered</td><td><%= @session['user'].created_at %></td></tr>
    <% end -%>
    </table>
    <h3>Backtrace</h3>
    <div><%= @trace.to_a.join("</p>\n<p>") -%></div>
    <h3>Params</h3>
    <hr/>
    <% for key, val in @params -%>
    <p><b><%= key %></b></p>
    <p><%= val.to_yaml.to_a.join("</p>\n<p>    ") %></p>
    <% end if @params -%>
    <h3>Session</h3>
    <hr/>
    <% for key, val in @session -%>
    <p><b><%= key %></b></p>
    <p><%= val.to_yaml.to_a.join("</p>\n<p>    ") %></p>
    <% end if @session -%>
    <h3>Environment</h3>
    <hr/>
    <table border="0">
    <% for key, val in @env -%>
    <tr>
    <td>
    <small><b><%= key %></b></small>
    </td>
    <td>
    <small><%= val %></small>
    </td>
    </tr>
    <% end if @env -%>
</table>

Now whenever an error happens you’ll get an email about it, good for the production environment.

Setup the Emailer

Remember to setup the emailer otherwise no emails will be sent.

By adding this to your environments/production.rb

config.action_mailer.raise_delivery_errors = true
ActionMailer::Base.delivery_method = :sendmail
ActionMailer::Base.sendmail_settings = {
    :location       => '/usr/sbin/sendmail',
    :arguments      => '-i -t'
}

Or more detailed,

Setup a DNS MX Record so you don’t get blacklisted!

A further note, remember to add an MX record for the domain your using otherwise your site will be blacklisted by anti-spam sites.

An MX record basically tells other sites where they should send emails to, it’s like saying where the postman should deliver incoming letters.

Now if your only sending emails you shouldn’t need this but as a previous commenter noted, most anti-spam sites blacklist you if your sending and don’t have one; regardless of whether you want the site to receive emails or not. Hence you’ve got to include one.

A simple example is…

type: MX
name: mysite.com
data: ASPMX.L.GOOGLE.COM. 
auxilary info: 1

Now ok, this is actually telling anti-spammers your using Google Applications to handle your email (which isn’t strictly true) but at least it get’s them off your back until you setup your own full-blown POSTFIX mail server.

Which is something I’m working on writing an article for.

Expect that in a future posting.

Older posts: 1 2 3 ... 7