well, that was a big waste of time

My knockoff Wiikey modchip proved to be too delicate a soul for this harsh world. $15 isn’t very much to pay for something delivered from Hong Kong, but in retrospect that low price may have contributed to its slightly off-kilter fit over the pads to which I was supposed to solder it. A few worked fine, but I was left trying to make awkward solder bridges for the rest. My soldering skills aren’t all that great by nerd standards, and my Radioshack iron leaves a lot to be desired. I’d already scorched the chip by the time I swooped in with some clippers to remove a misplaced solder strand, had the metal bond to the clippers and proceeded to pull up a sizable trace from the modchip. Whoops.

The good news is that the reassembled Wii seems to be fine despite now containing four fewer screws. But the removed modchip took a solder pad with it, so that’s it for this console: it’s now officially unmoddable — at least by someone with my meager skills. If some incredibly awesome homebrew or emulation project debuts that I can’t live without, I’ll have to buy another Wii. Ah well.

let’s pick on a different mp3 aggregator for a change

The Hype Machine is great, but it’s not the only one out there, after all. Besides, it’s got certain shortcomings: its “popular” page is fine if you want to listen to a ton of Bloc Party, but can suffer from a lack of variation. And looking at the front page is like drinking from a firehose. The podcast feed that I made last week suffers for it: you’re not getting a representative snapshot of what’s being talked about, but rather just a random sampling of what was popular when your copy of iTunes decided to check in. And, as I mentioned, the feed will no doubt be shut down by the HM guys (they may have already throttled iTunes’ bandwidth).

So what about elbo.ws? They publish a daily-updated list of popular tracks that contains more music I haven’t heard. And it’s persistent enough that querying it once a day could be useful. The only problem is that it doesn’t carry any MP3 links: users have to go hunting at the linked blogs to find links that are still alive. This makes it kind of a pain in the ass to check out the referenced music (and is why I generally prefer the Hype Machine).

But it is possible to create a podcast feed using techniques similar to the ones I applied to the Hype Machine. Here’s a pipe that simply retrieves the elbo.ws top tracks feed (or any other elbo.ws feed — it just defaults to that) and adds an enclosure tag to each entry. That tag tells iTunes (or whatever) to come talk to my server, passing the link associated with the elbo.ws entry.

At the server the request is intercepted via an .htaccess rewrite rule and redirected to a script (iTunes insists on URLs ending in .mp3, otherwise this would be unnecessary). The script pulls up the elbo.ws page and grabs the song name and listed blogs. It then loads the blogs and pulls out all of the MP3 links. From there it compares the link text to the collected song name and orders the results by similarity scores. Then it attempts to load each URL. For the first working one it finds it sends a redirect message to iTunes.

All this text processing and page-loading is pretty computationally expensive — it generally takes about half a minute to find a match — but with some caching it my server shouldn’t be completely destroyed. An occasional incorrect match is returned, but overall I’m pretty pleased with the thing.

Here’s the code for anyone interested. Given that this doesn’t affect the elbo.ws folks’ bandwidth or liability, I’m assuming they won’t mind:

<?php
// taken from http://www.php.net/manual/en/function.file-exists.php#79118
function url_exists($url)
{
$handle   = curl_init($url);
if (false === $handle)
{
return false;
}
curl_setopt($handle, CURLOPT_HEADER, false);
curl_setopt($handle, CURLOPT_FAILONERROR, true);
curl_setopt($handle, CURLOPT_NOBODY, true);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, false);
$connectable = curl_exec($handle);
curl_close($handle);
return $connectable;
}
function get_url($location)
{
$ch = curl_init($location);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: close'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
function usort_by_similarity($a,$b)
{
if($a['similarity']==$b['similarity'])
return 0;
else
return (($a['similarity']>$b['similarity']) ? 1 : -1);
}
function get_mp3_link_uncached($elbows_url)
{
$blog_matches = array();
$elbows_page_id = preg_replace('/^.*#/','',$elbows_url);
$elbows_page_html = get_url($elbows_url);
$blog_links = array();
if(preg_match_all('/<ul[^>]*>.*?<\/ul>/i',$elbows_page_html,$elbows_page_unordered_lists,PREG_SET_ORDER))
{
$matching_ul_html = '';
foreach($elbows_page_unordered_lists as $match)
{
if(stristr($match[0],$elbows_page_id))
$matching_ul_html .= $match[0];
}
preg_match_all('/href=[\'"](.*?)[\'"]/',$matching_ul_html,$blog_matches,PREG_SET_ORDER);
$song_name = $elbows_page_id;
if(preg_match_all('/<h3[^>]*>(.*?)<\/h3>/',$elbows_page_html,$song_name_matches,PREG_SET_ORDER))
$song_name = $song_name_matches[0][1];
}
$matches_for_analysis = array();
foreach($blog_matches as $match)
{
// find all mp3 links on the blog page
$html = get_url($match[1]);
if(preg_match_all('/<a[^>]+href=[\'"]([^\'"]*?\.mp3)[\'"][^>]*>(.*?)<\s*\/a\s*>/i',$html,$mp3_matches,PREG_SET_ORDER))
{
// retrieve the one with the most similar inner text and store it for more processing
$current_best_match = null;
foreach($mp3_matches as $mp3_match)
{
$l_similarity = levenshtein(substr($mp3_match[2],0,255), substr($song_name,0,255));
if((!is_array($current_best_match))||($current_best_match['similarity']>$l_similarity))
{
$current_best_match = array(
'url' => $mp3_match[1],
'text' => $mp3_match[2],
'similarity' => $l_similarity,
);
}
}
if($current_best_match!=null)
{
$matches_for_analysis[] = array(
'url' => $current_best_match['url'],
'text' => $current_best_match['text'],
'similarity' => $current_best_match['similarity'],
);
}
}
}
// sort the matches list from all blogs to find the one with the most similar title
usort($matches_for_analysis,'usort_by_similarity');
for($i=0;$i<sizeof($matches_for_analysis);$i++)
if(url_exists($matches_for_analysis[$i]['url']))
return $matches_for_analysis[$i]['url'];
}
if(isset($_GET['url']))
{
ini_set('max_execution_time',999999);
ini_set('include_path','.:/usr/lib/php:/usr/local/lib/php:/include:/home/metamon/php');
require_once('Cache/Function.php');
define('CACHE_EXPIRATION_IN_SECONDS',900);
$fcache = new Cache_Function('file', array('cache_dir' => './cache', 'filename_prefix' => 'fcache_elbows_'), CACHE_EXPIRATION_IN_SECONDS);
$mp3_url = $fcache->call('get_mp3_link_uncached',urldecode($_GET['url']));
header("HTTP/1.1 301 Moved Permanently");
header("Location: " . $mp3_url);
exit();
}
?>

And the .htaccess looks like this:

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^.*\.mp3(.*)$ index.php$1 [L,QSA]
</IfModule>

I should add that I know none of this is new or mindblowing — projects like Songbird are designed for exactly this sort of thing. But I like having my iPod automatically sync from one place, and I wanted to get at the elbo.ws feed specifically. Plus, y’know, it was fun to figure this out — it certainly taught me some things about the limits of Yahoo Pipes’ JSON functionality.

give-a give-a give-a Garmin

I woke up about fifteen minutes ago and turned the Redskins game on. Since then the following entities have used “The Carol of the Bells” to try to sell me things:

  • Garmin
  • Wal-mart
  • Hyundai
  • Verizon
  • Hyundai, again

In general, I don’t really mind having beloved parts of our shared culture appropriated by the great campaign to sell me injection-molded plastic from Shengzhou. But I am going to have to insist on a little more variety. Why so much “Carol of the Bells”? I suppose it’s got secular lyrics, which discourages the religious crazies from writing letters about how Jesus dislikes crass materialism and would prefer that we save our money for war with Iran. But mostly I think it’s because it’s one of the most lonely, haunting holiday songs, if not because of how it sounds then at least because it was used to that effect in Home Alone. This makes people think about sitting alone in the fading light of a winter day, left to wonder where their family is. Wouldn’t you rather spend that time carefully reading the manual to your new GPS unit?

Whatever happened to all those Gap ads where shame-faced musicians would listlessly plod through rocked-up carols? I need some more of those. I know Gap’s been facing some financial trouble, but I’d be willing to write my congressman about a federal bailout if only they’d promise to get, say, My Chemical Romance to tear through an emo version of Handel’s Messiah.

At any rate, here’s the only version of “Carol of the Bells” that I actually want to see on my television:

It’s even better than the version of “We Three Kings” with the swingin’ camels. I could’ve sworn those camels moonwalked, but YouTube disagrees.

all brooding westerns all the time

Saw No Country For Old Men last night; saw this today while catching up on Stereogum‘s feed:

Having seen them after this week’s visit to present-day California, I think I’ve now officially returned to psychological parity.

everything is connected

  1. As noted on their blog, some guy (not me; I wish I’d thought of it, although I wouldn’t have published the MP3 URLs publicly) has written a script that pulls RSS from the HM, adds Last.fm popular tags to songs, and posts the MP3s’ URLs to del.icio.us. The result is a huge, well-categorized stream of MP3s that represents most of the music blogosphere.
  2. As you probably know, it’s easy to filter a del.icio.us user’s entries by tag — for instance, here are the HM entries tagged “indie_rock” (I should point out that the tags get considerably more granular than this example). Thanks to del.icio.us’s cool PlayTagger Flash audio player, this is already pretty useful. But it gets better.
  3. It’s also very easy to get an RSS feed of all or part of a del.icio.us user’s entries.
  4. It’s only slightly harder to use Yahoo Pipes to turn an RSS feed of links to MP3s into an iTunes-compatible podcast feed. Here’s a pipe that lets you do exactly that to any given feed of MP3s.
  5. Add this up and you get an ipod-ready podcast version of the HM. This is a feature that the site used to offer but no longer does (I could never get it working, anyway, although I think this was probably due to PC iTunes’ suckiness at the time).

Incidentally, they also have a new flash MP3 player over there, which is very nicely done. It’s based on this guy’s MP3 player — I’ve used his Flash video player on a project at work and can attest to its awesomeness (javascript bindings!). It’s free for personal use, too, and cheap for commercial applications.

UPDATE: I should add that if you decide to try this out you should absolutely not set iTunes to update more often than once a day, as you’ll be getting too much music to listen to and burning through HM’s bandwidth for no good reason. Also, I should warn that the HM folks will probably shut this approach down shortly by disallowing iTunes’ HTTP user agent string. I wish they’d just run the feed themselves, sticking advertising in the podcast entries to pay for the bandwidth. But it’s probably pretty complicated to sell that particular kind of ad unit, so I’m not holding my breath waiting for it to happen.

Incidentally, this is yet another app that makes me wish Amazon’s S3 storage service was free. That’s a bit unrealistic, of course. But I’m increasingly convinced that we need an open P2P storage system. Something like this or an easier-to-use (and less porn-riddled) Freenet, but with a simple API. Ideally it’d be baked into some hugely-popular Firefox extension in order to garner sufficient levels of adoption.

UPDATE 2: At a cursory glance Oceanstore looks about right, although it seems as though it hasn’t been worked on for a couple of years.

I am returned

Back! Back from San Diego, which appeared to currently be running some sort of citywide promotional tie-in with upcoming feature file The Mist. It was nice enough, I guess: I attended meetings, ate continental breakfasts, and toured a number of culturally significant faux-adobe strip malls. Also, I watched about a million episodes of Deadwood’s second season. Combined with jetlag, this is leading me to formulate sentences in some pretty strange/pretentious ways.

The trip was good, but my primary objective was only partially accomplished: I wanted to eat as many fish tacos as possible. Admittedly, “as possible” is somewhat nebulous goal. Still, I can identify a full two meals that conceivably could have involved fish tacos but didn’t. I definitely could’ve done better than the soggy, lackluster experience at the airport Rubio’s. And although El Callejon was tasty, its lack of Baja sauce, cabbagelessness, and single-ply corn tortillas provided a different taco experience than I had been expecting. Fortunately, margaritas eased the shock.

Anyway, if you’re visiting San Diego I suggest you avoid those two restaurants and instead opt for That One Place Near The Water That I Went To With Jeff And Paul That One Time. It’s as delicious as you’ve heard.

dear internet

I’ve got a technical question for you. The demise of Oink and my rapidly-depleting server disk space have put me in the market for a new Bittorrent solution. I’m not up to administering a properly RAIDed box (getting it to email me when a disk fails is just too much of a pain, given the difficulty of sending mail out from a consumer ISP connection). And having a constantly-running PC fan in the living room is kind of annoying.

What I’d really like is to buy a network-attached storage device that has Bittorrent baked in. Something with RAID that’d sit quietly and download stuff, and that doesn’t cost too much money. There’s this thing, which looks promising but has so-so customer reviews — folks say it’s kind of loud and has flaky firmware. This is a bit pricier — you have to supply the disks, and I haven’t got spare SATA drives lying around — but apparently supports BT.

I imagine there’s a third option: get a cheaper, dumber RAID NAS and figure out a way to run BT on my router. It looks like this is possible with a custom firmware, but perhaps only with the user-unfriendly OpenWRT. Given how little I can find online about this subject (and the fact that I’ve only used DD-WRT and Sveasoft before), I’m a little wary of trying it.

So what do you say, internets? Any suggestions?

entropy: pro and con

  • PRO: Towels are self-drying.
  • CON: Dust accumulates on surfaces regardless of the moral culpability of the surface’s owner. This is typically the first thing that comes to mind when I hear the phrase “cosmic injustice”.
  • PRO: The tendency of energy to seek less-ordered states allows physical work to exist in the universe, which can can be harnessed by order-increasing processes, including those that form the basis of life.
  • CON: Videogame controller cords frequently become tangled.
  • PRO/CON: Bags of candy (e.g. Skittles) are self-mixing. However, this is somewhat offset by the resulting necessity of M&M sorting, which significantly drives up the per-unit cost of rock & roll.
  • PRO: Ice makes drinks colder.
  • CON: The inevitable heat death of the universe. This sounds like it will be a drag.

VERDICT: Mixed. Entropy allows life to exist, but also means that life will consist largely of tidying up. It’s unclear whether this is a net positive or negative.

notes for myself

NBC Direct’s DRM may be a tougher nut to crack, not least of all because of its insistence on using IE on XP. I don’t have an XP machine, and IE precludes the reliable mix of Firefox plugins that makes pulling apart website behavior a breeze. You can accomplish the same thing with other tools, but it’s a much bigger pain in the ass.

At any rate, here’s the XML that a properly authenticated request will return. As you can see, there’s not much useful here — I was hoping for a URL or encrypted key, but no such luck. Sniffing the HTTP traffic of the following exchange is the next thing to do. Given the XPcentricity of the app, I’m optimistic that this stuff would work on the downloaded files.

<!--
returned by command
curl -A"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)" "http://www.nbc.com/app/direct/services/?method=provisionLicenseAndDownload&assetPk=200135&devicePk=220499&productPk=200027"
-->
<?xml version="1.0" encoding="UTF-8"?>
<DirectProductGuide>
<provisionLicenseAndDownload>
<key_0>
<accountFk>221752</accountFk>
<assetFk>200135</assetFk>
<completeDate></completeDate>
<completeNote>Register asset message queued for S200122D200158E200159T200160C200161</completeNote>
<deviceFk>220499</deviceFk>
<productFk>200027</productFk>
<profileFk></profileFk>
<provisionId></provisionId>
<provisionName>30 Rock | Greenzo</provisionName>
<provisionPk>271150</provisionPk>
<provisionStatus>scheduled</provisionStatus>
<provisionType>download</provisionType>
<purchaseFk></purchaseFk>
<requestDate>2007-11-14T21:41:42.716Z</requestDate>
<xmlData></xmlData>
</key_0>
<key_1>
<accountFk>221752</accountFk>
<assetFk>200135</assetFk>
<completeDate></completeDate>
<completeNote>License new message queued for S200122D200158E200159T200160C200161</completeNote>
<deviceFk>220499</deviceFk>
<productFk>200027</productFk>
<profileFk></profileFk>
<provisionId></provisionId>
<provisionName>30 Rock | Greenzo</provisionName>
<provisionPk>271151</provisionPk>
<provisionStatus>initiated</provisionStatus>
<provisionType>license</provisionType>
<purchaseFk></purchaseFk>
<requestDate>2007-11-14T21:41:42.822Z</requestDate>
<xmlData></xmlData>
</key_1>
<status>success</status>
</provisionLicenseAndDownload>
</DirectProductGuide>

It’s all just an academic exercise, of course — all this stuff is on Bittorrent already.

the internet is just a tool

Hell is other commenters

Via Dan’s Data, check out this article, in which the author explains what foods are most compatible with “The Secret”, Oprah’s made-up religion for turning dumb luck into an intentional act. Aspartame is right out, as is caffeine: “the onslaught of daily stimulants leaves the body depleted of energy, unable to reach the level of vibration necessary to effectively broadcast intention to the universe.” Clearly.

Also, the author is quick to point out that native cultures around the world use drugs as powerful spiritual aids, that our, like, Western culture just doesn’t uderstand or can’t accept or something. However, the drugs that people actually like to use once they’ve got indoor plumbing are very bad for magically turning your crude drawing of a winning lottery ticket into that above-ground pool you’ve been hankering for. I know, it’s a drag. On the upside, you should feel free to eat all the microalgae you want.

Yes, this is just another moron making things up on the internet. Hell, I do it all the time. Look, here I go: “Python’s a dying language.” There, I said it. Soon Google will pick it up and it will be officially true. This process is called epistemology, and it’s the foundation of our modern society.

But scroll down. There are dozens of comments on the article, all of them deeply depressing. “Dear Crackpot,” they say, “Normally I enjoy your articles where you make things up that support my unscientific worldview. But this time the made up things contradicted some aspects of my elaborate system of dietetic make-believe! Please correct this at your earliest convenience.”

The internet was supposed to make things better. Sure, it seemed likely to make us dumber along the way. But this much dumber?

Redemption

As misanthropy-inducing as the above is, there’s reason for hope. Have a look at this. The collective intelligence of the network has been harnessed to identify a blurry book on a coffee table in an episode of The Hills. This is what it’s all about. Somewhere, tears of joy are streaming down Tim Berners-Lee’s face.