1 """Various utilities to simplify common tasks.
2
3 This module contains helper functions to make common tasks easier.
4
5 @author: Matthias Friedrich <matt@mafr.de>
6 """
7 __revision__ = '$Id: utils.py 11853 2009-07-21 09:26:50Z luks $'
8
9 import re
10 import urlparse
11 import os.path
12
13 __all__ = [
14 'extractUuid', 'extractFragment', 'extractEntityType',
15 'getReleaseTypeName', 'getCountryName', 'getLanguageName',
16 'getScriptName',
17 ]
18
19
20
21 PATH_PATTERN = '^/(artist|release|track|label|release-group)/([^/]*)$'
22
23
25 """Extract the UUID part from a MusicBrainz identifier.
26
27 This function takes a MusicBrainz ID (an absolute URI) as the input
28 and returns the UUID part of the URI, thus turning it into a relative
29 URI. If C{uriStr} is None or a relative URI, then it is returned
30 unchanged.
31
32 The C{resType} parameter can be used for error checking. Set it to
33 'artist', 'release', or 'track' to make sure C{uriStr} is a
34 syntactically valid MusicBrainz identifier of the given resource
35 type. If it isn't, a C{ValueError} exception is raised.
36 This error checking only works if C{uriStr} is an absolute URI, of
37 course.
38
39 Example:
40
41 >>> from musicbrainz2.utils import extractUuid
42 >>> extractUuid('http://musicbrainz.org/artist/c0b2500e-0cef-4130-869d-732b23ed9df5', 'artist')
43 'c0b2500e-0cef-4130-869d-732b23ed9df5'
44 >>>
45
46 @param uriStr: a string containing a MusicBrainz ID (an URI), or None
47 @param resType: a string containing a resource type
48
49 @return: a string containing a relative URI, or None
50
51 @raise ValueError: the given URI is no valid MusicBrainz ID
52 """
53 if uriStr is None:
54 return None
55
56 (scheme, netloc, path) = urlparse.urlparse(uriStr)[:3]
57
58 if scheme == '':
59 return uriStr
60
61 if scheme != 'http' or netloc != 'musicbrainz.org':
62 raise ValueError('%s is no MB ID.' % uriStr)
63
64 m = re.match(PATH_PATTERN, path)
65
66 if m:
67 if resType is None:
68 return m.group(2)
69 else:
70 if m.group(1) == resType:
71 return m.group(2)
72 else:
73 raise ValueError('expected "%s" Id' % resType)
74 else:
75 raise ValueError('%s is no valid MB ID.' % uriStr)
76
77
79 """Extract the fragment part from a URI.
80
81 If C{uriStr} is None or no absolute URI, then it is returned unchanged.
82
83 The C{uriPrefix} parameter can be used for error checking. If C{uriStr}
84 is an absolute URI, then the function checks if it starts with
85 C{uriPrefix}. If it doesn't, a C{ValueError} exception is raised.
86
87 @param uriStr: a string containing an absolute URI
88 @param uriPrefix: a string containing an URI prefix
89
90 @return: a string containing the fragment, or None
91
92 @raise ValueError: the given URI doesn't start with C{uriPrefix}
93 """
94 if uriStr is None:
95 return None
96
97 (scheme, netloc, path, params, query, frag) = urlparse.urlparse(uriStr)
98 if scheme == '':
99 return uriStr
100
101 if uriPrefix is None or uriStr.startswith(uriPrefix):
102 return frag
103 else:
104 raise ValueError("prefix doesn't match URI %s" % uriStr)
105
106
108 """Returns the entity type an entity URI is referring to.
109
110 @param uriStr: a string containing an absolute entity URI
111
112 @return: a string containing 'artist', 'release', 'track', or 'label'
113
114 @raise ValueError: if the given URI is no valid MusicBrainz ID
115 """
116 if uriStr is None:
117 raise ValueError('None is no valid entity URI')
118
119 (scheme, netloc, path) = urlparse.urlparse(uriStr)[:3]
120
121 if scheme == '':
122 raise ValueError('%s is no absolute MB ID.' % uriStr)
123
124 if scheme != 'http' or netloc != 'musicbrainz.org':
125 raise ValueError('%s is no MB ID.' % uriStr)
126
127 m = re.match(PATH_PATTERN, path)
128
129 if m:
130 return m.group(1)
131 else:
132 raise ValueError('%s is no valid MB ID.' % uriStr)
133
134
136 """Returns the name of a release type URI.
137
138 @param releaseType: a string containing a release type URI
139
140 @return: a string containing a printable name for the release type
141
142 @see: L{musicbrainz2.model.Release}
143 """
144 from musicbrainz2.data.releasetypenames import releaseTypeNames
145 return releaseTypeNames.get(releaseType)
146
147
149 """Returns a country's name based on an ISO-3166 country code.
150
151 The country table this function is based on has been modified for
152 MusicBrainz purposes by using the extension mechanism defined in
153 ISO-3166. All IDs are still valid ISO-3166 country codes, but some
154 IDs have been added to include historic countries and some of the
155 country names have been modified to make them better suited for
156 display purposes.
157
158 If the country ID is not found, None is returned. This may happen
159 for example, when new countries are added to the MusicBrainz web
160 service which aren't known to this library yet.
161
162 @param id_: a two-letter upper case string containing an ISO-3166 code
163
164 @return: a string containing the country's name, or None
165
166 @see: L{musicbrainz2.model}
167 """
168 from musicbrainz2.data.countrynames import countryNames
169 return countryNames.get(id_)
170
171
173 """Returns a language name based on an ISO-639-2/T code.
174
175 This function uses a subset of the ISO-639-2/T code table to map
176 language IDs (terminologic, not bibliographic ones!) to names.
177
178 @param id_: a three-letter upper case string containing an ISO-639-2/T code
179
180 @return: a string containing the language's name, or None
181
182 @see: L{musicbrainz2.model}
183 """
184 from musicbrainz2.data.languagenames import languageNames
185 return languageNames.get(id_)
186
187
189 """Returns a script name based on an ISO-15924 code.
190
191 This function uses a subset of the ISO-15924 code table to map
192 script IDs to names.
193
194 @param id_: a four-letter string containing an ISO-15924 script code
195
196 @return: a string containing the script's name, or None
197
198 @see: L{musicbrainz2.model}
199 """
200 from musicbrainz2.data.scriptnames import scriptNames
201 return scriptNames.get(id_)
202
203
204
205