Monday, August 24th, 2009 | Author: viking

This year for Rails Rumble, our team decided to write an app for tracking whom you’ve loaned your items to:

link.to

It was a blast, just like last year. Having James Pierce as our designer made a huge difference in the quality of our app.

Using Gawker, we recorded time lapse videos of our three sessions.

Session 1:

The fifth person in the video is our co-worker Will, who didn’t actually code anything for our Rumble app. He was there to provide some Git (and morale) support and keep Rumble Helper updated. So we didn’t cheat! :P

Session 2:

I forgot the timestamps on this one, but it lasted from about 9:30am on Saturday to 5am on Sunday (the last 15 seconds [3 hours or so real time] is dark… we forgot to turn the camera off). Ten points if you can spot our friends Ryan and Leah Stufflebam, who dropped off some homemade chili for us. It was delicious.

Session 3:

The last session! In total, we got about 8 hours of sleep each, drank like I don’t know how many cans of soda, ate a buttload of chips and pizza (and chili). It was a blast.

Go see our app: lend.to, and all the other Rumble apps when you get a chance!

Category: rails  | Tags:  | Leave a Comment
Monday, August 24th, 2009 | Author: viking

After a meeting of our Rails Rumble team the week before the competition, I decided to undertake a little project to keep track of stuff we wanted to get done during the Rumble. I came up with Rumble Helper:

screeny-thumb

You can drag and drop items from one bubble to another so you can easily track what needs to be done.

We used it during the Rumble in combination with SmartBoard:

Rumble Helper on SmartBoard

It turned out pretty well! Darcy was nice enough to put it up on the Rails Rumble blog before the competition. At the end, 45 users had signed up (representing 20 different teams) and 327 tasks had been created. I was happy it got some use. :)

It was a really good warmup for the Rumble. I worked on it solid from Friday (August 14) to about Thursday (August 20). There were several things about it that helped having experience with during Rails Rumble itself.

For next year I plan to add more features to it, like the ability to see what other teams are doing (if they made their team public, that is). There are also some Javascript issues that I need to see if I can take care of. If you leave the app open for too long, eventually the AJAX calls bloat up Firefox pretty badly.

Category: rails  | Tags:  | Leave a Comment
Wednesday, April 29th, 2009 | Author: viking

I have a couple of projects that are deployed on Windows, so I use a virtual Windows machine on my Ubuntu box for development. At first, I tried using Samba to mount a share to my virtual machine, but that ended up causing problems. If my virtual server went down and I forgot to unmount, bad things happened.

Googling around, I discovered a how-to on how to mount the virtual machine disk directly via loopback. I decided to write an init script for it:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          mount-windows-image
# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Mounts a KVM windows image
### END INIT INFO
 
# Author: Jeremy Stephens <viking415@gmail.com>
#
# Please remove the "Author" lines above and replace them
# with your own name if you copy and modify this script.
 
# Do NOT "set -e"
 
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/bin:/usr/bin
DESC="Mounts a KVM Windows image"
SCRIPTNAME=/etc/init.d/mount-windows-image
DEV_FILE=/var/run/mount-windows-image
 
MOUNT_DIR=/mnt/win
IMAGE_FILE=/etc/libvirt/qemu/xp.img
UID=1017
GID=1017
FMASK=0137
DMASK=0027
 
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
 
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
 
#
# Function that starts the daemon/service
#
do_start()
{
	# Return
	#   0 if daemon has been started
	#   1 if daemon was already running
	#   2 if daemon could not be started
        if [ `mount -l | grep $MOUNT_DIR | wc -l` -gt 0 ]; then
          return 1
        else
          DEV=`losetup -f`
          echo $DEV > $DEV_FILE
          losetup $DEV $IMAGE_FILE
          kpartx -a $DEV
          mount -t ntfs -o uid=$UID,gid=$GID,fmask=$FMASK,dmask=$DMASK \
            /dev/mapper/`echo $DEV | awk -F/ '{print $3}'`p1 $MOUNT_DIR
          if [ $? -eq 0 ]; then
            return 0
          else
            kpartx -d $DEV
            losetup -d $DEV
            rm -f $DEV_FILE
            return 2
          fi
        fi
}
 
#
# Function that stops the daemon/service
#
do_stop()
{
	# Return
	#   0 if daemon has been stopped
	#   1 if daemon was already stopped
	#   2 if daemon could not be stopped
	#   other if a failure occurred
        if [ `mount -l | grep $MOUNT_DIR | wc -l` -eq 0 ]; then
          return 1
        else
          umount $MOUNT_DIR
          if [ $? -eq 0 ]; then
            sleep 1
            DEV=`cat $DEV_FILE`
            kpartx -d $DEV
            losetup -d $DEV
            rm -f $DEV_FILE
            return 0
          else
            return 2
          fi
        fi
}
 
#
# Function that sends a SIGHUP to the daemon/service
#
#do_reload() {
#	#
#	# If the daemon can reload its configuration without
#	# restarting (for example, when it is sent a SIGHUP),
#	# then implement that here.
#	#
#	start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
#	return 0
#}
 
case "$1" in
  start)
	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
	do_start
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  stop)
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
	do_stop
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  #reload|force-reload)
	#
	# If do_reload() is not implemented then leave this commented out
	# and leave 'force-reload' as an alias for 'restart'.
	#
	#log_daemon_msg "Reloading $DESC" "$NAME"
	#do_reload
	#log_end_msg $?
	#;;
#  restart|force-reload)
#	#
#	# If the "reload" option is implemented then remove the
#	# 'force-reload' alias
#	#
#	log_daemon_msg "Restarting $DESC" "$NAME"
#	do_stop
#	case "$?" in
#	  0|1)
#		do_start
#		case "$?" in
#			0) log_end_msg 0 ;;
#			1) log_end_msg 1 ;; # Old process is still running
#			*) log_end_msg 1 ;; # Failed to start
#		esac
#		;;
#	  *)
#	  	# Failed to stop
#		log_end_msg 1
#		;;
#	esac
#	;;
  *)
	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
	echo "Usage: $SCRIPTNAME {start|stop}" >&2
	exit 3
	;;
esac
 
:


Install the script in /etc/init.d and make it executable. Make sure you change the following variables in the script: UID, GID, MOUNT_DIR, IMAGE_FILE. You can add the script to the boot process via the update-rc.d command:

chmod +x /etc/init.d/mount-windows-image
update-rc.d mount-windows-image defaults

This script mounts the first partition on a Windows virtual image, and it assumes the disk is formatted as NTFS. Tweaking the script to fit your needs shouldn’t be too difficult. I use Ubuntu, although I imagine the script would work in Debian. Your mileage may vary.

Note: I believe this only works with raw virtual images. Also, It’s probably a good idea to at least skim the post I linked above for additional information and caveats.

» Download script

Category: linux  | Tags: ,  | Leave a Comment
Thursday, April 16th, 2009 | Author: viking

The movers and shakers in the OSS community seem to be people with strong opinions. They feel strongly enough about a software paradigm to speak out about it and develop some software package or library that goes along with said paradigm. Often, these people also tend to not be very friendly. They have an agenda. They think that they are right, and if you think otherwise, you are wrong and/or ugly and/or stupid.

This is why OSS sometimes chafes me. I am a people pleaser. It’s just my personality. Sometimes I disagree with something one of the big guys is doing. But when it comes down to it, I really don’t have the chutzpah to express an adverse opinion openly. I’m confident in my programming abilities, but I question myself when it comes to these sort of situations.

It’s sort of like road rage. I can get quite angry at someone who is driving poorly in front of me, but if I were face to face with them, that anger would disappear. In fact, I would feel bad about being angry in the first place. Part of it has to do with my personality, and part of it has to do with the unapproachability of these software giants.

This is one of the reasons why I was so impressed with Matz, the creator of Ruby. This guy has the most right in the Ruby community to boast, but the man is one of the most humble. When I heard his keynote at last year’s RubyConf, I was blown away. It was like a breath of fresh air. Many of the American (and non-American) programmers seem quite arrogant. I’m not blameless, either. We can all learn from Matz and his attitude.

Category: oss  | Tags:  | Leave a Comment
Tuesday, March 24th, 2009 | Author: viking

The default Dokuwiki template was frying my eyes, so I made a new one. I simply took the default template and substituted some colors.

desert

Download »

For instructions on installation, see Dokuwiki’s template page.

UPDATE (2009-04-09): Fixed code blocks showing as white.

Category: web design  | Tags: , ,  | Leave a Comment
Thursday, March 12th, 2009 | Author: viking

The HTML specification dictates that unchecked check boxes should not supply a value in a form submission, which can be problematic for applications wishing to set a flag in a database based on an unchecked check box. Rails gets around this by using a trick in the check_box helper. It places a hidden input tag with the requested default value directly after the check box tag.

The reason this works is because form parameters are sent in the order that they appear. This means the hidden input value is submitted after the check box value would be, and Rails gives precedence to parameters appearing earlier in the request.

I tried this in PHP, hoping it would behave the same way. It doesn’t. It turns out that PHP overwrites earlier variables in the request with later ones. This behavior is dictated by the request_order directive (as of PHP 5.3.0, which is still in beta at the time of this post). The fix is simply to place the hidden input tag before the check box tag.

Hopefully this helps someone avoid the moderate pain I went through figuring all this out.

Category: php, rails  | Tags: ,  | Leave a Comment
Thursday, March 05th, 2009 | Author: viking

Yesterday I scoured the web for an animated progress bar background. Not an animated progress bar, a background. I wanted the ability to control my progress bar length with CSS and Javascript. I found some stripey backgrounds and what not, but none of them were animated. Maybe my Google skills failed me, but I couldn’t find one for the life of me. So I decided to make my own in GIMP.

Progress bar

Once I figured out the steps, it was quite simple.

  1. Start with a long solid color bar (I used 1000×25, which is probably overkill)
  2. Add a transparent layer and fill it with the Warning pattern (yellow and black stripes)
  3. Remove the yellow stripes via select by color, then change the opacity to something low (like 15%)
  4. Add a third layer for a white gradient in the top half to make it shiny
  5. Change the canvas size to 300×25 and align the layer to the right
  6. Merge the three layers together
  7. Copy the layer, move it 1 pixel to the right
  8. Repeat until you have 20 layers, each 1 pixel further right than the previous one
  9. Run the animation optimization filter, then save as animated GIF using 50ms delay
  10. Drink a beer!

Here’s the GIMP file before merging layers, and here’s the one just before optimization. Please take them (or the image above) and do whatever the hell you want with them.

Here’s a German flag version for good measure.

Category: web design  | Tags: ,  | Leave a Comment
Tuesday, December 09th, 2008 | Author: viking

In one of my Rails projects, I have some views that are rendered through ERB and others through HAML. This makes it annoying to jump to a view’s spec via rails.vim, since it currently doesn’t handle custom Rcommand’s that accept multiple suffixes.

When I asked tpope today about this, he brought up a good point. Why are view specs associated with an engine type (such as ERB or HAML) by default? You should be able to convert an ERB view to a HAML view and use the same tests.

Per his tip, I renamed my views from names like new.html.haml_spec.rb to just new.html_spec.rb. Unfortunately, autotest stopped recognizing the correlation between my views and my view specs. Putting this in my .autotest file fixed the issue:

Autotest.add_hook :initialize do |at|
  at.remove_mapping(%r%^app/views/(.*)$%)
  at.add_mapping(%r%^app/views/(.*)$%) do |f, md|
    # strip off engine name
    path = md[1].sub(/\.(erb|haml)$/, "")
    at.files_matching(%r{spec/views/#{path}_spec.rb})
  end
end

I hope that helps someone. :)

Category: rails  | Tags: , ,  | Leave a Comment
Monday, November 24th, 2008 | Author: viking

Ever since I started using Rails two and a half years ago, there’s been something that’s nagged me about the Rails community. Only recently have I been able to put my finger on it. I’m not sure if this applies to all OSS communities or just Rails’, but it really bugs me.

Everyone’s a bandwagon jumper.

Take the whole TextMate movement, for example. Two years ago, TextMate was the editor for Rails developers. All of a sudden though, Vim is the new hotness. Apparently the exodus from TextMate became full blown after Jamis Buck switched back to Vim. And, poof! Hard-core TextMaters are suddenly hard-core Vimmers. Some of them are switching back to Vim, but others are first time Vim users and now think it’s all the rage. It bothers me.

The same thing happened with the testing movement. Rails developers are known for their outspoken opinions about testing. “You should test all the effing time.” Everyone seemed to latch onto this idea without even thinking about it. I agree, testing is good, and it helps you write very stable code, but the blind acceptance of things just seems to happen a lot in this community.

Both Vim and unit testing have been around for a while. It takes a big name in the community to bring them to attention, and then everyone and their mother’s dog starts doing it.

And then there’s Git. Until a year ago, pretty much everyone used Subversion, and then Git comes out of nowhere. All it takes is a Google video of Linus Torvalds calling Subversion users idiots, and pretty soon after that, you’re behind the times if you’re still using SVN for your revision control. Github has exploded as the place to have your code if you’re somebody.

It seems like everyone’s racing to come up with the next big idea that will be adopted by the entire community. And if someone beats them to it, the next best thing is to latch onto an idea while it’s young so that they can be one of the few riding the crest of the wave that’s about to break onto unsuspecting John Q. Programmer.

To be honest, it’s like high school all over again. It’s the rush to be popular. The only difference now is that the stage is bigger and money is involved. If some new way of doing things comes up, consider it, and make up your own mind about it. Don’t switch just so you can be one of the first to do so. The tides change so drastically so often it’s staggering. If you don’t keep up, you might be not be in the in crowd anymore, oh noez!1!one!

Of course, everyone is entitled to their own opinion. This is just the way I view it.

Category: rails  | Tags:  | 3 Comments
Friday, November 21st, 2008 | Author: viking

I recently decided to write a Ruby wrapper for the oRTP library so I can eventually implement a little RTSP server in Ruby. I wanted to use autotest for my testing, but it didn’t work out of the box since I’m testing code that lives in the ext/ directory. I wanted autotest to rebuild my extension after each change to the source file. So I came up with an .autotest file that looks like this:

Autotest.add_hook :run_command do |at|
  puts "Re-building extensions..."
  Dir.chdir(File.dirname(__FILE__) + "/ext") do
    `make`
  end
end
 
Autotest.add_hook :initialize do |at|
  at.add_mapping(%r{^ext/(\w+)\.c$}) do |f, md|
    at.files_matching(%r{test/test_#{md[1]}.rb})
  end
end

The beginnings of my code for this project is on teh Githubz.

Category: ruby  | Tags: ,  | Leave a Comment