Wednesday, December 17, 2008

How to write a playlist maker script

I got an email asking for tips on writing a playlist maker script.

Using PHP, my process was this:
1. Choose a playlist format. My favorite playlists are Windows Media Player WPL files, which use the SMIL subtype of XML. There are tons of other types of playlists. Songbird and Winamp both use M3U, for example. Unfortunately, most playlist file types, including M3U, are not as "smart" as WPL files, in that they want the exact path to a single song on a user's computer, rather than just an artist name or song title. WPL files will take an artist or song name and give you a playlist of everything in your library that matches. I don't understand why Songbird and Winamp don't handle WPL or SMIL files (yet?). After I figured out which playlist format I wanted, I right-clicked a WPL file I'd made, opened it in Notepad, and used it to cut and paste the top, bottom, and repeating bits of the playlist code where needed in the following steps.

2. Find a source of artists or song names you want in your playlist. The best way was to use an RSS feed, but for my iLike and last.fm tag playlist makers, I scraped the source code of some web pages, which is messy, but it works. You can also offer a way to paste in or upload a list of artists.

3. Write an HTML form (called, for example, input.html) that takes user input (like a last.fm username) to get the source you want. The "Submit" button on the form will take you to your playlist making code (playlistmaker.php, for example).

4. Write code to convert your input (such as a last.fm username) into a URL to an XML or HTML file and get that file ready to be used. For example:
$handle = fopen("http://ws.audioscrobbler.com/1.0/user/".$username."/topartists.txt?type=overall", "r");

5. Write code to make an array of only artists or song names using your source. The exact code will vary depending on the source of artists or song names. This is the trickiest part, and I'd give examples of how I've done it, but it's different nearly every time, and I'm sure my ways are not especially elegant. One thing I'd like to do better is parsing the actual XML instead of finding where the artists turn up in the array and using numeric indices to grab the artists or song names.

6. Create a variable that will contain the entire text you want in the playlist file ($wpl, for example). Paste in the top bit of the playlist text. For a WPL file:
$wpl = "<?wpl version=\"1.0\"?>
<smil>
<head>
<meta name="\" content="\">
<title>".$username."</title>
</head>
<body>
<seq>
<smartplaylist version="\">";

7. Write a loop that adds the section of the playlist that repeats for each artist or song name to your playlist variable ($wpl., for example). Concatenate in the artist or song name variable. Make sure you convert HTML characters, as ampersands will render your playlist utterly worthless. For example, where the artist names are in $data[2]:
while ($data = fgetcsv($handle, 1000, ",")) {
$wpl.="<querySet>
<sourceFilter id=\"{4202947A-A563-4B05-A754-A1B4B5989849}\" name=\"Music in my library\">
<fragment name=\"Album Artist\">
<argument name=\"condition\"<Contains>/argument>
<argument name=\"value\">" . htmlspecialchars($data[2]) . "</argument>
</fragment>
</sourceFilter>
</querySet>";
}

8. Finish off your playlist text variable by pasting in the end text of the playlist variable (again, $wpl.). For a WPL file:
$wpl.="
</smartPlaylist>
</seq>
</body>
</smil>";

9. Create a new file containing your playlist variable text as follows:
$handle = fopen("filename.wpl","w");

10. Offer a link to download the new file.

11. Try it out!

Optional tweaks:
12. WPL playlist files offer you the option of finding an artist name that "Contains" the word "Bell" (for example), or finding an artist that "Is" the word "Bell." After the band "Bell" made Belle and Sebastian turn up in a festival playlist I made (oh, the brief crushing excitement), I added a conditional so that if the artist name is 5 characters or shorter, I use "Is", and if it's longer, I use "Contains". It's still inexact, and it's an area I'd like to improve. Handling "The" (Pixies, Beatles, Raveonettes) is another thing I'd like to work out at some point. Here's an example of one of my conditionals where the artist names are in $data[2]:
while ($data = fgetcsv($handle, 1000, ",")) {
$limit=6;
$num=count($data[2]);
for ($i=0;$i<$num;$i++) {
$len[$i]=strlen($data[2]);
if ($len[$i]<$limit) {
$wpl.="<querySet>
<sourceFilter id=\"{4202947A-A563-4B05-A754-A1B4B5989849}\" name=\"Music in my library\">
<fragment name=\"Album Artist\">
<argument name=\"condition\">Is</argument>
<argument name=\"value\">" . htmlspecialchars($data[2]) . "</argument>
</fragment>
</sourceFilter>
</querySet>";
}
else {
$wpl.="<querySet>
<sourceFilter id=\"{4202947A-A563-4B05-A754-A1B4B5989849}\" name=\"Music in my library\">
<fragment name=\"Album Artist\">
<argument name=\"condition\"<Contains>/argument>
<argument name=\"value\">" . htmlspecialchars($data[2]) . "</argument>
</fragment>
</sourceFilter>
</querySet>";
}
}
}

13. Greasemonkey! Using a tiny bit of Javascript, you can put a link to your playlist making code on relevant source pages. Clicking this link will give you the option to look at one of my Greasemonkey scripts. You'll especially want to change:
  • @include to reference the page you'd like to put a link on.
  • The link to the script that makes your playlist.
  • @name
  • @namespace
  • Colors (I'm using last.fm grey. Meh.)

You can grab the username for the last.fm URL they came from by putting this at the top of your playlist maker script (playlistmaker.php, for example):
$url = getenv("HTTP_REFERER");
$elements=explode("/", $url);
unset($url);
$username=$elements[4];
unset($elements);

Here's a zip folder with code for the input form and playlist maker, as well as a Greasemonkey playlist maker for a last.fm listener's most-played artists. This was one of the first things I did when I was learning PHP, so it's far, far, far from perfect. But feel free to use any bits of it you like. I'm not litigious.


I am crawling up a learning curve (Drupal) myself right now, but if you have questions or suggestions, comments are open.

For anyone more interested in making playlists than playlist-maker scripts, my playlist makers are here.

Tuesday, November 11, 2008

Fantasy Cabinet tool

The Onion recently suggested that people who'd been obsessed with the election were now going to realize our lives are devoid of any meaning.

Well, perhaps, but that doesn't mean we've stopped caring about politics.

For example, I'm working on a Fantasy Cabinet tool. Right now, it's ugly, but it works. Enjoy, America nerds.

Tuesday, November 4, 2008

Election Day resources online

NPR Election Map
Jumping the gun like ABC, but not quite as much.

ABC Election Map
First place I saw the number of counted votes for Obama and McCain, when it was down around 13,000. Cool.

MSNBC Decision '08 Dashboard
NBC has said they'll only call the race when the chance of getting it wrong is less than 1 in 200 according to statisticians. Their maps also show key Congressional races. You can tweak the page so it shows the information you want and leaves off the junk about what Cindy McCain wore to the polls. I had a link to their video stream, but I clicked it and it was goddamn Pat Buchanan. So that's out.

Twitter Vote Report Map
Maps of people's voting experiences as reported to Twitter.


Twitter Election
A lot of nonsense, but really the absolutest fastest way to get interesting new information when it isn't nonsense.

Video the Vote
Shows real people voting, or rather, waiting in ridiculous seven hour lines to vote. With two kids. On the one hand, those people are awesome. On the other hand, I hope more states switch to voting by mail like we do in Oregon.

Huffington Post Roundup
A collection of widgets and geegaws I've not yet mined, but am looking forward to investigating.

Is Obama President?
Simple.

CNN Live Stream
Watch CNN online.

TwitVote
Completely unscientific, but if you like Obama, totally gratifying.

CNN Election Tracker
A summary of polls. I'm not sure if they'll update it with exit polls when those come in after 5 p.m., but I'll be checking this to see if they do.

Sunday, November 2, 2008

American Bubbly for Election Night

Here are just a few suggestions for American sparkling wines to celebrate (or drown your sorrows) on Election Night.

1998 Argyle Brut Extended Tirage, Argyle Winery, Oregon, United States, WS 95, $25, $59

1997 Argyle Extended Tirage, Argyle Winery, Oregon, United States, WS 94, $24, $37, $40, CellarTracker, COLA

2000 Blanc de Blancs, Argyle Winery, Oregon, United States, WS 92, $40

2001 Schramsberg Vineyards Reserve, Schramsberg Vineyards, California, WS 91, 90, $76, $85, $100, COLA

2000 Knudsen Vineyard Brut, Argyle Winery, Oregon, United States, WS 91, $30, $40

Roederer Estate Brut, California, WS 90, $22

2002 Argyle Brut Sparkling Wine, Argyle Winery, Oregon, United States, WS 90, 91.5, 87, $24

2006 Argyle Brut Rosé, Argyle Winery, Oregon, United States, WS 90, $45

1996 Argyle Extended Tirage Brut, Argyle Winery, Oregon, United States, WS 90, $34, $37, $40, The Wine Camp Blog, COLA

Chateau Frank Celebre, Dr. Konstantin Frank Vinifera Wine Cellars, New York, WS 82, $19, 85, $20, COLA

Schramsberg Mirabelle Brut, Schramsberg Vineyards, California, 92, Good Wine Under $20, $18, $20, COLA

1998 Schramsberg Cremant, Schramsberg Vineyards, California, 92, $45, COLA

2001 Schramsberg Brut Rosé, Schramsberg Vineyards, California, A-, $23, $27, COLA


Glenora Peach Spumante, New York, 85, $9, $10, $11, Dowd's Tasting Notes, COLA

Glenora Raspberry Spumante, New York, 85, $9, $10, $11, COLA

Sofia Blanc de Blancs, Niebaum-Coppola Winery, California, $4, $13, $16, msnbc, winewaves, Tastes Of Life, yumsugar


Schulze Cuvee Rose, New York, $14, COLA

Domaine Ste. Michelle Cuvee Brut, Chateau Ste Michelle, Washington, $14, COLA

Schulze Blanc de Blanc Sec, Schulze Vineyards & Winery, New York, $16, COLA

Schulze Blanc de Blanc Brut, Schulze Vineyards & Winery, New York, $16, COLA

2005 McWilliam's Mount Pleasant Sparkling Pinot Noir, Mount Pleasant, Missouri, $18


2006 Cuvee Brut, Atwater Estate Vineyards, New York, $25, COLA

1998 Schramsberg Brut Rose, Schramsberg Vineyards, California, $30, $97, $120, COLA

1996 Schramberg J. Schram, Schramsberg Vineyards, California, $52, COLA

Thursday, October 30, 2008

Yes We Can (Hold Babies)


I just heard about the adorable Yes We Can (Hold Babies) web site. You should check it out, and remember to vote, vote, vote! Find out where and what ID to bring.

Monday, October 27, 2008

25 Wedding songs



Jonathan Coulton


Ben Gibbard of Death Cab for Cutie- Sasquatch Music Festival, The Gorge, WAspacehindu
The Pipettes
DSC_0095caloomba
Avett Brothers - Matrimony

Blitzen Trapper - Crazy On You [Buy mp3!!!]

Jonathan Coulton - Skullcrusher Mountain [ Buy mp3!!!]

The Boy Least Likely To - Rock Upon A Porch With You
Nada Surf - Always Love [Buy mp3!!!]

Elvis Perkins - While You Were Sleeping [YouTube][Buy mp3!!!]
The Brunettes - If You Were Alien [Buy mp3!!!]

Death Cab For Cutie - All Is Full Of Love

The Brunettes - Mars Loves Venus

Sufjan Stevens - To Be Alone With You

Feist - I Feel It All
Feist - It's Cool To Love Your Family [last.fm]

The Bees - I Love You [last.fm]

Wendy O. Williams and Lemmy Kilmister - Stand By Your Man

Matt Costa - Sunshine
Matt Costa - Sweet Rose [Lyrics]

Foo Fighters - Everlong

Of Montreal - Spoonful Of Sugar

The Pipettes - I Love You [Live][Live][Buy]

Cowboy Junkies - Sweet Jane [Live][Buy Album]

Crosby, Stills & Nash - Teach Your Children

The Velvet Underground - I'm Sticking With You

Gothic Archies - Shipwrecked

Holly Golightly - Your Love Is Mine

The Cure - Love Song

Friday, October 3, 2008

Google Chrome: I'll pass

My Firefox browser crept up to using 200 megs of system resources today, so I decided to try out the new Google Chrome browser, which treats every window and tab as a different process. Close one tab, use fewer system resources. Awesome!

While Chrome installed (it took a long time!), I started looking for del.icio.us, StumbleUpon, and download manager tools for Chrome. I found del.icio.us and StumbleUpon bookmarklets, hooray! But while I was deciding if no wonderful DownThemAll download manager would be a dealbreaker (I use DownThemAll in conjunction with my blog reader to feed my podcast addiction), I noticed the blog post "Why I Uninstalled Google Chrome." It's about Google's weird privacy situation. It's bad enough that every time any one of the kajillion random people we let use our wifi does a search, that gets logged in Google's database under our IP address. Google anonymizes that, but not really.

With Chrome, Google would keep a database of not just my searches, but absolutely everything I do online. Though I am not a terrorist or a pornographer or a promising young politician susceptible to Roveian use of spying agencies, having everything I do online in someone else's database is still creepy to me, and I don't think Firefox does that (it seems like phoning home to Google every time you load a web page would slow you down a bit).

Additionally, it occurs to me that Chrome would probably not allow anything like the NoScript and AdBlockPlus Firefox extensions that currently make my web browsing experience so downright pleasant. Nearly every page you visit wants you to be running some google-analytics script, presumably to harvest information about you and show you ads. NoScript means I don't have to have my information collected and used against me in annoying video ad form, so only under the severest page malfunction circumstances do I even temporarily allow google-analytics. And AdBlockPlus means I'm puzzled when I end up on a web page where people are complaining about the annoying video ad. What annoying video ad?

I think I'll just hope that Firefox's next version incorporates the cool individual-process feature* instead of switching to Chrome and hoping that Google will suddenly care more about my privacy than its ad revenue.

*Firefox has shown a weird combination of hard work and denial on the memory problem. It's clear they're trying to fix it. But they also suggest you're a weirdo for having the problem and you really ought to use fewer windows and restart Firefox more often.

Update: Google plans to open Chrome up for extensions.