Friday, February 29, 2008

ExtJS & Rails - ExtJS scaffold generator installation script

What?
An automatic installation script for the ExtJS scaffold generator plugin (demo keynotes)to get you up and running.

Why?
Rails' scaffolding gets you up an running lightning fast. ExtJS is a wonderful javascript desktop library. Let's marry them

How?
Run the following script - it will

  • Create the rails application
  • Install the ExtJS scaffolding plugin
  • Download and install ExtJS for your application
  • Generate two sample models - posts and purchases
  • Setup the database
  • Create links to the sample models on the application landing page
  • Run the server
Then all you have to do is point your browser to http://localhost:3000, assuming the server is running on your computer.

Have fun!

# Create the app
rails ext_scaffold_setup
cd ext_scaffold_setup

# Install the plugin and extjs
script/plugin install http://rug-b.rubyforge.org/svn/ext_scaffold
curl -O http://extjs.com/deploy/ext-2.0.2.zip
unzip -q ext-2.0.2.zip
rm ./ext-2.0.2.zip
mv ./ext-2.0.2 ./public/ext

# Generate some scaffolds - posts and purchases
./script/generate ext_scaffold post title:string body:text
./script/generate ext_scaffold purchase order_id:integer amount:decimal description:text

# Create the database for the models
rake db:migrate

# Create links to the models on the landing page
echo '<title>ExtJS Scaffold generator sample</title>echo '<style type="text/css" media="screen">a {text-decoration:none; color:#abc}</style><a href="http://www.blogger.com/posts">Posts</a> <a href="http://www.blogger.com/purchases">Purchases</a>' > ./public/index.html

# All set, run the server!
./script/server

Point your browser to http://localhost:3000, and you're good to go.

Wednesday, February 27, 2008

Manual Depth Perception (OpenGL Shading)

Shadows play a tremendous roles in our visual understanding of depth. This can be used to trick the eye:















In the above image, the color of square B is, in fact, the same as that of square A. Don't believe me? These are small crops of the above image:




However, shadows are also very important to aid the eye. Or so we learned in Graphics. So we had to make shadows for a map. Manually.

Here's the m
ap without shadows. Green is lowland, red is highland, black and white even higher.


















And, with shadows:


















Aiding, huh? Aaaand, just the shadows... Please note that each of these pixels is calculated based on two values - an evelation coordinate (z) of the map at any given point (x,y), and a static directional (x,y,z) vector of sun light.


Tuesday, February 26, 2008

Hidden OS X Gems

What?

A handpicking of 4 "hidden" OS X gems from OakInnovations' list of 10

  1. Easily compare versions of a file, and cherry pick among the differences: FileMerge

  2. Summarize any text: Summarize

  3. Save snippets of text and images by dragging them from your web browser to the Desktop: Drag n Drop Save

  4. Have folders update their content automatically based on simple rules: Smart Folders
How?
  1. FileMerge - Type in FileMerge in Searchlight, or use the Finder menu Finder > FileMerge > Compare Files

  2. Summarize - Select text, go to the application menu (e.g. Safari) > Services > Summarice

  3. Drag n Drop Save - Just mark the text or picture you want to save, and drag it to the Desktop. (Only works in Carbon applications - yet another reason to switch to WebKit)

  4. Smart Folders - In Finder, File > New Smart Folder (or just hist cmd + opt + N). A smart folder can be really simple and powerful, or complex and very powerful.

    (On my Desktop I have a smart folder Recent Ruby with rules Modified within last 1 day, and name ends in rb. This gives me a quick overview over all the files in all my current Ruby projects that I've worked on today.)

Monday, February 25, 2008

BackPackIT BackOffIT! ClockingIT isIT!

What?

ClockinIT: A free, beautiful, open source project management website.



"ClockingIT was created for fun, not profit, using Ruby on Rails"



While 37signal's Backpackit has had a bit of monopoly on the ajaxian project management frontier, ClockingIT recently sprung up from two dedicated Norwegian developers, and the community seems to be building strong.

ClockingIT specs: built leveraging a ton of open source goodies, including Ruby on Rails, MySQL, Juggernaut (cometing), and more.

Why?


Three main points for ClockingIT over Backpackit:

  • It's Free
  • It's Open source
  • It's Up and running in 2 minutes
How?

Go to ClockingIT.com and signup.

For developers who want to contribute, get the source with darcs (howto) or with git (repository: git://repo.clockingit.com/cit).

[git installation instructions on OS X 10.5]

Git on OS X 10.5

What?

Git on OS X 10.5 Leopard.

Why?

Git is YARC (yet another revision control system) with some outstanding differences. You can find out for yourself just what those are, but as a hint git is written by Linus Torvalds who hates CVS and SVN - "a bad idea and its bad fix walking hand in hand."

So what does git have going for it?

  • Distributed repositories - you don't need to rely on a central host
  • Branching made easy - in the same spirit, code branches is a breeze
  • Speed - it's just that much faster
How?

So you want it - now how do you get it?

Thanks Wincent.com for the seamless installation script. Just copy the text, paste it into the terminal, and stick around to watch it all happen (and type your password at sudo time.

More configuration scripts are also available, as well as an introductory tutorial.

# build expat dependency
curl -O http://surfnet.dl.sourceforge.net/sourceforge/expat/expat-2.0.1.tar.gz
tar xzvf expat-2.0.1.tar.gz
cd expat-2.0.1
./configure
make
make check
sudo make install
cd ..

# build GPG for signature verification
curl -O ftp://ftp.gnupg.org/gcrypt/gnupg/gnupg-1.4.7.tar.bz2
openssl sha1 gnupg-1.4.7.tar.bz2
tar xjvf gnupg-1.4.7.tar.bz2
cd gnupg-1.4.7
./configure
make
make check
sudo make install
cd ..

# copy GPG files from Tiger install
mkdir -m 700 ~/.gnupg
cp ${PATH_TO_TIGER_HOME_FOLDER}/.gnupg/*gpg* ~/.gnupg/

# git
curl -O http://kernel.org/pub/software/scm/git/git-1.5.2.4.tar.bz2 \
-O http://kernel.org/pub/software/scm/git/git-1.5.2.4.tar.bz2.sign
gpg --verify git-1.5.2.4.tar.bz2.sign git-1.5.2.4.tar.bz2
tar xjvf git-1.5.2.4.tar.bz2
cd git-1.5.2.4
make prefix=/usr/local all
make prefix=/usr/local test
echo $?
sudo make prefix=/usr/local install
cd ..

# manpages
curl -O http://www.kernel.org/pub/software/scm/git/git-manpages-1.5.2.4.tar.bz2 \
-O http://www.kernel.org/pub/software/scm/git/git-manpages-1.5.2.4.tar.bz2.sign
gpg --verify git-manpages-1.5.2.4.tar.bz2.sign git-manpages-1.5.2.4.tar.bz2
sudo tar xjv -C /usr/local/share/man -f git-manpages-1.5.2.4.tar.bz2

Barack knows me

Not only does Barack Obama (et al) know how I communicate (e-mail, blog presence, and youtube videos); he knows how I wear my t-shirts.


Sunday, February 24, 2008

Is YouTube down?

For the past 2 hours, I've been unable to get on to YouTube.


It's on the scale of unlikely that  a service with the administration and infrastructure of google would go down, but it's only a year and a half since it happened last time (which was the first time).

So is this the second of biannualish youtube failures? 

Update (2:55) - The site is back up and running. Here are some interesting theories on what happened:

Wednesday, February 20, 2008

Bill Gates cooks up plan to have UoC students switch to Vista.

Today Bill Gates came to speak on our campus. Access was restricted through a ticket lottery. Effectively, 99% of interested students and the rest of the world were left with the option of viewing a recording of the talk online.

Note the wmv file format. Also note that, when played on a mac (with or without Flip4Mac), it has no sound.

When I tried to download it for conversion, it gave me this:















My guess is it only plays on Vista, and this was all a scheme from Mr. Gates to get us to "up-grade" (get it?). Kind of like how the only way to get people to use MS Office 2007 is to force them, because, guess what - it's broken.

Skim - Potential OS X PDF Editor (Open Source)

Looking around for a PDF viewer that lets me annotate the document and doesn't suck, I ran into Skim, an open source PDF viewer and annotator for OS X. It has some obvious shortcomings (such as not being able to edit text), but it's ahead of all other contestants.

I wish it could but it can't...

  • ... edit the document text
  • ... export annotations such that other PDF viewers can see them
However, it...
  • Underlines
  • Highlights
  • Strikes-through
And, like Preview...
  • ... makes red ovals




  • ... creates blaring yellow comment boxes




And, somewhat unnecessarily...
  • ... Green Boxes!









  • ... Icon notes! (Text appears if you double click)








The verdict

Better armored than Preview, but also more cluttered. Clearly the best alternative so far - however, no cigar. It seems to me like someone could make a name for himself cracking this nut. Takers...?

Full screenshot



Review - Open Source PDF Editors

What?


There are plenty of good PDF viewers out there. Combined with the format's platform independence, it makes PDF a great format for presentation.

However, I've never gotten my hands on a good open source PDF editor.

So I took the time to look around a bit. Here's what I found:

  • PDFEdit - free and open source. I couldn't get it to compile on OS X. Here's an article pointing out all its flaws, and still hailing it. That's how bad we need a good open source PDF editor.
  • ReportLab Toolkit - a "mature PDF library." In fact, so mature that it took me 10 minutes of mature fighting with it before I maturely gave up trying to get its demo to work.
  • PDFCreator - Windows only... However, my guess goes against some Microsoft groupie randomly cracking this nut.
  • Skim - The only somewhat promising alternative.
Still no winner. If someone has one, let me know. In the meantime, check out my quick Skim review (it's worth the skim).

Mac OS X : Save PDF's of Any Document with a Click

What?

Save a PDF of any document or picture to pre-determined folders with a quick cmd+p and click (without navigating the directory structure)

How?

  1. Go to /Library (Open Finder, hit Cmd+Shift+G, type /Library, hit Enter)
  2. Find or create a folder named PDF Services
  3. Open a new Finder window, and create the Folders you want to save PDF's to (hit Cmd+N, and hit Cmd+Shift+N to create each Folder)
  4. Create an alias for each Folder (Select all folders, hit Cmd+L)
  5. Drag all aliases to the /Library/PDF Services folder in the first window
Done. You will now have the selected folders appear in the save menu.

Extra Hint

You can alias other things than Folders. If you often read and highlight created PDF's in, say, Acrobat Reader, then try to alias the Acrobat Reader application and put it in /Library/PDF Services as well.

Thank you

Macworld for the great article, with this and other tips.

Thursday, February 14, 2008

Ruby acts_as_taggable plugin bug fix for Rails 2.0.2

What?
I'm working on a small rails app and wanted tags, so I went ahead and installed the acts_as_taggable plugin. However, I had some problem with installation. First, I just ran

./script/plugin install acts_as_taggable

and followed setup procedures. However, I then got the following error when I called acts_as_taggable in my class

NameError: uninitialized constant Tag

I then found a post that directed me to the correct source for the tag:

./script/plugin install http://svn.rubyonrails.org/rails/plugins/legacy/acts_as_taggable/

However, running rails 2.0.2, the has_many API has changed, so I got the following error:

ArgumentError (The :dependent option expects either :destroy, :delete_all, or :nullify (true))

I traced the error down in the plugin to the file rails_root/vendor/plugins/acts_as_taggable/lib/acts_as_taggable.rb

The error is on line 18

has_many :taggings, :as => :taggable, :dependent => true

should be

has_many :taggings, :as => :taggable, :dependent => :destroy

Now it works!

Wednesday, February 13, 2008

Ruby: All Combinations / Permutations up to length n-1 of a String

What?
In writing a Scrabble like game, I needed a quick fix to get all possible combinations of a string (of length 1..n). I would then look these combinations up in the dictionary to determine if they are words valid for placement.

Why?
It would be nice to able to do the following:

'abc'.combinations.each do |combo|
dictionary.lookup(combo)
end
So I hacked up the following:
class String
# Get all the combinations of a string.
# Returns an array of all combinations of a string
# If a block is given, then that block is called once for each combination
def combinations &action
ret = []
0.upto length-1 do |n|
#rest = self.split('') # regular
rest = self.split(//u) # UTF-8
picked = rest.delete_at n
action.call picked if action
ret << picked
rest.join.combinations.each do |perm|
genperm = picked+perm
ret << genperm
action.call genperm if action
end
end
ret
end
end
Which does the following:
p 'abc'.combinations # => ["a", "ab", "abc", "ac", "acb", "b", "ba", "bac", "bc", "bca", "c", "ca", "cab", "cb", "cba"]

'abc'.combinations do |combination|
puts combination
end
# =>
# a
# ab
# abc
# ac
# acb
# b
# ba
# bac
# bc
# bca
# c
# ca
# cab
# cb
# cba
Just what I wanted!


Sunday, February 10, 2008

Sequential Contracts in Ruby - Design by Contract Extension


What?

Software Designed By Contract is constructed along with terms of use and guaranteed behavior.

There are (at least) three types of contracts:
  • Pre-conditional contracts specify conditions that have to be met before a function is used, e.g. the demand that a value passed into a function is greater than or equal to 0
  • Post-conditional contracts specify conditions that are guaranteed to be be fulfilled after a functionality is used, e.g. ruby's Array#flatten! method guarantees that the resulting array is either nil or one-dimensional.
  • Sequence contracts specify the sequence in which functionalities are allowed to be used. For example, a File class could specify the sequence File#open, multiple File#read's, File#close.
Why?

While documenting expected conditions gives the user of a software component an indicator what and what not to do, this cannot guarantee that conditions are actually met and can result in unexpected errors. Thus, we want a method to formally define contracts and ensure that they are met at run-time.

Ruby does not have built in support for contracts, but Ruby programmers Martin and Brian created a neat module for pre- and post-conditional contracts. However, it does not support sequential contracts. I recently had the need for sequential contracts in Ruby, and so decided to go ahead and implement it.

How?

To declare a sequential contract for a class, you first define the methods and then declare the sequence in which you expect the methods of any given object to be called. Let's say we have a Greeter class that creates conversing objects:

class Greeter

def greet
puts "Hello!"
end

def ignore
puts "Pss!"
end

def ask_question
puts "How are you?"
end

def talk
puts "Blah blah blah"
end

def give_answer
puts "Good thank you!"
end

def say_goodbye
puts "Bye!"
end

def leave
puts "Walking away..."
end
end


Obviously, we would not want our greeter to first greet and then ignore you, or leave before it says goodbye. So let's declare a sequence contract after the methods of the Greeter class:

g = Greeter.new
g.greet

g.ask_question
# Must say goodbye before you leave!
g.leave


Now, if we create a Greeter and have it behave in a bad manner (e.g. ask a question without saying hello, or leaving before saying goodbye), then an IllegalSequence exception is raised:


# Declare a sequential contract
extend SequenceContract
sequence_contract do
start do
transition 'greet' => :chat
transition 'ignore' => :walk_away
end
state :chat do
transition 'ask_question' => :chat
transition 'talk' => :chat
transition 'give_answer' => :chat
transition 'say_goodbye' => :walk_away
end
state :walk_away do
transition 'leave' => :done
end
end
Together with test cases, the whole baddabing looks like:

require 'test/unit'
class TestSequenceContract < Test::Unit::TestCase

class Greeter
# Declare a sequential contract
include SequenceContract

def greet
puts "Hello!"
end

def ignore
puts "Pss!"
end

def ask_question
puts "How are you?"
end

def talk
puts "Blah blah blah"
end

def give_answer
puts "Good thank you!"
end

def say_goodbye
puts "Bye!"
end

def leave
puts "Walking away..."
end

sequence_contract do
start do
transition 'greet' => :chat
transition 'ignore' => :walk_away
end
state :chat do
transition 'ask_question' => :chat
transition 'talk' => :chat
transition 'give_answer' => :chat
transition 'say_goodbye' => :walk_away
end
state :walk_away do
transition 'leave' => :done
end
end
end

def test_illegal_sequence
g = Greeter.new
assert_nothing_raised do
g.greet
g.ask_question
end
assert_raises SequenceContract::IllegalSequence do
g.leave
end
end

def test_legal_sequence
assert_nothing_raised do
g = Greeter.new
g.greet
g.ask_question
g.say_goodbye
g.leave
end
end

def test_multiple_instances
g = Greeter.new
assert_nothing_raised do
g.greet
g.ask_question
g.say_goodbye
end
g = Greeter.new
assert_raises SequenceContract::IllegalSequence do
g.leave
end
assert_nothing_raised do
g.greet
g.ask_question
g.say_goodbye
g.leave
end
end
end # TestSequenceContract

The SequenceContract module itself can be found here for now.