commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

r151 - in gnue-cddb: . lib schema


From: johannes
Subject: r151 - in gnue-cddb: . lib schema
Date: Thu, 2 Dec 2004 08:36:54 -0600 (CST)

Author: johannes
Date: 2004-12-02 08:36:52 -0600 (Thu, 02 Dec 2004)
New Revision: 151

Added:
   gnue-cddb/cddb.gpd
   gnue-cddb/disc.gfd
   gnue-cddb/dlgArtist.gfd
   gnue-cddb/dlgMatch.gfd
   gnue-cddb/lib/cddbplib.py
   gnue-cddb/schema/cddb-C.gld
Removed:
   gnue-cddb/artist.gfd
   gnue-cddb/cddb.gfd
   gnue-cddb/schema/auth.gsd
   gnue-cddb/schema/base.gsd
Modified:
   gnue-cddb/
   gnue-cddb/lib/helper.py
   gnue-cddb/schema/cddb.gcd
   gnue-cddb/schema/filedb.gcd
   gnue-cddb/schema/gen.gsd
Log:
Heavy reworked to get up to date with GNUe tools ... (will create ogg files now)



Property changes on: gnue-cddb
___________________________________________________________________
Name: svn:ignore
   - *.pyc

   + *.pyc
testing


Deleted: gnue-cddb/artist.gfd
===================================================================
--- gnue-cddb/artist.gfd        2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/artist.gfd        2004-12-02 14:36:52 UTC (rev 151)
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="iso8859-1"?>
-
-<!--  GNUe-Designer (0.5.4.99)
-      Saved on: 2004-06-11 19:56:44  -->
-
-<form title="GNUe CD Database / Artists">
-  <options/>
-  <datasource name="dts_artist" connection="appserver" table="cddb_artist"
-    order_by="cddb_name"/>
-
-  <logic>
-
-    <block name="blk" datasource="dts_artist" rows="20">
-      <field name="fldName" field="cddb_name" maxLength="30"/>
-    </block>
-
-  </logic>
-
-  <layout xmlns:c="GNUe:Layout:Char" c:height="25" c:width="107" tabbed="top">
-
-    <page name="Artists">
-      <label c:height="1" c:width="12" c:x="1" c:y="0" text="Name"/>
-      <entry c:height="1" c:width="30" c:x="1" c:y="1" block="blk"
-        field="fldName" name="entName"/>
-    </page>
-
-  </layout>
-
-</form>

Deleted: gnue-cddb/cddb.gfd
===================================================================
--- gnue-cddb/cddb.gfd  2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/cddb.gfd  2004-12-02 14:36:52 UTC (rev 151)
@@ -1,492 +0,0 @@
-<?xml version="1.0" encoding="iso8859-1"?>
-
-<!--  GNUe-Designer (0.5.4.99)
-      Saved on: 2004-06-11 19:56:44  -->
-
-<form title="GNUe CD Database">
-  <options/>
-  <datasource name="dts_artist" connection="appserver" table="cddb_artist"
-    order_by="cddb_name" prequery="Y"/>
-  <datasource name="dts_category" connection="appserver" table="cddb_category"
-    order_by="cddb_name" prequery="Y"/>
-  <datasource name="dts_disc" connection="appserver" table="cddb_disc"/>
-  <datasource name="dts_track" connection="appserver" detaillink="cddb_disc"
-    master="dts_disc" masterlink="gnue_id" table="cddb_track"
-    order_by="cddb_track"/>
-  <datasource name="dts_options" connection="appserver" table="cddb_options"/>
-
-  <trigger name="query_cd" type="NAMED"><![CDATA[
-    import DiscID
-    import CDDB
-    import re
-    from lib import helper
-
-    CDDB.proto = 6
-
-    setStatusText ('Retrieving disc information ...')
-
-    dev = DiscID.open ()
-    discInfo = DiscID.disc_id (dev)
-
-    print "RESULT:", discInfo
-
-    setStatusText ('Querying remote database at: %s' % CDDB.default_server)
-    result = CDDB.query (discInfo)
-    print "RESULT:", result
-
-    if result [0] == 200:
-      match = result [1]
-    elif result [0] == 210:
-      params = {'matches': result}
-      activateDialog ('selectMatch', params, 1)
-      if not params.has_key ('match'):
-        return
-      else:
-        match = params ['match']
-    else:
-      match = {'disc_id' : "%08x" % discInfo [0],
-               'category': 'misc',
-               'title': 'Various / Unknown'}
-
-    print "MATCH:", match
-
-    setStatusText ('Downloading record ...')
-    res = CDDB.read (match ['category'], match ['disc_id'])
-    cdbdata = res [1]
-    print "Download:", cdbdata.keys ()
-    for (k, x) in cdbdata.items ():
-      print "%s = %s" % (k, x)
-
-    artistRec = helper.processArtists (cdbdata, discInfo, dts_artist)
-
-    if len (artistRec ['new'].keys ()):
-      params = {'artists': artistRec}
-      activateDialog ('selectArtist', params, 1)
-
-      print "PARAMS:", params
-      if not params.has_key ('updartists'):
-        return
-
-      artistRec = params ['updartists']
-      blk_disc.fldArtist.resetForeignKey ()
-      blk_track.fldArtist.resetForeignKey ()
-
-    helper.updateArtists (artistRec)
-
-    discid = match ['disc_id']
-    res = dts_disc.simpleQuery ({'cddb_discid': discid})
-    if not res [0].has_key ('gnue_id'):
-      blk_disc.newRecord ()
-
-    res = dts_category.simpleQuery ({'cddb_matchcode': match ['category']})
-    category_id = res [0].get ('gnue_id', None)
-
-    blk_disc.fldTitle.set (artistRec ['title'])
-    blk_disc.fldArtist.set (artistRec ['disc']['id'])
-    blk_disc.fldCategory.set (category_id)
-    blk_disc.fldDiscid.set (match ['disc_id'])
-    if cdbdata.has_key ('DYEAR'):
-      blk_disc.fldYear.set (cdbdata ['DYEAR'])
-
-
-    tracks = artistRec ['tracks'].keys ()
-    tracks.sort ()
-
-    tracklens = discInfo [2:]
-    tracklens [-1] = discInfo [-1] * 75
-
-    blk_track.firstRecord ()
-    needNext = False
-    for tNum in tracks:
-      needNext = not blk_track.isEmpty ()
-      if not needNext:
-        blk_track.newRecord ()
-
-      blk_track.fldTrack.set (tNum+1)
-      blk_track.fldTitle.set (unicode (cdbdata ['TTITLE%d' % tNum], 'utf-8'))
-      blk_track.fldArtist.set (artistRec ['tracks'][tNum]['id'])
-      blk_track.fldLength.set (round ((tracklens [tNum+1]-tracklens 
[tNum])/75))
-
-      if needNext:
-        blk_track.nextRecord ()
-
-
-    setStatusText ('')
-    ]]>
-  </trigger>
-
-  <trigger name="rip_disc" type="NAMED">
-    from lib import cdparanoia
-    from lib import gogo
-    from os import path, makedirs
-    import mx.DateTime
-
-    discPath = blk_disc.fldUrl.get ()
-    print "DiscPath:", discPath
-
-    dae = cdparanoia.cdparanoia ()
-    enc = gogo.gogo ()
-
-    blk_track.firstRecord ()
-
-    while not blk_track.isEmpty ():
-      if blk_track.fldUrl.isEmpty ():
-        filename = 'Track%02d.wav' % blk_track.fldTrack.get ()
-        mp3file  = 'Track%02d.mp3' % blk_track.fldTrack.get ()
-        fullpath = path.join (discPath, filename)
-        try:
-          makedirs (discPath)
-        except:
-          # TODO: handle errors !
-          pass
-
-        print "Extracting track %d to '%s' ..." % (blk_track.fldTrack.get (),
-                                                   fullpath)
-        dae.runDAE (blk_track.fldTrack.get (), fullpath)
-        print "Encoding to MPEG 1 Layer 3 ..."
-        enc.runEncoding (fullpath, True)
-
-        blk_track.fldUrl.set (path.join (discPath, mp3file))
-        blk_track.fldRipdate.set (mx.DateTime.now ())
-
-      blk_track.nextRecord ()
-  </trigger>
-
-  <trigger name="tag_files" type="NAMED">
-    import ID3
-    import os.path
-
-    blk_track.firstRecord ()
-
-    while not blk_track.isEmpty ():
-      filename = blk_track.fldUrl.get ()
-      artistId = blk_track.fldArtist.get ()
-      artist   = blk_track.fldArtist.allowedValues () [0][artistId] or 
'unknown'
-
-      dts_category.simpleQuery ({'gnue_id': blk_disc.fldCategory.get ()})
-      genre = blk_category.fldId.get ()
-
-      if os.path.exists (filename):
-        itag = ID3.ID3 (filename)
-        print "tag created"
-        itag.album  = blk_disc.fldTitle.get () or 'Unknown'
-        title = blk_track.fldTitle.get () or 'Unknown'
-        itag.title  = title.encode ('latin-1')
-        itag.artist = artist.encode ('latin-1')
-        itag.genre  = genre
-        itag.year   = "%s" % blk_disc.fldYear.get ()
-        itag.comment= blk_track.fldComment.get ()
-        itag.track  = "%d" % blk_track.fldTrack.get ()
-
-        itag.write ()
-
-
-      blk_track.nextRecord ()
-
-    print "BLK:", dir (blk_track)
-  </trigger>
-
-  <trigger name="import_files" type="NAMED">
-    from lib import helper
-
-    basepath = blk_disc.fldUrl.get ()
-    helper.importFiles (blk_track, basepath)
-  </trigger>
-
-
-  <logic>
-
-    <block name="blk_artist" datasource="dts_artist">
-      <field name="fldName" field="cddb_name" maxLength="60"/>
-      <trigger name="updateReferences" type="POST-COMMIT">
-        <![CDATA[
-        blk_disc.fldArtist.resetForeignKey ()
-        blk_track.fldArtist.resetForeignKey ()
-        ]]>
-      </trigger>
-    </block>
-
-    <block name="blk_category" datasource="dts_category">
-      <field name="fldId" field="cddb_id" maxLength="3" typecast="number"/>
-      <field name="fldName" field="cddb_name" maxLength="30"/>
-      <field name="fldMatchcode" field="cddb_matchcode" maxLength="30"/>
-      <trigger name="updateReferences" type="POST-COMMIT">
-        blk_disc.fldCategory.resetForeignKey ()
-      </trigger>
-    </block>
-
-    <block name="blk_disc" datasource="dts_disc">
-      <field name="fldTitle" field="cddb_title" maxLength="60"/>
-      <field name="fldArtist" field="cddb_artist" fk_key="gnue_id"
-        fk_description="cddb_name" fk_source="dts_artist"/>
-      <field name="fldCategory" field="cddb_category" fk_key="gnue_id"
-        fk_description="cddb_name" fk_source="dts_category"/>
-      <field name="fldYear" field="cddb_year" maxLength="4" typecast="number"/>
-      <field name="fldDiscid" field="cddb_discid" maxLength="8" readonly="Y"/>
-      <field name="fldComment" field="cddb_comment" maxLength="70"/>
-      <field name="fldUrl" field="filedb_url" readonly="Y"/>
-    </block>
-
-    <block name="blk_track" datasource="dts_track" rows="15">
-      <field name="fldTrack" field="cddb_track" maxLength="2"
-             typecast="number"/>
-      <field name="fldTitle" field="cddb_title" maxLength="90"/>
-      <field name="fldArtist" field="cddb_artist" fk_key="gnue_id"
-        fk_description="cddb_name" fk_source="dts_artist"/>
-      <field name="fldLength" field="cddb_length" maxLength="4"
-             typecast="number"/>
-      <field name="fldComment" field="cddb_comment" maxLength="28"/>
-      <field name="fldUrl" field="filedb_url" maxLength="256"/>
-      <field name="fldRipdate" field="filedb_ripdate" typecast="date"/>
-    </block>
-
-    <block name="blk_options" datasource="dts_options">
-      <field name="fldBasepath" field="cddb_basepath" maxLength="250"/>
-    </block>
-
-  </logic>
-
-  <layout xmlns:c="GNUe:Layout:Char" c:height="25" c:width="107" tabbed="top">
-
-    <page name="Disc">
-      <label c:height="1" c:width="11" c:x="1"  c:y="1"  text="Title   :"/>
-      <label c:height="1" c:width="12" c:x="1"  c:y="2"  text="Artist  :"/>
-      <label c:height="1" c:width="14" c:x="1"  c:y="3"  text="Category:"/>
-      <label c:height="1" c:width="8"  c:x="48" c:y="1"  text="Year   :"/>
-      <label c:height="1" c:width="8"  c:x="48" c:y="2"  text="Discid :"/>
-      <label c:height="1" c:width="8"  c:x="48" c:y="3"  text="Comment:"/>
-
-      <button c:height="1" c:width="10" c:x="1" c:y="5" label="Query">
-        <trigger src="query_cd" name="query_cd" type="ON-ACTION"/>
-      </button>
-      <button c:height="1" c:width="10" c:x="12" c:y="5" label="DAE">
-        <trigger src="rip_disc" name="rip_disc" type="ON-ACTION"/>
-      </button>
-      <button c:height="1" c:width="10" c:x="23" c:y="5" label="Tag">
-        <trigger src="tag_files" name="tag_files" type="ON-ACTION"/>
-      </button>
-      <button c:height="1" c:width="10" c:x="34" c:y="5" label="Import">
-        <trigger src="import_files" name="import_files" type="ON-ACTION"/>
-      </button>
-
-      <entry name="entCddbTitle" c:height="1" c:width="30" c:x="16"
-        c:y="1" block="blk_disc" field="fldTitle"/>
-      <entry name="entCddbArtist" c:height="1" c:width="30" c:x="16"
-        c:y="2" block="blk_disc" field="fldArtist" style="dropdown"/>
-      <entry name="entCddbCategory" c:height="1" c:width="30"
-        c:x="16" c:y="3" block="blk_disc" field="fldCategory" 
style="dropdown"/>
-      <entry name="entCddbYear" c:height="1" c:width="10" c:x="57"
-             c:y="1" block="blk_disc" field="fldYear"/>
-      <entry name="entCddbDiscid" c:height="1" c:width="10" c:x="57"
-             c:y="2" block="blk_disc" field="fldDiscid"/>
-      <entry name="entCddbComment" c:height="1" c:width="30" c:x="57"
-             c:y="3" block="blk_disc" field="fldComment"/>
-      <entry c:height="1" c:width="30" c:x="57" c:y="4" block="blk_disc"
-             field="fldUrl"/>
-
-      <!-- tracks -->
-      <label c:height="1" c:width="2"  c:x="1"  c:y="6"  text="Nr"/>
-      <label c:height="1" c:width="12" c:x="5"  c:y="6"  text="Title"/>
-      <label c:height="1" c:width="4"  c:x="36" c:y="6"  text="Secs"/>
-      <label c:height="1" c:width="11" c:x="42" c:y="6"  text="Artist"/>
-      <label c:height="1" c:width="8"  c:x="72" c:y="6"  text="URL"/>
-      <label c:height="1" c:width="8"  c:x="99" c:y="6"  text="Date"/>
-
-      <entry c:height="1" c:width="3"  c:x="1"  c:y="7" name="entTrack"
-        block="blk_track" field="fldTrack"/>
-      <entry c:height="1" c:width="30" c:x="5"  c:y="7" name="entTitle"
-        block="blk_track" field="fldTitle"/>
-      <entry c:height="1" c:width="5"  c:x="36" c:y="7" name="entLength"
-        block="blk_track" field="fldLength"/>
-      <entry c:height="1" c:width="25" c:x="42"  c:y="7" name="entArtist"
-        block="blk_track" field="fldArtist" style="dropdown"/>
-
-      <entry c:height="1" c:width="30" c:x="68" c:y="7" name="entURL"
-        block="blk_track" field="fldUrl"/>
-      <entry c:height="1" c:width="8" c:x="99" c:y="7" name="entComment"
-        block="blk_track" field="fldComment"/>
-    </page>
-
-    <page name="Artists">
-      <label name="lblCddbName" c:height="1" c:width="12" c:x="1"
-        c:y="1" text="Artist Name:"/>
-      <entry name="entCddbName" c:height="1" c:width="30" c:x="15"
-             c:y="1" block="blk_artist" field="fldName" label=""/>
-    </page>
-
-    <page name="Category">
-      <label c:height="1" c:width="10" c:x="1"  c:y="1" text="ID3-Id   :"/>
-      <label c:height="1" c:width="10" c:x="1"  c:y="2" text="Name     :"/>
-      <label c:height="1" c:width="10" c:x="1"  c:y="3" text="Matchcode:"/>
-      <entry c:height="1" c:width="5"  c:x="12" c:y="1" name="entCddbId"
-        block="blk_category" field="fldId"/>
-      <entry c:height="1" c:width="30" c:x="12" c:y="2" name="entName"
-        block="blk_category" field="fldName"/>
-      <entry c:height="1" c:width="30" c:x="12" c:y="3" name="entMatchcode"
-        block="blk_category" field="fldMatchcode"/>
-    </page>
-
-    <page name="Options">
-      <label c:heigth="1" c:width="10" c:x="1" c:y="1" text="Basepath:"/>
-      <entry c:height="1" c:width="70" c:x="12" c:y="1" name="entBasepath"
-        block="blk_options" field="fldBasepath"/>
-    </page>
-  </layout>
-
-  <!-- =================================================================== -->
-  <!-- Dialog to select a remote database match                            -->
-  <!-- =================================================================== -->
-
-  <dialog xmlns:c="GNUe:Layout:Char" name="selectMatch">
-    <trigger type="On-Startup">
-      form.setFeature ('GUI:MENUBAR:SUPPRESS', True)
-      form.setFeature ('GUI:TOOLBAR:SUPPRESS', True)
-      form.setFeature ('GUI:STATUSBAR:SUPPRESS', True)
-    </trigger>
-
-    <trigger type="On-Activation">
-      matches = getParameter ('matches')
-      print "MATCHES:", matches
-      rs = dts.createResultSet ()
-      rec = None
-
-      for match in matches [1]:
-        if rec is None:
-          rec = rs.firstRecord ()
-        else:
-          rec = rs.insertRecord ()
-
-
-        blk.fldTitle.set (match ['title'])
-        blk.fldCategory.set (match ['category'])
-        blk.fldDiscid.set (match ['disc_id'])
-
-      blk.firstRecord ()
-    </trigger>
-
-    <datasource name="dts" type="static">
-      <staticset fields="title,category,discid">
-        <staticsetrow>
-          <staticsetfield name="title" value="Unknown / Unknown"/>
-          <staticsetfield name="category" value="unknown"/>
-          <staticsetfield name="discid" value=""/>
-        </staticsetrow>
-      </staticset>
-    </datasource>
-
-    <logic>
-      <block name="blk" datasource="dts" rows="12">
-        <field name="fldCategory"  field="category" readonly="Y"/>
-        <field name="fldTitle"     field="title"    readonly="Y"/>
-        <field name="fldDiscid"    field="discid"   readonly="Y"/>
-      </block>
-    </logic>
-
-    <layout xmlns:c="GNUe:Layout:Char" c:width="70" c:height="15">
-      <page>
-        <label c:x="0"  c:y="0" c:width="7" c:height="1" text="Disc-Id"/>
-        <label c:x="10" c:y="0" c:width="8" c:height="1" text="Category"/>
-        <label c:x="31" c:y="0" c:width="9" c:height="1" text="Title"/>
-
-        <entry c:x="0"  c:y="1" c:width="9"  block="blk" field="fldDiscid"/>
-        <entry c:x="10" c:y="1" c:width="20" block="blk" field="fldCategory"/>
-        <entry c:x="31" c:y="1" c:width="60" block="blk" field="fldTitle"/>
-
-        <button c:x="0" c:y="14" c:width="10" c:height="1" label="Ok">
-          <trigger name="Ok" type="On-Action"><![CDATA[
-            res = {'category': blk.fldCategory.get (), \
-                   'disc_id': blk.fldDiscid.get (), \
-                   'title': blk.fldTitle.get ()}
-            setParameter ('match', res)
-            close ()
-            ]]>
-          </trigger>
-        </button>
-        <button c:x="11" c:y="14" c:width="10" c:height="1" label="Abbrechen">
-          <trigger name="Cancel" type="On-Action">
-            close ()
-          </trigger>
-        </button>
-      </page>
-    </layout>
-  </dialog>
-
-
-  <!-- =================================================================== -->
-  <!-- Dialog to enter a new artist                                        -->
-  <!-- =================================================================== -->
-
-  <dialog xmlns:c="GNUe:Layout:Char" name="selectArtist">
-    <trigger type="On-Startup">
-      form.setFeature ('GUI:MENUBAR:SUPPRESS', True)
-      form.setFeature ('GUI:TOOLBAR:SUPPRESS', True)
-      form.setFeature ('GUI:STATUSBAR:SUPPRESS', True)
-    </trigger>
-
-    <trigger type="On-Activation">
-      artists = getParameter ('artists')
-
-      for artist in artists ['new'].keys ():
-        if not blk.isEmpty ():
-          blk.newRecord ()
-          org.newRecord ()
-
-        blk.fldName.set (artist)
-        org.artist.set (artist)
-    </trigger>
-
-    <datasource name="dts" connection="appserver" table="cddb_artist"
-      order_by="cddb_name"/>
-
-    <logic>
-      <block name="org" rows="10">
-        <field name="artist"/>
-      </block>
-      <block name="blk" datasource="dts" rows="10">
-        <field name="id" field="gnue_id"/>
-        <field name="fldName" field="cddb_name"/>
-      </block>
-    </logic>
-
-    <layout xmlns:c="GNUe:Layout:Char" c:width="80" c:height="15">
-      <page>
-        <label c:x="0"  c:y="0" c:width="10" c:height="1" text="Artist   "/>
-        <label c:x="35" c:y="0" c:width="10" c:height="1" text="Suggested"/>
-
-        <entry c:x="0" c:y="1" c:width="30" name="entArtist" block="blk"
-          field="fldName"/>
-        <entry c:x="35" c:y="1" c:width="30" name="artist" block="org"
-          field="artist" style="label"/>
-
-        <button c:x="0" c:y="14" c:width="10" c:height="1" label="Ok">
-          <trigger name="Ok" type="On-Action">
-            if not blk.isSaved ():
-              blk.commit ()
-
-            artists = getParameter ('artists')
-            newArtists = artists ['new']
-
-            blk.firstRecord ()
-            org.firstRecord ()
-
-            while not blk.isEmpty ():
-              newArtists [org.artist.get ()] = {'name': blk.fldName.get (),
-                                                'id'  : blk.id.get ()}
-              blk.nextRecord ()
-              org.nextRecord ()
-
-            setParameter ('updartists', artists)
-            close ()
-          </trigger>
-        </button>
-        <button c:x="11" c:y="14" c:width="10" c:height="1" label="Abbrechen">
-          <trigger name="Cancel" type="On-Action">
-            if not blk.isSaved ():
-              blk.rollback ()
-            close ()
-          </trigger>
-        </button>
-      </page>
-    </layout>
-  </dialog>
-</form>

Added: gnue-cddb/cddb.gpd
===================================================================
--- gnue-cddb/cddb.gpd  2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/cddb.gpd  2004-12-02 14:36:52 UTC (rev 151)
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+
+<processes title="GNUe CD Database">
+  <process title="Base Data">
+    <step type="form" location="appserver://appserver/form/cddb_category"
+      title="Categories">
+      <description><![CDATA[
+        <html><head></head><body>
+          <h1>Categories</h1>
+          <p>The path pattern of a category superseeds the pattern given in the
+          options to define the directory where all ripped and encoded files of
+          a disc will be stored. Additionally one can use the following special
+          patterns to build a path:</p>
+          <table>
+            <tr><th>Pattern</th><th>Replacement</th></tr>
+            <tr><td>%c</td><td>Name of the category</td></tr>
+            <tr><td>%m</td><td>Matchcode of the category</td></tr>
+            <tr><td>%a</td><td>Full name of the Artist</td></tr>
+            <tr><td>%t</td><td>Title of the album (disc)</td></tr>
+          </table>
+        </body></html>]]>
+      </description>
+    </step>
+
+    <step type="form" location="appserver://appserver/form/cddb_artist"
+      title="Artists" >
+      <description><![CDATA[
+        <html><head></head><body>
+          <h1>Artists</h1>
+          <p>The full name of an artist is built as 
+            "&lt;last name&gt; &lt;middle name&gt; &lt;firstname&gt;"</p>
+        </body></html>]]>
+      </description>
+    </step>
+
+    <step type="form" location="appserver://appserver/form/cddb_options"
+      title="Options">
+      <description><![CDATA[
+        <html><head></head><body>
+          <h1>Options</h1>
+          <p>The path pattern defines where all the ripped and encoded files of
+            a disc will be stored. Additionally one can use the following
+            special patterns to build a path:</p>
+          <table>
+            <tr><th>Pattern</th><th>Replacement</th></tr>
+            <tr><td>%c</td><td>Name of the category</td></tr>
+            <tr><td>%m</td><td>Matchcode of the category</td></tr>
+            <tr><td>%a</td><td>Full name of the Artist</td></tr>
+            <tr><td>%t</td><td>Title of the album (disc)</td></tr>
+          </table>
+        </body></html>]]>
+      </description>
+    </step>
+  </process>
+
+  <process title="Disc-Management">
+    <step type="form" location="./disc.gfd" title="Manage discs" />
+  </process>
+</processes>
+

Added: gnue-cddb/disc.gfd
===================================================================
--- gnue-cddb/disc.gfd  2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/disc.gfd  2004-12-02 14:36:52 UTC (rev 151)
@@ -0,0 +1,452 @@
+<?xml version="1.0" encoding="iso8859-1"?>
+
+<!-- CD Database main form
+
+     Copyright 2004 Free Software Foundation
+
+     This file is part of GNU Enterprise.
+
+     GNU Enterprise is free software; you can redistribute it and/or
+     modify it under the terms of the GNU General Public License as
+     published by the Free Software Foundation; either version 2 of
+     the License, or (at your option) any later version.
+
+     GNU Enterprise is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNU Enterprise; see the file COPYING.  If not, write to
+     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+
+     $Id: $ -->
+
+<form title="GNUe CD Database">
+  <options>
+  </options>
+
+
+  <!-- =================================================================== -->
+  <!-- Datasources                                                         -->
+  <!-- =================================================================== -->
+
+  <datasource connection="appserver" name="dtsDArtist"  table="cddb_artist"
+    order_by="cddb_name" prequery="True" cache="250" />
+
+  <datasource connection="appserver" name="dtsTArtist"  table="cddb_artist"
+    order_by="cddb_name" prequery="True" cache="250" />
+
+  <datasource connection="appserver" name="dtsCategory" table="cddb_category"
+    order_by="cddb_name" prequery="True" cache="250" />
+
+  <datasource connection="appserver" name="dtsOptions"  table="cddb_options"
+    prequery="True" />
+
+  <datasource connection="appserver" name="dtsDisc"  table="cddb_disc" />
+  <datasource connection="appserver" name="dtsTrack" table="cddb_track"
+    master="dtsDisc" masterlink="gnue_id" detaillink="cddb_disc"
+    order_by="cddb_track" />
+
+
+  <!-- =================================================================== -->
+  <!-- Blocks                                                              -->
+  <!-- =================================================================== -->
+
+  <logic>
+    <block name="blkDisc" datasource="dtsDisc">
+      <field name="title"    field="cddb_title" maxLength="60" />
+
+      <field name="artist"   field="cddb_artist" fk_key="gnue_id"
+        fk_description="cddb_name" fk_source="dtsDArtist" />
+
+      <field name="category" field="cddb_category" fk_key="gnue_id"
+        fk_description="cddb_name" fk_source="dtsCategory" />
+
+      <field name="year"    field="cddb_year"    maxLength="4" 
+        typecast="number"/>
+
+      <field name="discid"  field="cddb_discid"  maxLength="8" />
+      <field name="seconds" field="cddb_seconds" typecast="number" />
+      <field name="comment" field="cddb_comment" maxLength="70" />
+      <field name="url"     field="filedb_url"   readonly="True" />
+      <field name="length"  field="cddb_length"  typecast="date" />
+    </block>
+
+
+    <block name="blkTrack" datasource="dtsTrack" rows="15" >
+
+      <field name="track"   field="cddb_track"   maxLength="2" 
+        typecast="number" />
+
+      <field name="title"   field="cddb_title"   maxLength="90" />
+      <field name="comment" field="cddb_comment" maxLength="70" />
+      <field name="length"  field="cddb_length"  typecast="date" />
+
+      <field name="artist" field="cddb_artist" fk_key="gnue_id"
+        fk_description="cddb_name" fk_source="dtsTArtist" />
+
+      <field name="ripped" field="filedb_ripdate" typecast="date" />
+      <field name="url"    field="filedb_url" />
+      <field name="action" />
+
+    </block>
+
+    <block name="blkOptions" datasource="dtsOptions">
+      <field name="basepath" field="cddb_basepath" readonly="True" />
+    </block>
+
+  </logic>
+
+
+  <!-- =================================================================== -->
+  <!-- Layout (Main Form)                                                  -->
+  <!-- =================================================================== -->
+
+  <layout xmlns:c="GNUe:Layout:Char" c:height="23" c:width="100" tabbed="none">
+
+    <page name="pgDisc" caption="Disc">
+
+      <!-- ================================================================ -->
+      <!-- Master Record (Disc)                                             -->
+      <!-- ================================================================ -->
+
+      <label c:x="1"  c:y="1" c:width="9"  text="Title:" />
+      <label c:x="1"  c:y="2" c:width="9"  text="Artist:" />
+      <label c:x="1"  c:y="3" c:width="9"  text="Category:" />
+
+      <label c:x="50" c:y="1" c:width="8"  text="Disc-Id:" />
+      <label c:x="50" c:y="2" c:width="8"  text="Year:" />
+      <label c:x="50" c:y="3" c:width="10" text="Base path:" />
+
+      <label c:x="71" c:y="1" c:width="8"  text="Length:" />
+
+      <entry c:x="11" c:y="1" c:width="30" block="blkDisc" field="title"
+        focusorder="1" />
+
+      <entry c:x="11" c:y="2" c:width="30" block="blkDisc" field="artist"
+        style="dropdown" />
+
+      <button c:x="42" c:y="2" c:width="3" label="..." navigable="False">
+        <trigger type="ON-ACTION">
+          setParameter ('triggerArg', 'disc')
+          activateTrigger ('selectArtist')
+        </trigger>
+      </button>
+
+      <entry c:x="11" c:y="3" c:width="30" block="blkDisc" field="category"
+        style="dropdown" />
+
+      <entry c:x="60" c:y="1" c:width="10" block="blkDisc" field="discid"
+        style="label" />
+
+      <entry c:x="60" c:y="2" c:width="10" block="blkDisc" field="year" />
+      <entry c:x="60" c:y="3" c:width="39" block="blkDisc" field="url" />
+
+      <entry c:x="79" c:y="1" c:width="10" block="blkDisc" field="length"
+        displaymask="%X" style="label" />
+
+
+      <!-- ================================================================ -->
+      <!-- Button Row (Actions)                                             -->
+      <!-- ================================================================ -->
+
+      <button name="btnQuery" c:x="1" c:y="5" c:width="8" label="Query" >
+        <trigger type="ON-ACTION" src="query_cd" />
+      </button>
+
+      <button c:x="10" c:y="5" c:width="18" label="Audio Extraction" >
+        <trigger type="ON-ACTION" src="extract_audio" />
+      </button>
+
+      <button c:x="29" c:y="5" c:width="12"  label="Ogg-Encode" >
+        <trigger type="ON-ACTION" src="ogg_encode" />
+      </button>
+
+      <button c:x="42" c:y="5" c:width="8"  label="Tag" >
+        <trigger type="ON-ACTION" src="tag_files" />
+      </button>
+
+      <button c:x="51" c:y="5" c:width="8"  label="Import" />
+
+      <button c:x="60" c:y="5" c:width="12" label="Toggle all" >
+        <trigger type="ON-ACTION" src="toggle_action" />
+      </button>
+
+      <!-- ================================================================ -->
+      <!-- Detail-Record (Track)                                            -->
+      <!-- ================================================================ -->
+
+      <label c:x="1"  c:y="7" c:width="3" text="Nr" />
+      <label c:x="5"  c:y="7" c:width="6" text="Title" />
+      <label c:x="36" c:y="7" c:width="6" text="Length" />
+      <label c:x="45" c:y="7" c:width="6" text="Artist" />
+      <label c:x="61" c:y="7" c:width="6" text="Action" alignment="right" />
+      <label c:x="69" c:y="7" c:width="6" text="URL" />
+
+      <entry c:x="1"  c:y="8" c:width="3"  block="blkTrack" field="track"/>
+      <entry c:x="5"  c:y="8" c:width="30" block="blkTrack" field="title"/>
+
+      <entry c:x="36" c:y="8" c:width="8"  block="blkTrack" field="length"
+        inputmask="%X" displaymask="%X" />
+
+      <entry c:x="45" c:y="8" c:width="20" block="blkTrack" field="artist"
+        style="dropdown" />
+
+      <entry c:x="66" c:y="8" c:width="2"  block="blkTrack" field="action"
+        style="checkbox" />
+
+      <entry c:x="69" c:y="8" c:width="30" block="blkTrack" field="url" />
+    </page>
+
+  </layout>
+
+
+
+  <!-- ################################################################### -->
+  <!-- Trigger - Code                                                      -->
+  <!-- ################################################################### -->
+
+  <!-- ===================================================================
+       Select and/or modify an artist
+
+       @param triggerArg: 'disc' or 'track'; specifies which block to set an
+       artist for if the dialog is closed with Ok. 
+       =================================================================== -->
+  <trigger name="selectArtist" type="NAMED">
+    arg = getParameter ('triggerArg')
+    if ';' in arg:
+      (type, default) = arg.split (';')
+    else:
+      (type, default) = (arg, None)
+
+    block  = type == 'disc' and blkDisc or blkTrack
+    params = {'cancel': True, 'artist': default or block.artist.get ()}
+
+    runForm ('dlgArtist.gfd', params)
+
+    blkDisc.artist.resetForeignKey ()
+    blkTrack.artist.resetForeignKey ()
+
+    if not params.get ('cancel'):
+      block.artist.set (params.get ('artist'))
+
+    setParameter ('triggerArg', params)
+  </trigger>
+
+
+  <!-- ===================================================================
+       Query a disc
+
+       This trigger clears all blocks, reads the disc information from the
+       default cdrom device and either locates an apropriate record in the
+       backed database or query a remote server for it. In the latter case
+       a new disc record as well as all track records will be generated.
+       =================================================================== -->
+  <trigger name="query_cd" type="NAMED">
+    from lib import helper
+
+    blkDisc.rollback ()
+
+    discInfo = helper.getDiscInfo ()
+
+    <!-- First have a look if the disc is already listed in backend-db. The
+         reocrd must match the disc-id, length and in number of tracks. -->
+    idstr    = "%08x" % discInfo [0]
+    length   = "%s"   % discInfo [-1]
+
+    dtsDisc.createResultSet ({'cddb_discid': idstr, 'cddb_seconds': length})
+    if blkDisc.discid.get () == idstr and dtsTrack.count () == discInfo [1]:
+      return
+
+    <!-- Start off with a new disc. Disc-Id and length in seconds cannot change
+         through match-selection. -->
+    if dtsDisc.count () > 1:
+      blkDisc.rollback ()
+
+    blkDisc.discid.set (idstr)
+    blkDisc.seconds.set (discInfo [-1])
+
+    cddb = helper.openCDDB ()
+
+    try:
+      matches = helper.getMatches (cddb, discInfo)
+
+      if len (matches):
+        params = {'cancel': True, 'matches': matches, 'result': None}
+        runForm ('dlgMatch.gfd', params)
+        if params.get ('cancel'):
+          return
+
+        match = params ['result']
+      else:
+        abort ('No match could be created!')
+
+      <!-- Split the match title into a disc-title and an artist name and start
+           the selection / modification of the artist -->
+      (title, artist) = helper.splitTitle (match ['title'])
+      setParameter ('triggerArg', 'disc;%s' % artist)
+      activateTrigger ('selectArtist')
+      if getParameter ('triggerArg') ['cancel']:
+        return
+
+      blkDisc.title.set (title)
+      blkDisc.category.set (match ['category'])
+      blkDisc.url.set (blkDisc.call ('filedb_defaultURL', None))
+
+      <!-- Download the selected match from the remote cd database -->
+      download = helper.download (cddb, discInfo, match ['matchcode'])
+      blkDisc.year.set (download.get ('year'))
+
+    finally:
+      cddb.close ()
+
+    <!-- Iterate over all downloaded tracks and create a track-record. Note:
+         there is no 'empty' track record, because of the former procedure call
+         on the master record. This led to a post and theirfor removed the
+         pending, but empty detail record. -->
+    for (track, title, length) in download ['tracks']:
+      blkTrack.newRecord ()
+
+      blkTrack.track.set (track + 1)
+
+      <!-- If a track has a different artist than the album, split title and
+           artist and start artist selection / modification. -->
+      if title and '/' in title:
+        (title, artist) = helper.splitTitle (title)
+        setParameter ('triggerArg', 'track;%s' % artist)
+        activateTrigger ('selectArtist')
+        <!-- If the selection has been canceled we use the disc's artist -->
+        if getParameter ('triggerArg') ['cancel']:
+          blkTrack.artist.set (blkDisc.artist.get ())
+
+      else:
+        blkTrack.artist.set (blkDisc.artist.get ())
+
+      blkTrack.title.set (title)
+      blkTrack.length.set (length)
+
+
+    <!-- After adding all tracks move the record pointer to the first track and
+         update the master record's calculated stuff. -->
+
+    blkTrack.firstRecord ()
+    blkDisc.update ()
+  </trigger>
+
+
+  <!-- ===================================================================
+       Run Digital Audio Extraction
+
+       This trigger runs DAE on all selected tracks (having a positive action
+       flag set) whose 'filedb_url' is empty.
+       =================================================================== -->
+  <trigger name="extract_audio" type="NAMED">
+    import mx.DateTime
+    from lib import cdparanoia
+    from os import path, makedirs, unlink
+
+    <!-- Check if the base path exists and create it if needed -->
+    discPath = blkDisc.url.get ()
+    if not path.isdir (discPath):
+      try:
+        makedirs (discPath)
+      except:
+        pass
+
+    dae = cdparanoia.cdparanoia ()
+
+    blkTrack.firstRecord ()
+
+    while not blkTrack.isEmpty ():
+      <!-- If a track is marked for action and has no URL yet, extract it -->
+      if blkTrack.action.get () and blkTrack.url.isEmpty ():
+        track    = blkTrack.track.get ()
+        filename = "Track%02d.wav" % track
+        fullpath = path.join (discPath, filename)
+
+        if path.exists (fullpath):
+          unlink (fullpath)
+
+          <!-- Set a message on the status bar and start extraction. 
+               FIXME: this message is not displayed by uidriver until this
+               trigger has finished completely ! -->
+        print "Extracting %d to %s" % (track, fullpath)
+        setStatusText ("Extracting track %d to %s ..." % (track, fullpath))
+        dae.runDAE (track, fullpath)
+
+        blkTrack.ripped = mx.DateTime.now ()
+        blkTrack.url.set (fullpath)
+
+      blkTrack.nextRecord ()
+  </trigger>
+
+
+  <!-- ===================================================================
+       Toggle action flag
+
+       This trigger changes the action flag for all non-empty track records by
+       inverting it's current state.
+       =================================================================== -->
+  <trigger name="toggle_action" type="NAMED">
+    for tr in range (dtsTrack.count ()):
+      blkTrack.gotoRecord (tr)
+      if not blkTrack.isEmpty ():
+        blkTrack.action.set (not blkTrack.action.get ())
+  </trigger>
+
+
+  <!-- ===================================================================
+       Encode selected tracks into ogg/vorbis 
+
+       This trigger encodes all selected tracks with a valid URL pointing to a
+       wave file into ogg/vorbis files additionally tagging them.
+       =================================================================== -->
+
+  <trigger name="ogg_encode" type="NAMED">
+    import lib.helper
+
+    for tr in range (dtsTrack.count ()):
+      blkTrack.gotoRecord (tr)
+
+      if not blkTrack.isEmpty () and blkTrack.action.get ():
+        print "Encoding track %s to ogg/vorbis ..." % (tr + 1)
+        setStatusText ("Encoding track %s to ogg/vorbis ..." % (tr + 1))
+
+        oggfile = lib.helper.ogg_encode (blkTrack.url.get ())
+        if oggfile:
+          blkTrack.url.set (oggfile)
+
+    activateTrigger ('tag_files')
+  </trigger>
+
+
+  <!-- ===================================================================
+       Create vorbis comments for all selected files
+
+       This trigger creates a set of vorbis comments in all selected tracks
+       with a valid URL pointing to a ogg/vorbis file.
+       =================================================================== -->
+
+  <trigger name="tag_files" type="NAMED">
+    from lib import helper
+
+    blkTrack.firstRecord ()
+    for i in range (dtsTrack.count ()):
+      blkTrack.gotoRecord (i)
+
+      if blkTrack.action.get () and not blkTrack.url.isEmpty ():
+        setStatusText ("Tagging track %s ..." % (i + 1))
+
+        album    = blkDisc.title.get ()
+        category = blkDisc.category.getFKDescription ()
+        filename = blkTrack.url.get ()
+        title    = blkTrack.title.get ()
+        artist   = blkTrack.artist.getFKDescription ()
+        tracknum = blkTrack.track.get ()
+
+        helper.tag_oggfile (filename, album, category, title, artist, tracknum)
+  </trigger>
+</form>
+

Added: gnue-cddb/dlgArtist.gfd
===================================================================
--- gnue-cddb/dlgArtist.gfd     2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/dlgArtist.gfd     2004-12-02 14:36:52 UTC (rev 151)
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="iso8859-1"?>
+
+<!-- Artist Selection / Modification
+
+     Copyright 2004 Free Software Foundation
+
+     This file is part of GNU Enterprise.
+
+     GNU Enterprise is free software; you can redistribute it and/or
+     modify it under the terms of the GNU General Public License as
+     published by the Free Software Foundation; either version 2 of
+     the License, or (at your option) any later version.
+
+     GNU Enterprise is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNU Enterprise; see the file COPYING.  If not, write to
+     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+
+     $Id: $ -->
+
+<form title="Artists" style="dialog">
+  <options>
+  </options>
+
+  <parameter name="artist" default="" description="Preselected artist" />
+
+  <!-- =================================================================== -->
+  <!-- Datasources                                                         -->
+  <!-- =================================================================== -->
+
+  <datasource connection="appserver" name="dtsArtist"   table="cddb_artist"
+    order_by="cddb_name" cache="250" />
+
+  <datasource connection="appserver" name="dtsSearch"   table="cddb_artist"
+    
explicitfields="cddb_lastname,cddb_middlename,cddb_firstname,cddb_matchcode"
+    cache="250" />
+
+  <!-- =================================================================== -->
+  <!-- Blocks                                                              -->
+  <!-- =================================================================== -->
+
+  <logic>
+
+    <block name="blkArtist" datasource="dtsArtist">
+      <field name="first"  field="cddb_firstname"  maxLength="30" />
+      <field name="middle" field="cddb_middlename" maxLength="30" />
+      <field name="last"   field="cddb_lastname"   maxLength="30" />
+      <field name="full"   field="cddb_name"       maxLength="100" />
+      <field name="gnueid" field="gnue_id"         readonly="True" />
+    </block>
+
+  </logic>
+
+
+  <!-- =================================================================== -->
+  <!-- Trigger                                                             -->
+  <!-- =================================================================== -->
+
+  <trigger type="On-Activation" >
+    <!-- ====================================================================
+      If an 'default' record is requested, first try to find an artist with
+      such a gnue_id. On failure try to find an artist by it's matchcode, using
+      all possible permutations of the name.
+      ==================================================================== -->
+
+    setParameter ('cancel', True)
+    preselect = getParameter ('artist')
+
+    if preselect and len (preselect):
+      res = dtsSearch.simpleQuery ({'gnue_id': preselect})
+      if len (res):
+        dtsArtist.simpleQuery ({'gnue_id': res [0]['gnue_id']})
+        return
+
+      from lib import helper
+
+      rs = dtsSearch.createResultSet ()
+      if rs.getRecordCount ():
+        for name in helper.getArtistNames (preselect):
+          rec = rs.findRecord ({'cddb_matchcode': name.upper ()})
+          if rec is not None:
+            dtsArtist.simpleQuery ({'gnue_id': rec.getField ('gnue_id')})
+            return
+
+      blkArtist.last.set (preselect)
+  </trigger>
+
+  <!-- =================================================================== -->
+  <!-- Layout (Main Form)                                                  -->
+  <!-- =================================================================== -->
+
+  <layout xmlns:c="GNUe:Layout:Char" c:height="7" c:width="60" tabbed="none">
+
+    <page name="pgArtist" caption="Artist">
+
+      <label c:x="1"  c:y="1" c:width="12" text="First name:" />
+      <label c:x="1"  c:y="2" c:width="12" text="Middle Name:" />
+      <label c:x="1"  c:y="3" c:width="12" text="Last Name:" />
+      <label c:x="1"  c:y="4" c:width="12" text="Full Name:" />
+
+      <entry c:x="13" c:y="1" c:width="40" block="blkArtist" field="first"
+        focusorder="1" />
+
+      <entry c:x="13" c:y="2" c:width="40" block="blkArtist" field="middle" />
+      <entry c:x="13" c:y="3" c:width="40" block="blkArtist" field="last" />
+
+      <entry c:x="13" c:y="4" c:width="60" block="blkArtist" field="full"
+        navigable="False" style="label" />
+
+      <!-- ================================================================ -->
+      <!-- Button Row (Actions)                                             -->
+      <!-- ================================================================ -->
+
+      <button c:x="1"  c:y="6" c:width="10"  label="Ok" >
+        <trigger name="btnOk" type="ON-ACTION">
+          if not blkArtist.isSaved ():
+            blkArtist.commit ()
+
+          if not len (blkArtist.full.get ()):
+            abort ('Please specify an artist first')
+
+          setParameter ('artist', blkArtist.gnueid.get ())
+          setParameter ('cancel', False)
+
+          close ()
+        </trigger>
+      </button>
+
+      <button c:x="12" c:y="6" c:width="10" label="Cancel">
+        <trigger name="btnCancel" type="ON-ACTION">
+          if not blkArtist.isSaved ():
+            blkArtist.rollback ()
+
+          setParameter ('cancel', True)
+          setParameter ('artist', None)
+
+          close ()
+        </trigger>
+      </button>
+
+    </page>
+
+  </layout>
+</form>
+

Added: gnue-cddb/dlgMatch.gfd
===================================================================
--- gnue-cddb/dlgMatch.gfd      2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/dlgMatch.gfd      2004-12-02 14:36:52 UTC (rev 151)
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="iso8859-1"?>
+
+<!-- Match Selection
+
+     Copyright 2004 Free Software Foundation
+
+     This file is part of GNU Enterprise.
+
+     GNU Enterprise is free software; you can redistribute it and/or
+     modify it under the terms of the GNU General Public License as
+     published by the Free Software Foundation; either version 2 of
+     the License, or (at your option) any later version.
+
+     GNU Enterprise is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNU Enterprise; see the file COPYING.  If not, write to
+     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+
+     $Id: $ -->
+
+<form title="Select a match" style="dialog">
+  <options>
+  </options>
+
+  <parameter name="matches" default="" description="List of Match-Dicts" />
+
+  <!-- =================================================================== -->
+  <!-- Datasources                                                         -->
+  <!-- =================================================================== -->
+
+  <datasource connection="appserver" name="dtsCategory" table="cddb_category"
+    prequery="True" cache="250" />
+
+  <datasource name="dtsMatch" type="static">
+    <staticset fields="title,category,discid">
+      <staticsetrow>
+        <staticsetfield name="title"    value="Various / Unknown" />
+        <staticsetfield name="category" value="misc" />
+        <staticsetfield name="discid"   value="" />
+      </staticsetrow>
+    </staticset>
+  </datasource>
+
+
+  <!-- =================================================================== -->
+  <!-- Blocks                                                              -->
+  <!-- =================================================================== -->
+
+  <logic>
+
+    <block name="blkMatch" datasource="dtsMatch" rows="10"
+      restrictDelete="True" restrictInsert="True" >
+
+      <field name="title"    field="title"    readonly="True" />
+
+      <field name="category" field="category" readonly="True"
+        fk_key="cddb_matchcode" fk_description="cddb_name"
+        fk_source="dtsCategory" />
+
+      <field name="catid"    field="category" readonly="True"
+        fk_key="cddb_matchcode" fk_description="gnue_id"
+        fk_source="dtsCategory" />
+
+      <field name="discid"   field="discid"   readonly="True" />
+    </block>
+
+  </logic>
+
+
+  <!-- =================================================================== -->
+  <!-- Trigger                                                             -->
+  <!-- =================================================================== -->
+
+  <trigger type="On-Startup">
+    form.setFeature ('GUI:TOOLBAR:SUPPRESS', True)
+    form.setFeature ('GUI:MENUBAR:SUPPRESS', True)
+  </trigger>
+
+
+  <trigger type="On-Activation" >
+    setParameter ('cancel', True)
+    matches = getParameter ('matches')
+
+    if matches and len (matches):
+      record = None
+      rs = dtsMatch.createResultSet ()
+
+      for match in matches:
+        record = record and rs.insertRecord () or rs.firstRecord ()
+
+        blkMatch.title.set (match ['title'])
+        blkMatch.category.set (match ['category'])
+        blkMatch.discid.set (match ['disc_id'])
+
+      blkMatch.firstRecord ()
+  </trigger>
+
+
+  <!-- =================================================================== -->
+  <!-- Layout (Main Form)                                                  -->
+  <!-- =================================================================== -->
+
+  <layout xmlns:c="GNUe:Layout:Char" c:height="13" c:width="74" tabbed="none">
+
+    <page name="pgArtist" caption="Artist">
+
+      <label c:x="1"  c:y="0" c:width="10" text="Disc-ID" />
+      <label c:x="12" c:y="0" c:width="30" text="Category" />
+      <label c:x="43" c:y="0" c:width="30" text="Title" />
+
+      <entry c:x="1"  c:y="1" c:width="10"  block="blkMatch" field="discid"
+        focusorder="1" />
+
+      <entry c:x="12" c:y="1" c:width="30" block="blkMatch" field="category"
+        navigable="False" />
+
+      <entry c:x="43" c:y="1" c:width="30" block="blkMatch" field="title"
+        navigable="False" />
+
+      <!-- ================================================================ -->
+      <!-- Button Row (Actions)                                             -->
+      <!-- ================================================================ -->
+
+      <button c:x="1"  c:y="12" c:width="10"  label="Ok" >
+        <trigger name="btnOk" type="ON-ACTION">
+          cat = blkMatch.category.get ()
+          rs = dtsCategory.simpleQuery ({'cddb_matchcode': cat})
+
+          setParameter ('cancel', False)
+          setParameter ('result', \
+            {'disc_id'  : blkMatch.discid.get (),
+             'category' : blkMatch.catid.getFKDescription (),
+             'matchcode': blkMatch.category.get (),
+             'title'    : blkMatch.title.get ()})
+
+          close ()
+        </trigger>
+      </button>
+
+      <button c:x="12" c:y="12" c:width="10" label="Cancel">
+        <trigger name="btnCancel" type="ON-ACTION">
+          setParameter ('cancel', True)
+          close ()
+        </trigger>
+      </button>
+
+    </page>
+
+  </layout>
+
+</form>
+

Added: gnue-cddb/lib/cddbplib.py
===================================================================
--- gnue-cddb/lib/cddbplib.py   2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/lib/cddbplib.py   2004-12-02 14:36:52 UTC (rev 151)
@@ -0,0 +1,749 @@
+# GNU CD Database - CDDB Protocol Implementation
+#
+# Copyright 2001-2004 Free Software Foundation
+#
+# This file is part of GNU Enterprise
+#
+# GNU Enterprise is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2, or (at your option) any later version.
+#
+# GNU Enterprise is distributed in the hope that it will be
+# useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+# PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with program; see the file COPYING. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place
+# - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id: $
+
+"""
+Module implementing the CD Database Protocol version 1
+This module provides a client class for accessing CDDB server using CDDBP.
+"""
+
+import socket
+import sys
+import os
+import string
+import re
+
+# ===========================================================================
+# Constants
+# ===========================================================================
+
+_DEFAULTS = {'server': 'freedb.org',
+             'port'  : 8880,
+             'user'  : 'unknown',
+             'host'  : 'localhost',
+             'client': 'unknown',
+             'clvers': '0.0PL0' }
+
+LF   = '\n'
+CRLF = '\r' + LF
+
+# ===========================================================================
+# Exception classes
+# ===========================================================================
+
+class Error (Exception): pass             # general exception
+class ECannotPerform (Error): pass        # 4xx error-codes
+class EUnImplemented (Error): pass        # 5xx error-codes
+class EInvalidProtocol (Error): pass      # max. protocol level below 4
+class ENoMatch (Error): pass              # cddb query found no match
+class EInvalidData (Error): pass          # downloaded match is corrupt
+class EInvalidLine (Error): pass          # invalid characters in raw data
+class EEmptyLine (Error): pass            # raw data has empty lines
+
+# ===========================================================================
+# CDDBP: implement access to CDDB using CDDB-Protocol
+# ===========================================================================
+
+class CDDBP:
+  """A CDDBP client class"""
+
+  # -------------------------------------------------------------------------
+  # Constructor
+  # -------------------------------------------------------------------------
+  def __init__ (self, server=_DEFAULTS['server'], port=_DEFAULTS['port']):
+    """Constructor: Initializes the instance If the environment 
+       variable CDDB_EMAIL is set, both username and hostname are 
+       extracted from this variable."""
+    self.server        = server
+    self.port          = port
+    self.user          = _DEFAULTS['user']
+    self.hostname      = _DEFAULTS['host']
+    self.clientName    = _DEFAULTS['client']
+    self.clientVersion = _DEFAULTS['clvers']
+    self.welcome       = None
+    self.readonly      = 1
+
+    if os.environ.has_key('CDDB_EMAIL'):
+      (self.user, self.hostname) = string.split (os.environ['CDDB_EMAIL'], '@')
+
+    self.__socket      = None
+    self.__file        = None
+    
+  # -------------------------------------------------------------------------
+  # Connect to the CDDBP-Server
+  # -------------------------------------------------------------------------
+  def connect (self, server='', port=0):
+    """Connect to server:port and run the initial handshake. The 
+       protocol level will be set to the maximum level supported by 
+       the server"""
+    if server: self.server = server
+    if port  : self.port   = port
+
+    # open a socket 
+    self.__socket = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
+    self.__socket.connect ((self.server, self.port))
+    self.__file = self.__socket.makefile ('rb')
+
+    # after connecting we should recieve the welcome message
+    self.welcome  = self.readResponse ()
+    self.readonly = (self.welcome[0] == '200')
+
+    # now start the initial handshake
+    self.sendCommand ("cddb hello %s %s %s %s" % (self.user, self.hostname,
+                      self.clientName, self.clientVersion))
+    self.readResponse ()
+
+    # now set the cddb protocol level to the maximum available
+    self.maxProtocol = self.maxProtocolLevel ()
+    if self.maxProtocol < 4:
+      raise EInvalidProtocol, (self.maxProtocol, 
+        'Maximum protocol level supported is too low')
+
+    self.sendCommand ("proto %d" % self.maxProtocol)
+    self.readResponse ()
+
+  # -------------------------------------------------------------------------
+  # Disconnect from CDDBP-Server (sign-off)
+  # -------------------------------------------------------------------------
+  def close (self):
+    """Disconnect from the server."""
+    if self.__file:
+      self.sendCommand ('quit')
+      self.__file.close ()
+      self.__socket.close ()
+      self.__file = self.__socket = None
+
+  # -------------------------------------------------------------------------
+  # Get the maximum protocol level supportet by the remote server
+  # -------------------------------------------------------------------------
+  def maxProtocolLevel (self):
+    """Returns the maximum protocol level supported by the server"""
+    self.sendCommand ('proto')
+    self.readResponse ()
+    patt = re.compile (r'.*(\d+)$')
+
+    lev_match = patt.match (self.data)
+    if not lev_match: 
+      raise Error, 'Cannot determine protocol level'
+
+    return int ("%s" % lev_match.groups())
+
+  # -------------------------------------------------------------------------
+  # Fetch a list of valid categories known by the server
+  # -------------------------------------------------------------------------
+  def listCategories (self):
+    """Returns an array with all categories supported by the server"""
+    return self.execArray ('cddb lscat')
+
+  # -------------------------------------------------------------------------
+  # Query the server for the CD specified with discinfo.
+  # -------------------------------------------------------------------------
+  def queryCd (self, discinfo):
+    """Query the server for the CD specified by discinfo.
+       discinfo is an array as returned by the DiscID module's disc_id() 
+       function. This array consists of: 
+       disc_id, num_tracks, offset_1, ..., offset_n, num_seconds
+       The result is a list of tuples (categ, discid, dtitle) per match.
+    """
+    # prepare the query-string
+    qstr = "cddb query %08lx %d " % (discinfo [0], discinfo [1])
+    for ofs in discinfo [2:]:
+      qstr = qstr + ("%d " % ofs)
+    qstr = string.rstrip (qstr)
+
+    self.sendCommand (qstr)
+    self.readResponse ()
+
+    if self.code == '202':
+      raise ENoMatch
+
+    if self.code == '200':
+      (category, discid, title) = self.data.split (' ', 2)
+      result = {'category': category, 'disc_id': discid, 'title': title}
+    else:
+      result = []
+
+      for line in string.split (self.data, LF) [1:]:
+        (category, discid, title) = line.split (' ', 2)
+        result.append ({'category': category,
+                        'disc_id' : discid,
+                        'title'   : title})
+
+    return (int (self.code), result)
+
+
+  # -------------------------------------------------------------------------
+  # Download a specified entry from the database. 
+  # -------------------------------------------------------------------------
+  def download (self, entry):
+    """
+    Download a specified entry from the database.
+    
+    @param entry: a dictionary with at least two keys: category and disc_id.
+
+    The result is the downloaded text of the record as an array of lines.
+    """
+    return self.execArray ("cddb read %s %s" % (entry ['category'],
+                                                entry ['disc_id']))
+
+  # -------------------------------------------------------------------------
+  # Like download(), but returns an instance of CDDBMatch.
+  # -------------------------------------------------------------------------
+  def downloadMatch (self, entry):
+    """Like CDDBP.download(), but returns an instance of CDDBMatch 
+       instead of the raw record data."""
+    return CDDBMatch (self.download (entry), self.maxProtocol, self.clientName)
+
+  # -------------------------------------------------------------------------
+  # Upload a new/modified entry to the database.
+  # -------------------------------------------------------------------------
+  def upload (self, entry, data):
+    """Upload a new/modified entry to the database. entry must be a
+       tuple of (category, discid) and data must be the database record
+       as an array of lines _without_ trailing CR/LF characters.
+       If the client is allowed to do uploads, the attribute CDDBP.readonly
+       must be flase."""
+    self.sendCommand ("cddb write %s %s" % entry)
+    self.readResponse ()
+
+    if self.code == '320':
+       block = string.join (data, CRLF) + CRLF + '.'
+       self.sendCommand (block)
+       self.readResponse ()
+
+  # -------------------------------------------------------------------------
+  # Like upload(), but expects the data as instance of CDDBMatch.
+  # -------------------------------------------------------------------------
+  def uploadMatch (self, entry, match):
+    """Like CDDBP.upload(), but expects the data as instance of CDDBMatch"""
+    self.upload (entry, match.encode ())
+
+  # -------------------------------------------------------------------------
+  # Disc-ID calculation
+  # -------------------------------------------------------------------------
+  def calcDiscid (self, discinfo):
+    """Disc-ID calculation: returns the calculated discid from values
+       given in discinfo-array, which consists of:
+       num_tracks, offset_1, ... , offset_n, num_seconds."""
+    dstr = string.join (map (lambda x: "%d" % x, discinfo), ' ')
+    self.sendCommand ("discid %s" % dstr)
+    self.readResponse ()
+
+    return string.split (self.data, ' ')[-1]
+
+  # -------------------------------------------------------------------------
+  # Retrieve the message of the day from the server.
+  # -------------------------------------------------------------------------
+  def getMotd (self):
+    """Get the servers message-of-the-day. The result is a tuple of
+       ( date-last-modified, array-with-message )."""
+    self.sendCommand ('motd')
+    self.readResponse ()
+
+    answ = string.split (self.data, LF)
+    mod_date = string.join (string.split (answ[0], ' ')[2:4], ' ')
+
+    return (mod_date, answ[1:])
+
+  # -------------------------------------------------------------------------
+  # Retrieve a list of alternate server-sites. 
+  # -------------------------------------------------------------------------
+  def getSiteList (self):
+    """Get a list of alternate server-sites. Each site is given as a 
+       tuple of the form ( site, protocol, port, address, latitude, 
+       longitude, description ). address is the location of the cgi-
+       script at the remote-site (if protocol is http)."""
+    self.sendCommand ('sites')
+    self.readResponse ()
+
+    result = []
+    for site in string.split (self.data, LF)[1:]:
+      parts = string.split (site, ' ')
+      # site, protocol, port, address, latitude, longitude, description
+      result.append ((parts[0], parts[1], parts[2],
+                      parts[3], parts[4], parts[5],
+                      string.join (parts[6:], ' ')))
+
+    return result
+
+  # -------------------------------------------------------------------------
+  # Retrieve a status message from the server
+  # -------------------------------------------------------------------------
+  def getStatus (self):
+    """Get the server's status message. See cddbp documentation for more
+       details about this message. The result is an array of lines."""
+    return self.execArray ('stat')
+
+  # -------------------------------------------------------------------------
+  # Retrieve the server's version information
+  # -------------------------------------------------------------------------
+  def getServerVersion (self):
+    """Get the servers version information."""
+    self.sendCommand ('ver')
+    self.readResponse ()
+
+    if self.code == '200':
+      res = [self.data]
+    else:
+      res = string.split (self.data, LF)[1:]
+
+    return res
+
+  # -------------------------------------------------------------------------
+  # Update the database
+  # -------------------------------------------------------------------------
+  def databaseUpdate (self):
+    """Perform a database update (if you have permission to do so)."""
+    self.sendCommand ('update')
+    self.readResponse ()
+
+  # -------------------------------------------------------------------------
+  # Get a list of server users
+  # -------------------------------------------------------------------------
+  def serverUsers (self):
+    """Get a list of users currently logged on at the server."""
+    return self.execArray ('whom')
+
+
+
+  # -------------------------------------------------------------------------
+  # Internal: send a command to remote site
+  # -------------------------------------------------------------------------
+  def sendCommand (self, command):
+    """INTERNAL: send the command plus CRLF to the server."""
+    line = command + CRLF
+    self.__socket.sendall (line)
+
+  # -------------------------------------------------------------------------
+  # Internal: return one line from the server, stripping CRLF.
+  # -------------------------------------------------------------------------
+  def getLine (self):
+    """INTERNAL: Get one line from the server, stripping trailing CRLF.
+       If the server has no data waiting for input, raise EOFError.""" 
+    line = self.__file.readline ()
+    if not line: raise EOFError
+
+    if line[-2:] == CRLF: line = line[:-2]
+    if line[-1:] in CRLF: line = line[:-1]
+
+    return line
+
+  # -------------------------------------------------------------------------
+  # Internal: get a response from the server
+  # -------------------------------------------------------------------------
+  def getMultiLine (self):
+    """Get a response from the server, which might consist of multiple
+       lines (code = x1x). Multiple lines are concatenated by a newline 
+       into a single string result."""
+    line = self.getLine ()
+
+    # code x1x means there's more data waiting for retrieval
+    if line[1] == '1':
+      while 1:
+        nextline = self.getLine ()
+       # a line with a single '.' is treated as termination marker
+       if nextline == '.': break
+       line = line + (LF + nextline)
+
+    return line
+
+  # -------------------------------------------------------------------------
+  # Internal: get a response from the server, raise various errors if needed
+  # -------------------------------------------------------------------------
+  def readResponse (self):
+    """INTERNAL: get a response from the server, raise various errors 
+       if the response indicates an error. This method sets the attributes
+       code and data, and returns a tuple (code, data)"""
+    resp = self.getMultiLine ()
+    self.code = resp[:3]
+    self.data = resp[4:]
+
+    if   self.code[0] == '4':
+         raise ECannotPerform, (self.code, self.data)
+
+    elif self.code[0] == '5':
+         raise EUnImplemented, (self.code, self.data)
+
+    return (self.code, self.data)
+
+  # -------------------------------------------------------------------------
+  # Executes the 'command' and returns the result as an array
+  # -------------------------------------------------------------------------
+  def execArray (self, command):
+    """Execute command, read the server's response and split it into an
+       array of lines."""
+    self.sendCommand (command)
+    self.readResponse ()
+    return string.split (self.data, LF)[1:]
+
+
+
+
+# ===========================================================================
+# This class implements encoding and decoding of raw cd database matches
+# ===========================================================================
+
+# _XMAP defines a translation-table of attributes supported by the class
+# CDDBMatch. Every key is corresponding to an attribute of this class.
+# The values in _XMAP are used as keys of the dictionary data.
+_XMAP = { 'discTitle'    : 'DTITLE',
+          'discId'       : 'DISCID',
+          'discYear'     : 'DYEAR',
+          'discGenre'    : 'DGENRE',
+          'discExtended' : 'EXTD',
+          'playorder'    : 'PLAYORDER',
+          'discLength'   : 'discLength',
+          'revision'     : 'revision',
+          'submitted'    : 'submitted' }
+
+# Allowed characters for comment-lines and keyword-lines
+_COMMENTS = map (lambda x: chr (x), range (0x20, 0x7F)) + ['\t']
+_KEYWORDS = map (lambda x: chr (x), range (0x20, 0x7F) + range (0xA0,0xFF))
+
+# ===========================================================================
+# Class for encoding and decoding of raw CDDB matches.
+# ===========================================================================
+class CDDBMatch:
+  """This class provides an interface to CDDB records."""
+
+  # -------------------------------------------------------------------------
+  # Constructor
+  # -------------------------------------------------------------------------
+  def __init__ (self, match, proto=5, client='unknown'):
+    """match is a raw record as returnd by CDDBP.download(); if match
+       is specified it will be decoded immediately. proto is the protocol
+       level used by the server.  """
+    # don't trigger __setattr__ here :))
+    self.__dict__['raw']    = match
+    self.__dict__['data']   = {}
+    self.__dict__['tracks'] = []
+    self.__dict__['frames'] = []
+    self.__dict__['proto']  = proto
+    self.__dict__['client'] = client
+
+    if len (self.raw):
+      self.decode (self.raw)
+
+  # -------------------------------------------------------------------------
+  # Retrieve an attribute's value (either from data-dict. or from instance)
+  # -------------------------------------------------------------------------
+  def __getattr__ (self, attrname):
+    """Internal: Retrieve an attribute's value (either from the dictionary
+       or the instancde itself."""
+    # if _xmap defines the attribute, return this value from data-dictionary
+    if _XMAP.has_key (attrname):
+      return self.data[_XMAP[attrname]]
+    else:
+      # ohterwise it should be an already defined attribute
+      if self.__dict__.has_key (attrname):
+        return self.getattr (attrname)
+      else:
+        raise AttributeError, attrname
+
+  # -------------------------------------------------------------------------
+  # Set an attribute's value (either in data-dict. or in the instance)
+  # -------------------------------------------------------------------------
+  def __setattr__ (self, attr, value):
+    """Internal: Set an attribute's value either by accessing the 
+       dictionary or the instance's attribute."""
+    # if attribute is defined in _xmap, set the value into data-dict.
+    if _XMAP.has_key (attr):
+      self.data[_XMAP[attr]] = value
+    else:
+      # otherwise set it as instance-attribute's value (if possible)
+      if self.__dict__.has_key (attr):
+        self.__dict__[attr] = value
+      else:
+        raise AttributeError, attr
+
+  # -------------------------------------------------------------------------
+  # Decode data of a 'raw match'
+  # -------------------------------------------------------------------------
+  def decode (self, rawdata):
+    """Decode rawdata (which is an array as returned by CDDBP.download)
+       and populate the instances attributes."""
+    dlen  = re.compile (r'^#\s*Disc length:\s*(\d+)\s*seconds')
+    revn  = re.compile (r'^#\s*Revision:\s*(\d+)')
+    subm  = re.compile (r'^#\s*Submitted via:\s*(.*)')
+    frame = re.compile (r'^#\s*(\d+)')
+    kword = re.compile (r'([^=]+)=(.*)')
+
+    # transform the raw-data into a dictionary
+    self.data = {}
+    frix = 0
+
+    for line in rawdata:
+      string.rstrip (line)
+      line = string.replace (line, r'\t', "\t")
+      line = string.replace (line, r'\n', "\n")
+      line = string.replace (line, r'\\', "\\")
+
+      # if the line starts with 'SOMETHING = DATA' we have a keyword
+      kw_match = kword.match (line)
+      if kw_match:
+        (key, data) = kw_match.groups ()
+
+       if self.data.has_key (key):
+          self.data[key] = self.data[key] + data
+        else:
+          self.data[key] = data
+        continue
+
+      # Commentline with disc-length
+      dl_match = dlen.match (line)
+      if dl_match:
+       self.discLength = int (dl_match.group (1))
+       continue
+
+      # Commentline with revision
+      rv_match = revn.match (line)
+      if rv_match:
+        self.revision = int (rv_match.group (1))
+       continue
+
+      # Commentline with sumbission infos
+      su_match = subm.match (line)
+      if su_match:
+        self.submitted = su_match.group (1)
+       continue
+
+      # Commentline with a frame-offset
+      fr_match = frame.match (line)
+      if fr_match:
+        self.data["FRAME%d" % frix] = int (fr_match.group (1))
+       frix = frix + 1
+       continue
+
+    # transform all track-data into a list 
+    max = 0
+    for key in self.data.keys ():
+      if key[:6] == 'TTITLE': max = max + 1
+
+    self.tracks = []
+    self.frames = []
+    for ix in range (max):
+      tit = self.data["TTITLE%d" % ix]
+      if self.data.has_key ("EXTT%d" % ix):
+        ext = self.data["EXTT%d" % ix]
+      else:
+        ext = ''
+      if self.data.has_key ("FRAME%d" % ix):
+        fro = self.data["FRAME%d" % ix]
+       self.frames.append (fro)
+      else:
+        fro = 0
+      
+      self.tracks.append ({ 'ID'    : ix+1,
+                            'TITLE' : tit,
+                            'EXTD'  : ext,
+                            'OFFSET': fro })
+
+    # there must be the same number of frames as tracks
+    if len (self.frames) != len (self.tracks):
+      raise EInvalidData, 'Invalid format of raw data; cannot decode.'
+
+  # -------------------------------------------------------------------------
+  # Encode a match to raw data ready for an upload
+  # -------------------------------------------------------------------------
+  def encode (self):
+    """Encode the current data of the instance into an array of raw
+       data, so it will be accepted by CDDBP.upload()."""
+    result = []
+    _empty = '#'
+    
+    self.__fmtComment (['# xmcd', _empty, '# Track frame offsets:'], result)
+    self.__fmtComment (map (lambda x: "#\t%d" % x, self.frames), result)
+
+    ### TODO: Increment revision and create an own 'submitted via' string
+    self.__fmtComment ([_empty, 
+         "# Disc length: %d seconds" % self.discLength,
+        _empty,
+         "# Revision: %d" % self.revision,
+         "# Submitted via: %s" % self.submitted,
+        _empty], result)
+
+    ### TODO: self.discId might be a list of id's instead of a single id.
+    self.__fmtKeyword (self.__fmtLine ('DISCID', self.discId), result)
+    self.__fmtKeyword (self.__fmtLine ('DTITLE', self.discTitle), result)
+   
+    # both keywords DYEAR and DGENRE are supported since protocol level 5
+    if self.proto > 4:
+      self.__fmtKeyword (self.__fmtLine ('DYEAR' , self.discYear), result)
+      self.__fmtKeyword (self.__fmtLine ('DGENRE', self.discGenre), result)
+    
+    for trk in self.tracks:
+      self.__fmtKeyword ( self.__fmtLine ("TTITLE%d" % trk['ID'], 
trk['TITLE']),
+                          result)
+
+    self.__fmtKeyword (self.__fmtLine ('EXTD', self.discExtended), result)
+
+    for trk in self.tracks:
+      self.__fmtKeyword (self.__fmtLine ("EXTT%d" % trk['ID'], trk['EXTD']),
+                         result)
+
+    self.__fmtKeyword (self.__fmtLine ('PLAYORDER', self.playorder), result)
+
+    return result
+      
+
+  # -------------------------------------------------------------------------
+  # Create a list of lines according to the length-restrictions of a db-match
+  # -------------------------------------------------------------------------
+  def __fmtLine (self, prefix, data, max=78):
+    """INTERNAL: Format a line of 'prefix=data' and make sure it's
+       lenght won't exceed max characters. Result is an array of all 
+       parts needed to create this line."""
+    line   = "%s=%s" % (prefix, data) 
+    result = []
+
+    while len (line) > max:
+      result.append (line[:max])
+      line = "%s=%s" % (prefix, line[max:])
+
+    result.append (line)
+    return result
+      
+  # -------------------------------------------------------------------------
+  # Check comment-lines and add them to result
+  # -------------------------------------------------------------------------
+  def __fmtComment (self, toadd, result):
+    """INTERNAL: append all lines in toadd to the array result. Before
+       adding, all lines are checked for invalid characters."""
+    for line in toadd:
+      if not string.strip(line):
+        raise EEmptyLine
+
+      for char in line:
+        if char not in _COMMENTS: 
+         raise EInvalidLine, (char, line)
+      result.append (line)
+
+  # -------------------------------------------------------------------------
+  # Check keyword-lines and add them to result
+  # -------------------------------------------------------------------------
+  def __fmtKeyword (self, toadd, result):
+    """INTERNAL: append all lines from toadd to the array result. Before
+       adding all lines are checked for invalid characters."""
+    for line in toadd:
+      if not string.strip(line):
+        raise EEmptyLine
+
+      line = string.replace (line, "\\", r'\\')
+      line = string.replace (line, "\t", r'\t')
+      line = string.replace (line, "\n", r'\n')
+
+      for char in line:
+        if char not in _KEYWORDS:
+         raise EInvalidLine, (char, line)
+
+      result.append (line)
+
+# ===========================================================================
+# Module's self-test
+# ===========================================================================
+if __name__ == '__main__':
+  cddb = CDDBP ()
+
+  cddb.connect ()
+  try:
+    try:
+      # this shoud match the signs - soundtrack :)
+      atest = [ 2701831181L, 13, 150, 8062, 22692, 33167, 41867, 67550,
+                72732, 82595, 108652, 122200, 146475, 163127, 188075, 2734 ]
+
+      (code, info) = cddb.queryCd (atest)
+      if code == 200:
+        entry = info
+        print "Match [%s]: %s (%s)" % (info ['category'], info ['title'],
+                                       info ['disc_id'])
+      elif code in [210, 211]:
+        for match in info:
+          print "Match [%s]: %s (%s)" % (match ['category'], match ['title'],
+                                         match ['disc_id'])
+        entry = info [0]
+
+      match = cddb.downloadMatch (entry)
+
+      print "Title = %s" % match.discTitle
+      print "Length: %d" % match.discLength
+
+      for track in match.tracks:
+        print "%02d [%06d]: %s" % (track['ID'], track['OFFSET'], 
track['TITLE'])
+
+      sys.exit ()
+      # change some data and encode match
+      match.discTitle = "Just to change something / Nobody"
+      match.tracks[3]['TITLE'] = "Another new track title."
+      match.tracks[2]['EXTD'] = """This is some very long extended information 
+      for the third track. Just to see if linebreaking works as intended.""" 
+
+      enc = match.encode ()
+
+      print "encoded modified match:"
+      for i in enc:
+        print i
+  
+
+      ### -----
+      xy = cddb.calcDiscid (atest[1:])
+      print "calcDiscid == %s" % xy
+
+      ### -----
+      modt = cddb.getMotd ()
+      print "MOTD last modified: %s" % modt[0]
+      for line in modt[1]:
+        print ">> %s" % line
+
+      ### -----
+      print "Server version: %s" % cddb.getServerVersion ()
+
+      ### -----
+      print "Site-List:"
+      for site in cddb.getSiteList ():
+        print "%s://%s:%s %s %s %s %s" % (site[1], site[0], site[2], site[3],
+             site[4], site[5], site[6])
+
+      ### -----
+      print "Categories:"
+      for cat in cddb.listCategories ():
+        print ">> %s" % cat
+
+      ### -----
+      print "Server-Status:"
+      for line in cddb.getStatus ():
+        print ">> %s" % line
+
+      ### -----
+      print "Server-Users:"
+      try:
+        for user in cddb.serverUsers ():
+          print "user %s" % user
+
+      except ECannotPerform, info:
+        print "Error %s: %s" % (info[0], info[1])
+
+    except ENoMatch:
+      print "Sorry, there's no record for this disc found."
+
+  finally:
+    cddb.close ()
+


Property changes on: gnue-cddb/lib/cddbplib.py
___________________________________________________________________
Name: svn:executable
   + *

Modified: gnue-cddb/lib/helper.py
===================================================================
--- gnue-cddb/lib/helper.py     2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/lib/helper.py     2004-12-02 14:36:52 UTC (rev 151)
@@ -1,7 +1,9 @@
-
+# GNUe CD Database - Helper functions
 #
-# This file is part of GNU Enterprise CD Database.
+# Copyright 2001-2004 Free Software Foundation
 #
+# This file is part of GNU Enterprise
+#
 # GNU Enterprise is free software; you can redistribute it
 # and/or modify it under the terms of the GNU General Public
 # License as published by the Free Software Foundation; either
@@ -17,106 +19,362 @@
 # write to the Free Software Foundation, Inc., 59 Temple Place
 # - Suite 330, Boston, MA 02111-1307, USA.
 #
-# Copyright 2001-2004 Free Software Foundation
-#
+# $Id: $
 
-def processArtists (cddbData, discInfo, dts):
+import string
+import DiscID
+import CDDB
+import mx.DateTime
+import cddbplib
+import wave
+import os.path
+import ogg.vorbis
+from gnue.common.apps import errors
+
+CDDB.proto = 6
+
+
+# -----------------------------------------------------------------------------
+# Esablish a new connection to the remote cd database
+# -----------------------------------------------------------------------------
+
+def openCDDB ():
+  cddb = cddbplib.CDDBP ('at.freedb.org')
+  cddb.connect ()
+  return cddb
+
+# -----------------------------------------------------------------------------
+# Get the disc information array
+# -----------------------------------------------------------------------------
+
+def getDiscInfo ():
   """
-  This function processes artists given by a cd database match and returns a
-  dictionary with all artist information.
+  This function returns a sequence with disc information usable by the remote
+  cd database.
   """
-  result = {'disc'  : {},
-            'new'   : {},
-            'tracks': {}}
 
-  (discArtist, discTitle) = cddbData ['DTITLE'].split ('/')
-  discArtist = discArtist.strip ()
-  discTitle  = discTitle.strip ()
+  dev = DiscID.open ()
+  return DiscID.disc_id (dev)
+  
+  
+# -----------------------------------------------------------------------------
+# Get the disc info and all CDDB matches for the current disc
+# -----------------------------------------------------------------------------
 
-  result ['title'] = discTitle
+def getMatches (cddb, discInfo):
+  """
+  This function queries a remote cd database for the disc specified by the
+  discInfo sequence.
 
-  qRes = dts.simpleQuery ({'cddb_name': discArtist})
-  artId = qRes [0].get ('gnue_id', None)
-  if artId is None:
-    result ['new'][discArtist] = {}
+  @param discInfo: sequence as returned by DiscID module describing the disc
+  @return: sequence of dictionaries. Each match is a dictitionary with three
+      keys: 'category', 'disc_id', 'title'
+  """
 
-  result ['disc'] = {'name': discArtist,
-                     'id'  : artId}
+  try:
+    (code, matches) = cddb.queryCd (discInfo)
 
-  for tNum in range (discInfo [1]):
-    parts = cddbData ['TTITLE%d' % tNum].split ('/')
-    if len (parts) == 2:
-      parts [0] = parts [0].strip ()
-      parts [1] = parts [1].strip ()
+  except cddbplib.ENoMatch:
+    code = cddb.code
 
-      artName = parts [0]
-      cddbData ['TTITLE%d' % tNum] = parts [1]
+  mlist = []
 
-      qRes = dts.simpleQuery ({'cddb_name': artName})
-      artId = qRes [0].get ('gnue_id', None)
-      if artId is None:
-        result ['new'][artName] = {}
+  if code == 200:
+    mlist = [matches]
 
-    else:
-      artName = result ['disc']['name']
-      artId   = result ['disc']['id']
+  elif code in [210, 211]:
+    mlist = matches
 
-    result ['tracks'][tNum] = {'name': artName,
-                               'id'  : artId}
+  mlist.append ({'disc_id' : "%08x" % discInfo [0],
+                 'title'   : 'Various / Unknown',
+                 'category': 'misc'})
 
-  return result
+  return mlist
 
 
-def updateArtists (artists):
+# -----------------------------------------------------------------------------
+# Split a title row into an albumname and an artist
+# -----------------------------------------------------------------------------
+
+def splitTitle (dbTitle):
   """
+  This function splits a disc-title into an albumname and an artist.
+  @param dbTitle: title as retrieved from cd database ('artist/album')
+  @return: tuple with albumname and artist
   """
-  if artists ['disc']['id'] is None:
-    new = artists ['new'].get (artists ['disc']['name'], None)
-    if new is not None:
-      artists ['disc']['name'] = new ['name']
-      artists ['disc']['id']   = new ['id']
 
-  for track in artists ['tracks'].values ():
-    if track ['id'] is None:
-      new = artists ['new'].get (track ['name'], None)
-      if new is not None:
-        track ['name'] = new ['name']
-        track ['id']   = new ['id']
+  if '/' in dbTitle:
+    (artist, title) = map (string.strip, dbTitle.split ('/', 1))
+  else:
+    (artist, title) = ('Various', dbTitle)
 
-  print "UPDATE-DISC:", artists ['disc']
-  print "UPDATE-TRAC:", artists ['tracks']
+  return (title, artist)
 
 
-def getOutputPath (dtsOptions, blkDisc):
-  from os import path, environ
+# -----------------------------------------------------------------------------
+# Create a sequence of all possible permutations of a given name
+# -----------------------------------------------------------------------------
 
-  res = dtsOptions.createResultSet ()
-  res.firstRecord ()
-  if res.current is not None:
-    basepath = path.normpath (res.current.getField ('cddb_basepath'))
+def getArtistNames (aName):
+  """
+  This function splits a name by whitespaces and creates a sequence of all
+  permutations of these parts.
+
+  @param aName: name to get permutations for
+  @return: sequence with all permutations of the name
+  """
+
+  parts = aName.split ()
+
+  if len (parts) > 1:
+    perms  = [getPermutation (parts, i) for i in range (faculty (len (parts)))]
+    result = [string.join (item, ' ') for item in perms]
+
   else:
-    basepath = path.normpath (environ ['HOME'])
+    result = [string.join (parts, ' ')]
 
-  catId    = blkDisc.fldCategory.get ()
-  artistId = blkDisc.fldArtist.get ()
-  category = blkDisc.fldCategory.allowedValues () [0][catId] or 'misc'
-  artist   = blkDisc.fldArtist.allowedValues () [0][artistId] or 'unknown'
-  title    = blkDisc.fldTitle.get () or 'unknown'
-  discPath = path.join (basepath, category, artist, title).replace (' ', '_')
+  return result
 
-  return discPath
+
+# -----------------------------------------------------------------------------
+# Get a permuation of a sequence
+# -----------------------------------------------------------------------------
+
+def getPermutation (seq, index):
+  """
+  Returns the n-th permutation of the sequence seq
+  """
+
+  seqc = list (seq [:])
+  seqn = [seqc.pop ()]
+  divider = 2 # divider is meant to be len (seqn) + 1, just a bit faster
+
+  while seqc:
+    index, new_index = index // divider, index % divider
+    seqn.insert (new_index, seqc.pop ())
+    divider += 1
+
+  return seqn
+
+# -----------------------------------------------------------------------------
+# Caculate the faculty of n
+# -----------------------------------------------------------------------------
+
+def faculty (n):
+  """
+  This function calculates the faculty of n (n!)
+  """
+
+  result = 1
+  for i in range (2, n + 1):
+    result *= i
+
+  return result
+
+
+# -----------------------------------------------------------------------------
+# Download a match from remote db
+# -----------------------------------------------------------------------------
+
+def download (cddb, discInfo, category):
+  """
+  This function downloads a record - specified by a discInfo sequence and a
+  category - from a remote cd database.
+
+  @param discInfo: disc info sequence as returned by DiscId module
+  @param category: name of the category to look in
+  @return: dictionary with the following keys:
+      'dlength': length of the disc as mx.DateTime.Time
+      'year'   : Year of the recording or None (if not given)
+      'tracks' : sequence of track-tuples (tracknum, title, length) where the
+                 length is given as mx.DateTime.Time
+  """
+
+  tracks = []
+  result = {'tracks' : tracks,
+            'dlength': mx.DateTime.Time (seconds = discInfo [-1])}
+
+  try:
+    data = cddb.downloadMatch ({'category': category,
+                                'disc_id': "%08x" % discInfo [0]})
+  except cddbplib.ECannotPerform:
+    data = None
+
+  tlen       = discInfo [2:]
+  tlen [-1] *= 75
+
+  for i in range (discInfo [1]):
+    title  = data and data.tracks [i]['TITLE'] or None
+    length = mx.DateTime.Time (seconds = (tlen [i+1] - tlen [i]) / 75.0)
+    tracks.append ((i, title, length))
+
+  tracks.sort ()
+
+  if data:
+    result ['year'] = data.discYear
+
+  return result
+
+
+# -----------------------------------------------------------------------------
+#
+# -----------------------------------------------------------------------------
+
+def __checkSoundFile (filename):
+  try:
+    oggfile = ogg.vorbis.VorbisFile (filename)
+    return False
+
+  except:
+    pass
+
+  try:
+    wavefile = wave.open (str (filename), 'rb')
+    wavefile.close ()
+    return True
+
+  except:
+    pass
+
+  return None
+
+# -----------------------------------------------------------------------------
+# Encode a wave file into ogg/vorbis
+# -----------------------------------------------------------------------------
+
+def ogg_encode (filename, encQuality = 0.5):
+  """
+  This function encodes the given wave-file into an ogg/vorbis file.
+
+  @param filename: name of the wave-file
+  @return: name of the ogg-file created or None if something went wrong
+  """
+
+  state = __checkSoundFile (filename)
+  if not state:
+    return state is None and state or filename
   
-def importFiles (blkTrack, basePath):
-  from os import path
+  oggname  = "%s.ogg" % os.path.splitext (filename) [0]
+  wavefile = wave.open (str (filename), 'rb')
+  oggfile  = open (oggname, 'wb')
 
-  blkTrack.firstRecord ()
+  vi = ogg.vorbis.VorbisInfo (channels = wavefile.getnchannels (),
+                              rate     = wavefile.getframerate (),
+                              quality = encQuality)
+  vc = ogg.vorbis.VorbisComment ()
 
-  while not blkTrack.isEmpty ():
-    url = blkTrack.fldUrl.get ()
-    tNum = blkTrack.fldTrack.get ()
-    if not len (url):
-      filename = path.join (basePath, 'Track%02d.mp3' % tNum)
-      if path.exists (filename):
-        blkTrack.fldUrl.set (filename)
+  vd = vi.analysis_init ()
+  vb = vd.create_block ()
+  (header, header_com, header_code) = vd.headerout (vc)
 
-    blkTrack.nextRecord ()
+  try:
+    stream = ogg.OggStreamState (5)
+    stream.packetin (header)
+    stream.packetin (header_com)
+    stream.packetin (header_code)
+
+    og = stream.flush ()
+    while og:
+      og.writeout (oggfile)
+      og = stream.flush ()
+
+    eos = False
+    while not eos:
+      data = wavefile.readframes (2048)
+      if not data:
+        vd.write (None)
+      else:
+        vd.write_wav (data)
+
+      vb = vd.blockout ()
+      while vb:
+        vb.analysis ()
+        vb.addblock ()
+
+        op = vd.bitrate_flushpacket ()
+        while op:
+          stream.packetin (op)
+          while not eos:
+            og = stream.pageout ()
+            if not og:
+              break
+
+            og.writeout (oggfile)
+            eos = og.eos ()
+
+          op = vd.bitrate_flushpacket ()
+
+        vb = vd.blockout ()
+
+  finally:
+    vd.close ()
+    oggfile.close ()
+
+  wavefile.close ()
+  os.unlink (filename)
+
+  return oggname
+
+  
+# -----------------------------------------------------------------------------
+# Create a tag in the ogg/vorbis file
+# -----------------------------------------------------------------------------
+
+def tag_oggfile (filename, album, category, title, artist, tracknum):
+
+  try:
+    oggfile = ogg.vorbis.VorbisFile (filename)
+
+  except:
+    print "Sorry, no valid ogg-file"
+    return
+
+  c = {'ALBUM' : album,
+       'ARTIST': artist,
+       'GENRE' : category,
+       'TITLE' : title,
+       'TRACKNUMBER': "%s" % tracknum}
+  
+  comment = ogg.vorbis.VorbisComment ()
+  for (k, v) in c.items ():
+    if v is not None:
+      comment [k] = v
+
+  comment.write_to (filename)
+
+
+
+# =============================================================================
+# Self test code
+# =============================================================================
+
+if __name__ == '__main__':
+
+  title = 'Foo bar / Baz Bar shit'
+  print splitTitle (title), "\n"
+
+  title = 'Troy / James Horner'
+  print splitTitle (title), "\n"
+
+  title = 'Baz / Various'
+  print splitTitle (title), "\n"
+
+  title = 'Bazious'
+  print splitTitle (title), "\n"
+
+  title = 'Foo / Bar / Baz'
+  print splitTitle (title), "\n"
+
+  artist = 'John Williams'
+  print getArtistNames (artist)
+
+  artist = 'John F. Kennedy'
+  print getArtistNames (artist)
+
+  print "Encoding foo.wav"
+  res = ogg_encode ('foo.wav')
+  print "Res =", res
+
+  print "Encoding bar.wav"
+  res = ogg_encode ('bar.wav')
+  print "Res =", res

Deleted: gnue-cddb/schema/auth.gsd
===================================================================
--- gnue-cddb/schema/auth.gsd   2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/schema/auth.gsd   2004-12-02 14:36:52 UTC (rev 151)
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Schema definition created by GNUe Appserver's Schema Support. -->
-<!-- run this file through gnue-schema to create SQL scripts -->
-<schema author="Appserver SchemaSupport" title="Appserver Schema Dump"
-        version="1.0">
-  <tables>
-    <table name="gnue_useraccess">
-      <fields>
-        <field name="gnue_accesslist"
-               description="List of classes with access allowed" length="100" 
type="string"/>
-        <field name="gnue_id" description="Object ID" length="32" nullable="N"
-               type="string"/>
-        <field name="gnue_password" description="Password" length="70"
-               type="string"/>
-        <field name="gnue_username" description="Username" length="20"
-               nullable="N" type="string"/>
-      </fields>
-      <constraints/>
-      <indexes/>
-      <primarykey name="gnue_id_pk_gnue_useraccess">
-        <pkfield name="gnue_id"/>
-      </primarykey>
-    </table>
-  </tables>
-  <data>
-    <tabledata name="gnue_module_dump" tablename="gnue_module">
-      <definition>
-        <column field="gnue_comment" type="string(70)"/>
-        <column field="gnue_id" type="string(32)"/>
-        <column field="gnue_name" type="string(35)"/>
-      </definition>
-      <rows>
-        <row>
-          <value field="gnue_id" 
key="Y">00000000000000000000000000000000</value>
-          <value field="gnue_name">gnue</value>
-          <value field="gnue_comment">GNU Enterprise System Management</value>
-        </row>
-      </rows>
-    </tabledata>
-    <tabledata name="gnue_class_dump" tablename="gnue_class">
-      <definition>
-        <column field="gnue_comment" type="string(70)"/>
-        <column field="gnue_id" type="string(32)"/>
-        <column field="gnue_module" type="string(32)"/>
-        <column field="gnue_name" type="string(35)"/>
-      </definition>
-      <rows>
-        <row>
-          <value field="gnue_id" 
key="Y">00000000000000000000000000000060</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">useraccess</value>
-          <value field="gnue_comment">GNU Enterprise User 
Authentication</value>
-        </row>
-      </rows>
-    </tabledata>
-    <tabledata name="gnue_property_dump" tablename="gnue_property">
-      <definition>
-        <column field="gnue_class" type="string(32)"/>
-        <column field="gnue_comment" type="string(70)"/>
-        <column field="gnue_id" type="string(32)"/>
-        <column field="gnue_length" type="number(6)"/>
-        <column field="gnue_module" type="string(32)"/>
-        <column field="gnue_name" type="string(35)"/>
-        <column field="gnue_nullable" type="boolean"/>
-        <column field="gnue_scale" type="number(4)"/>
-        <column field="gnue_type" type="string(35)"/>
-      </definition>
-      <rows>
-        <row>
-          <value field="gnue_id" 
key="Y">00000000000000000000000000000064</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_class">00000000000000000000000000000060</value>
-          <value field="gnue_name">accesslist</value>
-          <value field="gnue_type">string</value>
-          <value field="gnue_length">100</value>
-          <value field="gnue_scale">0</value>
-          <value field="gnue_comment">List of classes with access 
allowed</value>
-          <value field="gnue_nullable">TRUE</value>
-        </row>
-        <row>
-          <value field="gnue_id">00000000000000000000000000000061</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_class">00000000000000000000000000000060</value>
-          <value field="gnue_name">id</value>
-          <value field="gnue_type">id</value>
-          <value field="gnue_length">0</value>
-          <value field="gnue_scale">0</value>
-          <value field="gnue_comment">Object ID</value>
-          <value field="gnue_nullable">FALSE</value>
-        </row>
-        <row>
-          <value field="gnue_id">00000000000000000000000000000063</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_class">00000000000000000000000000000060</value>
-          <value field="gnue_name">password</value>
-          <value field="gnue_type">string</value>
-          <value field="gnue_length">70</value>
-          <value field="gnue_scale">0</value>
-          <value field="gnue_comment">Password</value>
-          <value field="gnue_nullable">TRUE</value>
-        </row>
-        <row>
-          <value field="gnue_id">00000000000000000000000000000062</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_class">00000000000000000000000000000060</value>
-          <value field="gnue_name">username</value>
-          <value field="gnue_type">string</value>
-          <value field="gnue_length">20</value>
-          <value field="gnue_scale">0</value>
-          <value field="gnue_comment">Username</value>
-          <value field="gnue_nullable">FALSE</value>
-        </row>
-      </rows>
-    </tabledata>
-    <tabledata name="gnue_procedure_dump" tablename="gnue_procedure">
-      <definition>
-        <column field="gnue_class" type="string(32)"/>
-        <column field="gnue_code" type="string"/>
-        <column field="gnue_comment" type="string(70)"/>
-        <column field="gnue_compiledcode" type="string"/>
-        <column field="gnue_id" type="string(32)"/>
-        <column field="gnue_language" type="string(10)"/>
-        <column field="gnue_module" type="string(32)"/>
-        <column field="gnue_name" type="string(35)"/>
-      </definition>
-      <rows/>
-    </tabledata>
-    <tabledata name="sample_accounts" tablename="gnue_useraccess">
-      <definition>
-        <column field="gnue_id" type="string(32)"/>
-        <column field="gnue_username" type="string(20)"/>
-        <column field="gnue_password" type="string(70)"/>
-        <column field="gnue_accesslist" type="string(100)"/>
-      </definition>
-      <rows>
-        <row>
-          <value field="gnue_id" 
key="Y">00000000000000000000001000000001</value>
-          <value field="gnue_username">test</value>
-          <value field="gnue_password">test</value>
-          <value field="gnue_accesslist">address_person,address_country</value>
-        </row>
-        <row>
-          <value field="gnue_id">00000000000000000000001000000002</value>
-          <value field="gnue_username">hacker</value>
-          <value field="gnue_password">secret</value>
-          <value field="gnue_accesslist">all</value>
-        </row>
-      </rows>
-    </tabledata>
-  </data>
-</schema>

Deleted: gnue-cddb/schema/base.gsd
===================================================================
--- gnue-cddb/schema/base.gsd   2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/schema/base.gsd   2004-12-02 14:36:52 UTC (rev 151)
@@ -1,557 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Schema definition created by GNUe Appserver's Schema Support. 
-     Run this file through gnue-schema to create SQL scripts       -->
-<schema author="Appserver SchemaSupport" title="Appserver Schema Dump"
-        version="1.0">
-  <tables>
-    <table name="gnue_class">
-      <fields>
-        <field name="gnue_comment" description="Comment" length="70"
-               type="string"/>
-        <field name="gnue_id" description="Object ID" length="32" nullable="N"
-               type="string"/>
-        <field name="gnue_module" description="Module that defined this class"
-               length="32" nullable="N" type="string"/>
-        <field name="gnue_name" description="Classname without modulename"
-               length="35" nullable="N" type="string"/>
-      </fields>
-      <indexes/>
-      <constraints>
-        <constraint name="gnue_class_gnue_module_fk" type="foreignkey">
-          <constraintfield name="gnue_module"/>
-          <constraintref name="gnue_id" table="gnue_module"/>
-        </constraint>
-      </constraints>
-      <primarykey name="gnue_id_pk_gnue_class">
-        <pkfield name="gnue_id"/>
-      </primarykey>
-    </table>
-    <table name="gnue_module">
-      <fields>
-        <field name="gnue_comment" description="Comment" length="70"
-               type="string"/>
-        <field name="gnue_id" description="Object ID" length="32" nullable="N"
-               type="string"/>
-        <field name="gnue_name" description="Name" length="35" nullable="N"
-               type="string"/>
-      </fields>
-      <indexes/>
-      <constraints/>
-      <primarykey name="gnue_id_pk_gnue_module">
-        <pkfield name="gnue_id"/>
-      </primarykey>
-    </table>
-    <table name="gnue_parameter">
-      <fields>
-        <field name="gnue_comment" description="Comment" length="70"
-               type="string"/>
-        <field name="gnue_id" description="Object ID" length="32" nullable="N"
-               type="string"/>
-        <field name="gnue_length" description="Lenght of the parameter"
-               length="6" type="number"/>
-        <field name="gnue_name" description="Name of the parameter"
-               length="35" nullable="N" type="string"/>
-        <field name="gnue_procedure"
-               description="Procedure the parameter belongs to" length="32" 
nullable="N" type="string"/>
-        <field name="gnue_scale" description="Scale of numeric data"
-               length="4" type="number"/>
-        <field name="gnue_type" description="Parameter type" length="35"
-               nullable="N" type="string"/>
-      </fields>
-      <indexes/>
-      <constraints>
-        <constraint name="gnue_parameter_gnue_procedure_fk" type="foreignkey">
-          <constraintfield name="gnue_procedure"/>
-          <constraintref name="gnue_id" table="gnue_procedure"/>
-        </constraint>
-      </constraints>
-      <primarykey name="gnue_id_pk_gnue_parameter">
-        <pkfield name="gnue_id"/>
-      </primarykey>
-    </table>
-    <table name="gnue_procedure">
-      <fields>
-        <field name="gnue_class" description="Class the procedure belongs to"
-               length="32" nullable="N" type="string"/>
-        <field name="gnue_code" description="Procedure code" nullable="N"
-               type="string"/>
-        <field name="gnue_comment" description="Comment" length="70"
-               type="string"/>
-        <field name="gnue_compiledcode" description="Compiled procedure code"
-               type="string"/>
-        <field name="gnue_id" description="Object ID" length="32" nullable="N"
-               type="string"/>
-        <field name="gnue_language" description="Procedure language"
-               length="10" nullable="N" type="string"/>
-        <field name="gnue_length"
-               description="Length of the procedures result" length="6" 
type="number"/>
-        <field name="gnue_module"
-               description="Module that defined this procedure" length="32" 
nullable="N" type="string"/>
-        <field name="gnue_name" description="Procedurename without modulename"
-               length="35" nullable="N" type="string"/>
-        <field name="gnue_nullable"
-               description="Result of the procedure can contain NULL values" 
nullable="N" type="boolean"/>
-        <field name="gnue_scale" description="Scale of the procedures result"
-               length="4" type="number"/>
-        <field name="gnue_type" description="Type of the procedures result"
-               length="35" type="string"/>
-      </fields>
-      <indexes/>
-      <constraints>
-        <constraint name="gnue_procedure_gnue_class_fk" type="foreignkey">
-          <constraintfield name="gnue_class"/>
-          <constraintref name="gnue_id" table="gnue_class"/>
-        </constraint>
-        <constraint name="gnue_procedure_gnue_module_fk" type="foreignkey">
-          <constraintfield name="gnue_module"/>
-          <constraintref name="gnue_id" table="gnue_module"/>
-        </constraint>
-      </constraints>
-      <primarykey name="gnue_id_pk_gnue_procedure">
-        <pkfield name="gnue_id"/>
-      </primarykey>
-    </table>
-    <table name="gnue_property">
-      <fields>
-        <field name="gnue_class" description="Class the property belongs to"
-               length="32" nullable="N" type="string"/>
-        <field name="gnue_comment" description="Comment" length="70"
-               type="string"/>
-        <field name="gnue_id" description="Object ID" length="32" nullable="N"
-               type="string"/>
-        <field name="gnue_length" description="Lenght of the property"
-               length="6" type="number"/>
-        <field name="gnue_module"
-               description="Module that defined this property" length="32" 
nullable="N" type="string"/>
-        <field name="gnue_name" description="Propertyname without modulename"
-               length="35" nullable="N" type="string"/>
-        <field name="gnue_nullable"
-               description="Property can contain NULL values" nullable="N" 
type="boolean"/>
-        <field name="gnue_scale" description="Scale of numeric data"
-               length="4" type="number"/>
-        <field name="gnue_type" description="Property type" length="35"
-               nullable="N" type="string"/>
-      </fields>
-      <indexes/>
-      <constraints>
-        <constraint name="gnue_property_gnue_class_fk" type="foreignkey">
-          <constraintfield name="gnue_class"/>
-          <constraintref name="gnue_id" table="gnue_class"/>
-        </constraint>
-        <constraint name="gnue_property_gnue_module_fk" type="foreignkey">
-          <constraintfield name="gnue_module"/>
-          <constraintref name="gnue_id" table="gnue_module"/>
-        </constraint>
-      </constraints>
-      <primarykey name="gnue_id_pk_gnue_property">
-        <pkfield name="gnue_id"/>
-      </primarykey>
-    </table>
-  </tables>
-  <data>
-    <tabledata name="gnue_module_dump" tablename="gnue_module">
-      <definition>
-        <column field="gnue_comment" type="string(70)"/>
-        <column field="gnue_id" type="string(32)"/>
-        <column field="gnue_name" type="string(35)"/>
-      </definition>
-      <rows>
-        <row>
-          <value field="gnue_comment">GNU Enterprise System Management</value>
-          <value field="gnue_id">00000000000000000000000000000000</value>
-          <value field="gnue_name">gnue</value>
-        </row>
-      </rows>
-    </tabledata>
-    <tabledata name="gnue_class_dump" tablename="gnue_class">
-      <definition>
-        <column field="gnue_comment" type="string(70)"/>
-        <column field="gnue_id" type="string(32)"/>
-        <column field="gnue_module" type="string(32)"/>
-        <column field="gnue_name" type="string(35)"/>
-      </definition>
-      <rows>
-        <row>
-          <value field="gnue_comment">GNU Enterprise Business Object 
Class</value>
-          <value field="gnue_id">00000000000000000000000000000020</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">class</value>
-        </row>
-        <row>
-          <value field="gnue_comment">GNU Enterprise Business Object 
Module</value>
-          <value field="gnue_id">00000000000000000000000000000010</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">module</value>
-        </row>
-        <row>
-          <value field="gnue_comment">GNU Enterprise Business Object Procedure 
Parameter</value>
-          <value field="gnue_id">00000000000000000000000000000050</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">parameter</value>
-        </row>
-        <row>
-          <value field="gnue_comment">GNU Enterprise Business Object 
Procedure</value>
-          <value field="gnue_id">00000000000000000000000000000040</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">procedure</value>
-        </row>
-        <row>
-          <value field="gnue_comment">GNU Enterprise Business Object 
Property</value>
-          <value field="gnue_id">00000000000000000000000000000030</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">property</value>
-        </row>
-      </rows>
-    </tabledata>
-    <tabledata name="gnue_property_dump" tablename="gnue_property">
-      <definition>
-        <column field="gnue_class" type="string(32)"/>
-        <column field="gnue_comment" type="string(70)"/>
-        <column field="gnue_id" type="string(32)"/>
-        <column field="gnue_length" type="number(6)"/>
-        <column field="gnue_module" type="string(32)"/>
-        <column field="gnue_name" type="string(35)"/>
-        <column field="gnue_nullable" type="boolean"/>
-        <column field="gnue_scale" type="number(4)"/>
-        <column field="gnue_type" type="string(35)"/>
-      </definition>
-      <rows>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000020</value>
-          <value field="gnue_comment">Comment</value>
-          <value field="gnue_id">00000000000000000000000000000024</value>
-          <value field="gnue_length">70</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">comment</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000020</value>
-          <value field="gnue_comment">Object ID</value>
-          <value field="gnue_id">00000000000000000000000000000021</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">id</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">id</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000020</value>
-          <value field="gnue_comment">Module that defined this class</value>
-          <value field="gnue_id">00000000000000000000000000000022</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">module</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">gnue_module</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000020</value>
-          <value field="gnue_comment">Classname without modulename</value>
-          <value field="gnue_id">00000000000000000000000000000023</value>
-          <value field="gnue_length">35</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">name</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000010</value>
-          <value field="gnue_comment">Comment</value>
-          <value field="gnue_id">00000000000000000000000000000013</value>
-          <value field="gnue_length">70</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">comment</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000010</value>
-          <value field="gnue_comment">Object ID</value>
-          <value field="gnue_id">00000000000000000000000000000011</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">id</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">id</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000010</value>
-          <value field="gnue_comment">Name</value>
-          <value field="gnue_id">00000000000000000000000000000012</value>
-          <value field="gnue_length">35</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">name</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000050</value>
-          <value field="gnue_comment">Comment</value>
-          <value field="gnue_id">00000000000000000000000000000057</value>
-          <value field="gnue_length">70</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">comment</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000050</value>
-          <value field="gnue_comment">Object ID</value>
-          <value field="gnue_id">00000000000000000000000000000051</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">id</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">id</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000050</value>
-          <value field="gnue_comment">Lenght of the parameter</value>
-          <value field="gnue_id">00000000000000000000000000000055</value>
-          <value field="gnue_length">6</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">length</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">number</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000050</value>
-          <value field="gnue_comment">Name of the parameter</value>
-          <value field="gnue_id">00000000000000000000000000000053</value>
-          <value field="gnue_length">35</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">name</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000050</value>
-          <value field="gnue_comment">Procedure the parameter belongs 
to</value>
-          <value field="gnue_id">00000000000000000000000000000052</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">procedure</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">gnue_procedure</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000050</value>
-          <value field="gnue_comment">Scale of numeric data</value>
-          <value field="gnue_id">00000000000000000000000000000056</value>
-          <value field="gnue_length">4</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">scale</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">number</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000050</value>
-          <value field="gnue_comment">Parameter type</value>
-          <value field="gnue_id">00000000000000000000000000000054</value>
-          <value field="gnue_length">35</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">type</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Class the procedure belongs to</value>
-          <value field="gnue_id">00000000000000000000000000000042</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">class</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">gnue_class</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Procedure code</value>
-          <value field="gnue_id">00000000000000000000000000000046</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">code</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Comment</value>
-          <value field="gnue_id">00000000000000000000000000000048</value>
-          <value field="gnue_length">70</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">comment</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Compiled procedure code</value>
-          <value field="gnue_id">00000000000000000000000000000047</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">compiledcode</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Object ID</value>
-          <value field="gnue_id">00000000000000000000000000000041</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">id</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">id</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Procedure language</value>
-          <value field="gnue_id">00000000000000000000000000000045</value>
-          <value field="gnue_length">10</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">language</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Length of the procedures result</value>
-          <value field="gnue_id">0000000000000000000000000000004A</value>
-          <value field="gnue_length">6</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">length</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">number</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Module that defined this 
procedure</value>
-          <value field="gnue_id">00000000000000000000000000000043</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">module</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">gnue_module</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Procedurename without modulename</value>
-          <value field="gnue_id">00000000000000000000000000000044</value>
-          <value field="gnue_length">35</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">name</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Result of the procedure can contain NULL 
values</value>
-          <value field="gnue_id">0000000000000000000000000000004C</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">nullable</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">boolean</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Scale of the procedures result</value>
-          <value field="gnue_id">0000000000000000000000000000004B</value>
-          <value field="gnue_length">4</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">scale</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">number</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000040</value>
-          <value field="gnue_comment">Type of the procedures result</value>
-          <value field="gnue_id">00000000000000000000000000000049</value>
-          <value field="gnue_length">35</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">type</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000030</value>
-          <value field="gnue_comment">Class the property belongs to</value>
-          <value field="gnue_id">00000000000000000000000000000032</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">class</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">gnue_class</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000030</value>
-          <value field="gnue_comment">Comment</value>
-          <value field="gnue_id">00000000000000000000000000000038</value>
-          <value field="gnue_length">70</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">comment</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000030</value>
-          <value field="gnue_comment">Object ID</value>
-          <value field="gnue_id">00000000000000000000000000000031</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">id</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">id</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000030</value>
-          <value field="gnue_comment">Lenght of the property</value>
-          <value field="gnue_id">00000000000000000000000000000036</value>
-          <value field="gnue_length">6</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">length</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">number</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000030</value>
-          <value field="gnue_comment">Module that defined this property</value>
-          <value field="gnue_id">00000000000000000000000000000033</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">module</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">gnue_module</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000030</value>
-          <value field="gnue_comment">Propertyname without modulename</value>
-          <value field="gnue_id">00000000000000000000000000000034</value>
-          <value field="gnue_length">35</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">name</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">string</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000030</value>
-          <value field="gnue_comment">Property can contain NULL values</value>
-          <value field="gnue_id">00000000000000000000000000000039</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">nullable</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">boolean</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000030</value>
-          <value field="gnue_comment">Scale of numeric data</value>
-          <value field="gnue_id">00000000000000000000000000000037</value>
-          <value field="gnue_length">4</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">scale</value>
-          <value field="gnue_nullable">TRUE</value>
-          <value field="gnue_type">number</value>
-        </row>
-        <row>
-          <value field="gnue_class">00000000000000000000000000000030</value>
-          <value field="gnue_comment">Property type</value>
-          <value field="gnue_id">00000000000000000000000000000035</value>
-          <value field="gnue_length">35</value>
-          <value field="gnue_module">00000000000000000000000000000000</value>
-          <value field="gnue_name">type</value>
-          <value field="gnue_nullable">FALSE</value>
-          <value field="gnue_type">string</value>
-        </row>
-      </rows>
-    </tabledata>
-  </data>
-</schema>

Added: gnue-cddb/schema/cddb-C.gld
===================================================================
--- gnue-cddb/schema/cddb-C.gld 2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/schema/cddb-C.gld 2004-12-02 14:36:52 UTC (rev 151)
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- CD Database - Standard Language Definitions
+
+     Copyright 2004 Free Software Foundation
+
+     This file is part of GNU Enterprise.
+
+     GNU Enterprise is free software; you can redistribute it and/or
+     modify it under the terms of the GNU General Public License as
+     published by the Free Software Foundation; either version 2 of
+     the License, or (at your option) any later version.
+
+     GNU Enterprise is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNU Enterprise; see the file COPYING.  If not, write to
+     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+
+     $Id$ -->
+
+<module name="cddb" language="C" >
+
+  <class name="artist" label="Artist" >
+    <property name="firstname"  pos="100" label="First name"/>
+    <property name="middlename" pos="200" label="Middle name"/>
+    <property name="lastname"   pos="300" label="Last name"/>
+    <property name="name"       pos="400" label="Name" search="100" />
+    <property name="matchcode"  pos="500" label="Matchcode" />
+  </class>
+
+  <class name="category" label="Category">
+    <property name="name"           pos="100" label="Name" search="100" />
+    <property name="matchcode"      pos="200" label="Matchcode" />
+    <property name="id3"            pos="300" label="ID3-Genre-ID" />
+    <property name="filedb_pattern" pos="400" label="Path-Pattern"
+      page="Cddb" />
+  </class>
+
+  <class name="disc" label="Disc">
+    <property name="title"    pos="100" label="Title"   search="100" />
+    <property name="artist"   pos="200" label="Artist" />
+    <property name="category" pos="300" label="Category" />
+    <property name="discid"   pos="400" label="Disc-Id" search="200" />
+    <property name="year"     pos="500" label="Year" />
+    <property name="comment"  pos="600" label="Comment" />
+    <property name="length"   pos="700" label="Length" />
+  </class>
+
+
+  <class name="track" label="Track">
+    <property name="disc"    pos="100" label="Disc" />
+    <property name="track"   pos="200" label="Track" search="100" />
+    <property name="title"   pos="300" label="Title" search="200" />
+    <property name="artist"  pos="400" label="Artist" />
+    <property name="length"  pos="500" label="Length" />
+    <property name="comment" pos="600" label="Comment" />
+  </class>
+
+  <class name="options" label="Options">
+    <property name="basepath" pos="300" label="Base path" />
+  </class>
+
+</module>


Property changes on: gnue-cddb/schema/cddb-C.gld
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: gnue-cddb/schema/cddb.gcd
===================================================================
--- gnue-cddb/schema/cddb.gcd   2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/schema/cddb.gcd   2004-12-02 14:36:52 UTC (rev 151)
@@ -1,60 +1,129 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
+<!-- CD Database Module
+
+     Copyright 2004 Free Software Foundation
+
+     This file is part of GNU Enterprise.
+
+     GNU Enterprise is free software; you can redistribute it and/or
+     modify it under the terms of the GNU General Public License as
+     published by the Free Software Foundation; either version 2 of
+     the License, or (at your option) any later version.
+
+     GNU Enterprise is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNU Enterprise; see the file COPYING.  If not, write to
+     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+
+     $Id$ -->
+
 <module name="cddb" comment="CD Database">
+
+  <!-- ================================================================= -->
+  <!-- cddb_artist                                                       -->
+  <!-- ================================================================= -->
+
   <class name="artist" comment="Artists">
-    <property name="name" type="string(30)" nullable="N"/>
+    <property name="firstname"  type="string(30)" />
+    <property name="middlename" type="string(30)" />
+    <property name="lastname"   type="string(30)" nullable="False" />
+
+    <property name="name"       type="string(100)">
+      import re
+      result = re.sub ('\s+', ' ', "%s %s %s" % \
+          (self.lastname or '', self.middlename or '', self.firstname or ''))
+      return result.strip ()
+    </property>
+
+    <property name="matchcode"  type="string(100)">
+      return self.name.upper ()
+    </property>
   </class>
 
+
+  <!-- ================================================================= -->
+  <!-- cddb_category                                                     -->
+  <!-- ================================================================= -->
+
   <class name="category" comment="Category/Genre">
-    <property name="id" type="number(3)" comment="ID3-Genre-ID" nullable="N"/>
-    <property name="name" type="string(30)" comment="Name of the genre"
-      nullable="N"/>
-    <property name="matchcode" type="string(30)" 
-      comment="Matchcode of the category" nullable="N"/>
+    <property name="name"      type="string(30)" nullable="False" />
+    <property name="matchcode" type="string(30)" nullable="False" />
+
+    <property name="id3"       type="number(3)"  nullable="False"
+      comment="ID3-Genre-ID" />
   </class>
 
+
+  <!-- ================================================================= -->
+  <!-- cddb_disc                                                         -->
+  <!-- ================================================================= -->
+
   <class name="disc" comment="Disc">
-    <property name="title" type="string(60)" nullable="N" 
-      comment="Title of the disc"/>
-    <property name="artist" type="cddb_artist" comment="Artist of the disc"/>
-    <property name="category" type="cddb_category" 
-      comment="Category of the disc"/>
-    <property name="year" type="number(4)" comment="Year of the recording"/>
-    <property name="discid" type="string(8)" comment="CDDB-Disc-Id (hex)"
-      nullable="N"/>
-    <property name="comment" type="string(70)" comment="Comment"/>
+    <property name="title"    type="string(60)" nullable="False" />
+    <property name="artist"   type="cddb_artist" />
+    <property name="category" type="cddb_category" />
+    <property name="year"     type="number(4)" comment="Year of the 
recording"/>
+    <property name="comment"  type="string(70)" />
+    <property name="discid"   type="string(8)" nullable="False"
+      comment="CDDB-Disc-Id (hex)" />
 
-    <property name="length" type="number(4)"
-      comment="Length of the disc in seconds">
-      <![CDATA[
-      cond = ['eq', ['field', 'cddb_disc'], ['const', self.gnue_id]]
-      tracks = find ('cddb_track', cond, [], ['cddb_length'])
-      res = 0
+    <property name="seconds"  type="number(5)" />
+    <property name="length" type="time" comment="Length of the disc">
+      import mx.DateTime
+      tracks = session.find ('cddb_track', {'cddb_disc': self.gnue_id}, [],
+                             ['cddb_length'])
+
+      result = [mx.DateTime.Time (0, 0, 0)]
+
       for track in tracks:
         if track.cddb_length is not None:
-          res += track.cddb_length
+          l = track.cddb_length
+          result.append (mx.DateTime.Time (l.hour, l.minute, l.second))
 
-      return res
-      ]]>
+      return sum (result)
     </property>
+
+
+
+    <!-- ############################################################## -->
+    <!-- Triggers in cddb_disc                                          -->
+    <!-- ############################################################## -->
+
+    <procedure name="OnDelete">
+      <!-- If a disc get's deleted, make sure to remove all tracks too  -->
+      tracks = session.find ('cddb_track', {'cddb_disc': self.gnue_id}, [], [])
+      for item in tracks:
+        item.delete ()
+    </procedure>
   </class>
 
+
+  <!-- ================================================================= -->
+  <!-- cddb_track                                                        -->
+  <!-- ================================================================= -->
+
   <class name="track" comment="Tracks of a disc">
-    <property name="disc" type="cddb_disc" nullable="N" 
-      comment="Disc this track is from"/>
-    <property name="track" type="number(3)" nullable="N" 
-      comment="Number of the track on the disc"/>
-    <property name="title" type="string(60)" nullable="N" 
-      comment="Title of the track"/>
-    <property name="artist" type="cddb_artist" comment="Artist of the track"/>
-    <property name="length" type="number(4)" 
-      comment="Length of the track in seconds"/>
-    <property name="comment" type="string(28)" comment="Comment on the track"/>
+    <property name="disc"    type="cddb_disc"  nullable="False" />
+    <property name="track"   type="number(3)"  nullable="False" />
+    <property name="title"   type="string(60)" nullable="False" />
+    <property name="artist"  type="cddb_artist" />
+    <property name="length"  type="time" />
+    <property name="comment" type="string(28)" />
   </class>
 
+
+  <!-- ================================================================= -->
+  <!-- cddb_options                                                      -->
+  <!-- ================================================================= -->
+
   <class name="options">
-    <property name="ripcmd" type="string(80)"/>
-    <property name="enccmd" type="string(80)"/>
-    <property name="basepath" type="string(250)"/>
+    <property name="basepath" type="string(250)" />
   </class>
+
 </module>


Property changes on: gnue-cddb/schema/cddb.gcd
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: gnue-cddb/schema/filedb.gcd
===================================================================
--- gnue-cddb/schema/filedb.gcd 2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/schema/filedb.gcd 2004-12-02 14:36:52 UTC (rev 151)
@@ -1,29 +1,77 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
+<!-- File Database Module
+
+     Copyright 2004 Free Software Foundation
+
+     This file is part of GNU Enterprise.
+
+     GNU Enterprise is free software; you can redistribute it and/or
+     modify it under the terms of the GNU General Public License as
+     published by the Free Software Foundation; either version 2 of
+     the License, or (at your option) any later version.
+
+     GNU Enterprise is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+     GNU General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNU Enterprise; see the file COPYING.  If not, write to
+     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+
+     $Id$ -->
+
 <module name="filedb" comment="CD Database in the filesystem">
+
+  <!-- ================================================================= -->
+  <!-- cddb_category                                                     -->
+  <!-- ================================================================= -->
+
+  <class module="cddb" name="category">
+    <property name="pattern" type="string(250)" />
+  </class>
+
+
+  <!-- ================================================================= -->
+  <!-- cddb_disc                                                         -->
+  <!-- ================================================================= -->
+
   <class name="disc" module="cddb">
-    <property name="url" type="string" comment="Base dir of the disc">
+    <property name="url" type="string(250)" />
+
+    <procedure name="defaultURL" type="string" >
       from os import path, environ
-      opt = find ('cddb_options', [], [], ['cddb_basepath'])
-      basepath = len (opt) and opt [0].cddb_basepath or environ ['HOME'] 
-      basepath = path.normpath (basepath)
+      opt = session.find ('cddb_options', [], [], ['cddb_basepath'])
+      default = opt and opt [0].cddb_basepath or environ ['HOME']
 
-      category = self.cddb_category.cddb_name
-      artist   = self.cddb_artist.cddb_name
-      title    = self.cddb_title
-
-      if self.cddb_category.cddb_matchcode == 'soundtrack':
-        discPath = path.join (basepath, category, title)
+      if self.cddb_category:
+        pattern   = self.cddb_category.filedb_pattern or default
+        category  = self.cddb_category.cddb_name
+        matchcode = self.cddb_category.cddb_matchcode
       else:
-        discPath = path.join (basepath, category, artist, title)
+        pattern   = default
+        category  = 'Unknown'
+        matchcode = 'unknown'
 
-      return discPath.replace (' ', '_')
-    </property>
+      artist = self.cddb_artist and self.cddb_artist.cddb_name or 'Various'
+      title  = self.cddb_title or 'Unknown'
+
+      reps = {'%a': artist, '%t': title, '%c': category, '%m': matchcode}
+
+      for (item, value) in reps.items ():
+        if item in pattern:
+          pattern = pattern.replace (item, value)
+
+      return pattern.replace (' ', '_')
+    </procedure>
   </class>
 
   <class name="track" module="cddb">
     <property name="url" type="string(254)" 
       comment="location where the track can be found"/>
+
     <property name="ripdate" type="date" 
       comment="Date when this track has been ripped"/>
   </class>


Property changes on: gnue-cddb/schema/filedb.gcd
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: gnue-cddb/schema/gen.gsd
===================================================================
--- gnue-cddb/schema/gen.gsd    2004-12-02 13:55:01 UTC (rev 150)
+++ gnue-cddb/schema/gen.gsd    2004-12-02 14:36:52 UTC (rev 151)
@@ -3,899 +3,899 @@
   <data>
     <tabledata name="cddb_category" tablename="cddb_category">
       <definition>
-        <column field="gnue_id" type="string"/>
+        <column field="gnue_id" type="string" key="Y"/>
         <column field="cddb_name" type="string"/>
         <column field="cddb_matchcode" type="string"/>
-        <column field="cddb_id" type="number(3)"/>
+        <column field="cddb_id3" type="number(3)"/>
       </definition>
       <rows>
          <row>
-           <value field="gnue_id" 
key="Y">66701866162529911928725201445908</value>
+           <value field="gnue_id">66701866162529911928725201445908</value>
            <value field="cddb_name">Blues</value>
            <value field="cddb_matchcode">blues</value>
-           <value field="cddb_id">0</value>
+           <value field="cddb_id3">0</value>
          </row>
          <row>
            <value field="gnue_id">00218526255349161424646652034701</value>
            <value field="cddb_name">Classic Rock</value>
            <value field="cddb_matchcode">classic rock</value>
-           <value field="cddb_id">1</value>
+           <value field="cddb_id3">1</value>
          </row>
          <row>
            <value field="gnue_id">35765124130626636119738674886283</value>
            <value field="cddb_name">Country</value>
            <value field="cddb_matchcode">country</value>
-           <value field="cddb_id">2</value>
+           <value field="cddb_id3">2</value>
          </row>
          <row>
            <value field="gnue_id">81276407449117225734881052379489</value>
            <value field="cddb_name">Dance</value>
            <value field="cddb_matchcode">dance</value>
-           <value field="cddb_id">3</value>
+           <value field="cddb_id3">3</value>
          </row>
          <row>
            <value field="gnue_id">40617821044142761915776991535674</value>
            <value field="cddb_name">Disco</value>
            <value field="cddb_matchcode">disco</value>
-           <value field="cddb_id">4</value>
+           <value field="cddb_id3">4</value>
          </row>
          <row>
            <value field="gnue_id">52058749571386082714885708618681</value>
            <value field="cddb_name">Funk</value>
            <value field="cddb_matchcode">funk</value>
-           <value field="cddb_id">5</value>
+           <value field="cddb_id3">5</value>
          </row>
          <row>
            <value field="gnue_id">76361996279967140679858636794335</value>
            <value field="cddb_name">Grunge</value>
            <value field="cddb_matchcode">grunge</value>
-           <value field="cddb_id">6</value>
+           <value field="cddb_id3">6</value>
          </row>
          <row>
            <value field="gnue_id">34940971625955962005215891603019</value>
            <value field="cddb_name">Hip-Hop</value>
            <value field="cddb_matchcode">hip-hop</value>
-           <value field="cddb_id">7</value>
+           <value field="cddb_id3">7</value>
          </row>
          <row>
            <value field="gnue_id">77366474092568650154415024362175</value>
            <value field="cddb_name">Jazz</value>
            <value field="cddb_matchcode">jazz</value>
-           <value field="cddb_id">8</value>
+           <value field="cddb_id3">8</value>
          </row>
          <row>
            <value field="gnue_id">96901223117082517024400665401032</value>
            <value field="cddb_name">Metal</value>
            <value field="cddb_matchcode">metal</value>
-           <value field="cddb_id">9</value>
+           <value field="cddb_id3">9</value>
          </row>
          <row>
            <value field="gnue_id">90335976249381425215540963031148</value>
            <value field="cddb_name">New Age</value>
            <value field="cddb_matchcode">newage</value>
-           <value field="cddb_id">10</value>
+           <value field="cddb_id3">10</value>
          </row>
          <row>
            <value field="gnue_id">29085334926763595781149645474921</value>
            <value field="cddb_name">Oldies</value>
            <value field="cddb_matchcode">oldies</value>
-           <value field="cddb_id">11</value>
+           <value field="cddb_id3">11</value>
          </row>
          <row>
            <value field="gnue_id">33644200081232766128504476940826</value>
            <value field="cddb_name">Other</value>
            <value field="cddb_matchcode">misc</value>
-           <value field="cddb_id">12</value>
+           <value field="cddb_id3">12</value>
          </row>
          <row>
            <value field="gnue_id">79751860849835125979684421095295</value>
            <value field="cddb_name">Pop</value>
            <value field="cddb_matchcode">pop</value>
-           <value field="cddb_id">13</value>
+           <value field="cddb_id3">13</value>
          </row>
          <row>
            <value field="gnue_id">59960660020899644352013251911231</value>
            <value field="cddb_name">R &amp; B</value>
            <value field="cddb_matchcode">r &amp; b</value>
-           <value field="cddb_id">14</value>
+           <value field="cddb_id3">14</value>
          </row>
          <row>
            <value field="gnue_id">91700082290071534136065428088871</value>
            <value field="cddb_name">Rap</value>
            <value field="cddb_matchcode">rap</value>
-           <value field="cddb_id">15</value>
+           <value field="cddb_id3">15</value>
          </row>
          <row>
            <value field="gnue_id">95221275641236371662120424246556</value>
            <value field="cddb_name">Reggea</value>
            <value field="cddb_matchcode">reggea</value>
-           <value field="cddb_id">16</value>
+           <value field="cddb_id3">16</value>
          </row>
          <row>
            <value field="gnue_id">10215867214258687425685630124939</value>
            <value field="cddb_name">Rock</value>
            <value field="cddb_matchcode">rock</value>
-           <value field="cddb_id">17</value>
+           <value field="cddb_id3">17</value>
          </row>
          <row>
            <value field="gnue_id">22660823988001403664484933334615</value>
            <value field="cddb_name">Techno</value>
            <value field="cddb_matchcode">techno</value>
-           <value field="cddb_id">18</value>
+           <value field="cddb_id3">18</value>
          </row>
          <row>
            <value field="gnue_id">40167531571821501287448705768026</value>
            <value field="cddb_name">Industrial</value>
            <value field="cddb_matchcode">industrial</value>
-           <value field="cddb_id">19</value>
+           <value field="cddb_id3">19</value>
          </row>
          <row>
            <value field="gnue_id">89285049801313761427318659151302</value>
            <value field="cddb_name">Alternative</value>
            <value field="cddb_matchcode">alternative</value>
-           <value field="cddb_id">20</value>
+           <value field="cddb_id3">20</value>
          </row>
          <row>
            <value field="gnue_id">83875436357139389972565153538127</value>
            <value field="cddb_name">Ska</value>
            <value field="cddb_matchcode">ska</value>
-           <value field="cddb_id">21</value>
+           <value field="cddb_id3">21</value>
          </row>
          <row>
            <value field="gnue_id">11220442361881550085985618493603</value>
            <value field="cddb_name">Death Metal</value>
            <value field="cddb_matchcode">death metal</value>
-           <value field="cddb_id">22</value>
+           <value field="cddb_id3">22</value>
          </row>
          <row>
            <value field="gnue_id">44290396337211915772457802687764</value>
            <value field="cddb_name">Pranks</value>
            <value field="cddb_matchcode">pranks</value>
-           <value field="cddb_id">23</value>
+           <value field="cddb_id3">23</value>
          </row>
          <row>
            <value field="gnue_id">95100737118440617119068250963228</value>
            <value field="cddb_name">Soundtrack</value>
            <value field="cddb_matchcode">soundtrack</value>
-           <value field="cddb_id">24</value>
+           <value field="cddb_id3">24</value>
          </row>
          <row>
            <value field="gnue_id">17785417424876986843449621388194</value>
            <value field="cddb_name">Euro-Techno</value>
            <value field="cddb_matchcode">euro-techno</value>
-           <value field="cddb_id">25</value>
+           <value field="cddb_id3">25</value>
          </row>
          <row>
            <value field="gnue_id">28213764694219247509976246936588</value>
            <value field="cddb_name">Ambient</value>
            <value field="cddb_matchcode">ambient</value>
-           <value field="cddb_id">26</value>
+           <value field="cddb_id3">26</value>
          </row>
          <row>
            <value field="gnue_id">86439617551457781076943395364402</value>
            <value field="cddb_name">Trip-Hop</value>
            <value field="cddb_matchcode">trip-hop</value>
-           <value field="cddb_id">27</value>
+           <value field="cddb_id3">27</value>
          </row>
          <row>
            <value field="gnue_id">07871356297905626318433262085438</value>
            <value field="cddb_name">Vocal</value>
            <value field="cddb_matchcode">vocal</value>
-           <value field="cddb_id">28</value>
+           <value field="cddb_id3">28</value>
          </row>
          <row>
            <value field="gnue_id">78841042548415367589855954726433</value>
            <value field="cddb_name">Jazz+Funk</value>
            <value field="cddb_matchcode">jazz+funk</value>
-           <value field="cddb_id">29</value>
+           <value field="cddb_id3">29</value>
          </row>
          <row>
            <value field="gnue_id">44109730557254851684921622613068</value>
            <value field="cddb_name">Fusion</value>
            <value field="cddb_matchcode">fusion</value>
-           <value field="cddb_id">30</value>
+           <value field="cddb_id3">30</value>
          </row>
          <row>
            <value field="gnue_id">02686943600137307369951295736875</value>
            <value field="cddb_name">Trance</value>
            <value field="cddb_matchcode">trance</value>
-           <value field="cddb_id">31</value>
+           <value field="cddb_id3">31</value>
          </row>
          <row>
            <value field="gnue_id">58029714176699050813566230485317</value>
            <value field="cddb_name">Classical</value>
            <value field="cddb_matchcode">classical</value>
-           <value field="cddb_id">32</value>
+           <value field="cddb_id3">32</value>
          </row>
          <row>
            <value field="gnue_id">29812540319085453469966223142305</value>
            <value field="cddb_name">Instrumental</value>
            <value field="cddb_matchcode">instrumental</value>
-           <value field="cddb_id">33</value>
+           <value field="cddb_id3">33</value>
          </row>
          <row>
            <value field="gnue_id">27568702327474131529228658180411</value>
            <value field="cddb_name">Acid</value>
            <value field="cddb_matchcode">acid</value>
-           <value field="cddb_id">34</value>
+           <value field="cddb_id3">34</value>
          </row>
          <row>
            <value field="gnue_id">43970929206191803128779680454997</value>
            <value field="cddb_name">House</value>
            <value field="cddb_matchcode">house</value>
-           <value field="cddb_id">35</value>
+           <value field="cddb_id3">35</value>
          </row>
          <row>
            <value field="gnue_id">37702681000521283100050892189287</value>
            <value field="cddb_name">Game</value>
            <value field="cddb_matchcode">game</value>
-           <value field="cddb_id">36</value>
+           <value field="cddb_id3">36</value>
          </row>
          <row>
            <value field="gnue_id">95911720659292655925869556323755</value>
            <value field="cddb_name">Sound Clip</value>
            <value field="cddb_matchcode">sound clip</value>
-           <value field="cddb_id">37</value>
+           <value field="cddb_id3">37</value>
          </row>
          <row>
            <value field="gnue_id">42592318770541561780719561000648</value>
            <value field="cddb_name">Gospel</value>
            <value field="cddb_matchcode">gospel</value>
-           <value field="cddb_id">38</value>
+           <value field="cddb_id3">38</value>
          </row>
          <row>
            <value field="gnue_id">29589953054634694104173066597473</value>
            <value field="cddb_name">Noise</value>
            <value field="cddb_matchcode">noise</value>
-           <value field="cddb_id">39</value>
+           <value field="cddb_id3">39</value>
          </row>
          <row>
            <value field="gnue_id">20592838984603503210087320071803</value>
            <value field="cddb_name">Alt. Rock</value>
            <value field="cddb_matchcode">alt. rock</value>
-           <value field="cddb_id">40</value>
+           <value field="cddb_id3">40</value>
          </row>
          <row>
            <value field="gnue_id">48757509453564626473763128907241</value>
            <value field="cddb_name">Bass</value>
            <value field="cddb_matchcode">bass</value>
-           <value field="cddb_id">41</value>
+           <value field="cddb_id3">41</value>
          </row>
          <row>
            <value field="gnue_id">04919185963943906109925801278230</value>
            <value field="cddb_name">Soul</value>
            <value field="cddb_matchcode">soul</value>
-           <value field="cddb_id">42</value>
+           <value field="cddb_id3">42</value>
          </row>
          <row>
            <value field="gnue_id">73927086405639579940901558470711</value>
            <value field="cddb_name">Punk</value>
            <value field="cddb_matchcode">punk</value>
-           <value field="cddb_id">43</value>
+           <value field="cddb_id3">43</value>
          </row>
          <row>
            <value field="gnue_id">91433799844331669775531486844441</value>
            <value field="cddb_name">Space</value>
            <value field="cddb_matchcode">space</value>
-           <value field="cddb_id">44</value>
+           <value field="cddb_id3">44</value>
          </row>
          <row>
            <value field="gnue_id">27472857179004275197190369270596</value>
            <value field="cddb_name">Meditative</value>
            <value field="cddb_matchcode">meditative</value>
-           <value field="cddb_id">45</value>
+           <value field="cddb_id3">45</value>
          </row>
          <row>
            <value field="gnue_id">37080212594853356587745246589261</value>
            <value field="cddb_name">Instrumental Pop</value>
            <value field="cddb_matchcode">instrumental pop</value>
-           <value field="cddb_id">46</value>
+           <value field="cddb_id3">46</value>
          </row>
          <row>
            <value field="gnue_id">17982473067048442168117750841731</value>
            <value field="cddb_name">Instrumental Rock</value>
            <value field="cddb_matchcode">instrumental rock</value>
-           <value field="cddb_id">47</value>
+           <value field="cddb_id3">47</value>
          </row>
          <row>
            <value field="gnue_id">22893981031194399847611735219524</value>
            <value field="cddb_name">Ethnic</value>
            <value field="cddb_matchcode">ethnic</value>
-           <value field="cddb_id">48</value>
+           <value field="cddb_id3">48</value>
          </row>
          <row>
            <value field="gnue_id">06301987749808109719612360352708</value>
            <value field="cddb_name">Gothic</value>
            <value field="cddb_matchcode">gothic</value>
-           <value field="cddb_id">49</value>
+           <value field="cddb_id3">49</value>
          </row>
          <row>
            <value field="gnue_id">77708840238518963607988104218290</value>
            <value field="cddb_name">Darkwave</value>
            <value field="cddb_matchcode">darkwave</value>
-           <value field="cddb_id">50</value>
+           <value field="cddb_id3">50</value>
          </row>
          <row>
            <value field="gnue_id">47742859607452832752972178229577</value>
            <value field="cddb_name">Techno-Industrial</value>
            <value field="cddb_matchcode">techno-industrial</value>
-           <value field="cddb_id">51</value>
+           <value field="cddb_id3">51</value>
          </row>
          <row>
            <value field="gnue_id">73087271431351657263589816638698</value>
            <value field="cddb_name">Electronic</value>
            <value field="cddb_matchcode">electronic</value>
-           <value field="cddb_id">52</value>
+           <value field="cddb_id3">52</value>
          </row>
          <row>
            <value field="gnue_id">10440536357325185361305205669166</value>
            <value field="cddb_name">Pop-Folk</value>
            <value field="cddb_matchcode">pop-folk</value>
-           <value field="cddb_id">53</value>
+           <value field="cddb_id3">53</value>
          </row>
          <row>
            <value field="gnue_id">40858869305243497297564597819507</value>
            <value field="cddb_name">Eurodance</value>
            <value field="cddb_matchcode">eurodance</value>
-           <value field="cddb_id">54</value>
+           <value field="cddb_id3">54</value>
          </row>
          <row>
            <value field="gnue_id">63175318176656070094765088882782</value>
            <value field="cddb_name">Dream</value>
            <value field="cddb_matchcode">dream</value>
-           <value field="cddb_id">55</value>
+           <value field="cddb_id3">55</value>
          </row>
          <row>
            <value field="gnue_id">06404618275235933937112732290648</value>
            <value field="cddb_name">Southern Rock</value>
            <value field="cddb_matchcode">southern rock</value>
-           <value field="cddb_id">56</value>
+           <value field="cddb_id3">56</value>
          </row>
          <row>
            <value field="gnue_id">66305564033441826319248502634948</value>
            <value field="cddb_name">Comedy</value>
            <value field="cddb_matchcode">comedy</value>
-           <value field="cddb_id">57</value>
+           <value field="cddb_id3">57</value>
          </row>
          <row>
            <value field="gnue_id">93991799085286060136737906909649</value>
            <value field="cddb_name">Cult</value>
            <value field="cddb_matchcode">cult</value>
-           <value field="cddb_id">58</value>
+           <value field="cddb_id3">58</value>
          </row>
          <row>
            <value field="gnue_id">81872436418932463688015141880448</value>
            <value field="cddb_name">Gangsta Rap</value>
            <value field="cddb_matchcode">gangsta rap</value>
-           <value field="cddb_id">59</value>
+           <value field="cddb_id3">59</value>
          </row>
          <row>
            <value field="gnue_id">13999598585465379583160276315076</value>
            <value field="cddb_name">Top 40</value>
            <value field="cddb_matchcode">top 40</value>
-           <value field="cddb_id">60</value>
+           <value field="cddb_id3">60</value>
          </row>
          <row>
            <value field="gnue_id">72189552068680123645283782201095</value>
            <value field="cddb_name">Christian Rap</value>
            <value field="cddb_matchcode">christian rap</value>
-           <value field="cddb_id">61</value>
+           <value field="cddb_id3">61</value>
          </row>
          <row>
            <value field="gnue_id">17583933017162517302598789918750</value>
            <value field="cddb_name">Pop/Funk</value>
            <value field="cddb_matchcode">pop/funk</value>
-           <value field="cddb_id">62</value>
+           <value field="cddb_id3">62</value>
          </row>
          <row>
            <value field="gnue_id">59494040682148369323201438805404</value>
            <value field="cddb_name">Jungle</value>
            <value field="cddb_matchcode">jungle</value>
-           <value field="cddb_id">63</value>
+           <value field="cddb_id3">63</value>
          </row>
          <row>
            <value field="gnue_id">53997376895665093106457409976905</value>
            <value field="cddb_name">Native American</value>
            <value field="cddb_matchcode">native american</value>
-           <value field="cddb_id">64</value>
+           <value field="cddb_id3">64</value>
          </row>
          <row>
            <value field="gnue_id">12649698699945247265339951841617</value>
            <value field="cddb_name">Cabaret</value>
            <value field="cddb_matchcode">cabaret</value>
-           <value field="cddb_id">65</value>
+           <value field="cddb_id3">65</value>
          </row>
          <row>
            <value field="gnue_id">36451569275671911969390638816653</value>
            <value field="cddb_name">New Wave</value>
            <value field="cddb_matchcode">new wave</value>
-           <value field="cddb_id">66</value>
+           <value field="cddb_id3">66</value>
          </row>
          <row>
            <value field="gnue_id">80281330043254501247543251151786</value>
            <value field="cddb_name">Psychedelic</value>
            <value field="cddb_matchcode">psychedelic</value>
-           <value field="cddb_id">67</value>
+           <value field="cddb_id3">67</value>
          </row>
          <row>
            <value field="gnue_id">88292858410908156134063151676974</value>
            <value field="cddb_name">Rave</value>
            <value field="cddb_matchcode">rave</value>
-           <value field="cddb_id">68</value>
+           <value field="cddb_id3">68</value>
          </row>
          <row>
            <value field="gnue_id">65455069700988714628984145421224</value>
            <value field="cddb_name">Showtunes</value>
            <value field="cddb_matchcode">showtunes</value>
-           <value field="cddb_id">69</value>
+           <value field="cddb_id3">69</value>
          </row>
          <row>
            <value field="gnue_id">49824828123564496458135096460258</value>
            <value field="cddb_name">Trailer</value>
            <value field="cddb_matchcode">trailer</value>
-           <value field="cddb_id">70</value>
+           <value field="cddb_id3">70</value>
          </row>
          <row>
            <value field="gnue_id">61653578555156607713964973570004</value>
            <value field="cddb_name">Lo-Fi</value>
            <value field="cddb_matchcode">lo-fi</value>
-           <value field="cddb_id">71</value>
+           <value field="cddb_id3">71</value>
          </row>
          <row>
            <value field="gnue_id">48264714576801299921510443672292</value>
            <value field="cddb_name">Tribal</value>
            <value field="cddb_matchcode">tribal</value>
-           <value field="cddb_id">72</value>
+           <value field="cddb_id3">72</value>
          </row>
          <row>
            <value field="gnue_id">40265716738335812893192259650524</value>
            <value field="cddb_name">Acid Punk</value>
            <value field="cddb_matchcode">acid punk</value>
-           <value field="cddb_id">73</value>
+           <value field="cddb_id3">73</value>
          </row>
          <row>
            <value field="gnue_id">12100889003685752752375330032054</value>
            <value field="cddb_name">Acid Jazz</value>
            <value field="cddb_matchcode">acid jazz</value>
-           <value field="cddb_id">74</value>
+           <value field="cddb_id3">74</value>
          </row>
          <row>
            <value field="gnue_id">13613372866137118273152719599162</value>
            <value field="cddb_name">Polka</value>
            <value field="cddb_matchcode">polka</value>
-           <value field="cddb_id">75</value>
+           <value field="cddb_id3">75</value>
          </row>
          <row>
            <value field="gnue_id">62144662958123128909645381793358</value>
            <value field="cddb_name">Retro</value>
            <value field="cddb_matchcode">retro</value>
-           <value field="cddb_id">76</value>
+           <value field="cddb_id3">76</value>
          </row>
          <row>
            <value field="gnue_id">89525304541875758193824761068278</value>
            <value field="cddb_name">Musical</value>
            <value field="cddb_matchcode">musical</value>
-           <value field="cddb_id">77</value>
+           <value field="cddb_id3">77</value>
          </row>
          <row>
            <value field="gnue_id">63614692867659499557079218357300</value>
            <value field="cddb_name">Rock &amp; Roll</value>
            <value field="cddb_matchcode">rock &amp; roll</value>
-           <value field="cddb_id">78</value>
+           <value field="cddb_id3">78</value>
          </row>
          <row>
            <value field="gnue_id">32882539661462108873672536579731</value>
            <value field="cddb_name">Hard Rock</value>
            <value field="cddb_matchcode">hard rock</value>
-           <value field="cddb_id">79</value>
+           <value field="cddb_id3">79</value>
          </row>
          <row>
            <value field="gnue_id">29478318130247644864406058691023</value>
            <value field="cddb_name">Folk</value>
            <value field="cddb_matchcode">folk</value>
-           <value field="cddb_id">80</value>
+           <value field="cddb_id3">80</value>
          </row>
          <row>
            <value field="gnue_id">78132195209540626594770655762882</value>
            <value field="cddb_name">Folk/Rock</value>
            <value field="cddb_matchcode">folk/rock</value>
-           <value field="cddb_id">81</value>
+           <value field="cddb_id3">81</value>
          </row>
          <row>
            <value field="gnue_id">21047689577134160999043954322132</value>
            <value field="cddb_name">National Folk</value>
            <value field="cddb_matchcode">national folk</value>
-           <value field="cddb_id">82</value>
+           <value field="cddb_id3">82</value>
          </row>
          <row>
            <value field="gnue_id">19089819891746467199714776790066</value>
            <value field="cddb_name">Swing</value>
            <value field="cddb_matchcode">swing</value>
-           <value field="cddb_id">83</value>
+           <value field="cddb_id3">83</value>
          </row>
          <row>
            <value field="gnue_id">25147045177113572787273851121591</value>
            <value field="cddb_name">Fast-Fusion</value>
            <value field="cddb_matchcode">fast-fusion</value>
-           <value field="cddb_id">84</value>
+           <value field="cddb_id3">84</value>
          </row>
          <row>
            <value field="gnue_id">27471736827354061256004497983924</value>
            <value field="cddb_name">Bebob</value>
            <value field="cddb_matchcode">bebob</value>
-           <value field="cddb_id">85</value>
+           <value field="cddb_id3">85</value>
          </row>
          <row>
            <value field="gnue_id">07793971034894454769270504371796</value>
            <value field="cddb_name">Latin</value>
            <value field="cddb_matchcode">latin</value>
-           <value field="cddb_id">86</value>
+           <value field="cddb_id3">86</value>
          </row>
          <row>
            <value field="gnue_id">60498238144083329597103495211186</value>
            <value field="cddb_name">Revival</value>
            <value field="cddb_matchcode">revival</value>
-           <value field="cddb_id">87</value>
+           <value field="cddb_id3">87</value>
          </row>
          <row>
            <value field="gnue_id">57885876441077439698033313017974</value>
            <value field="cddb_name">Celtic</value>
            <value field="cddb_matchcode">celtic</value>
-           <value field="cddb_id">88</value>
+           <value field="cddb_id3">88</value>
          </row>
          <row>
            <value field="gnue_id">63688791660379709051431162480550</value>
            <value field="cddb_name">Bluegrass</value>
            <value field="cddb_matchcode">bluegrass</value>
-           <value field="cddb_id">89</value>
+           <value field="cddb_id3">89</value>
          </row>
          <row>
            <value field="gnue_id">82783069969179696950205246665203</value>
            <value field="cddb_name">Avantgarde</value>
            <value field="cddb_matchcode">avantgarde</value>
-           <value field="cddb_id">90</value>
+           <value field="cddb_id3">90</value>
          </row>
          <row>
            <value field="gnue_id">98644970504440423078095225393791</value>
            <value field="cddb_name">Gothic Rock</value>
            <value field="cddb_matchcode">gothic rock</value>
-           <value field="cddb_id">91</value>
+           <value field="cddb_id3">91</value>
          </row>
          <row>
            <value field="gnue_id">49214527806577983579266382187053</value>
            <value field="cddb_name">Progressive Rock</value>
            <value field="cddb_matchcode">progressive rock</value>
-           <value field="cddb_id">92</value>
+           <value field="cddb_id3">92</value>
          </row>
          <row>
            <value field="gnue_id">42109545139200694337441346902374</value>
            <value field="cddb_name">Psychedelic Rock</value>
            <value field="cddb_matchcode">psychedelic rock</value>
-           <value field="cddb_id">93</value>
+           <value field="cddb_id3">93</value>
          </row>
          <row>
            <value field="gnue_id">62629945210463848971626835732999</value>
            <value field="cddb_name">Symphonic Rock</value>
            <value field="cddb_matchcode">symphonic rock</value>
-           <value field="cddb_id">94</value>
+           <value field="cddb_id3">94</value>
          </row>
          <row>
            <value field="gnue_id">05105596192676406137481275862923</value>
            <value field="cddb_name">Slow Rock</value>
            <value field="cddb_matchcode">slow rock</value>
-           <value field="cddb_id">95</value>
+           <value field="cddb_id3">95</value>
          </row>
          <row>
            <value field="gnue_id">75627783131405317464107500151166</value>
            <value field="cddb_name">Big Band</value>
            <value field="cddb_matchcode">big band</value>
-           <value field="cddb_id">96</value>
+           <value field="cddb_id3">96</value>
          </row>
          <row>
            <value field="gnue_id">77558967585728977821136576939525</value>
            <value field="cddb_name">Chorus</value>
            <value field="cddb_matchcode">chorus</value>
-           <value field="cddb_id">97</value>
+           <value field="cddb_id3">97</value>
          </row>
          <row>
            <value field="gnue_id">69695051754699783346286384433574</value>
            <value field="cddb_name">Easy Listening</value>
            <value field="cddb_matchcode">easy listening</value>
-           <value field="cddb_id">98</value>
+           <value field="cddb_id3">98</value>
          </row>
          <row>
            <value field="gnue_id">49578803358034034276543585284440</value>
            <value field="cddb_name">Acoustic</value>
            <value field="cddb_matchcode">acoustic</value>
-           <value field="cddb_id">99</value>
+           <value field="cddb_id3">99</value>
          </row>
          <row>
            <value field="gnue_id">18086924775608029347346867959230</value>
            <value field="cddb_name">Humour</value>
            <value field="cddb_matchcode">humour</value>
-           <value field="cddb_id">100</value>
+           <value field="cddb_id3">100</value>
          </row>
          <row>
            <value field="gnue_id">44683471388167167037364729180508</value>
            <value field="cddb_name">Speech</value>
            <value field="cddb_matchcode">speech</value>
-           <value field="cddb_id">101</value>
+           <value field="cddb_id3">101</value>
          </row>
          <row>
            <value field="gnue_id">33255805384581798289539613557449</value>
            <value field="cddb_name">Chanson</value>
            <value field="cddb_matchcode">chanson</value>
-           <value field="cddb_id">102</value>
+           <value field="cddb_id3">102</value>
          </row>
          <row>
            <value field="gnue_id">17410350969689700588940938547048</value>
            <value field="cddb_name">Opera</value>
            <value field="cddb_matchcode">opera</value>
-           <value field="cddb_id">103</value>
+           <value field="cddb_id3">103</value>
          </row>
          <row>
            <value field="gnue_id">07960967650668730770880512299941</value>
            <value field="cddb_name">Chamber Music</value>
            <value field="cddb_matchcode">chamber music</value>
-           <value field="cddb_id">104</value>
+           <value field="cddb_id3">104</value>
          </row>
          <row>
            <value field="gnue_id">12515828113282307306833482620270</value>
            <value field="cddb_name">Sonata</value>
            <value field="cddb_matchcode">sonata</value>
-           <value field="cddb_id">105</value>
+           <value field="cddb_id3">105</value>
          </row>
          <row>
            <value field="gnue_id">47675474224023131227193278067302</value>
            <value field="cddb_name">Symphony</value>
            <value field="cddb_matchcode">symphony</value>
-           <value field="cddb_id">106</value>
+           <value field="cddb_id3">106</value>
          </row>
          <row>
            <value field="gnue_id">26008406302255464865855808750925</value>
            <value field="cddb_name">Booty Bass</value>
            <value field="cddb_matchcode">booty bass</value>
-           <value field="cddb_id">107</value>
+           <value field="cddb_id3">107</value>
          </row>
          <row>
            <value field="gnue_id">18381878326008673623470673372089</value>
            <value field="cddb_name">Primus</value>
            <value field="cddb_matchcode">primus</value>
-           <value field="cddb_id">108</value>
+           <value field="cddb_id3">108</value>
          </row>
          <row>
            <value field="gnue_id">88075370894526952273074838090125</value>
            <value field="cddb_name">Porn Grove</value>
            <value field="cddb_matchcode">porn grove</value>
-           <value field="cddb_id">109</value>
+           <value field="cddb_id3">109</value>
          </row>
          <row>
            <value field="gnue_id">28826655636244665527579339030441</value>
            <value field="cddb_name">Satire</value>
            <value field="cddb_matchcode">satire</value>
-           <value field="cddb_id">110</value>
+           <value field="cddb_id3">110</value>
          </row>
          <row>
            <value field="gnue_id">26462847698462243084683270142356</value>
            <value field="cddb_name">Slow Jam</value>
            <value field="cddb_matchcode">slow jam</value>
-           <value field="cddb_id">111</value>
+           <value field="cddb_id3">111</value>
          </row>
          <row>
            <value field="gnue_id">53260547276376099177779434722371</value>
            <value field="cddb_name">Club</value>
            <value field="cddb_matchcode">club</value>
-           <value field="cddb_id">112</value>
+           <value field="cddb_id3">112</value>
          </row>
          <row>
            <value field="gnue_id">49229313233830021492915210123128</value>
            <value field="cddb_name">Tango</value>
            <value field="cddb_matchcode">tango</value>
-           <value field="cddb_id">113</value>
+           <value field="cddb_id3">113</value>
          </row>
          <row>
            <value field="gnue_id">38575838137836537421750358377795</value>
            <value field="cddb_name">Samba</value>
            <value field="cddb_matchcode">samba</value>
-           <value field="cddb_id">114</value>
+           <value field="cddb_id3">114</value>
          </row>
          <row>
            <value field="gnue_id">24213536962270350908403902560833</value>
            <value field="cddb_name">Folklore</value>
            <value field="cddb_matchcode">folklore</value>
-           <value field="cddb_id">115</value>
+           <value field="cddb_id3">115</value>
          </row>
          <row>
            <value field="gnue_id">32265929046692559877459697474424</value>
            <value field="cddb_name">Ballad</value>
            <value field="cddb_matchcode">ballad</value>
-           <value field="cddb_id">116</value>
+           <value field="cddb_id3">116</value>
          </row>
          <row>
            <value field="gnue_id">65756800363438344723655076240414</value>
            <value field="cddb_name">Power Ballad</value>
            <value field="cddb_matchcode">power ballad</value>
-           <value field="cddb_id">117</value>
+           <value field="cddb_id3">117</value>
          </row>
          <row>
            <value field="gnue_id">85015586358331776279358456511791</value>
            <value field="cddb_name">Rhythmic Soul</value>
            <value field="cddb_matchcode">rhythmic soul</value>
-           <value field="cddb_id">118</value>
+           <value field="cddb_id3">118</value>
          </row>
          <row>
            <value field="gnue_id">72652292817382074678426880213775</value>
            <value field="cddb_name">Freestyle</value>
            <value field="cddb_matchcode">freestyle</value>
-           <value field="cddb_id">119</value>
+           <value field="cddb_id3">119</value>
          </row>
          <row>
            <value field="gnue_id">55765496432138428423200153915597</value>
            <value field="cddb_name">Duet</value>
            <value field="cddb_matchcode">duet</value>
-           <value field="cddb_id">120</value>
+           <value field="cddb_id3">120</value>
          </row>
          <row>
            <value field="gnue_id">12745144784874063605799389089625</value>
            <value field="cddb_name">Punk Rock</value>
            <value field="cddb_matchcode">punk rock</value>
-           <value field="cddb_id">121</value>
+           <value field="cddb_id3">121</value>
          </row>
          <row>
            <value field="gnue_id">48230208647196736830751298337937</value>
            <value field="cddb_name">Drum Solo</value>
            <value field="cddb_matchcode">drum solo</value>
-           <value field="cddb_id">122</value>
+           <value field="cddb_id3">122</value>
          </row>
          <row>
            <value field="gnue_id">62558858920620957194078666671697</value>
            <value field="cddb_name">A Cappella</value>
            <value field="cddb_matchcode">a cappella</value>
-           <value field="cddb_id">123</value>
+           <value field="cddb_id3">123</value>
          </row>
          <row>
            <value field="gnue_id">52678748736733873194093288042772</value>
            <value field="cddb_name">Euro-House</value>
            <value field="cddb_matchcode">euro-house</value>
-           <value field="cddb_id">124</value>
+           <value field="cddb_id3">124</value>
          </row>
          <row>
            <value field="gnue_id">95995169125526380140436737425304</value>
            <value field="cddb_name">Dance Hall</value>
            <value field="cddb_matchcode">dance hall</value>
-           <value field="cddb_id">125</value>
+           <value field="cddb_id3">125</value>
          </row>
          <row>
            <value field="gnue_id">49181567725454580922754977799494</value>
            <value field="cddb_name">Goa</value>
            <value field="cddb_matchcode">goa</value>
-           <value field="cddb_id">126</value>
+           <value field="cddb_id3">126</value>
          </row>
          <row>
            <value field="gnue_id">03290804280881122639640728385338</value>
            <value field="cddb_name">Drum &amp; Bass</value>
            <value field="cddb_matchcode">drum &amp; bass</value>
-           <value field="cddb_id">127</value>
+           <value field="cddb_id3">127</value>
          </row>
          <row>
            <value field="gnue_id">57886011079776899270764489269270</value>
            <value field="cddb_name">Club-House</value>
            <value field="cddb_matchcode">club-house</value>
-           <value field="cddb_id">128</value>
+           <value field="cddb_id3">128</value>
          </row>
          <row>
            <value field="gnue_id">59949198638528069894359189928221</value>
            <value field="cddb_name">Hardcore</value>
            <value field="cddb_matchcode">hardcore</value>
-           <value field="cddb_id">129</value>
+           <value field="cddb_id3">129</value>
          </row>
          <row>
            <value field="gnue_id">86174932529628690292212716588512</value>
            <value field="cddb_name">Terror</value>
            <value field="cddb_matchcode">terror</value>
-           <value field="cddb_id">130</value>
+           <value field="cddb_id3">130</value>
          </row>
          <row>
            <value field="gnue_id">34998820100578081340968442032572</value>
            <value field="cddb_name">Indie</value>
            <value field="cddb_matchcode">indie</value>
-           <value field="cddb_id">131</value>
+           <value field="cddb_id3">131</value>
          </row>
          <row>
            <value field="gnue_id">61478697229297297008918680782458</value>
            <value field="cddb_name">BritPop</value>
            <value field="cddb_matchcode">britpop</value>
-           <value field="cddb_id">132</value>
+           <value field="cddb_id3">132</value>
          </row>
          <row>
            <value field="gnue_id">55852832742951796485460107358839</value>
            <value field="cddb_name">NegerPunk</value>
            <value field="cddb_matchcode">negerpunk</value>
-           <value field="cddb_id">133</value>
+           <value field="cddb_id3">133</value>
          </row>
          <row>
            <value field="gnue_id">98444631587441731134381000873361</value>
            <value field="cddb_name">PolskPunk</value>
            <value field="cddb_matchcode">polskpunk</value>
-           <value field="cddb_id">134</value>
+           <value field="cddb_id3">134</value>
          </row>
          <row>
            <value field="gnue_id">93983533225639269410317273438986</value>
            <value field="cddb_name">Beat</value>
            <value field="cddb_matchcode">beat</value>
-           <value field="cddb_id">135</value>
+           <value field="cddb_id3">135</value>
          </row>
          <row>
            <value field="gnue_id">02459127420165062942118616225232</value>
            <value field="cddb_name">Christian GanstaRap</value>
            <value field="cddb_matchcode">christian ganstarap</value>
-           <value field="cddb_id">136</value>
+           <value field="cddb_id3">136</value>
          </row>
          <row>
            <value field="gnue_id">76749776816155577254765763922590</value>
            <value field="cddb_name">Heavy Metal</value>
            <value field="cddb_matchcode">heavy metal</value>
-           <value field="cddb_id">137</value>
+           <value field="cddb_id3">137</value>
          </row>
          <row>
            <value field="gnue_id">93823148939625682498916790270374</value>
            <value field="cddb_name">Black Metal</value>
            <value field="cddb_matchcode">black metal</value>
-           <value field="cddb_id">138</value>
+           <value field="cddb_id3">138</value>
          </row>
          <row>
            <value field="gnue_id">83005761662283054145337367147868</value>
            <value field="cddb_name">Crossover</value>
            <value field="cddb_matchcode">crossover</value>
-           <value field="cddb_id">139</value>
+           <value field="cddb_id3">139</value>
          </row>
          <row>
            <value field="gnue_id">03167378290707082533943235184850</value>
            <value field="cddb_name">Contemporary Christian</value>
            <value field="cddb_matchcode">contemporary christian</value>
-           <value field="cddb_id">140</value>
+           <value field="cddb_id3">140</value>
          </row>
          <row>
            <value field="gnue_id">80024595667757763069936159381757</value>
            <value field="cddb_name">Christian Rock</value>
            <value field="cddb_matchcode">christian rock</value>
-           <value field="cddb_id">141</value>
+           <value field="cddb_id3">141</value>
          </row>
          <row>
            <value field="gnue_id">22417156925207224270261794438355</value>
            <value field="cddb_name">Merengue</value>
            <value field="cddb_matchcode">merengue</value>
-           <value field="cddb_id">142</value>
+           <value field="cddb_id3">142</value>
          </row>
          <row>
            <value field="gnue_id">84345077684357090757855813011150</value>
            <value field="cddb_name">Salsa</value>
            <value field="cddb_matchcode">salsa</value>
-           <value field="cddb_id">143</value>
+           <value field="cddb_id3">143</value>
          </row>
          <row>
            <value field="gnue_id">79492183360817918687992709279828</value>
            <value field="cddb_name">Trash Metal</value>
            <value field="cddb_matchcode">trash metal</value>
-           <value field="cddb_id">144</value>
+           <value field="cddb_id3">144</value>
          </row>
          <row>
            <value field="gnue_id">37433373555270910197913138925903</value>
            <value field="cddb_name">Anime</value>
            <value field="cddb_matchcode">anime</value>
-           <value field="cddb_id">145</value>
+           <value field="cddb_id3">145</value>
          </row>
          <row>
            <value field="gnue_id">69545103302249279429922020219231</value>
            <value field="cddb_name">JPop</value>
            <value field="cddb_matchcode">jpop</value>
-           <value field="cddb_id">146</value>
+           <value field="cddb_id3">146</value>
          </row>
          <row>
            <value field="gnue_id">55429642853283235682066707379246</value>
            <value field="cddb_name">Synthpop</value>
            <value field="cddb_matchcode">synthpop</value>
-           <value field="cddb_id">147</value>
+           <value field="cddb_id3">147</value>
          </row>
       </rows>
     </tabledata>





reply via email to

[Prev in Thread] Current Thread [Next in Thread]