I Love It When The Lego Bricks Come Together

The promise of modern programming is this: you take a library here, a nuget package there, combine them with a webservice et voila! a working application. This is what I though creating my next hobby project would be. Just put some lego bricks together to create a usefull application.

In reality it didn't go that smooth. The experience was more like taking some Lego bricks and duktaping them so some Mega Blocks. Also string was needed to tie some Playmobil together. Oh, and a 3D-printed piece was needed because the thing I needed didn't exist yet. But when everything finally was jammed in it's place, the feeling of accomplishment was amazing. I made this!

Mutant Toys

Some background

I was one of the few owners of a Windows Home Server (WHS) machine. It sat in my utility closet, serving files all over the house and backing up various machines. One of the neat features of Windows Home Server was its plugin ecosystem. The most usefull plugin I had was My Music Disc Copier, which automatcally ripped CDs I put in the machine. It was a great way of converting my CD collection to mp3. After the platform died in 2012, I replaced the OS on my closet server with Windows 8 (which includes some of the backup and sharing capablilities of WHS). But that meant that I could no longer rip my CDs the way I was used to. No problem, I thought, I'm a programmer. I can make that myself!

The Vision

The vision was clear: To have a windows service that checks if there is a CD in the drive and kicks off the ripping process. Progress of the ripping needed to be monitored from a website. I also had a collection of tools/libraries I wanted to try out. I'm a firm believer in Golden Hammers for hobby projects. You don't use the best tool for the job, but the tool you're eager to try out. I wanted to learn Reactive Extensions, NancyFx and Knockout and this seemed like the ideal project to use them.

A few months of stealing moments of free time here and there, this is the result:

The work

This is how it all went down:

  • I used Topshelf for creating a windows service. This is a brilliant library that really takes all friction out dealing with windows services.
  • All components are tied together with Castle Windsor. This was the safe choice as I'm already using it at work.
  • With Castle Windsor's Startable Facility a background Task is fired up that will check if there is a CD inserted in the drive. This process is orchestrated by Reactive Extensions (Rx). I love the programming model of Rx, but I had some problems getting up to speed with it. It's really a completely different way typing your code.
  • Once a CD is found in the drive, the Ripping process is started. Since there is no library available for ripping CD's in .net, I had to create one myself. Luckely I found a few articles with sample code where all the hard work was already done for me. All I had to do was to craft a nice api on top for the p-invoke calls.
    • I also needed to fetch the album information in order to write the id3-tags. MusicBrainz.org has a webservice you can query, but you need a hashed code based on the cd-toc in order to do that. Creating that hash meant translating some c code to c#, which was ... interesting.
    • Once I could read a physical cd in .net and I had the albuminformation from MusicBrainz, all I needed to do was to pipe that information into a Lame process. That was suprisingly easy.
  • Now I had a service that could automatically rip a cd on insertion. But I still needed a way to report the progress of the ripping. The idea was to have NancyFx host a website inside the same windows service as the ripping process. Realtime information of the ripping would be relayed to the client using SignalR.
  • In order to run both NancFx and SignalR in the same process on the same port, the hosting aspect of both frameworks is handled by microsoft's OWIN implementation. OWIN will abstract away the hosting from both web frameworks, making it possible to run them side by side in the same process.
  • At this point I had a service ripping CDs and sending realtime information of it's progress to a website. In order to update the UI of the ripping progress, I used the Knockout javascript MVVM framework. It's amazing to see how easy it is to databind stuff using one of these modern javascipt frameworks. If I think about the mountains of jQuery code I have written in my career that can by replaced by a few lines of databinding code in knockout...

You can find the code of this little project here. It's a mess at the moment and most of the stuff is ductaped together. But it works and that's amazing!

Comments

Want to leave a comment? Visit this post's issue page on GitHub.

Loading comments...