Time.onrails.org is closing! 1

Posted by Daniel Wanja Thu, 18 Feb 2010 03:15:03 GMT

I just send an email to thousands of users to notify them that time.onrails.org is closing down. I don’t think many of these users are active but just in case I wanted everyone to be able to get their data out of the system if so they wished.

I will turn down the service on March 17th at 9pm.

Now why in the hell would I close this service. In brief I created it for myself on the plane to RubyConf 2005, thought it was cool and opened it to the public in April 2006. I haven’t updated the code much since many years and just don’t have the time to add new features, and trust me Rails code from 2005 looks slightly different than nowadays Rails code.

For posterity here is the “official” announcement blog entry of the creation of the service:

April 13, 2006 – LAUNCH time.onrails.org, time tracking made simple!

And here are few more articles related to time.onrails.org.

Here is part of the email I send to the users:

Time.onrails.org is closing down March 17th 2010 at 9pm Mountain time.

You can export your time entry for each project by clicking on the export buttons at the bottom of each project page or you can export your full account by just login and then go to this url:

    http://time.onrails.org/export/xml/user

This will export each of the projects will all sections including the notes.

Please start transitioning to a new service now.

As a replacement service I would suggest harvest (http://www.getharvest.com/) which offers a free plan which allows for 2 projects, 4 clients, unlimited invoicing for 1 user absolutely FREE.

Thank you to all the users over the years I hope you enjoyed this free service. Time.onrails.org enjoyed thousands of users and I received many nice complimenting emails for the service over the years. The main reason that I close this service is that I am starting to use harvestapp for my own time tracking. I wrote time.onrails.org back in 2005 just for fun and thought it could be useful to others. It fulfilled my needs of keeping track of time for the various customer projects I worked on over the last few years.

Since we moved to slicehost it was very stable and I just have good things to say about slicehost, they are just great. Recently one of the slice time.onrails.org was running on had issues and got moved twice over two days. Again slicehost was on top of that situation and I just sat back and they did all the work. But this also reminded me that I cannot just keep the service running without giving it the time and effort it deserves and just now I don’t have that time as I am working on other projects, such as http://appsden.com.

So I went on the search for a replacement service and  looked at many out there. And Harvest just added the timestamp feature, which is exactly how I track time, their app is more fleshed out than time.onrails.org, so I decided to move over to use their services.

The great news is while I tweeted about my move to Harvest, Doug, which I knew from his time in Denver mentioned that he now works for Harvest. So he put me in contact with the cofounder and I asked him if they could get some deal for my current users, and they where very responsive and create a special promo code. Thanks for that and I hope you try and enjoy their services. Just for disclaimer I didn’t ask for any monetization or anything for referring you to Harvest, the idea was just to have an alternate offering in case you needed one. But they offered me a free Solo plan, so hey, at least I got that out of this whole ordeal.

Please don’t hesitate to contact me for any question at daniel@onrails.org.

Thank you again for having tried out or being a user of time.onrails.org over all these years.

Kind regards, Daniel Wanja

Mi-Fi 1.1 in AppStore Now and what I learned along the way... 3

Posted by Daniel Wanja Tue, 17 Nov 2009 05:23:00 GMT

During 360idev (Sept 27-30) I wrote a small app to check the battery and connectivity level of my Mifi Card. I didn’t think many people would have an iPhone and a Mifi card. The iPhone is already 3g, but effectively there is not tethering allowed and the AT&T network is crapy. Nevertheless I thought my Mi-Fi App could be useful to others and along the way I would learn what it takes to submit an app to the AppStore.


I submitted the app on September 29th (during 360idev) and it was approved on October 12th. I submitted two other version since and last Monday I started collecting details of my experience of the AppStore, thoughts on the process, and various tibits around the web regarding this app and started writing this blog entry, but didn’t finished it as it was getting too late. Then last week I stumbled upon this article of Rogue Amoeba which detailed their experience with the store. I could relate on the feeling of waiting to know if you apps goes through or not, but fortunately the process took only two weeks for the first release. However I only had a Verizon card and was so eager to submit my app that I didn’t wait to find someone with a Sprint card. And of course the first version didn’t work with the Sprint card. Around the time the first version was approved I wrote a fix to support the Sprint cards and submitted that fix as version 1.1. Thanks to @2busy2blog and pdsphil for helping supporting the Sprint version. Then before it got approved Verizon put out a firmware update for their Mi-Fi card which of course broke version 1.1 (and 1.0). So I updated my Mi-Fi card and wrote a new version which additionally added support for the GSM version of the Mi-Fi card thanks to @jkkmobile. That’s when I made a mistake…I wasn’t sure how to submit a new version when there is one waiting for approval so I just replaced the binary. What I didn’t know is that updating the binary puts you to the back of the queue. And I submitted version 1.1 two weeks before, and it took two more weeks to approve this “new” version 1.1 which was fortunately approved. Now I am not sure how they tested my app as it requires a piece of hardware. So maybe part of the two weeks is to find an approver that had a mifi card.


So all this approval process was new to me and indeed very frustrating when you are used to deploy several times a day fixes to your application in a “web” world. Now this is just a different paradigm and wether you like it or not thats’ the rules you need to play with (for the moment). That means several things. First your application must be tested way better before submitting and be more resilient to different scenarios. If you really have a bug that “Kills” you are just out of luck. It’s similar to developers writing games for the Nintendo DS…once you ship it…tough luck. Note the situation is slightly better, but if you have a fatal bug then people may never give it a second look, not time to cover up issues in a timely fashion. So Apple must find a way to allow fixes to be submitted and approved in a shorter time frame. Maybe two queues for approvals? Now I must admit the Rogue Amoeba guys had a different issue and they had to cripple their application just to have it approved and that for reasons that don’t make sense. Again this was an update to an application that was previously approved, so the wait time has to be way shorter and then again there needs to be some sort of “appeal” process where developers can justify why the app really should be approved.


Now you may argue why an approval process at all, why don’t let the user decide what to install. You may certainly not agree with me, but I like the fact that I can install apps and know they won’t reck my iPhone. I don’t think with an OS and an SDK like the iphone that this could be automated. Maybe an automation build where the apps are compiled by Apples and the compiler could check for any api call infringements? That would be fair, no? I don’t think no approval process is viable for the Apple as this would open the door to malware applications and even though many more savvy users would avoid bad apps the majority of users could end up just downloading any thing, would have issues, and that would be a bigger nightmare than facing the unhappy users. So in the mean time the iPhone development ecosystem is what it is and the platform is too cool to ignore. I’ll be working on several more iPhone apps over the next few months.

But will it make me rich?

Well, that was not the intend of the Mi-Fi app and I sold it for $0 and I can assume that I won’t make it up in numbers. So what are the numbers?
download.png

As of today a little more than 2000 downloads which includes 695 upgrades. Wouhao, AT&T must really suck to have that many people that may potentially have an iPhone and a Mi-Fi card. Note these number are ridiculous compared to certain apps that get downloaded thousands a time a day, but hey, it’s all about learning here for me :-)

The interesting thing is that when Andy Ihnatko tweeted about it and Robert Scoble re-tweeted it the downloads made a nice bump:

“This is a must-have iPhone app for MiFi users: shows complete status of device. http://j.mp/2HBsso—big thanks to @2busy2blog – Andy Ihnatko”

And it shows of the iPhone community is active as many iPhone blogs picked on it, here are a few reviews:

So this was a good first learning experience and hopefully there will be more.

Enjoy! Daniel

Amazon RDS: Amazon Relational Database Service or MySQL in the Cloud for Ruby On Rails. 2

Posted by Daniel Wanja Thu, 29 Oct 2009 03:02:27 GMT

For watchthatsite.com (not public yet) I have an instance on EC2 with Rails and MySQL but was looking for a more solid hosting solution for MySQL. And how fortunate, Amazon came out with the solution I need this week. Basically with two command line instructions you can start a new server with mysql configured, tuned, and secured. In this blog entry I will go through the steps that perform to move my sql database to Amazon RDS.

You can find more information on Amazon Relational Database Service (API Version 2009-10-16) here.

Prerequisite: you need to signup for an account on aws.amazon.com, it can be used for EC2, S3, SimpleDb and all the other services AWS provides.

1) Install the Command Line Toolkit

First thing, go download the command line toolkit and read the README.TXT on how to install it. In short you unzip the files, I did put mine at /Developer/aws/RDSCli-1.0.001. Then you create a credential file which contains your AWS access key id and secret key. Then I configured my ~/.bash_profile as follows:

export AWS_RDS_HOME=/Developer/aws/RDSCli-1.0.001
export AWS_CREDENTIAL_FILE=$AWS_RDS_HOME/credential-file-path.conf
export JAVA_HOME=/Library/Java/Home
export PATH=$AWS_RDS_HOME/bin:$PATH

to see that the command line toolkit is setup correctly type $rds—help

You will need the command line tool to execute several commands described here after.

2) Create an Instance

Let’s create a MySQL Server instance. RDS offers the following 5 server instance classes:

  • db.m1.small (1.7 GB of RAM, $0.11 per hour)
  • db.m1.large (7.5 GB of RAM, $0.44 per hour)
  • db.m1.xlarge (15 GB of RAM, $0.88 per hour)
  • db.m2.2xlarge (34 GB of RAM, $1.55 per hour)
  • db.m2.4xlarge (68 GB of RAM, $3.10 per hour)

I will choose a small instance which I will call dbserver1 with a database name db1 and allocate 5g of database space. I also set the master username as admin and password as secret.

$ rds-create-db-instance --db-instance-identifier db1 --allocated-storage 5 --db-instance-class db.m1.small --engine MySQL5.1 --master-username admin --master-user-password secret --db-name db1 --headers

The output is the following:

DBINSTANCE  DBInstanceId  Class        Engine    Storage  Master Username  Status    Backup Retention
DBINSTANCE  db1           db.m1.small  mysql5.1  5        admin            creating  1               
      SECGROUP  Name     Status
      SECGROUP  default  active
      PARAMGRP  Group Name        Apply Status
      PARAMGRP  default.mysql5.1  in-sync

Now you have a server running and you are being billed $0.11 per hour, that’s like $80 a month without bandwidth but with backup…and it took only 2 minutes to get going. Can’t beat that.

To see all the instances you have you can issue the

rds-describe-db-instances --headers

3) Grant Network Access

So I will grant access from my notebook, assuming the ip address is 24.19.0.48 (you can also specify ranges i.e. 24.19.0.0/50). (Note that access was revoked by AWS, not sure why??)

rds-authorize-db-security-group-ingress default --cidr-ip 24.19.0.48 --headers

I also have an ec2 instance which I want to grant access to

rds-authorize-db-security-group-ingress default --ec2-security-group-name watchthatsite --ec2-security-group-owner-id 526541544691

Note the ec2-security-group-owner-id is your Amazon AWS account number, you can find it for example on you account activity page. To see your security configuration issue the following command: rds-describe-db-security-groups default—headers

4) Using the Database

To use your database you first need to find out the endpoint address of your new server. So describe you instances:

rds-describe-db-instances --headers command
DBINSTANCE  DBInstanceId  Created                   Class        Engine    Storage  Master Username  Status     Endpoint Address                              Port  AZ          Backup Retention
DBINSTANCE  db1           2009-10-28T22:53:31.666Z  db.m1.small  mysql5.1  5        admin            available  db1.cyhik6zpub5c.us-east-1.rds.amazonaws.com  3306  us-east-1b  1               
      SECGROUP  Name     Status
      SECGROUP  default  active
      PARAMGRP  Group Name        Apply Status
      PARAMGRP  default.mysql5.1  in-sync

You find out your endpoint address, for me db1.cyhik6zpub5c.us-east-1.rds.amazonaws.com

So now you can connect to your database:

mysql -h db1.cyhik6zpub5c.us-east-1.rds.amazonaws.com -P 3306 -u admin -p db1

Let’s configure my Rails application to point to that database and run a migration:

So I change my config/database.yml to point to the above database

development:
    adapter: mysql
    host: db1.cyhik6zpub5c.us-east-1.rds.amazonaws.com
    reconnect: false
    database: db1
    username: admin
    password: secret
 rake db:migrate
Wow, seem to work.

Let connect to the mysql console and do a show tables;

+-------------------+
| Tables_in_db1     |
+-------------------+
| schema_migrations | 
| users             | 
| watches           | 
+-------------------+

Yep, all there.

Now I still have to move my old production database to the new one, so let’s dump the data from my old database:

mysqldump watchthatsite_development -u admin > wts.sql

and reload that data in the new database:

mysql -h db1.cyhik6zpub5c.us-east-1.rds.amazonaws.com -P 3306 -u admin -p db1 < wts.sql

Restarting my Rails server…That’s all!

Enjoy, Daniel.

You Mifi card status iPhone App on the Available on the AppStore now. 2

Posted by Daniel Wanja Wed, 14 Oct 2009 13:50:46 GMT

If you have an iPhone and like several people i know you didn't tether it and you are not happy with AT&T's 3G network chances are you have a Mifi 2200 card from Sprint or Verizon. These Mifi cards are pretty cool and now you can use the Mi-Fi app from your iPhone and see the following status: Battery Level, Connectivity, Data Received and Transmitted (since connected), Time Connected and IP address. Try it out and if you like it rate it! Enjoy! Daniel.
mi-fi.png

360iDev is next week in Denver...and it's nearly sold out! 2

Posted by Daniel Wanja Wed, 23 Sep 2009 03:31:03 GMT

360iDev is around the corner and if you know the organizers or have been to 360flex then you know Denver is the place to be starting next Sunday if you are or wanna be an iPhone developer. The conference starts with a day of tutorials on Sunday then kicks in full gear Monday through Wednesday with three tracks of 80 minute sessions covering all angles of iPhone development from some of the best authorities in the fields.

You can find the schedule as ical or download a pdf

Here is my schedule:

On Sunday I’ll attend the “Hands-On with the Appcelerator platform.” session.

Monday

360idev_monday.png

Tuesday

360idev_tuesday.png

Wednesday

360idev_wednesday.png

If you are not signed up yet…you better hurry.

I hope I’ll see you there!

Daniel

RMagick (from source) on Snow Leopard 39

Posted by Solomon White Fri, 04 Sep 2009 00:31:00 GMT

After the release of 10.5, I published an article about building RMagick from source on Leopard. I won’t rehash the why, you can read the original article for that. My clean install necessitated updating the RMagick script, so here’s what worked for me to install from source on Snow Leopard! For the impatient, here’s the download link: rmagick-build.sh

First, we start with installing wget, as it seems to be a bit more clever than curl about dealing with mirrors, etc. Then, we compile and install each prerequisite package. Finally, we install the gem.

All the links in the script worked for me, but, depending on your location, network, conditions, etc, your mileage may vary. Enjoy!

#!/bin/sh

# install wget, which is cleverer than curl
curl -O http://ftp.gnu.org/gnu/wget/wget-1.11.tar.gz
tar zxvf wget-1.11.tar.gz 
cd wget-1.11
./configure --prefix=/usr/local
make
sudo make install
cd /usr/local/src

# prerequisite packages
wget http://nongnu.askapache.com/freetype/freetype-2.3.9.tar.gz
tar zxvf freetype-2.3.9.tar.gz
cd freetype-2.3.9
./configure --prefix=/usr/local
make
sudo make install
cd /usr/local/src

wget http://superb-west.dl.sourceforge.net/sourceforge/libpng/libpng-1.2.39.tar.gz
tar zxvf libpng-1.2.39.tar.gz
cd libpng-1.2.39
./configure --prefix=/usr/local
make
sudo make install
cd /usr/local/src

wget ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz
tar xzvf jpegsrc.v6b.tar.gz
cd jpeg-6b
ln -s `which glibtool` ./libtool
export MACOSX_DEPLOYMENT_TARGET=10.6
./configure --enable-shared --prefix=/usr/local
make
sudo make install
cd /usr/local/src

wget ftp://ftp.remotesensing.org/libtiff/tiff-3.9.1.tar.gz
tar xzvf tiff-3.9.1.tar.gz
cd tiff-3.9.1
./configure --prefix=/usr/local
make
sudo make install
cd /usr/local/src

wget http://superb-west.dl.sourceforge.net/sourceforge/wvware/libwmf-0.2.8.4.tar.gz
tar xzvf libwmf-0.2.8.4.tar.gz
cd libwmf-0.2.8.4
make clean
./configure
make
sudo make install
cd /usr/local/src

wget http://www.littlecms.com/lcms-1.17.tar.gz
tar xzvf lcms-1.17.tar.gz
cd lcms-1.17
make clean
./configure
make
sudo make install
cd /usr/local/src

wget ftp://mirror.cs.wisc.edu/pub/mirrors/ghost/GPL/gs870/ghostscript-8.70.tar.gz
tar zxvf ghostscript-8.70.tar.gz
cd ghostscript-8.70
./configure  --prefix=/usr/local
make
sudo make install
cd /usr/local/src

wget ftp://mirror.cs.wisc.edu/pub/mirrors/ghost/GPL/gs860/ghostscript-fonts-std-8.11.tar.gz
tar zxvf ghostscript-fonts-std-8.11.tar.gz
sudo mv fonts /usr/local/share/ghostscript

# Image Magick
wget ftp://ftp.fifi.org/pub/ImageMagick/ImageMagick.tar.gz
tar xzvf ImageMagick.tar.gz
cd `ls | grep ImageMagick-`
export CPPFLAGS=-I/usr/local/include
export LDFLAGS=-L/usr/local/lib
./configure --prefix=/usr/local --disable-static --with-modules --without-perl --without-magick-plus-plus --with-quantum-depth=8 --with-gs-font-dir=/usr/local/share/ghostscript/fonts --disable-openmp
make
sudo make install
cd /usr/local/src

# RMagick
sudo gem install rmagick

UPDATE There is a bug with libgomp that breaks the convert utility (See comments below). the --disable-openmp configure option has been added to the script to fix this.

UPDATE 2 A new patchlevel of ImageMagick has been released that supersedes the original one referenced in this script, and the original has been removed from the server. Thanks to Sebastian for this update that will grab the latest release.

Introducing Hashdown 4

Posted by Solomon White Tue, 04 Aug 2009 23:51:00 GMT

If your database is normalized, you will almost always end up with small tables (often referred to as reference data or lookup tables) which provide a set of possible values for a particular attribute. (e.g. Currency, Category, etc.) A common pattern that emerges in many applications is accessing these records by a symbolic name (as opposed to by id) for purposes of clarity when reading the code. In C (and friends), the database ids can be mapped to the positions of an enum datatype. I recently released the hashdown plugin that provides hash-like access for reference data records, and also adds some dropdown option list generation support, since this data is often used to populate select list in forms.

As an example of what hashdown does, suppose we have the following model:

class CardType < ActiveRecord::Base
end

with the following data:

+----+-------+------------------+
| id | code  | name             |
+====+=======+==================+
| 1  | visa  | Visa             |
| 2  | mc    | MasterCard       |
| 3  | disc  | Discover         |
| 4  | amex  | American Express |
+----+-------+------------------+

By adding the following line to the model:

class CardType < ActiveRecord::Base
  finder :code
end

You get the functionality of a hash-like square-bracket accessor for the model that will let you do something like:

@order.card_type = CardType[:visa]

The underlying implementation is similar to:

def CardType < ActiveRecord::Base
  def self.[](value)
    find_by_code(value)
  end
end

...except it adds a caching layer to boost performance by preventing repeated database access.

Adding the following directive:

def CardType < ActiveRecord::Base
  selectable
end

to the model gives you a class method called select_options that can be used to populate a select list like this:

<%= form.select :card_type_id, CardType.select_options %>

produces:

<input type="select" name="order[card_type_id]" id="order_card_type_id">
  <option value="1">Visa</option>
  <option value="2">MasterCard</option>
  <option value="3">Discover</option>
  <option value="4">American Express</option>
</input>

By default, this will use the id attribute as the submitted value of the option and call a display_name method (if it exists) for the displayed value of the option, falling back to the name method/attribute. Each of these can be overridden by passing a symbol attribute / method name, or a lambda that will be executed to generate the value. For (a contrived) example:

<%= form.select :card_type_id, CardType.select_options(:key => :code, :value => lambda{|card_type| card_type.name.reverse }) %>

produces:

<input type="select" name="order[card_type_id]" id="order_card_type_id">
  <option value="visa">asiV</option>
  <option value="mc">draCretsaM</option>
  <option value="disc">revocsiD</option>
  <option value="amex">sserpxE naciremA</option>
</input>

Again, the select_option results are cached for better performance.

This is a pretty small plugin that I’m using to DRY up some code in a current project I’m working on. Let me know if you have feature requests (or fork and patch it on GitHub!)

Behind the scene: Quiltivate.com a beautiful Flex on Rails website.

Posted by Daniel Wanja Thu, 16 Jul 2009 04:20:01 GMT

I met Phil several years ago at Derailed, the (Denver Ruby on Rails user group, and for a long time he was curious about how Flex can be integrated with Rails, about the graphical possibilities that Flex offers, the advantages over plain HTML/CSS/Javascript. Then he told me Kacie, his wife, had an idea about a website. She is passionate about quilts and has an eye for details and excellence. Phil is a geek that loves Rails, Kacie loves quilts, it's like Quilting meets Web 2.0 and quiltivate.com was born. In fact Phil and Kacie hired me to create a Quilt Builder that integrates with Quiltivate.com. Kacie had the vision for the whole concept, a simple to use quilt builder that removes lots of the hassle of calculating how much fabric of what color is needed and allows to play with blocks, shapes and colors. She drew a paper prototype that really highlights the tag line of their site" Innovating Traditional Quilting". Quiltivate.com offer much more than a Quilt Builder, it's a blog and a community centered around the art and craft of quilting. Over the last year I spent a couple of hours here and there, well a little more than that, to transform the paper prototype into a real Flex application. Rather than writing about what the tool does and how it does it, let's have a little look at behind the scene of the Quilt Builder with this video:

Behind the scene: Quiltivate.com a beautiful Flex on Rails website. from daniel wanja.

Check out quiltivate.com for a video on how to really use the Quilt Builder and go try it out. As it's fresh out of the gates their may be a little quirks here and there, so please let me know what you find. So thank you Kacie and Phil for getting me on this project, it was really fun! Enjoy, Daniel.

Screencast: Testing Flex Apps with Cucumber - Take 2 1

Posted by Daniel Wanja Mon, 13 Jul 2009 17:04:11 GMT

I was not really happy with last week's screencast I did on testing Flex with Cucumber. Effectively doing screencast is not an easy endeavor and trying to it myself is making me appreciate all the other screencast I watch so much more. So last week I just wasn't comfortable while I recorded it, not sure why, but I thought I should try to capture it again. And the second time around I felt better, maybe I should alway take two takes (or even more :-). So here is the new one...

Screencast: Testing Flex Apps with Cucumber - Take 2 from daniel wanja.
To run this code you need to have all the gems installed. So config your Rails to run Cucumber with FunFx (in config/environments/test.rb):

config.gem "rspec", :lib => false, :version => ">= 1.2.7"
config.gem "rspec-rails", :lib => false, :version => ">= 1.2.7"
config.gem "webrat", :lib => false, :version => ">= 0.4.4"
config.gem "cucumber", :lib => false
config.gem "funfx"
config.gem "safariwatir"
Config Cucumber to have @flex available (in features/support/env.rb)
require 'funfx'
require 'funfx/browser/safariwatir'

browser = Watir::Safari.new
browser.goto("http://localhost:3000")

Before do
  @flex = browser.flex_app('flashContent', 'flashContent')
end

at_exit do
  browser.close
end
In the same file disable transactional fixtures
Cucumber::Rails.use_transactional_fixtures
Ensure that your Flex application is compiled with the funfx library and the automation library linked in.
<flex-config>
  <compiler>
	<include-libraries append="true">
		<library>../../lib/funfx-0.2.2.swc</library>
		<library>../../lib/automation.swc</library>
		<library>../../lib/automation_agent.swc</library>
		<library>../../lib/automation_dmv.swc</library>
		<library>../../lib/automation_agent_rb.swc</library>
	</include-libraries>
  </compiler>
</flex-config>

Screencast: Testing Flex Apps with Cucumber 7

Posted by Daniel Wanja Wed, 08 Jul 2009 07:03:00 GMT

I was playing with Cucumber and FunFx to drive a Flex application and it's really cool and created this screencast to show how this all works together. The first 5 minutes I build a Restfulx scaffolded Flex application. The following 5 minutes I configure the Flex app with FunFx, which is required to be able to drive the app from Cucumber. Then the main part which is 20 minutes of creating three cucumber scenarios that drives the Flex application. Check it out:

Testing Flex Apps with Cucumber from daniel wanja The source code can be found on github Enjoy! Daniel
UPDATE: An updated version (and slightly) different version of the screencast can be found here.

Older posts: 1 2 3 4 ... 23