#
# $Source: /home/blais/repos/cvsroot/arubomu/lib/python/arubomu/playfile.py,v $
# $Id: playfile.py,v 1.14 2004/02/12 00:32:44 blais Exp $
#

"""Index parsing for play manager."""

__version__ = "$Revision: 1.14 $"
__author__ = "Martin Blais <blais@furius.ca>"


import sys, os
import xml.sax



class SongIdxData:
    "Song data for songs in the index."

    def __init__(self):
        self.listen = 0


class IndexSAXHandler(xml.sax.ContentHandler):

    def __init__(self):
        self.outmap = {}
        self.dirmap = None
        
    def startElement(self, name, attrs):
        if name == 'dir':
            dirid = attrs['id']
            self.dirmap = self.outmap.setdefault(dirid, {})

        elif name == 's':
            assert(self.dirmap != None)
            no = int(attrs['n'])
            songidx = SongIdxData()
            self.dirmap[no] = songidx
            try:
                songidx.listen = int(attrs['l'])
            except KeyError:
                pass
            
    def endElement(self, name):
        if name == 'dir':
            self.dirmap = None


def read(f):
    """Read index file."""

    from xml.sax.handler import feature_external_ges
    p = xml.sax.make_parser() #(["xml.sax.drivers2.drv_xmlproc_val"])
    p.setFeature(feature_external_ges,0)
    handler = IndexSAXHandler()
    p.setContentHandler(handler)

    try:
        dom = p.parse(f)
    except IOError, e:
        print >> sys.stderr, '  Error: cannot open file "%s"' % fn
        print >> sys.stderr, e
        raise

    return handler.outmap


def write(indexmap, f):
    """Write out index file."""

    try:
        print >> f, """<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>
<!DOCTYPE playfile SYSTEM \"http://furius.ca/jukebox/share/dtd/playfile.dtd\">
<playfile>

        """

        dirfmt = '<dir id="%s">'
        dirend = '</dir>'
        songfmt0 = '   <s n="%d" />'
        songfmt1 = '   <s n="%d" l="%d"/>'

        dirids = indexmap.keys()
        dirids.sort()
        for dirid in dirids:
            print >> f, dirfmt % dirid
            try:
                nosmap = indexmap[dirid]
                nos = nosmap.keys()
                nos.sort()
                for no in nos:
                    idxdata = nosmap[no]
                    if idxdata.listen == 0:
                        print >> f,  songfmt0 % no
                    else:
                        print >> f, songfmt1 % (no, idxdata.listen)
            except:
                print >> sys.stderr, \
                      'ATTENTION ATTENTION Error during write (covered).'
            print >> f, dirend

        print >> f, """
</playfile>
"""
    except IOError:
        print >> sys.stderr, '  Error: cannot open file "%s"' % fn
        raise


def countListened(indexmap):
    "Returns a (total, listened) pair with counts of songs listened to."

    # count and report the number of songs listened to.
    total = 0
    listened = 0
    for id in indexmap.keys():
        for s in indexmap[id].keys():
            si = indexmap[id][s]
            total += 1
            if si.listen > 0:
                listened += 1
    return (total, listened)
