Stewrt Matheson
rails
django
javascript
otherstuff...
Big game for Liverpool!! Come on #reds 22 hrs ago
Ruby Acronyms
December 12th, 2011 by

I love extending the ruby core! Makes code so neat and works so well with rails initializers. This method allows you to fetch the Acronym of an array of strings. It would be kinda cool to write something that works the other way taking a single string. Make using Faker… but I can’t think of any use. Then again IBM could not understand why people needed computers in their home so who knows. Anyway… it’s code time.

class Array
  def acronym
    result = ""
    self.each do |item|
      result << item[0]
    end
    result
  end
end
Rounding time to the closest hour in Ruby
December 9th, 2011 by

Ahhh… its one of the moments in life that make you so happy your a ruby developer.

class Time
  def round(seconds = 60)
    Time.at((self.to_f / seconds).round * seconds)
  end
 
  def floor(seconds = 60)
    Time.at((self.to_f / seconds).floor * seconds)
  end
 
  def round_to_closest_hour
    if self.min > 30
      self.round(1.hour)
    else
      self.floor(1.hour)
    end
  end
end

Source:
http://stackoverflow.com/questions/449271/how-to-round-a-time-down-to-the-nearest-15-minutes-in-ruby

Converting dates form Javascript to Rails
November 30th, 2011 by

Time based web applications written in rails and javascript will sooner or later have to think about the following object life cycle.

1. Javascript Object
2. Request Params
3. Rails object
4. MySQL row

While rails has the last two covered and jQuery has mostly the second covered how do we get our data in to a form where this flow will be smooth. Javascript date objects don’t directly fit so I extended the date prototype to allow for this. This porototype mirrors the rails date time form helper and creates the correct data with the keys rails would expect to have.

  Date.prototype.toRails = function(name) {
    var dateParams;
    dateParams = {};
    dateParams[name + "(1i)"] = this.getFullYear();
    dateParams[name + "(2i)"] = this.getMonth() + 1;
    dateParams[name + "(3i)"] = this.getDate();
    dateParams[name + "(4i)"] = this.getHours();
    dateParams[name + "(5i)"] = this.getMinutes();
    return dateParams;
  };
 
  //Use
 
  d = new Date();
  date = d.toRails('start');
 
  //now we can put this object on the server
  $.ajax
      ...
      data : date
      ...

As far as rails is concerned we might as well be using the datetime helper.

Want to learn Javascript?
October 29th, 2011 by

I have set-up a tutorial site for JavaScript with plans to add other languages. Its a getting started guide for any new programmers looking to start out with JavaScript development. If I get some positive feedback I will add more tutorials. To check them out head to Stewtorials

Installing Ruby 1.9.2 on Mac os x 10.7 (Lion)
September 22nd, 2011 by

The other day I updated to Lion from Leopard. I know… I was keeping it real with an old OS but it got to the point where new apps where not working with leopard. While everything with the operating system update was fine there was a lot of time spent getting my ruby on rails install back up and running. One thing I did not understand is that I had made the leap to a 64bit system. This means a lot of recompiling as I hate package managers for osx.

Reinstalling MySQL

First things first you will need to recompile MySQL from source. I am using 5.1. It seems to be the version of mysql that everyone is using. Some people might stick with sqlite however as I would never use it in production I would also never use it in development so I stick with MySQL. These commands are taken from Dan Benjamin’s hivelogic blog. Great work Dan! The link to the article is below in the sources section so if you run in to trouble check the article out.

cd /usr/local/src
curl -O http://mysql.he.net/Downloads/MySQL-5.1/mysql-5.1.33.tar.gz
tar xzvf mysql-5.1.33.tar.gz
cd mysql-5.1.33
CC=gcc CFLAGS="-O3 -fno-omit-frame-pointer" CXX=gcc 
CXXFLAGS="-O3 -fno-omit-frame-pointer -felide-constructors 
-fno-exceptions -fno-rtti" 
./configure --prefix=/usr/local/mysql 
--with-extra-charsets=complex --enable-thread-safe-client 
--enable-local-infile --enable-shared --with-plugins=innobase
make
sudo make install

Removing the old ruby

After these steps you should have the database recompiled for the new architecture of Lion. Great lets move on. Its worth noting that I am using RVM. The first thing I needed to do after the update is remove my existing version of ruby. This is the 32bit version and will not work.

rvm remove 1.9.2

Reinstalling dependencies

With that done we need to reinstall ruby 1.9.2. We can use RVM to do this however there are a few things we need to update before this. Lets start with libxml. Download the latest version and compile it.

tar xzvf libxml2-2.7.3.tar.gz 
cd libxml2-2.7.3
./configure --with-python=/System/Library/Frameworks/Python.framework/Versions/2.3/
make
sudo make install

After this we need to install libxlst.

cd /usr/local/src
curl -O ftp://xmlsoft.org/libxslt/libxslt-1.1.20.tar.gz
cd libxslt-1.1.20
./configure
make
sudo make install

All done now lets move on to readline.

Installing Readline

At the time of this writing I was unable to install readline via rvm packages. There is a patch that fixes this however I am not sure its in head yet. The catch here is that in the current state when you install readline it will say that the install has been successful. This is not true. There is a topic on the RVM mailing list about this. For the moment I was able to get around this by compiling and installing readline myself. I have no doubt that this will be fixed soon but for the moment you will need to take this step. This last step is done assuming that you have readline 5.2 downloaded and untared. If you need help then I can add the download link.

export MACOSX_DEPLOYMENT_TARGET=10.7
export CFLAGS="-arch x86_64 -g -Os -pipe -no-cpp-precomp"
export CCFLAGS="-arch x86_64 -g -Os -pipe"
export CXXFLAGS="-arch x86_64 -g -Os -pipe"
export LDFLAGS="-arch x86_64 -bind_at_load"
./configure --prefix=/usr/local
cd shlib
sed -e 's/-dynamic/-dynamiclib/' Makefile > Makefile.good
mv Makefile.good Makefile
cd ..
make && sudo make install

Next lets install zlib and iconv and openssh via RVM.

rvm pkg install zlib
rvm pkg install iconv
rvm pkg install openssl

Installing Ruby

Now we can install ruby 1.9.2. This will install the 64 bit version for us.

rvm install 1.9.2-head -C --enable-shared,--with-readline-dir=/usr/local --with-iconv-dir=$rvm_path/usr  --with-zlib-dir=$rvm_path/usr --with-openssl-dir=$HOME/.rvm/usr,--build=x86_64-apple-darwin10

Finishing Up

Once you have recompiled ruby you will need to create a new gem set. For me I have a gem set for each one of my projects so it was a matter of creating the gem set again and then running a bundle install.

Sources

http://www.markhneedham.com/blog/2010/07/08/installing-ruby-1-9-2-with-rvm-on-snow-leopard/

http://stackoverflow.com/questions/6317980/bundle-rake-error

http://exceptionz.wordpress.com/2010/02/03/how-to-fix-the-iconv-require-error-in-ruby-1-9/

http://groups.google.com/group/rubyversionmanager/browse_thread/thread/4130f40a654242a6?hl=en

http://techdebug.com/blog/2009/01/03/compiling-readline-on-an-osx-105-intel-x86_64

https://rvm.beginrescueend.com/packages/zlib/

http://nokogiri.org/tutorials/installing_nokogiri.html

http://hivelogic.com/articles/installing-mysql-on-mac-os-x/

Reload values on blur with jQuery
May 2nd, 2011 by

Sometimes an existing value in a HTML field can do so much for usability. The problem is these “existing values” can sometimes get in the way and make the page more difficult to use. Its fair to say that you want to clear that value when the user is ready to fill out the form. The focus event has you covered in this situation, but what about when the user does not enter any data after clicking on the form element? The element needs to perform some sort of persistence to reload the value that it was initialised with.

jQuery provides a great way to do this with the “data()” function. This function allows any data to be attached any DOM element. Very handy when you throw(excuse the pun) it in with a jQuery function. Here is my solution to reloading values for DOM form elements. Works best with type=”text” :)

jQuery.fn.contentOnBlur = function() {
 
    $(this).each(function(index, value){
        $(value).data('initValue', $(value).val());
        $(value).data('changed', false);
    });
 
    $(this).focus(function(){
        if(!$(this).data('changed')) {
          $(this).val('');
        }
    });
 
    $(this).change(function(){
        $(this).data('changed', true);
    }); 
 
    $(this).blur(function(){
        if($(this).val() === '' && !$(this).data('changed')) {
            $(this).val($(this).data('initValue'));
        }
    });
}
Renaming files in ruby
March 29th, 2011 by

Its programs like this that make me love ruby. I think the code looks fucking awesome when its done.

require 'fileutils'
Dir.glob("*.jpg").each do |file_name|
  new_name = file_name[2..file_name.length] 
  new_name.gsub! "-", "_" 
  puts "Renaming #{file_name} => #{new_name}"
  File.rename file_name, new_name
end
Deploying a Django site with Fabric
March 11th, 2011 by

I just deployed my first Django site. Parts of it where slightly painful because I am new to python/django/mod_wsgi. Also because for some reason that still escapes me now I opted for centos and not ubuntu. I am not saying anything about about centos its just different to ubuntu… what I normally work with. However one thing I really liked about the process was fabric. It just works and don’t we all just love that. I did however notice that a lot of the “fabfiles” out there are not up to date. Others out there are very specific to peoples set ups and others out there do things that did not make any sense to me. So here is mine that will work on the latest version of fabric at hte time of this writing. Its also generic so you should be able to plonk it in to any django project and have it work. I used capistarno as a model to create it.

Things to note about this fabfile:
1. It assumes that you have your wsgi file in your project dir.(dont worry this is moved out after the deployment in to a shared folder)
2. It assumes your using git. You should be but incase your not it’s not hard to change.
3. It assumes your using virtualenv
4. It creates a new folder each time you run the deploy task allowing you to roll back
5. It moves wsgi files out of the project folder in to a shared folder
6. It creates a folder structure all under one folder of your choosing

Things that the file does not do:
1. Roll back versions
2. Set up web server config

Anyway. Here it is.

env.hosts = ['name@host']
env.path = '/root/deployment/path'
env.virtual_env_path = '%(path)s/virtual_env' % env # virtual env path
env.project_name = 'your_project_name'
env.activate = 'source %(path)s/virtual_env/bin/activate' % env # how to activate your virtual env
env.deploy_user = 'deployment_user_name'
env.python_version = '2.6' #nuf said
env.site_packages_path = '/%(virtual_env_path)s/lib/python%(python_version)s/site-packages' % env # where do your virtual env site packages live
 
def pythonversion():
    run('python -V')
 
def virtualenv(command):
    with cd(env.path):
        sudo(env.activate + '&&' + command, user=env.deploy_user)
 
def create_deployment_folders():
    """
    Create the base set of folders for the deployment
    """
    run('mkdir %(path)s' % env)
    with cd('%(path)s' % env):
        run('mkdir releases')
        run('mkdir shared')
        run('mkdir tmp')
        run('mkdir content')
        run('chmod 777 content')
 
 
def build_virtual_env():
    """
    Create virtual env for the project
    """
    run('mkdir %(virtual_env_path)s' % env)
    with cd('%(virtual_env_path)s' % env):
        run('virtualenv --no-site-packages --python=python%(python_version)s .' % env)
 
 
def install_requirements():
    """
    Install the required packages from the requirements file using pip
    """
    with cd('%(path)s' % env):
        virtualenv('pip install -r ./%(project_name)s/requirements.txt' % env)
 
def reinstall_requirements():
    """
    Reinstall the required packages from the requirements file using pip
    """
    run('rm -Rf %(virtual_env_path)s' % env)
    build_virtual_env()
    install_requirements()
    restart_webserver()
 
def setup():
    """
    Setup a fresh virtualenv as well as a few useful directories, then run
    a full deployment
    """
    create_deployment_folders()
    build_virtual_env()
 
 
def deploy():
    """
    Deploy the latest version of the site to the servers, install any
    required third party modules, install the virtual host and 
    then restart the webserver
    """
    import time
    env.release = time.strftime('%Y%m%d%H%M%S')
    upload_tar_from_git()
    symlink_current_release()
    install_requirements()
    #migrate()
    restart_webserver()
 
 
def upload_tar_from_git():
    "Create an archive from the current Git master branch and upload it"
    local('git archive --format=tar master | gzip > %(release)s.tar.gz' % env)
    run('mkdir %(path)s/releases/%(release)s' % env)
    put('%(release)s.tar.gz' % env, '%(path)s/tmp/' % env)
 
    with cd('%(path)s/releases/%(release)s' % env):
        run('tar zxf ../../tmp/%(release)s.tar.gz' % env)
        run('rm ../../tmp/%(release)s.tar.gz' % env)
 
    local('rm %(release)s.tar.gz' % env)
 
 
def symlink_current_release():
    "Symlink our current release"
    with settings(warn_only=True):
        run('rm %(path)s/%(project_name)s' % env)
 
    run('ln -sf %(path)s/releases/%(release)s %(path)s/%(project_name)s' % env)
    run('mv -f %(path)s/%(project_name)s/%(project_name)s.wsgi %(path)s/shared' % env)
 
 
def migrate():
    "Update the database"
    with cd('%(path)s/%(project_name)s' % env):
        virtualenv('python manage.py syncdb --settings="production_settings" --noinput' % env)
 
 
def restart_webserver():
    "Restart the web server"
    run('touch %(path)s/shared/%(project_name)s.wsgi' % env)
 
 
def link_admin_media():
    "Add the admin media to the site"
    run('ln -sf %(site_packages_path)s/django/contrib/admin/media %(path)s/shared/admin_media' % env)

This deployment file is based on the one at the “mnorethanseven” blog. Check this detailed yet out-dated post about django deployment for further reading.

Object Oriented Javascript with jQuery
January 4th, 2011 by

Lately I have been working with Javascript. A lot. As a result I have been doing research on javascript.  The more I learn about it the more intrigued I am. I love using jQuery but never fully understood what javascript was about. Now I have a better idea I would like to share with you a rough pattern that I use when writing javascript for jQuery.

Firstly I like to think of every bit of javascript functionality as its own object. This allows for two things. Firstly it keeps scope nice and tidy and secondly it keeps the frequency in which your searching the DOM to a minimum which helps make your scripts run faster.

Here is a simple example that adds behavior  to a search bar. I have commented each line to explain what’s happening.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// everything in its own function. This creates an object when using the new key word
function SideBarSearch(){
        //text value for the field
	this.initValue = "Search the blog";
 
        //Find the search field element. Once found we dont have to reference the dom again. This is a good thing as searching the dom is very slow.
	this.searchField = $('#blog_query');
 
        //setting the value of the search field. This could also be done with html.
        this.searchField.val(this.initValue);
 
        //This next line copies the whole scope of this object so it can be used in jQuery callbacks. Make sure you do this because the jQuery callback will set its own scope.
        var self = this;
 
        //the jQuery event call back.
	this.searchField.focus(function(){
		$(this).val('');
		$(this).css('color', '#000');
	});
 
        //another jquery event call back. Note nether of these search the dom.
	this.searchField.blur(function(){
		$(this).val(self.initValue);
		$(this).css('color', '#9A9A9A');
	});
 
	this.searchField.keypress(function(event){
		//note the === always use this and not == as == can return unexpected results.
                if(event.keyCode === '13')
		{
			$('.search-bar .loading').css('display', 'inline');
		}
	});
}
Introducing assert-random
August 3rd, 2010 by

Something I have been meaning to do for a long time now is create and release a ruby gem. Today I have done this. Introducing assert-random. Its a VERY simple gem that adds an assertion to test/unit. Assert random as a test accepts a block and runs this block 10 times. Once the block has been run it then checks the results of the block. Currently it tests to make sure that no objects that are the result of the block match. Not much but its a start.

Example that passes:

1
2
3
assert_random do
    rand(1000)
end

Example that fails:

1
2
3
assert_random do
    1000
end

Basic stuff but I plan to extend it in the future so something like this will fail:

1
2
3
4
counter = 1
assert_random do
    counter += 1
end

I used the gem Jeweler. I got up and running very quickly and was able to focus on the functionality of the gem and not all of the meta details a gem needs. All that was generated for me. Awesome really.

Source: http://github.com/stewartmatheson/assert-random
RubyGem: http://rubygems.org/gems/assert-random

Next Page »