Using raspell with your own custom dictionary digg delicious su

Posted by daniel
on Wednesday, August 08

A good search engine should be smart enough to detect spelling errors and provide suggestions. For example if you misspelled a word when using Google search, it will ask Do you mean:.... It will be cool to have such feature for our own search engine. So I started to explore possible solutions what works will rails and came upon this blog post by Evan Weaver. He has implemented a ruby gem raspell to interface with Aspell. That sounds like a good solution and I decided to check it out.

1. Installing Aspell

As mentioned in Evan’s post to install Aspell just type the following command from terminal:


sudo port install aspell aspell-dict-en

This will install both the aspell library and aspell English dictionary.

2. Install raspell

This is straight forward.


sudo gem install raspell -- --with-opt-dir=/opt/local

3. Setting up your own dictionary

For my case I needed aspell to check against my own custom dictionary. I create a text file containing the list of words with each word on a new line save it as wordlist. e.g.


John
Simon
Mae
Tim
Louis

Then run it with the following command.


aspell --lang=en create master ./en_SG-name.rws < wordlist

Note that for the language option I’m using ‘en’ which is the standard code for English. If you are generating a word list in other languages you will have to change lang option accordingly. The name of the output file is important because Aspell only pick up dictionary file in a certain naming format. The dictionary file should start with the language code then follow by a country code which is optional. For my case I have chosen SG because I do not want to override the default en dictionaries from Aspell. The ‘name’ after the ’-’ is actually the jargon. So if you are generating a word list of street names in US you might want to name you dictionary as en_US-street.rws. Once you have generated the dictionary you will have to place it in Aspell default dictionary directory.


sudo mv en_SG-name.rws /opt/local/share/aspell/

Because Aspell will only look for dictionaries with .multi file extension in the default directory. I’ll need to create a en_SG-name.multi file for my new dictionary

sudo vi /opt/local/share/aspell/en_SG-name.multi

and add the following line.


add en_SG-name.rws

You can add multiple dictionary to this file. If you needed the common English dictionary together with your custom one. Just add it accordingly.

4. Using your own dictionary in ruby.

Finally to use the dictionary I have just created.


require 'rubygems'
require 'raspell'

sp = Aspell.new('en_SG', 'name')
sp.suggest('Mea')
=> ["Mae"]

The first parameter is the language part of the file name and the second is the jargon. So if you have named your dictionary as en_US-street.multi then you will need to initialize it with


sp = Aspell.new('en_US', 'street')

Rails plugin to combine CSS and Javascript files digg delicious su

Posted by jason
on Friday, July 27

While multiple CSS and Javascript files aid manageability and facilitate a modular style of development, HTTP performance takes a hit because multiple requests are sent to the server for each of these files.

When we first launched HBO Asia’s recently revamped site, we found that the response time for pages to load was somewhat slow and thought that the many separated Javascript and CSS assets we were using might be a contributing factor.

David Heinemeier Hansson’s keynote at Railsconf 2007 mentioned that the upcoming Rails 2.0 will have a feature to combine all Javascript and CSS assets to help with this problem. In the meantime, however, we made do by manually combining the assets.

True enough, after doing so, the site’s performance was a little better. However, maintainability was compromised and every time I updated the combined files, I would have to update the individual files as well (as other parts of the site that do not need all the assets might be referencing the individual files).

Tired of such unproductivity, I decided to search for a Rails plugin that can automate this process and found CachedAssets. I’m currently testing this on development and will push this out to production soon if all goes well.

Ruby one click installer for mac OSX Tiger digg delicious su

Posted by chardy
on Wednesday, July 25

Once upon a time when I still use windows laptop as my workstation, I used to know there is a Ruby One click Installer for Windows. Just notice, another one click installer for mac is born. Visit http://rubyosx.rubyforge.org/ to download.

The good things are this package help to install basic framework to get you started with Ruby on Rails, It done the installation in UNIX way, which installed everything on /usr/local and it replaces the broken Readline library, updates to a current version of SQLite3 and prepares your OSX for Rails, which needs at least Ruby 1.8.4 to run.

After, do not forget to set your environment for /usr/local path.

 export PATH="/usr/local/bin:/usr/local/sbin:$PATH" 

But if you still prefer the Terminal way to install Ruby on Rails framework on OSX , I have fews good links below: (Just stick to these links, you will be fine)

  1. Hivelogic Guide
  2. NubyonRails Guide

Setting up Rspec, Autotest and Growl on Mac OS X digg delicious su

Posted by daniel
on Sunday, July 22
p> We have recently decided to use BDD for our upcoming projects. To make testing more fun and efficient I have hook up Growl with ZenTest’s autotest to display test results from Rspec. Some of the following instructions is taken from http://wincent.com/knowledge-base/Setting_up_autotest_to_use_Growl

What follows are the instructions to install the software to setup your own if you like to try out.

  1. Growl
  2. ZenTest
  3. Rspec

Installing Growl

  1. Download the dmg package from Growl
  2. Open the disk image, and double click in the Growl.prefPane icon.
  3. Next is to install growlnotify . Double click on the Growl disk image again if you have close it and execute the following commands from a terminal
 cd /Volumes/Growl/Extras/growlnotify
 sudo ./install.sh
 cd
 hdiutil detach /Volumes/Growl 

Installing ZenTest

ZenTest provides 4 different tools and 1 library: zentest, unit_diff, autotest, multiruby, and Test::Rails. For our purpose we will be using autotest. The latest version of ZenTest has added rspec support and it’ll auto detect rspec and run tests in the background whenever there’s any changes to the specs.

Installing ZenTest is easy just run the following command:

 sudo gem install ZenTest 

Installing Rspec

To test rails with rspec you will need to install rspec and rspec_on_rails plugins . Run the following command from your project root directory.

 script/plugin install svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec
 script/plugin install svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec_on_rails 

After you have installed the plugins you will need to run following command once to bootstrap your Rails app with RSpec.

 script/generate rspec 

Customize Autotest

The last step is to customize Autotest. Download the following 2 images and save them under ~/.autotest_images (create this directory if it does not exist). You can also create your own images if you want.

Open your favorite editor and copy and paste the code, then save the file as .autotest under your user home directory.

 module Autotest::Growl

   def self.growl title, msg, img, pri=0, sticky=""
     system "growlnotify -n autotest --image #{img} -p #{pri} -m #{msg.inspect} #{title} #{sticky}"
   end

  Autotest.add_hook :ran_command do |at|
    results = [at.results].flatten.join("\n")
    output = results.slice(/(\d+)\s+examples?,\s*(\d+)\s+failures?(,\s*(\d+)\s+not implemented)?/) 
      if output
        if $~[2].to_i > 0
          growl "FAIL", "#{output}", "~/.autotest_images/fail.png", 2
       else
         growl "Pass", "#{output}", "~/.autotest_images/pass.png" 
       end
     end
   end 
 end 

Configure Growl

Finally you can configure growl to with different display style via System Preference -> Growl. Try out all the different display style to see which one you prefer. Personally I like “Music Video”.

Once you have setup all the above. Run autotest under your project root directory and you will see Growl in action. Have fun!!

Why Ruby is exciting? digg delicious su

Posted by chardy
on Thursday, July 19

Sometime there is some fun on writing a duck type so called Ruby Programming Language. The language is neat and close to English as humanity language which we use daily. I use example of counting how many word in a String below:

class String 
  # Common usage using regular expression 
  def count_words 
    n = 0 
    scan(/\b\S+\b/) { n += 1} 
    n 
  end 

  # Ruby way (sort of) 
  # No vulgarity intention here, do not misunderstanding 
  def yet_another_count_words 
    self.strip.squeeze.split.size 
  end 
end 

"Passionately Remarkable Programmers".count_words #=> 3 
"Passionately Remarkable Programmers".yet_another_count_words #=> 3 

Both resulted the same result, so which one you like to follow, method count_words, or method yet_another_count_words. You make the choice. Cheer, have fun :-)

Naturally sort strings with numbers using Rails digg delicious su

Posted by jason
on Monday, July 16

A recent project required natural sorting of strings with numbers in them, i.e. in the order:

Series 1 
Series 2 
Series 3 
Series 10 
Series 23 
Series 35 

Sorting these strings 'unnaturally' would result in the following:

Series 1 
Series 10 
Series 2 
Series 23 
Series 3 
Series 35 

I was kind of surprised that Ruby nor Rails had this feature built-in. However, thankfully, the open-source community helped me solve my problem without cracking my brains too much. What I found were these:

The first solution extends the Array object with two methods: natcmp and natcmp!. Both of which will naturally sort an array of strings:

array_of_strings = ["Series 10", "Series 23", "Series 3", "Series 35", "Series 2", "Series 1"] 
array_of_strings.natcmp! # => ["Series 1", "Series 2", "Series 3", "Series 10", "Series 23", "Series 35"] 

The second piece of code adds a class method to the String object, accepting two strings as parameters to be sorted, returning either 1 or -1 (similar to the <=> method). I eventually used this solution, as what I needed to sort was an array of ActiveRecord objects, which I could do as follows:

array_of_records = Series.find(:all) 
array_of_records.sort! {|x,y| String.natcmp(x.name, y.name)} 

Sending emails using GMail smtp with ActionMailer digg delicious su

Posted by daniel
on Wednesday, July 11

If you have been following our blog you should have read the post Swiss Amry Knife 2.0 . We have recently switch our mail server to Google Apps. This is nice but that also means we have to change our ActionMailer server settings to GMail’s smtp server and this pose a problem. Because default ActionMailer does not support SSL authentication which is required by GMail. I tried searching for a solution and lucky enough I managed to came across this post and got to work! Check out the link if you are facing the same problem.

Install Gem in Local User Directory for Back Up Purpose digg delicious su

Posted by chardy
on Wednesday, July 11

It seems not maintainable when we have too many gems installed on your local machine gem repositories, indeed in UNIX machine, our access is granted by user group itself. How if one day, my harddisk crashes and I loss all my data, BTW, I only backup my home folder in this case. So due to this incident, I need to reinstall all my ruby gems again to get Ruby on Rails development environment ready to use. Too much work.

Try this to solve the issue, by installing all your gem inside you home folder.

$ cd ~ 
$ mkdir .gem 
$ export GEM_PATH=~/.gem 
$ gem install -i ~/.gem haml 

You can also put this export GEM_PATH=~/.gem to your ~/.profile or ~/.bash_profile.
Whats the .gem directory look like:

$ ls ~/.gem 
./ ../ bin/ cache/ doc/ gems/ source_cache specifications/ 

Rake file for SVN default ignores digg delicious su

Posted by daniel
on Wednesday, July 11

After reading the rake tutorial and reading about doing proper svn ignores . I had the idea of creating a rake file to do the default ignores. Here’s the code:


 namespace :svn do
   desc "Ignore standard files from svn" 
   task(:default_ignores => 'tmp:clear') do 
     `svn remove log/*` 
     `svn commit -m "removing all log files from subversion"` 
     `svn propset svn:ignore "*.log" log/` 
     `svn update log/` 
     `svn commit -m "Ignore all files in /log/ ending in .log"` 
     `svn remove tmp/*` 
     `svn propset svn:ignore "*" tmp/` 
     `svn update tmp/` `svn commit -m "Ignore all files in /tmp/"` 
     `svn move config/database.yml config/database.example` 
    `svn commit -m "Moving database.yml to database.example to provide a template for anyone who checks out the code"` 
     `svn propset svn:ignore "database.yml" config/` 
     `svn update config/` 
     `svn commit -m "Ignoring database.yml"` 
     `cp config/database.example config/database.yml`
   end
 end 

Save or download this code as svn_default_ignores.rake under the lib/tasks folder. Then run it using the following command from your project root directory:

 rake svn:default_ignores 

Enjoy!

Setting up SVN server on Mac digg delicious su

Posted by daniel
on Tuesday, July 10

As a software house, we need a way to track and manage all our different versions of source code. We are currently using subversion for version control (If you are not using any kind of version control for you source code you should serious think about it.) . There’s an article on how to install svn on mac from hivelogic .

After installation you will need to create the repository and configure the server before it’s ready to run.

STEP 1 : Create the repository

SVN stores all it’s files under a repository. We will need to create one before it can start running. Open the terminal and change directory a your desired location for the repository. Then issue the commoand:

 svnadmin create repos 

A ‘repos’ directory will be create.

STEP 2 : Securing your repository

Most of the time we do not want anybody to access our source codes unless it’s open source. Therefore we need to control user access. Using the same terminal from the previous step issue the command (You may use your preferred editor to edit the file):

vi repos/conf/svnserve.conf

The default svnserve.conf file will iinclude the following lines but are all commented out.

 # anon-access = read 
 # auth-access = write 
 # password-db = passwd 

The first line anon-access = read means that everyone have read access. But we do not want that. Therefore we have to change it to anon-access = none . The second line auth-access = write means that authorize users has read and write.

Just uncomment out these lines and change the anon-access value to none and save the file. The resulting file should be:

 anon-access = none
 auth-access = write
 password-db = passwd 

Since we only allow authorized users to access, we will need to modify the users database file passwd, which is in the same directory as the svnserve.conf file. Using vi command again :

vi repos/conf/passwd

Add in users under the “[users]” section and save the file:

 [users]
 harry = harrysecret
 sally = sallysecret 

STEP 3 Starting the server

Finally it’s time to start running the server. From the same terminal issue the following command:

 svnserve -d -r repos 

This will start the server in daemon mode using the repository ‘repos’ which you have created in step 1.

Proper ignores digg delicious su

Posted by shoop
on Friday, June 29

Working in a team with svn mean you gotta be careful with a number of things, especially if your svn repo goes all the way to the production site. 'Ignores' are something you cannot ignore.

For those special directories, e.g. RAILS_ROOT/config, create a .ignore file that might look like this (assuming you're testing with RailsBench and using Mongrel clusters)

benchmarks.*
database.yml
mongrel_cluster.yml

Once in place, use the "svn propset" command to set the svn:ignore attribute on the appropriate files.

$ svn propset svn:ignore -F .ignore .
property 'svn:ignore' set on '.'

As usual, svn status --no-ignore to check on what's been ignored.

$ svn status --no-ignore
I      benchmarks.rb
I      mongrel_cluster.yml
I      database.yml
I      benchmarks.yml
M      .

Date on Ruby digg delicious su

Posted by chardy
on Wednesday, June 27

Recently have been working a lot with Date in ruby, basically Ruby has Date, DateTime as subclass to Date and Time. Lets do some work out on Date with Ruby:

  • Time.now != DateTime.now && Time.superclass != Date
  • There is no method in Time class to convert object to a Date object, but you can write date = Date.new(time.year, time.mon, time.day). Rails Active Support extends DateTime and Time classes which allows to_date and to_time conversions for both classes.
  • Today is Date.today and now it is Time.now, there is no such thing as Date.now but there is Time.today
  • Tomorrow is Date.today+1, yesterday Date.today-1, to add or substract a month use Date.today >> 1 or Date.today << 1. See also Rails extensions to time class which allows to write things like Date.today.to_time.at_beginning_of_week
  • Date class includes Comparable module which allows us to write some_date.between?(Date.today, Date.today + 7)
  • Time.now.beginning_of_month.to_date.upto( Time.now.next_month.beginning_of_month.to_date-1) {|d| puts d.to_s} would print all days in current month in your Rails application.

On bugs and such... digg delicious su

Posted by jason
on Monday, June 25

I was stuck for several hours last week trying to solve a CSS problem that occurred with the following code:

div#content.home { .. }

div#content.secondary { .. }

The above CSS was applied to a page with this XHTML:

<div id="content" class="secondary">..</div>

The problem was that on IE6, the div#content.secondary selector does not affect anything on the div it was targeting. I tried adding margins, background colors, etc. but nothing would get any attributes declared within div#content.secondary to show up on IE6.

What I found out was: if I removed the div#content.home selector, everything works fine. Previously, when faced with such problems, it was usually the case that there was a silly syntax error somewhere, either within the CSS or XHTML. So I stripped the markup and styles down to its bare minimum (to try and see if I could spot any errors), validated the XHTML and CSS, but again, nothing worked.

I also tried switching the position of the selectors, putting div#content.secondary before div#content.home, and voila, it worked, albeit only for this page, as the problem reared its head on another page, with the div#content.home selector.

I was then several hours into this problem, and decided to leave it till the next day, when I would perhaps be mentally fresher and better primed to tackle the problem.

The next morning, after several attempts to solve the problem to no avail, I decided to Google the web to see if anything could be found and sure enough, I saw the following on css-discuss: Missing class assigments and Style rule based upon ID and Class?

Both the above links succinctly describe the problem as a bug on IE6 (for the record, this bug is fixed in IE7) so I won’t go into the details, but what I eventually did was not to use div#content.secondary at all and instead used div#content to set the styles I originally wanted for <div id="content" class="secondary"> and used div#content.home to override the styles I didn’t want to apply to <div id="content" class="home">..</div> (works because of CSS specificity).

This brings me to my next point: the problem of quickly identifying bugs that have already been solved by others before.

With situations as such, it isn’t immediately apparent what a particular bug is, until you narrow down the problem and have a few good keywords to search for. At this point, you’d probably be several hours into the problem already.

The same thing happened previously when I came across what I eventually found to be a bug within prototype.js (whereby Hash.toQueryString() would encode array values twice) and was even ready to submit a patch to Rails Trac, only to find that the problem was already solved.

Oh well, hope this post might help prevent you from spending the same amount of time I spent trying to solve the above-mentioned problems (that is, if you haven’t already spent the time narrowing down the problem(s) before landing here).

Installing Mephisto on Centos (Slicehost) digg delicious su

Posted by shoop
on Thursday, June 21
One of the prerequisites, ImageMagick, turns out to be quick a handful to install. Let's go through them one at a time.

GNU LibTool
LibTool is required to install the various RMagick delegate libraries as shared libraries. Check to see if you have GNU LibTool, usually installed in /usr/local/bin/libtool. If it's not there, do this (do check out the latest version from www.gnu.org/software/libtool ):
$ cd /usr/local/src
$ wget -v http://ftp.gnu.org/gnu/libtool/libtool-1.5.22.tar.gz
$ tar -zxvf http://ftp.gnu.org/gnu/libtool/libtool-1.5.22.tar.gz
   ...
$ cd libtool-1.5.22
$ ./configure
   ...
$ make
   ...
$ sudo make install
   ...
$

IJG JPEG Library

This is one of the delegate libraries recommended in the RMagick Install Guide. I thought I'll need it (get the latest library from www.ijg.org):
$ cd /usr/local/src
$ wget -v http://www.ijg.org/files/jpegsrc.v6b.tar.gz
$ tar -zxvf http://www.ijg.org/files/jpegsrc.v6b.tar.gz
   ...
$ cd jpeg-6b
$ ln -s /usr/local/bin/libtool ./libtool
$ ./configure --enable-shared
   ...
$ make
   ...
$ sudo make install
   ...
$


PNG LIbrary

Get this too if you think you'd be playing with PNGs (home: libpng.sourceforge.net):
$ cd /usr/local/src
$ wget -v http://downloads.sourceforge.net/libpng/libpng-1.2.18.tar.gz?modtime=1179259677&big_mirror=0
$ tar -zxvf libpng-1.2.18.tar.gz
   ...
$ cd libpng-1.2.18
$ ./configure --enable-shared
   ...
$ make
   ...
$ sudo make install
   ..
$


FreeType & Ghostscript
It turns out RMagick needs both FreeType and Ghostscript to install properly. (Source: freetype.sourceforge.net, www.cs.wisc.edu/~ghost)
$ cd /usr/local/src
$ wget -v http://download.savannah.gnu.org/releases/freetype/freetype-2.3.4.tar.gz
$ tar -zxvf freetype-2.3.4.tar.gz
   ...
$ cd freetype-2.3.4
$ ./configure --enable-shared
   ...
$ make
   ...
$ sudo make install
   ...
$
$ cd /usr/local/src
$ wget -v ftp://mirror.cs.wisc.edu/pub/mirrors/ghost/GPL/current/ghostscript-8.57.tar.gz
$ tar -zxvf
ghostscript-8.57.tar.gz
   ...
$ cd
ghostscript-8.57
$ ./configure --enable-shared
   ...
$ make
   ...
$ sudo make install
   ...
$

Image Magick
This is required for Mephisto (www.imagemagick.org)
$ cd /usr/local/src
$ wget -v ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick-6.3.4-9.tar.gz
$ cd ImageMagick-6.3.4-9
$ ./configure --disable-static --with-modules --without-perl --without-magick-plus-plus --with-quantum-depth=8
   ...
$ make
   ...
$ sudo make install
$

During the configuration, watch out towards the end of the output for the following, just to ensure the JPEG and PNG libraries are properly in place.
                  Option                        Value
-------------------------------------------------------------------------------
Shared libraries  --enable-shared=yes           yes
Static libraries  --enable-static=no            no
Module support    --with-modules=yes            yes
GNU ld            --with-gnu-ld=no              no
Quantum depth     --with-quantum-depth=8        8
High Dynamic Range Imagery
                  --with-hdri=no                no

Delegate Configuration:
BZLIB             --with-bzlib=yes              yes
DJVU              --with-djvu=yes               no
DPS               --with-dps=yes                no (failed tests)
FlashPIX          --with-fpx=no                 no
FontConfig        --with-fontconfig=yes         no
FreeType          --with-freetype=yes           no (failed tests)
GhostPCL          None                          pcl6 (unknown)
Ghostscript       None                          gs (unknown)
Ghostscript fonts --with-gs-font-dir=default    none
Ghostscript lib   --with-gslib=yes              no
Graphviz          --with-gvc=yes                no
JBIG              --with-jbig=yes               no
JPEG v1           --with-jpeg=yes               yes
JPEG-2000         --with-jp2=yes                no
LCMS              --with-lcms=yes               no
Magick++          --with-magick-plus-plus=no    no
OpenEXR           --with-openexr=yes            no
PERL              --with-perl=no                no
PNG               --with-png=yes                yes
RSVG              --with-rsvg=yes               no
TIFF              --with-tiff=yes               no
Windows fonts     --with-windows-font-dir=      none
WMF               --with-wmf=yes                no
X11               --with-x=                     yes
XML               --with-xml=yes                yes
ZLIB              --with-zlib=yes               yes


RMagick (Optional)
We can install RMagick with rubygems:
$ sudo gem install rmagick
Building native extensions.  This could take a while...
Successfully installed rmagick-1.15.7

In my Centos4.5 installation, the RMagick gem install failed due to missing Ghostscript fonts. Here's where to get them (pages.cs.wisc.edu/~ghost/doc/AFPL/5.50/Fonts.htm):
$ cd /usr/local/share/ghostscript
$ wget -v http://downloads.sourceforge.net/gs-fonts/ghostscript-fonts-std-8.11.tar.gz?modtime=1059609600&big_mirror=0
$ tar -zxvf ghostscript-fonts-std-8.11.tar.gz
   ...
$

Do this to check that RMagick is installed properly:
$ irb -rubygems -r RMagick
irb(main):001:0> puts Magick::Long_version
This is RMagick 1.15.7 ($Date: 2007/06/09 16:45:25 $) Copyright (C) 2007 by Timothy P. Hunter
Built with ImageMagick 6.3.4 06/13/07 Q8 http://www.imagemagick.org
Built for ruby 1.8.5 (2007-03-13 patchlevel 35) [x86_64-linux]
Web page: http://rmagick.rubyforge.org
Email: rmagick@rubyforge.org
=> nil


Mephisto
The following instructions came from this page (mephisto.stikipad.com/help/show/Installing+Mephisto)

  1. Create a database named mephisto (or one of your choosing).
  2. Copy config/database.example.yml to config/database.yml
  3. Edit database.yml and set your database credentials.
  4. Upload the entire mephisto directory to your webserver.
  5. Run rake db:bootstrap from a terminal of some sorts (use rake db:bootstrap RAILS_ENV=production to be sure you’ve bootstrapped the production database.)
  6. Run script/server --e production or mongrel_rails start or whatever’s appropriate to get the Rails web server going.
  7. Login to your administration at http://domain.com/admin with the username: admin and password: test