Rails 3.0-R.C Installation (RubyGems 1.2+ index not found)

If you are having problem with installation of Rails 3 (–pre)
and you are receiving following message:

“WARNING: RubyGems 1.2+ index not found for:”

You should take a look at your .gemrc file and see if you have
repositories that don’t support pre-released gems

I had to remove everything except:

:sources
- http://gemcutter.org
- http://gems.github.com
- http://gems.rubyforge.org

Hopefully this will fix your problem.

Vim line enumeration

If you are doing a lot of enumerations inside of vim this may help:

command -range=% Enumerate : , !ruby -e “STDIN.each_with_index{|l,idx| puts (idx + 1).to_s + ‘. ‘ + l}”

What does it do?

Given a range of lines it inserts line number in front of the line starting with 1 and increments the line numbers from there.

Before:


This is a test
Second line of the test
Finally end of the test

After:


1. This is a test
2. Second line of the test
3. Finally end of the test

How do I use this thing?

1. Open your .vimrc
2. Add the line from above
3. Open Vim
4. Select few lines (v)
5. Type :Enumerate

Requirements

Ruby interpreter

Ruby Metaprogramming quiz #1

Implement only MyHelper module and make the tests pass. Good luck.

require 'test/unit'
 
module MyHelper
 
end
 
class Foo
  BAR = 1
  NORM = 3
  include MyHelper
end
 
class Baz
  BAR = 2
  NORM = 4
  include MyHelper
end
 
class MyTest < Test::Unit::TestCase
  def test_Foo
    foo = Foo.new
    assert_equal(1, foo.score)
    assert_equal(1, Foo.bar)
    assert_equal(1, foo.bar)
    assert_equal(3, Foo.norm)
    assert_equal(3, foo.norm)
  end
 
  def test_Baz
    baz = Baz.new
    assert_equal(2, baz.score)
    assert_equal(2, Baz.bar)
    assert_equal(2, baz.bar)
    assert_equal(4, Baz.norm)
    assert_equal(4, baz.norm)
  end
end

Tidy incantations

I have been using tidy on and off for a few years now and it’s been a great tool for finding problems with the html markup. I always wanted to use it for reformatting (cleaning up) output. Especially wanted it for reformatting xml output of some web services that have a nasty habit of putting the whole content on a single line.

But now I have found the right incantation:

 
$ cat source_file.xml | tidy -q -xml -i -w 300 > reformatted_file.xml

Updating rubygems from 1.2.0 to 1.3.5

You would think it this process is straight forward but it appears there were changes that prevent simple update but here are the steps:

1. Update to 1.3.0:

$> sudo gem install rubygems-update -v 1.3.0
...
 
$> sudo update_rubygems
...

2. Update to the most recent release

$> sudo gem update --system
...

3. Check the version

$> gem --version
1.3.5

That’s it.

AutoGrowling: making autotest and spectest work with Growl

I like test and feature driven development. It keeps me on track when writing ruby code. Since I work on few different projects and some of these projects use TestUnit while others use Rspec I needed the .autospec hook to handle both formats.

So here is another tutorial on how to get these things working together:

  1. Download Growl from: http://growl.info/
  2. Install the downloaded dmg
  3. Install growlnotify from Extras/growlnotify folder in the dmg
  4. Copy the folder to your desktop
    Open the terminal and run following commands.

    $ cd Desktop/growlnotify
    $ sudo sh install.sh
  5. Create
    ~/.autotest_images/

    folder.

  6. Save following images into the folder.

Install following gems: ZenTest, redgreen:

$ [sudo] gem install ZenTest
$ [sudo] gem install redgreen

Download the script below and rename the file to .autotest and place it in your home folder user folder.

##!/usr/bin/ruby
require 'autotest/redgreen'
require 'autotest/timestamp'
 
class AutoTestNotifier
  IMAGEDIR = File.expand_path("~/.autotest_images")
  FAIL_IMG = IMAGEDIR + "/rails_fail.png"
  PASS_IMG = IMAGEDIR + "/rails_pass.png"
  PEND_IMG = IMAGEDIR + "/rails_pending.png"
 
  def self.growl(data)
    AutoTestNotifier.new(data).notify
  end
 
  def initialize(data)
    @priority = nil
    @result = {}
    if data.last =~ /examples/i
      parse_spec_message(data)
    else
      parse_unit_message(data)
    end
  end
 
  def parse_spec_message(data)
    @result[:type] = :spec
    output = data.last.strip.gsub(/\e\[\d+m/, '').split(',')
    output.map do |i| 
      val, lbl = i.strip.split(" ")
      @result[lbl.to_sym] = val.to_i
    end
  end
 
  def parse_unit_message(data)
    @result[:type] = :unit
    output = data.last.chop.split(',')
    output.map do |i| 
      val, lbl = i.strip.split(" ")
      @result[lbl.to_sym] = val.to_i
    end
  end
 
  def img
    return FAIL_IMG if @result[:errors].to_i > 0 || @result[:failures].to_i > 0 
    return PEND_IMG if @result[:pending].to_i > 0 
    return PASS_IMG
  end
 
  def title
    pre = @result[:type] == :spec ? "Spec Tests" : "Unit Tests"
    return "#{pre} Failed:" if @result[:errors].to_i > 0 || @result[:failures].to_i > 0 
    return "#{pre} Pending:" if @result[:pending].to_i > 0 
    return "#{pre} Passed:"
  end
 
  def to_s
    msg = ""
    msg << "Examples: #{@result[:examples]}     " if @result[:examples]
    msg << "Tests: #{@result[:tests]}     " if @result[:tests]
    msg << "Assertions: #{@result[:assertions]}     " if @result[:assertions]
    msg << "Pending: #{@result[:pending]}      " if @result[:pending]
    msg << "Failures: #{@result[:failures]}     "
    msg << "Errors: #{@result[:errors]}" if @result[:errors]
    msg
  end
 
  def priority
    return @priority || 0
  end
 
  def stick
    return ""
  end
 
  def notify
    cmd = "growlnotify -n autotest --image #{img} -p #{priority} -m '#{to_s}' #{title} #{stick}" 
    `#{cmd}`
  end
 
end
 
module Autotest::Growl
  Autotest.add_hook :ran_command do |at|
    AutoTestNotifier.growl(at.results)
  end
end

This should take care for both the UnitTest and RSpec messages.

Fixing libxml-ruby 0.9.9 on Leopard OS X

Update: The problem has been fixed in version 1.0.0.

Recently I have tried to update my gems and I have noticed that things just stopped to a grinding halt when it got to libxml-ruby. It appears that the 0.9.9 spectacularly barfed all over itself and it stopped other gems from being updated. Not good!

I started Googling for some answers but since the release has only 2 days I guess not that many people have run into it just yet.

I have found a repo with a patch:

http://github.com/tadman/libxml-ruby/tree/master

If you not paranoid you may do:

$ git clone git://github.com/tadman/libxml-ruby.git 
$ cd libxml-ruby
$ ruby setup.rb
$ rake gem
$ sudo gem install admin/pkg/libxml-ruby-0.9.9.gem

If you are paranoid then you would go to the install directory where the original gem broke:

$ cd /Library/Ruby/Gems/1.8/gems/libxml-ruby-0.9.9
$ cd ext/libxml

Edit:

ruby_xml_html_parser_context.c
ruby_xml_parser_context.c
by inserting “extern” before “ID IO_ATTR;” statement.

After these files are updated

$ cd ../..
$ ruby setup.rb
$ rake gem
$ sudo gem install admin/pkg/libxml-ruby-0.9.9.gem

Few words on cracking iPhone applications

Few days ago I was reading about Craculous being released as an open source application. Since Craculous is an iPhone application cracking tool and I have a few apps in the AppStore I have a few points to make to all those people who are considering using the tool.

I know a few developers who write apps for the AppStore. They aren’t millionaires. Some of them barely make enough money to cover their bills. Others, work second jobs because the income from the AppStore is just not enough to pay for their necessities.

Yes, there are few people who were lucky enough to make good money but, if you think for a second, how many of those have you heard about? 3, 5, 20? And how many apps are in the AppStore? The last number was around 18′000. So who do you think you are stealing from? You may as well go to the poorest part of town you live in, find a woman who is working 2 jobs to support her and two children and then rob her. That’s pretty much an real life equivalent of you cracking an app from the AppStore.

Now that you know how it feels from the other side of the AppStore let me tell you a little bit of what happens when the third party developers can’t make enough money. People like I and my friends have two choices.

First, is just to say “fuck it!” and do something else where we can make some money. The second option is to develop ad supported apps. Both of these options aren’t very good for you.

See, unlike artists (musicians, actors, producers) we developers can do other things. We can work for companies and write business apps for them. We can create subscription web apps for which you will shell out way more money then a simple app on your phone. We can work for big companies Apple, Adobe, Microsoft and create apps that are locked
so tight that you will need a blood sample to authenticate yourself as a user. It’s not the most attractive work but it does pay the bills. We can do that but then you will not get the cool apps on your phone.

Honestly, most of the indy developers would rather create apps for you. Find out what you need and help you out with the solution. All we ask is for you to help us pay our bills.

Now the second option. Adware! Sounds almost like a curse word and it really is. When someone develops adware they are no longer working for you. The are working for the people who peddle their products through the software. You will never have as good experience with adware as with software that is developed for you. You loose the control of what features are added to the program because you aren’t paying for it. This is why most adware software are pieces of garbage.

Take for example the shows you get on TV stations supported by commercials and the ones that are not. Most of the shows on commercials supported channels are designed to sell you stuff. The plot is created to build the suspense up and stop for a commercial break. They will always leave you hanging and show you the stuff they want to sell to you.

On the other hand when you watch shows from stations which do not have to rely on sponsors you will get the whole story. They don’t have to worry about placing the ads and creating the shows with ads in mind. They just want to give YOU the best experience. The best show.

Similar things you will find in software. Either you pay for the best experience there is or you are going to get junk that sells you other junk. Your choice.

The last thing I would like to bring to your attention is the word “honor.” Where is their honor? I realize that some people might have forgotten the word. Others, may be confused by the myriad of definitions.

I am talking about this one:

honor
- noun
“honesty, fairness, or integrity in one’s beliefs and actions”

Is cracking $0.99 app worth giving up your integrity?

Please comment and let me know what you think.

iPhone screenshot processing – part 2

Today I was working on automating of preparation of iPhone screen shots for usage on the website. The new eideticsoftware.com website design requires for the images to have drop shadows so instead processing everything in Adobe® Photoshop® I have decided it would be much nicer to just automate the process with rmagick.

If you are impatient and just want the script jump to the bottom of the post and download image_processor.rb but if you want to know how it works then read on.

This script scales the images for the post.

example_scaled
First we take the original image and scale it by 50% –

source = original.scale(0.5)











example_scaled_stripped
Next we strip out the status bar with crop method:

source = source.crop(0, 10, 160, 240)











example_scaled_stripped_canvas_with_shadow
We create a transparent canvas that is 10px wider and 10px longer and another identical canvas that we are going to use for the shadow. On the image_shadow canvas we draw a rectangle with the same dimensions as the original image. In the source file the rectangle is created by the “drop_shadow_rectangle” function.

We use the image_shadow canvas to create two shadows, first is the actual shadow, the second we use as a mask to soften the shadow itself.

We apply the first shadow to the original canvas with “OverCompositeOp” option and then we apply the mask on top of that with “CopyOpacityCompositeOp” option.


example_scaled_stripped_canvas_with_image
We apply the scaled and cropped image on top of the shadow and draw a white border. The white border is only necessary when the screen shot is dark to distinguish the shadow from the image.

Finally we write the image to a file with “canvas.write” method.







Source Code

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
require 'rubygems'
require 'rmagick'
 
include Magick
 
img_filename = "example.png"
 
 
# Helper function to create new name
def new_name(img_filename, modifier = "_shadow")
  chunks = img_filename.split(".")
  chunks[0..-2].join(".") + modifier + ".#{chunks[-1]}"  
end
 
# Creates drop show rectangle
def drop_shadow_rectangle(x,y,width,height)
  gc = Draw.new
  gc.fill_color("black")
  gc.rectangle(x,y,width,height)
end
 
# creates frame draw object
def white_frame(x,y,width, height)
  frame = Draw.new
  frame.fill_opacity(0)
  frame.stroke_color("white")
  frame.rectangle(x,y,width,height)
end
 
 
def add_shadow(img_filename)  
  original = ImageList.new(img_filename)
 
  source = original.scale(0.5)
  source.write(new_name(source.filename, "_scaled"))
  source = source.crop(0, 10, 160, 240)
 
  canvas = Image.new(source.columns + 10, source.rows + 10) do
    self.background_color = "transparent"
  end
 
  # Generates intermediate images
  #source.write(new_name(source.filename, "_stripped"))
  #canvas.write(new_name(source.filename, "_raw_canvas"))
 
  image_shadow = Image.new(canvas.columns, canvas.rows) do
    self.background_color = "transparent"
  end
 
  drop_shadow_rectangle(0, 0, source.columns, source.rows).draw(image_shadow)
 
  blur = 1
  x, y = 1, 1
 
  image_shadow = image_shadow.shadow(x, y, blur, 1)
  shadow_mask = image_shadow.shadow(x, y, blur, 1)
 
  # Place the shadow
  canvas.composite!(image_shadow, 0, 0, OverCompositeOp)
 
  # Place the mask to soften the shadow
  canvas.composite!(shadow_mask, 0, 0, CopyOpacityCompositeOp)
 
  # Intermediate image  
  # canvas.write(new_name(source.filename, "_canvas_with_shadow"))
 
  # Now place the image on the canvas
  canvas.composite!(source, 1, 1, OverCompositeOp)
 
  # And draw the white border on top of the image
  white_frame(0, 0, source.columns, source.rows).draw canvas
 
  # save the final image
  canvas.write(new_name(source.filename, "_canvas_with_image"))
end
 
add_shadow(img_filename)

Processor: image_processor.rb

Logo artwork

There are days when your work is appreciated and rejected at the same time. Today is one of those days. I was told by my boss that she liked the logo but we have to keep everything branded so we will not use it. In my opinion one of the less creative marketing drones was deeply involved in the decision making. Oh well, since they did not want it I figured some of you may enjoy it.

tti_university_towers