source: trunk/src/testing/bin/fileServer/misc/mmpython/disc/CDDB.py @ 4

Revision 4, 4.3 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1#!/usr/bin/env python
2
3# Module for retrieving CDDB v1 data from CDDB servers via HTTP
4
5# Written 17 Nov 1999 by Ben Gertzfield <che@debian.org>
6# This work is released under the GNU GPL, version 2 or later.
7
8# Release version 1.3
9# CVS ID: $Id: CDDB.py,v 1.4 2004/11/14 19:26:38 dischi Exp $
10
11import urllib, string, socket, os, struct, re
12
13name = 'CDDB.py'
14version = 1.3
15
16if os.environ.has_key('EMAIL'):
17    (default_user, hostname) = string.split(os.environ['EMAIL'], '@')
18else:
19    try:
20        default_user = os.geteuid() or os.environ['USER'] or 'user'
21    except:
22        default_user = 'user'
23    hostname = socket.gethostname() or 'host'
24
25proto = 4
26default_server = 'http://freedb.freedb.org/~cddb/cddb.cgi'
27
28def query(track_info, server_url=default_server,
29          user=default_user, host=hostname, client_name=name,
30          client_version=version, trying=0):
31
32    disc_id = track_info[0]
33    num_tracks = track_info[1]
34
35    query_str = (('%08lx %d ') % (long(disc_id), num_tracks))
36
37    for i in track_info[2:]:
38        query_str = query_str + ('%d ' % i)
39       
40    query_str = urllib.quote_plus(string.rstrip(query_str))
41
42    url = "%s?cmd=cddb+query+%s&hello=%s+%s+%s+%s&proto=%i" % \
43          (server_url, query_str, user, host, client_name,
44           client_version, proto)
45
46    response = urllib.urlopen(url)
47   
48    # Four elements in header: status, category, disc-id, title
49    header = string.split(string.rstrip(response.readline()), ' ', 3)
50
51    try:
52        header[0] = string.atoi(header[0])
53    except:
54        if trying > 10:
55            return [ 900, None ]
56        return query(track_info, default_server,
57                     default_user, hostname, name, version, trying+1)
58
59    if header[0] == 200:                # OK
60        result = { 'category': header[1], 'disc_id': header[2], 'title':
61                   header[3] }
62
63        return [ header[0], result ]
64
65    elif header[0] == 211 or header[0] == 210: # multiple matches
66        result = []
67
68        for line in response.readlines():
69            line = string.rstrip(line)
70
71            if line == '.':             # end of matches
72                break
73                                        # otherwise:
74                                        # split into 3 pieces, not 4
75                                        # (thanks to bgp for the fix!)
76            match = string.split(line, ' ', 2)
77
78            result.append({ 'category': match[0], 'disc_id': match[1], 'title':
79                            match[2] })
80
81        return [ header[0], result ]
82
83    else:
84        return [ header[0], None ]
85
86def read(category, disc_id, server_url=default_server,
87         user=default_user, host=hostname, client_name=name,
88         client_version=version, trying=0):
89
90    url = "%s?cmd=cddb+read+%s+%s&hello=%s+%s+%s+%s&proto=%i" % \
91          (server_url, category, disc_id, user, host, client_name,
92           client_version, proto)
93
94    response = urllib.urlopen(url)
95   
96    header = string.split(string.rstrip(response.readline()), ' ', 3)
97
98    try:
99        header[0] = string.atoi(header[0])
100    except:
101        if trying > 10:
102            return [ 900, None ]
103        return read(category, disc_id, default_server,
104                    user, host, client_name, client_version, trying+1)
105
106    if header[0] == 210 or header[0] == 417: # success or access denied
107        reply = []
108
109        for line in response.readlines():
110            line = string.rstrip(line)
111
112            if line == '.':
113                break;
114
115            line = string.replace(line, r'\t', "\t")
116            line = string.replace(line, r'\n', "\n")
117            line = string.replace(line, r'\\', "\\")
118
119            reply.append(line)
120
121        if header[0] == 210:            # success, parse the reply
122            return [ header[0], parse_read_reply(reply) ]
123        else:                           # access denied. :(
124            return [ header[0], reply ]
125    else:
126        return [ header[0], None ]
127
128def parse_read_reply(comments):
129   
130    len_re = re.compile(r'#\s*Disc length:\s*(\d+)\s*seconds')
131    revis_re = re.compile(r'#\s*Revision:\s*(\d+)')
132    submit_re = re.compile(r'#\s*Submitted via:\s*(.+)')
133    keyword_re = re.compile(r'([^=]+)=(.*)')
134
135    result = {}
136
137    for line in comments:
138        keyword_match = keyword_re.match(line)
139        if keyword_match:
140            (keyword, data) = keyword_match.groups()
141
142            if result.has_key(keyword):
143                result[keyword] = result[keyword] + data
144            else:
145                result[keyword] = data
146            continue
147
148        len_match = len_re.match(line)
149        if len_match:
150            result['disc_len'] = int(len_match.group(1))
151            continue
152
153        revis_match = revis_re.match(line)
154        if revis_match:
155            result['revision'] = int(revis_match.group(1))
156            continue
157
158        submit_match = submit_re.match(line)
159        if submit_match:
160            result['submitted_via'] = submit_match.group(1)
161            continue
162
163    return result
Note: See TracBrowser for help on using the repository browser.