dbm: A music library tool

Table of Contents


dbm does useful things with a library of music files:

The playlists and links can be used on a standalone digital music player such as an ipod, as long as it's running rockbox. For example, I use dbm to set up my ipod so that the main file menu looks like1


dbm relies on MusicBrainz identifiers to keep track of artists, albums and tracks. That means that you will only get good results if a fair proportion of your music library has been tagged in this way. Use the MusicBrainz Picard tagger to add these identifiers to your music library.

Similarity between artists is based on data from the last.fm server. Here are the similar artist playlists it created for me. I will be adding the ability to define similarity by maintaining a personal spreadsheet file positioning each artist in some sort of 'music space' (This is currently implemented in R, but not yet in the python code that I'm distributing).

I'm still working on this; some of the features described above are in more polished states than others. So at the moment it would make sense to (a) make sure you've downloaded the latest version (>= 0.12), and (b) get in touch with me: davison at stats dot ox dot ac dot uk. In fact, I'm basically looking for people to try it out at the moment. And a better name.


dbm is written in python. It is available here.

Setting things up

Windows | Linux | OS X

Using dbm

dbm is a command-line program. Basically, you use the -i and -o options to specify the locations of the input music library, and the output folder. So to run dbm, open a terminal window (aka command prompt), use the cd command to move into the directory containing the downloaded dbm files, and enter something like

python dbm.py -i E:\Music -o dbm-output-folder

on Windows, which might look like this on linux:

python dbm.py -i /media/ipod/Music -o dbm-output-folder

This example tells dbm to read a music library stored in a folder called Music on an external drive (e.g. an ipod), and create a bunch of output files and folders in a folder called dbm-output-folder. This output folder will be created in whatever folder you are in when you issue the command. If you've got a lot of music, it'll take some time to read the library and make the last.fm and musicbrainz web queries for every artist. You'll get some output to look at, but I can't recommend doing that for long.

IMPORTANT: Currently, dbm assumes artist music folders live in the top level of the music library. Hopefully an example will make this clear. Suppose that your music library is organised as follows:

-i E:\MusicFolders\AllMusic\Artist\Album\Track.mp3

Then dbm will work correctly if you use -i E:\MusicFolders\AllMusic, but it will not work correctly with -i E:\MusicFolders, nor with -i E:.

If there are no major problems, the output directory will contain the following folders:

In addition, a file called album_report.txt will be created. This lists album folders that have tracks lacking the musicbrainz ID tags which dbm relies upon.

There are two extra options that you can use:

To use these extra options, just supply -m or -n in addition to the -i and -o options, e.g.

./dbm.py -m -i /media/ipod/Music -o dbm-output-folder

If you run dbm without any options, or do something it doesn't understand, it will print out a help message like this

dbm version 0.10
Use -i and -o options to specify location of music library and output folder. E.g.

./dbm.py -i /media/ipod/music -o ~/music/ipod-dbm-output

To additionally check for incomplete albums, use -m
If you want to re-use saved database files in an existing output
directory rather than scanning your music library again, use -n.
To print this help message, use -h.

The playlist files are in the .m3u format, and can be transferred to an mp3 player which supports them. If you are not running rockbox on your mp3 player then I strongly suggest investigating it.

"davison@stats.ox.ac.uk") ; // Insert this code into web page to log all visitors (excluding certain search engines and other specified IPs to ignore) // The following variables must be defined: // $visitorlog_mailto (array of email addresses for notification of genuine hits) // $visitorlog_msg (string to add to email message) // $visitorlog_file (name of log file) // llf520160.crawl.yahoo.net // llf320013.crawl.yahoo.net // crawler4027.ask.com // crawl-66-249-65-196.googlebot.com // msnbot-65-55-104-208.search.msn.com // crawl1.nat.svl.searchme.com $ignore_hosts = array("yahoo" => "crawl\.yahoo\.", "ask" => "crawler.*\.ask\.", "google" => "crawl.*\.googlebot\.", "msn" => "msnbot.*\.search\.msn\.", "searchme" => "\.searchme\.", "googlebox" => "googlebox", "me" => "mnoble-dan") ; $ignore_ips = array(butler_dan => "", haywards_cottage => "") ; $ip=$_SERVER['REMOTE_ADDR'] ; $host = gethostbyaddr($ip) ; $currenturl = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] ; $genuine = true ; foreach($ignore_hosts as $regex) { if(ereg($regex, $host)) { $genuine = false ; } } foreach($ignore_ips as $ignore_ip) { if($ip == $ignore_ip) { $genuine = false ; } } echo "

" ; // $visitorlog_num = system("wc -l <".$visitorlog_file." 2> /dev/null") ; // passthru("wc -l <".$visitorlog_file." 2> /dev/null", &$visitorlog_num) ; both these alternatives seem to echo the output as well as return it. if(! $visitorlog_num) { $visitorlog_num = 0 ; } if( $genuine ) { $visitorlog_num = $visitorlog_num + 1 ; $time = date("Y-m-d-H:i") ; $msg = "Well done! On " . $time . " someone with IP address " . $ip . " visited " . $currenturl . ". That IP address comes up as " . $host . "\nNumber of visitors so far is " . $visitorlog_num ; $msg = $msg . "\n" . $visitorlog_msg ; foreach($visitorlog_mailto as $addr) { mail($addr,"website hit!", $msg) ; } // $fh = fopen($visitorlog_file, "a") ; // fwrite($fh, $time." ".$ip." ".$host."\n") ; // fclose($fh) ; } // echo "visitor number ".$visitorlog_num."
" ; ?>


1 The background image is 'Sidewinder' by London artist Rob Logan