You can kill the background for speed, if you wish.[x]

Monday, August 9, 2010

More Stupid Vim Tricks

Today I had an SVN log that was in descending order by date (most recent at the top), and I wanted it in ascending order (most recent at the bottom). Now there may be a flag on the svn log command to do this, but I thought I'd see what I could do with Vim. One of the most useful tools for doing such things is macros. I read this article a while back about using macros over regexes for many situations, and it's proved to be a very useful technique, and one that looked to be of use here, too. Here's what the svn log looks like:

------------------------------------------------------------------------
r21783 | jbradsha | 2010-08-04 14:41:02 -0700 (Wed, 04 Aug 2010) | 2 lines

Log notes

------------------------------------------------------------------------
r21765 | jbradsha | 2010-08-03 16:09:05 -0700 (Tue, 03 Aug 2010) | 2 lines

Log notes

------------------------------------------------------------------------
r21519 | jbradsha | 2010-07-22 16:51:04 -0700 (Thu, 22 Jul 2010) | 4 lines

Log notes

And so on.

The log notes can be of any length and number of lines, so obviously this wasn't going to be a straightforward task. But it ended up being pretty easy with macros. What I wanted to do was sort those blocks by revision number. To do that, I figured the easiest way is to get each block on one line in a way that I could revert, sort the lines, and then put them back. So I put my cursor on the first character of the first line and did this:

qj 
v
/\n\n---- 
:'<,'> s/[\r\n]/#!#/g
j
q
100@j
:% sort
:% s/#!#/\r/g

Which quite nicely did the trick. Here's what each bit did:
  1. Started recording a macro labelled "j" (for "join")
  2. Started visual selection mode
  3. Searched for two newlines followed by ----: this selects up to the end of the line before the end of the current block (by going two lines before the beginning of the next)
  4. Within that selection, replace all newlines with a unique symbol (#!#), making it all one line ready to be re-exploded afterwards
  5. Move down one line to the beginning of the next block
  6. Stop recording the macro
  7. Run the macro 100 times (I had less than 100 commits to sort)
  8. Sort the now-one-line commits, increasing in number (sort! would reverse the sort)
  9. Replace my delimiters with newlines, restoring the original format
It may sound and look horrendous, but it was pretty straighforward, and macros are a lot easier when you're actually doing them. I just love the power and flexibility you have to do such things in Vim - I can't compare it to emacs, but no other editor allows you nearly this amount of power or flexibility. And if I had wanted to do an even more complex sort, I could have easily piped it out to a command line utility instead of using Vim's built-in sort. But for my purposes, this was plenty.

Thursday, August 5, 2010

Presenting: Wreck's This?

Woo hoo! Jen featured this in her Saturday post this week. It's awesome that so many people have enjoyed this crazy thing! Downloads/ringtones are available down below the video.

Among my blogs that I read sometimes sporadically are Cake Wrecks, a wonderful project by a woman named Jen (with frequent contributions from her husband John) dedicated to sharing the results when, as the motto goes, "professional cakes go horribly, hilariously wrong." It's always entertaining, and I've been especially amused by the occasional geeky and/or childhood references that make their way into her posts - a quick, subtle Veggie Tales reference, the inevitable display of Star Wars butchery - as well as classic and fantastic word journeys that are inexplicable in their hilarity.

But all of this reached a fantastic new height, when a whole post was set to the tune of one of my favorite songs from one of my favorite movies - What's This? from Nightmare Before Christmas - I was delighted. I have both of the awesome cover albums from Nightmare Before Christmas, and both the original and Fall Out Boy's cover are fantastic* - if you haven't heard the latter, do yourself a favor and check it out. Suffice it to say, I loved this post already. But then, at the bottom, was a fantastic and hilarious video of John and one of their friends SINGING the blog post, and doing a pretty decent job of it!

I couldn't help but imagine how awesome it would be to back this terrific effort with some music - and fortunately, I've done enough twiddling with Audacity that it was quite possible to try, anyway. So try I did, and this was the result. Before listening, you should probably read the original post if you haven't already. Read it? Okay, I call this...

Wreck's This?: A Parody:

But of course, I couldn't stop there. I e-mailed Jen and John, and they loved it, and agreed that it was simply begging for a video/slideshow to go with it. And who am I to keep such a thing from being in existence? So I fired up Openoffice Impress to get a slideshow up and running, recorded my clicking through it to the music with xvidcap, and then hopped over to Blender (which is fantastic as a video editor, by the way) to edit and put everything together. And yes, I'm a Linux man, through and through. Anyway, after all that, I came out with this:

...and now my work is done. Hopefully.

Update: Thanks for all the comments, here and over on Cake Wrecks. It's great to see my augmentation of the original Cake Wrecks genius bring a bit of joy and laughter to so many people! For you crazies that want to download it, here's a Normal-quality (~128k, 3.7MB) and High-quality (256k, 6.3MB) version.

And for those of you who are even more crazy, and want ringones, I made a few:
"Popular" by John
Donkey Tank Surprise!
Dumpa dumpa dumpa dumpa whee-you whee-you
Meteorite-bird Fiiiiish (with subsequent ring!)
Rappiness
Can we wrap this up?
If you have Bluetooth on your phone and computer, you can send them to your phone that way. Otherwise, there are internet sites that should be able to do so. From some brief looking, Myxer looks like the most legit/easy way to do this (you can even upload the full song above and chop to make custom ones!). The file it sent to my phone didn't play, but sometimes my phone is weird like that. So good luck?
If you want to chop them up without Myxer (like for Bluetooth), the tool I used is Audacity, which is really easy, I promise - just open one of the full songs above in it, select the portion you want, and hit File->Export Selection. Done!

My favorite part of this whole thing is still "I'm with Jen and John and we're doing this thing... but it's dumb." Cracks me up every time. I still kind of want to put it in a video with the pictures being sung about, but for now this will suffice. Hey, look! I did! The song was surprisingly easy to put together - my compliments on the singers for being remarkably on tempo. The middle was a little iffy, as the tune didn't exactly line up to anything actually in the song as far as I could tell, and the "rappy" part at the end gets a little muddled, but it works, and finishes strong. My favorite part is that the timing of the phone call works perfectly in the space that's not filled by actual lyrics. Thank you, Jen, John, and "the other Jen", for an awesome blog, post, and song.

I think this all should be good, being a parody and all, and I doubt anyone will get riled about it anyway. Jen and John loved it, and agreed that it was begging for a video - hence the addition.

*While many of the other additional covers on Nightmare Revisited are fantastic (Rodrigo y Gabriela, Korn, and even All-American Rejects and Plain White T's are all wonderful), Flyleaf's version of What's This? just made me very sad.

Monday, May 3, 2010

CakePHP, cakephp-instaweb, and PHP 5.3

Today I tried to get a CakePHP app up and running on my home computer, with the excellent cakephp-instaweb, a nifty little Python script that lets you run any CakePHP app from anywhere on your computer. Unfortunately, it didn't work, and was giving me a HTTP 500 CGI Script Error: Premature End of Script Headers error. From looking around the internet, this basically means "Ahh! Something went wrong," which isn't terribly helpful. My first guess* was that my .htaccess files got messed up, which is a good first guess when such things go wrong, but everything was as it should be.

After some more digging, I found out that PHP 5.3 by default flipped a switch (cgi-bin.force-redirect) that previously had been defaulted to off. This issue, I suspect, cropped up because I just recently upgraded to Ubuntu 10.04 Lucid Lynx, and I'm assuming my PHP was upgraded in the process - it is indeed now at 5.3.

From what I can tell, it's a security measure that makes sure scripts are running from where they're supposed to be - which is great, except that that's exactly what CakePHP doesn't do. Fortunately, the solution was as simple as turning this off in my php.ini. A quick locate revealed three of those, in three subfolders of /etc/php5: /cgi, /apache2, and /cli. I initially turned them all off, but only the CGI version ended up needing it. Where exactly your php.ini is depends on your operating system, configuration, and all kinds of things. But if you run into an error like this, try un-commenting and changing the section in your php.ini to look like this:

; cgi.force_redirect is necessary to provide security running PHP as a CGI under
; most web servers.  Left undefined, PHP turns this on by default.  You can
; turn it off here AT YOUR OWN RISK
; **You CAN safely turn this off for IIS, in fact, you MUST.**
; http://php.net/cgi.force-redirect
cgi.force_redirect = 0
Things should start working better, or at least they did for me.

*For general Cake debugging reference, the first thing you should suspect is your cache. If debug is set to 0, it doesn't recreate the cached models and such, so many modifications you make won't actually take effect. Setting debug to 1 or 2, in your core.php, or just clearing your app/tmp/cache folder (only the files inside it though, leave the folder there!) will often resolve some unexpected behaviors.

Sunday, April 4, 2010

A little data to go with your Easter

It's Easter today, and one of my friends' Facebook statuses reminded me of a little fact that I gleaned from Wikipedia a while back. It's always bugged me that Easter changes every year, seemingly at random. When I went to look this up, I found out that it's not quite random, but is horribly complicated. There's a very long writeup over at Wikipedia that I couldn't quite wrap my head around, but the bottom line is that the sequence of Easter dates repeats only after 5.7 million years. I made up a graph from the percentages I found of how often each date is Easter, and then found that Wikipedia already had a graph very similar to mine. Of course, I thought mine looked nicer, so I uploaded it as a replacement. And as you can see, this year is actually a pretty average Easter date, as you can see: I hope you have enjoyed this bit of random trivia resulting from idiosyncrasy piled upon idiosyncrasy, with a touch of tradition to make it that much better.

Wednesday, March 31, 2010

UserScripting it up!

For a long time, I've been using Greasemonkey for all kinds of things in Firefox, both enjoying Userscripts from others, and writing a few of my own. They're basically little Javascripts that run on whatever pages you choose, so that you can add functionality to websites at your whim. A couple of my favorites are a Youtube Download that actually still works, and inYOf4ceBook, which gives you mouse-over enlargements of photo thumbnails on Facebook. Greasemonkey has become a de-facto standard of sorts, and as such, Userscripts even have limited (but growing) support in the latest builds of Chrome.

When I saw the course schedule in Banner (a management system my school uses), I figured I could probably hack some bookmarklets to grab the course info from that and put it into Courses 2.0, an excellent Facebook application that lets you post your class schedule on Facebook, where it's much easier to get to that on Banner. As it turns out, due to iFrames and such nastiness, I had to write a Greasemonkey script for it. I built the initial version a couple quarters ago, and at the beginning of this quarter, beefed it up a bit, fixed some issues, and made it compatible with Chrome, in preparation for uploading it to UserScripts.org, a great repository for everything Greasemonkey.

So check it out - installing Greasemonkey is just as easy as any other extension - just go to the addon page and install it. Chrome you don't need any addons, and in both Firefox and Chrome, you can just click the Install button on Userscripts, and follow the prompts to install a Userscript. If you use Banner, check out my Banner Bridge. Regardless, do yourself a favor and browse through UserScripts.org - you'll probably find something that will make your online life a bit easier.