Yearly Archives: 2009

iTunes iMovie on Lenovo’s new Media Center PC

0 minutes, 22 seconds

Flipping through a recent blog post, I clicked through to Lenovo’s new media center PC, the Q700. Ho hum, another small form factor desktop. Wait…those icons on the features page look familure. Hey! Those are the iTunes (slight color tweak) and iMovie icons (verbatim)!

Here’s the two icons followed by a screenshot with blow up of the icons on the page:
imovie_iconitunes_icon

q700webpage

I’m not getting into any sort of “Apple is better than Windows” or “Linus Rulez”. However, this is just sloppy!

Don’t just commit, commit intelligently

1 minute, 33 seconds

If you’re a developer, you probably use a revision control software. For both work and personal projects, I use SVN, which is great. At work we use SVN as a way of releasing new features and bug fixes to our web site. We can push a specific a revision as well as roll back to a previous revision, thus leveraging revision control to be our release software for a 4 server load balanced site. SVN + rsync + shell scripting = : )

Recently at work we were doing a bunch of little changes all over the site, including having the designers do a bunch of css and DOM tweak as well. The time came to commit all of the changes. Instead of doing the commit at the root of the repository and stuff all the changed files in at once, I enforced a multiple granular commits of the functionally changed files. Each commit had a relevant comment.

Enter a week later. We hadn’t done sufficient regression testing and a visual element was broken in ie6. Which of the thousands of new lines we committed and pushed was the culprit? Had we done one massive commit we would have been screwed. However, we were able to cull over the commites via our trac instance (awesome!) and review the comments. In this case we couldn’t actually find the exact commit that caused ie6 to break, but we were able to step through our dev instance of the site, slowly adding each revision to it until it broke in ie6.

The moral of the story is that, much like backup, revision software is only as good as it’s end user. Think of every commit as chunk of functional related code. Think of every comment for these commits needing to solve the problem for another developer who has no idea what the code was and they’re up at 2am trying to figure WTF is up with the site. For every commit, where possible, you should also site a bug number so that should the bug crop up again, it’s easy to cross reference the “fix” with the code.

Happy revising!

The very, very poor man’s Google Analytics: tail, cut, sort, uniq & wc

1 minute, 6 seconds

I still have what most would call an unfounded fear of privacy when it comes to Google. They may receive a copy of every email I send to my friends who use gmail, they may place every call to me via Google Voice, they may server every ad from Double Click (which I then block) and I sure as heck never stray from their bad-ass search on google.com, but I don’t host anything with them directly.

I’ve run my share of web analizer tools, but some times I wanna know, right now, “how many people subscribe to my blog feed?”. Now, I probably should be using FeedBurner (No shit – I did not know, ’til just this second, that they too are now owned by Google. Oh, the irony!), but my site, despite its claims, is still a bit of the cobbler’s child when it comes to analytics. Heck, I still don’t have mod_usertrack on!

Enter tail, cut, sort, uniq and wc!

tail -10000 access_log|grep /blog|cut -d" " -f 1|sort|uniq|wc

In layman’s term’s that’s “get the last 10000 lines of my access log, cut each line into fields separated by the space character, grab the first field (the IP address in this case), sort the resulting lines of now just an IP address per line, remove the duplicates and count the number resuling lines (or IP addresses)”. Presto! 388 of you out there, including all the bots, spiders, crawlers, trolls and goblins. Thanks for the interest!

Ruby-less way to add key frames to flv videos for the likes of JWPlayer

2 minutes, 2 seconds

At work we’ve been working on a good way to roll our own videos. We initially started with the generic off the shelf swf player + flv to make our videos go. This was OK, but was lacking some key features folks were used to, primarily full screen play back and the ability to seek to a specific spot in a video. Additionally, for videos that were over 20 minutes being viewed over slower connections, precious apache children would be chewed up potentially causing a slow down for the web head doing the serving.

Enter JWPlayer! This is a great, easy to configure, free for non-commercial use, flv player that offers the features we’re looking for. Further, we could offload the flv’s to our image server, lighttpd . (By the way lighttpd is extremely awesome; I can not recommend it enough. I first learned about from my friend over at WikiSpaces where they had dropped apache entirely in favor or lighttpd. Noteworthy is that lighttpd was first concieved as an attempted answer to the c10k problem. I’ve personally seen it handle over 2000 connections per minute and the server load didn’t go above 0.5 (though the full meaning of load average is a curious one (sorry for the double, now triple parenthetical statements )).) Simply add a little flv streaming foo to lighttpd, and you’re good to go.

At this point, we hit a stumbling block. In order for JWPlayer to seek, it would send a request for the FLV to the web server and give it a starting point, like so:

10.1.6.221 lighttpd.domain.dom - [29/Jul/2009:12:46:37 -0700] 
"GET /web_assets/video/your.flv?start=17038076 HTTP/1.1" 200
 17765145 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; 
en-US; rv:1.9.1.1) Gecko/20090715 Firefox/3.5.1"

However, if the flv you were serving didn’t have key frames then the web server would simply ignore the query string, and indeed, the click all together.

We do most of our development and video authoring on a mac and then serve our files off a load balanced linux server. At first, we used flvtool2 on linux to embed the key frames on our flvs. This kinda works, but it’d be easier to have the video author be able to add them himself with out needing to download and install ruby and rails and all that crazy server scripting foo. As his flv creator/codec/authoring app/chumpy wasn’t playing nice, I was given the task to find a simple solution.

Now, finally, we get to the point of the post. If you’ve gotten this far and wanna know how to embed keyframes with out ruby, get thee to the multi-platform, command line tool called flvmeta and go home happy!

Update: This post would not be complete without mentioned our use of swfobject to render the flash HTML.

Secret Jumps of Tunnel

0 minutes, 23 seconds

If you ride off road, you’re always looking for new ways to get from point A to point B and stay on the dirt. Today is Thursday which means that it’s leave work early and ride day! H and K and I were exploring off of Tunnel and found a full on hidden BMX track. I never road BMX as a kid, which makes my MTB skills a bit lacking. BMX skills or no, none of actually road this track. 4′ tall jumps with a 5′ gap? No thanks!

secretjumps

Macchiato!

0 minutes, 17 seconds

macchiatoI will be the first to confess that I love the ritual around coffee as much as I love the the actual drinking of coffee. Today, joining my pal from twtitw, I went to the wonderful Cento Cafe. It was sunny, the two macchiatos looked lovely and I was as happy as, well, as a me drinking phenomenal coffee with a good friend in the sun!

Rogue MySQL queries

1 minute, 32 seconds

Do you you ever have those moments where you’re trying out a query in MySQL and realize after you executed it that it’s going to kill your database server? If you’re like me, you’re often working in a LAMP stack in which case you’ve executed the query via a web page. The first thing you do is hit “esc” to stop the page from loading. MySQL doesn’t head the “full stop” call from Apache, if issued. If you’re silly and you did this on some sort production machine, you don’t exactly want to restart Apache or even worse, restart MySQL which can often take a while.

Enter show processlist; and kill PID! Yeah, mysql has it’s on version of “ps” and “kill -9”. In our case, this is extremely handy because it saves us the headache of rebooting MySQL and taking the DB offline for a minute. Connect to your DB as root and type:

mysql> show processlist;
+------+------+-----------+------+---------+------+----------------------+--------------+
| Id   | User | Host      | db   | Command | Time | State                | Info         |
+------+------+-----------+------+---------+------+----------------------+--------------+
| 1693 | root | localhost | rei  | Query   |   75 | Copying to tmp table | SELECT     di| 
| 1695 | root | localhost | NULL | Query   |    0 | NULL                 | show processl| 
+------+------+-----------+------+---------+------+----------------------+--------------+

Indeed this one query is killing the CPU:

top - 08:57:50 up 30 days, 20:59,  2 users,  load average: 0.53, 0.14, 0.04
Tasks:  72 total,   2 running,  70 sleeping,   0 stopped,   0 zombie
Cpu(s): 20.1% us, 30.1% sy,  0.0% ni, 49.8% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:   2074628k total,  2010740k used,    63888k free,   142648k buffers
Swap:   524280k total,      192k used,   524088k free,  1549692k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                              
 3119 mysql     16   0  549m 115m 5076 S 99.8  5.7   9:53.40 mysqld                                                                                                                                

All we have to do is kill it and the box is back to idle. Sweet!

mysql> kill 1693;
Query OK, 0 rows affected (0.00 sec)

mysql> show processlist;
+------+------+-----------+------+---------+------+-------+------------------+
| Id   | User | Host      | db   | Command | Time | State | Info             |
+------+------+-----------+------+---------+------+-------+------------------+
| 1695 | root | localhost | NULL | Query   |    0 | NULL  | show processlist | 
+------+------+-----------+------+---------+------+-------+------------------+
1 row in set (0.00 sec)

This is what makes a happy Sunday

0 minutes, 16 seconds

Well, this and a good bike ride!

With out really knowing it, I’ve been working my way through the Joy of Cooking’s pancake recipes. I’ve done basic, cornmeal and today was buttermilk. The basic is a bit watery, resulting in flatter pancakes. Today was the opposite, a bit fluffy. However, the fluff made for a great 3d pacman pic.

Toss Your Salad Code

2 minutes, 31 seconds

After my friend over at The Worst Thing in the World (TWTITW) recently had a post about Radar charting a salad’s many axes, I thought it’d be funny to write a page that actually made the graphs. I’d been meaning to write a post about using Maxmind’s GeoIP library and data to do heat map of web activity, but this will be a good warm up. Behold the fully functional Plip Salad Tosser.

Let’s take a look at the components of the Tosser:

The Chart: I like using APIs that are easy, make me look good, and are well documented. That’s why I love Google’s Chart API. For this page I used a their radar chart and referenced which features are available at the handy chart feature matrix. A few nice touches were adding the dotted lines and the extra data point to complete the loop (is a that radar chart faux pas?).

Arrays and quick forms: Arrays are really handy. They make a form like these easy to change and you can implode them like mad for loop-less string creation of chart labels and the like. Further, you can bust out a quick loop to check for posted values or init random values for the form. WAY easier than hard coding the HTML and making edits over and over again.

Final Product: Here’s a salad radar chart made from step 3, Publish!

PHP: Here’s the top part of the page which does the actual form processing and image source concatenating.

// seed all options
$options = array(
		'Architectural',
		'Conceptual',
		'Cultural',
		'Financial',
		'Gustatory',
		'Logistical',
		'Taxonomic',
	);

// see if they want a random one
if (isset($_POST['No,_no,_wait____toss_me_a_random_salad!'])){
	unset($_POST['d']);
}

// hand POST or init
if (isset($_POST['d'])){
	// grab vals if posted, pull name into local
	// and unset name for easy imploding below
	$postedAxes = $_POST['d'];
	$name = $postedAxes['name'];
	unset($postedAxes['name']);
} else {
	// init empty chart
	foreach ($options as $axes){
		$postedAxes[$axes] = rand(1,100);
	}
	$name = "Random Chart";
}

// seed drop down vals
$i = 1;
while ($i < 101){
	$dropValsRaw[] = $i++;
}

// build up form HTML by looping through
// every axes
$formHTML = "";
foreach ($options as $axes){
	$formHTML .= ' ';
	$formHTML .= '';

	// loop through evey axes value and check for
	// posted value so folks can easily tweak graphs
	$i = 1;
	while ($i < 101){
		if ($i == $postedAxes[$axes]) {
			$formHTML .= "$i";
		} else {
			$formHTML .= "$i";
		}
		$i++;
	}
	$formHTML .= $dropValsHTML;
	$formHTML .= '';
	$formHTML .= '
';
}

// concat final img src and use
// implode along the way where needed
$imgSrc  = "http://chart.apis.google.com/chart?";
$imgSrc .= "cht=r&chs=500x400&";
$imgSrc .= "chd=t:".implode(",",$postedAxes).",".array_shift($postedAxes)."&";
$imgSrc .= "chco=669933&";
$imgSrc .= "chls=2.0,4.0,0.0&";
$imgSrc .= "chxt=x&";
$imgSrc .= "chxl=0:|".implode("|",$options)."&";
$imgSrc .= "chxr=0,0.0,360.0&";
$imgSrc .= "chm=B,66993380,0,1.0,5.0&";
$imgSrc .= "chg=25.0,25.0,4.0,4.0&";
$imgSrc .= "chtt=$name"; 

HTML: Below the PHP I have some descriptive text and a few headers and then I output the fruit of our lil’ scripts labor:

Salad Maker

My friend over at The Worst Thing in the World (TWTITW) recently had a post about the axes of salad complexity. Based on their findings of 7 axes*, I wrote a lil' form to enter and toss your own salad. Read up on the code behind this page over at yon blog .

Go forth, make your salad, rate it, and use this form to publish your salad's findings (or is that finding your salad?).

* - Subject to TWTITW's whim and research

Step 1: Data Entry


Step 2: Analize

" />

Step 3: Publish

Final Thought: Projects like this that take about two hours are fun and very gratifying for me. Leveraging existing code bases like Google’s Chart API is a great way to make a friend’s funny blog post into a fun educational experience that looks snazzy. Send in questions or comments!