a day in the pit my view from inside

20Aug/111

Visualizing Subversion’s Commit History

Yeah, it's Friday! Woohoo. Yup, that's right people, it's time to kick off your shoes and code...

I have not posted in like two weeks. Lemme tell ya, One of those weeks I spent in Vegas on a much needed vacation without a laptop. It was pretty spectacular. This week has just flown by. But today I felt like doing something fun; I felt like being a movie producer, director, composer, etc. However, I don't really like to get off the couch just to film a movie when I have a at least 25 storylines wandering around my computer.

Without further pause here is my story of the main Subversion repository I contribute to at work:
[ By the way, dots (or nodes) are directories or files. As the two people-icons run around the screen they are making subversion commits. Explosions typically occur when a big check-in happens. ]

Enjoy? Let's make you a video. Visualizing Subversion commit activity is crazy simple. Dayum! I'm running Mac OS X 10.6.8 so all of following was done on that environment.

You'll want to get ffmpeg and some codecs. I use Darwin Ports to manage packages like these so if you're like me here's the quick fix

sudo port install ffmpeg +gpl +lame +x264 +xvid

Next, we're going to need Gource, and ffmpeg.

Download gource. unzip it and head into the directory. once in the gource directory go ahead and

sudo ./configure
sudo make; sudo make install
gource --help

Alright we're pretty much ready to go. Head over to one of your subversion root directories. Add this file to your directory: summerfun.conf
and in it put

[gource]
bloom-intensity=0.25
colour-images=true
hide=filenames,dirnames
path=my-project-log.xml
seconds-per-day=0.1

You'll see the my-project-log.xml is nowhere to be found. Let's create it:

svn log -r 1:HEAD --xml --verbose --quiet > my-project-log.xml

That will make the video play a little faster. You can remove or muck with all of the settings; just read the README for available options. Now here is the command I executed:

gource --load-config summerfun.conf -1280x720 -o - | ffmpeg -y -b 10000K -r 60 -f image2pipe -vcodec ppm -i - -vcodec libx264 -vpre default -threads 0 -bf 0 gource.x264.mp4

This command launches a video; watch it & interact with it. Give it a try. All interactions get recorded in the video output. So zoom as you wish, to entertain your watchers. Let me know how it goes and post your videos.

Reference:

3Aug/110

You can play music on a locked Mac OS X

At some point today my Macbook Pro, running Mac OS X 10.6.8, locked my screen due to inactivity yet I was still able to control the audio via helper keys on the top row of the keyboard. That's pretty cool. It made me think of my Android phone, and how that too offers audio controls when locked. It made me think of how designing a product requires attention to the most subtle of details.

When beginning a new project, I often start off in total ignorance at the amount of work that will ensue. I think to myself, "sashimi slices, it'll all work out" and then I plug away at writing some code, designing some views, and seeing it all come together. At some point I find myself customizing the little pieces of the Application: the footer. Woah, seriously the footer is valuable real estate but I rarely look at it that way. Yet, in it's tiny form it can hold some of the most important links and people naturally go there. We actually expect a footer on the pages we frequent; we expect it has worthwhile resources that we may need. And what goes into this footer is exactly what I'm talking about: subtle features.

I've tried to come up with a name for these features and I think I'll stick to unoriginality and call them Core Application Functionality - CAFs.

Apple loves their CAFs and it shows. My Macbook Pro understands me. It knows that just because I'm not logged into my computer I still may need to adjust the volume. It knows that physical components of my machine, like sound, need physical controls.

Mac OS X reminds me of how CAFs can make or break an (web) application. For example, looking at user authentication we have a baseline rubric for what we need to use a service. We expect a web application to let us register, login, and logout. That's the basics. Of course we are missing one very important feature: password reset. Unfortunately, not all web apps are created equally and some fail to provide a password reset mechanism. A missing CAF like this highlights the little attention to detail in core functionality of the Application. That's pretty bad and what's worse is how the user is left feeling helpless. A negative experience such as this will have the Application failing -- what a silly way to break the bank!

CAF gaps happens. Trust me. As an avid user of new web applications I find myself stuck more often than I'd like. These gaps creep up on start-ups as well as medium-to-large sized companies. They just happen. And they suck. So my advice is to take a moment and ask yourself this, "does my application get me?"

2Aug/111

Wrapping text in a jQuery jqGrid cell

I've been using jqGrid now for about a year and I'm relatively satisfied. I use jqGrid to prettify, ajaxify, and make more functional pre-generated reports for our customers. The first thing you might notice about the grid is that it uses Alt text to display full cell content. This is nice, for sure, but it cuts off a lot of content depending on the amount. At times I'd like to be able to display the full amount of data in a row and not have to make the width of a column overly wide! So I'm employing CSS to do the trick.

To wrap a cell's text (non header) include this CSS after all of the jquery & jqgrid css has loaded:

.ui-jqgrid tr.jqgrow td {
    white-space: normal !important;
    height:auto;
    vertical-align:text-top;
}

And to wrap a column cell's text:

.ui-jqgrid .ui-jqgrid-htable th div {
    white-space:normal !important;
    height:auto;
    vertical-align:text-top;
    position:relative;
    overflow:hidden;
}

jqGrid can be customized to add classes onto elements but not the parent of elements in the table thus we're unable to set the parent td or div element to have the correct white-space CSS property. That's why we have to add our own CSS in, after the fact, to get the effect we want.

Filed under: Code, CSS, JavaScript 1 Comment
1Aug/110

Under the hood – Ruby methods Array#map, Array#inject

In the spirit or writing some Ruby methods I'm going to add three in this post. We'll begin with mapping elements of an Array.

class Array
    def rb_map
        n_array = []
        self.each { |elm| n_array << yield(elm) }
        n_array
    end
end

Then we do Inject,

class Array
    def rb_inject initial = nil
        value = initial
        self.each { |elm| value = yield(value,elm) }
        value
    end
end

And finally, let's revisit map using our inject:

class Array
    def new_map_using_inject
        rb_inject([]) { |set, elm| set << elm }
    end
end

You'll notice I did not do any error handling. That's not the point of the exercise; we want to know what the methods we call daily do behind the scenes.

Filed under: Code, Learning, Ruby No Comments
28Jul/110

Rails 3, Webrick, Mac OS X, Error: missing :action (ArgumentError)

I was making some changes in a routes.rb file and fat fingered the wrong line:

match '/public_html', "domains#public_html", :as => 'public'

Ran rails server, hit localhost:3000 and quickly saw a huge stack trace with this little gem of an error at the top:

/Users/miker/projects/projects/logthingy/vendor/bundle/ruby/1.8/gems/actionpack-3.0.7/lib/action_dispatch/routing/mapper.rb:171:in `default_controller_and_action': missing :action (ArgumentError)

To me, that error message is not the most helpful. Because the only change I had made was in routes.rb I knew the issue was there. By the way, this is where I feel a little bit sorry for newcomers to Ruby and Rails... The error messages are not always entirely clear. For those of us who have been in Ruby long enough to know the "breadcrumb logic" we can get by, but for those who don't it can be a nightmare.

The fix was simple and subtle... was missing some punctuation:

match '/public_html' => "domains#public_html", :as => 'public'