itunekb.py
changeset 379: b1668055c25d
parent 378:b15429e38d52
manifest: b1668055c25d
author: Dan Connolly <http://www.w3.org/People/Connolly/>
date: Thu Jan 31 05:29:08 2008 -0800 (3 months ago)
permissions: -rw-r--r--
put itunekb.py on the GRDDL; add album info, play time
        1 """itunekb.py -- treat iTunes playlists as semantic web data
        2 
        3 refs: http://weborganics.co.uk/haudio-rss/
        4 http://microformats.org/wiki/haudio
        5 """
        6 
        7 import plistlib
        8 import os
        9 
       10 from genshi.template import MarkupTemplate # http://genshi.edgewall.org/ http://pypi.python.org/pypi/Genshi/
       11 
       12 def main(argv):
       13     import sys
       14 
       15     #@@ usage check...
       16     playlistname = unicode(argv[1])
       17 
       18     library = plistlib.readPlistFromString(open(musicPath()).read())
       19     tpl = MarkupTemplate(TEMPLATE)
       20 
       21     for bytes in pour(library, tpl, playlistname):
       22 	sys.stdout.write(bytes)
       23 
       24 def pour(library, tpl, playlistname):
       25     playlists = [v for v in library['Playlists'] if v['Name'] == playlistname]
       26     if not playlists:
       27 	raise KeyError, playlistname # sorta like 404 not found
       28     for playlist in playlists:
       29 	fullitems(playlist, library)
       30 
       31     for chunk in tpl.generate(playlists=playlists).serialize():
       32 	yield chunk.encode('utf-8')
       33 
       34 def fullitems(playlist, library):
       35     playlist['Playlist Items'] = [library['Tracks'][`item['Track ID']`]
       36 				  for item in playlist['Playlist Items']]
       37 
       38 def musicPath(path="Music/iTunes/iTunes Music Library.xml"):
       39     return os.path.join(os.environ["HOME"], path)
       40     
       41 def _test():
       42     import pprint
       43 
       44     txt = open(musicPath()).read()
       45     lib = plistlib.readPlistFromString(txt)
       46     print lib.keys()
       47 
       48     pprint.pprint(lib['Tracks'])
       49 
       50 TEMPLATE="""
       51 <!DOCTYPE html>
       52 <html xmlns="http://www.w3.org/1999/xhtml"
       53       xmlns:py="http://genshi.edgewall.org/">
       54 <head  profile="http://www.w3.org/2003/g/data-view#">
       55   <title>${playlists[0]['Name']}</title>
       56   <link rel="transformation" href="http://tools.weborganics.co.uk/xsl/hAudio2RDF.xsl" />
       57   <style type="text/css">
       58     dl dt { font-weight: bold }
       59   </style>
       60 </head>
       61 <body>
       62 
       63 <div py:def="playtime(ms)" py:strip="1">
       64   <tt py:with="secs = ms / 1000;
       65     mm = secs / 60;
       66     ss = secs % 60">${"%d:%02d" % (mm, ss)}</tt>
       67 </div>
       68 
       69 <div py:for="playlist in playlists" class="haudio">
       70   <h1>${playlist['Name']}</h1> <!-- assume just one playlist for now@@ -->
       71   <ol>
       72    <li py:for="item in playlist['Playlist Items']">
       73      <cite class="fn">${item.Name}</cite>
       74      by <b class="contributor">${item.Artist}</b>
       75      <br />
       76      ${playtime(item['Total Time'])}
       77      from <cite class="album">${item.Album}</cite> (<em class="year">${item.Year}</em>)
       78    </li>
       79   </ol>
       80 </div>
       81 
       82 <p>This document follows the <a
       83 href="http://microformats.org/wiki/haudio">haudio</a> conventions and
       84 licenses data extraction via <a rel="transformation"
       85 href="http://tools.weborganics.co.uk/xsl/hAudio2RDF.xsl">hAudio2RDF.xsl</a>.</p>
       86 
       87 <address>
       88 generated from itunekb.py by Dan Connolly
       89 </address>
       90 </body>
       91 </html>
       92 """
       93 
       94 if __name__ == '__main__':
       95     import sys
       96     if '--test' in sys.argv:
       97 	_test()
       98     else:
       99 	main(sys.argv)
      100