1 """The MusicBrainz domain model.
2
3 These classes are part of the MusicBrainz domain model. They may be used
4 by other modules and don't contain any network or other I/O code. If you
5 want to request data from the web service, please have a look at
6 L{musicbrainz2.webservice}.
7
8 The most important classes, usually acting as entry points, are
9 L{Artist}, L{Release}, and L{Track}.
10
11 @var VARIOUS_ARTISTS_ID: The ID of the special 'Various Artists' artist.
12
13 @var NS_MMD_1: Default namespace prefix for all MusicBrainz metadata.
14 @var NS_REL_1: Namespace prefix for relations.
15 @var NS_EXT_1: Namespace prefix for MusicBrainz extensions.
16
17 @see: L{musicbrainz2.webservice}
18
19 @author: Matthias Friedrich <matt@mafr.de>
20 """
21 try:
22 set
23 except NameError:
24 from sets import Set as set
25
26 __revision__ = '$Id: model.py 12708 2010-03-15 17:45:25Z matt $'
27
28 __all__ = [
29 'VARIOUS_ARTISTS_ID', 'NS_MMD_1', 'NS_REL_1', 'NS_EXT_1',
30 'Entity', 'Artist', 'Release', 'Track', 'User', 'ReleaseGroup',
31 'Relation', 'Disc', 'ReleaseEvent', 'Label', 'Tag', 'Rating',
32 'AbstractAlias', 'ArtistAlias', 'LabelAlias',
33 ]
34
35
36 VARIOUS_ARTISTS_ID = 'http://musicbrainz.org/artist/89ad4ac3-39f7-470e-963a-56509c546377'
37
38
39
40 NS_MMD_1 = 'http://musicbrainz.org/ns/mmd-1.0#'
41 NS_REL_1 = 'http://musicbrainz.org/ns/rel-1.0#'
42 NS_EXT_1 = 'http://musicbrainz.org/ns/ext-1.0#'
43
44
46 """A first-level MusicBrainz class.
47
48 All entities in MusicBrainz have unique IDs (which are absolute URIs)
49 as well as any number of L{relations <Relation>} to other entities
50 and free text tags. This class is abstract and should not be
51 instantiated.
52
53 Relations are differentiated by their I{target type}, that means,
54 where they link to. MusicBrainz currently supports four target types
55 (artists, releases, tracks, and URLs) each identified using a URI.
56 To get all relations with a specific target type, you can use
57 L{getRelations} and pass one of the following constants as the
58 parameter:
59
60 - L{Relation.TO_ARTIST}
61 - L{Relation.TO_RELEASE}
62 - L{Relation.TO_TRACK}
63 - L{Relation.TO_URL}
64
65 @see: L{Relation}
66 """
67
69 """Constructor.
70
71 This should only used by derived classes.
72
73 @param id_: a string containing an absolute URI
74 """
75 self._id = id_
76 self._relations = { }
77 self._tags = { }
78 self._rating = Rating()
79
81 """Returns a MusicBrainz ID.
82
83 @return: a string containing a URI, or None
84 """
85 return self._id
86
88 """Sets a MusicBrainz ID.
89
90 @param value: a string containing an absolute URI
91 """
92 self._id = value
93
94 id = property(getId, setId, doc='The MusicBrainz ID.')
95
96 - def getRelations(self, targetType=None, relationType=None,
97 requiredAttributes=(), direction=None):
98 """Returns a list of relations.
99
100 If C{targetType} is given, only relations of that target
101 type are returned. For MusicBrainz, the following target
102 types are defined:
103 - L{Relation.TO_ARTIST}
104 - L{Relation.TO_RELEASE}
105 - L{Relation.TO_TRACK}
106 - L{Relation.TO_URL}
107
108 If C{targetType} is L{Relation.TO_ARTIST}, for example,
109 this method returns all relations between this Entity and
110 artists.
111
112 You may use the C{relationType} parameter to further restrict
113 the selection. If it is set, only relations with the given
114 relation type are returned. The C{requiredAttributes} sequence
115 lists attributes that have to be part of all returned relations.
116
117 If C{direction} is set, only relations with the given reading
118 direction are returned. You can use the L{Relation.DIR_FORWARD},
119 L{Relation.DIR_BACKWARD}, and L{Relation.DIR_NONE} constants
120 for this.
121
122 @param targetType: a string containing an absolute URI, or None
123 @param relationType: a string containing an absolute URI, or None
124 @param requiredAttributes: a sequence containing absolute URIs
125 @param direction: one of L{Relation}'s direction constants
126 @return: a list of L{Relation} objects
127
128 @see: L{Entity}
129 """
130 allRels = [ ]
131 if targetType is not None:
132 allRels = self._relations.setdefault(targetType, [ ])
133 else:
134 for (k, relList) in self._relations.items():
135 for rel in relList:
136 allRels.append(rel)
137
138
139
140 if direction is not None:
141 allRels = [r for r in allRels if r.getDirection() == direction]
142
143
144
145 if relationType is None:
146 return allRels
147 else:
148 allRels = [r for r in allRels if r.getType() == relationType]
149
150
151
152 tmp = []
153 required = set(iter(requiredAttributes))
154
155 for r in allRels:
156 attrs = set(iter(r.getAttributes()))
157 if required.issubset(attrs):
158 tmp.append(r)
159 return tmp
160
161
162 - def getRelationTargets(self, targetType=None, relationType=None,
163 requiredAttributes=(), direction=None):
164 """Returns a list of relation targets.
165
166 The arguments work exactly like in L{getRelations}, but
167 instead of L{Relation} objects, the matching relation
168 targets are returned. This can be L{Artist}, L{Release},
169 or L{Track} objects, depending on the relations.
170
171 As a special case, URL strings are returned if the target
172 is an URL.
173
174 @param targetType: a string containing an absolute URI, or None
175 @param relationType: a string containing an absolute URI, or None
176 @param requiredAttributes: a sequence containing absolute URIs
177 @param direction: one of L{Relation}'s direction constants
178 @return: a list of objects, depending on the relation
179
180 @see: L{getRelations}
181 """
182 ret = [ ]
183 rels = self.getRelations(targetType, relationType,
184 requiredAttributes, direction)
185
186 for r in rels:
187 if r.getTargetType() == Relation.TO_URL:
188 ret.append(r.getTargetId())
189 else:
190 ret.append(r.getTarget())
191
192 return ret
193
194
196 """Adds a relation.
197
198 This method adds C{relation} to the list of relations. The
199 given relation has to be initialized, at least the target
200 type has to be set.
201
202 @param relation: the L{Relation} object to add
203
204 @see: L{Entity}
205 """
206 assert relation.getType is not None
207 assert relation.getTargetType is not None
208 assert relation.getTargetId is not None
209 l = self._relations.setdefault(relation.getTargetType(), [ ])
210 l.append(relation)
211
212
214 """Returns a list of target types available for this entity.
215
216 Use this to find out to which types of targets this entity
217 has relations. If the entity only has relations to tracks and
218 artists, for example, then a list containg the strings
219 L{Relation.TO_TRACK} and L{Relation.TO_ARTIST} is returned.
220
221 @return: a list of strings containing URIs
222
223 @see: L{getRelations}
224 """
225 return self._relations.keys()
226
228 """Return the tag with the given value (aka the tag's name).
229
230 @return: the L{Tag} with the given name or raises a KeyError
231 """
232 return self._tags[value]
233
240
241 tags = property(getTags, doc='The tags for this entity.')
242
244 """Add a new tag.
245
246 This merges an existing tag with the same name.
247
248 @param tag: the L{Tag} object to add
249
250 @see: L{getTags}
251 """
252 if self._tags.has_key(tag.value):
253 existing = self._tags[tag.value]
254 existing.count += tag.count
255 else:
256 self._tags[tag.value] = tag
257
259 """Return the rating of this Entity.
260 0 = Unrated
261 1 - 5 = Rating
262
263 @return: rating
264 """
265 return self._rating
266
267 rating = property(getRating, doc='The rating for this entity.')
268
271
272
274 """Represents an artist.
275
276 Artists in MusicBrainz can have a type. Currently, this type can
277 be either Person or Group for which the following URIs are assigned:
278
279 - C{http://musicbrainz.org/ns/mmd-1.0#Person}
280 - C{http://musicbrainz.org/ns/mmd-1.0#Group}
281
282 Use the L{TYPE_PERSON} and L{TYPE_GROUP} constants for comparison.
283 """
284 TYPE_PERSON = NS_MMD_1 + 'Person'
285 TYPE_GROUP = NS_MMD_1 + 'Group'
286
287 - def __init__(self, id_=None, type_=None, name=None, sortName=None):
288 """Constructor.
289
290 @param id_: a string containing an absolute URI
291 @param type_: a string containing an absolute URI
292 @param name: a string containing the artist's name
293 @param sortName: a string containing the artist's sort name
294 """
295 Entity.__init__(self, id_)
296 self._type = type_
297 self._name = name
298 self._sortName = sortName
299 self._disambiguation = None
300 self._beginDate = None
301 self._endDate = None
302 self._aliases = [ ]
303 self._releases = [ ]
304 self._releasesCount = None
305 self._releasesOffset = None
306 self._releaseGroups = [ ]
307 self._releaseGroupsCount = None
308 self._releaseGroupsOffset = None
309
311 """Returns the artist's type.
312
313 @return: a string containing an absolute URI, or None
314 """
315 return self._type
316
318 """Sets the artist's type.
319
320 @param type_: a string containing an absolute URI
321 """
322 self._type = type_
323
324 type = property(getType, setType, doc="The artist's type.")
325
327 """Returns the artist's name.
328
329 @return: a string containing the artist's name, or None
330 """
331 return self._name
332
334 """Sets the artist's name.
335
336 @param name: a string containing the artist's name
337 """
338 self._name = name
339
340 name = property(getName, setName, doc="The artist's name.")
341
343 """Returns the artist's sort name.
344
345 The sort name is the artist's name in a special format which
346 is better suited for lexicographic sorting. The MusicBrainz
347 style guide specifies this format.
348
349 @see: U{The MusicBrainz Style Guidelines
350 <http://musicbrainz.org/style.html>}
351 """
352 return self._sortName
353
355 """Sets the artist's sort name.
356
357 @param sortName: a string containing the artist's sort name
358
359 @see: L{getSortName}
360 """
361 self._sortName = sortName
362
363 sortName = property(getSortName, setSortName,
364 doc="The artist's sort name.")
365
367 """Returns the disambiguation attribute.
368
369 This attribute may be used if there is more than one artist
370 with the same name. In this case, disambiguation attributes
371 are added to the artists' names to keep them apart.
372
373 For example, there are at least three bands named 'Vixen'.
374 Each band has a different disambiguation in the MusicBrainz
375 database, like 'Hip-hop' or 'all-female rock/glam band'.
376
377 @return: a disambiguation string, or None
378
379 @see: L{getUniqueName}
380 """
381 return self._disambiguation
382
384 """Sets the disambiguation attribute.
385
386 @param disambiguation: a disambiguation string
387
388 @see: L{getDisambiguation}, L{getUniqueName}
389 """
390 self._disambiguation = disambiguation
391
392 disambiguation = property(getDisambiguation, setDisambiguation,
393 doc="The disambiguation comment.")
394
396 """Returns a unique artist name (using disambiguation).
397
398 This method returns the artist name together with the
399 disambiguation attribute in parenthesis if it exists.
400 Example: 'Vixen (Hip-hop)'.
401
402 @return: a string containing the unique name
403
404 @see: L{getDisambiguation}
405 """
406 d = self.getDisambiguation()
407 if d is not None and d.strip() != '':
408 return '%s (%s)' % (self.getName(), d)
409 else:
410 return self.getName()
411
413 """Returns the birth/foundation date.
414
415 The definition of the I{begin date} depends on the artist's
416 type. For persons, this is the day of birth, for groups it
417 is the day the group was founded.
418
419 The returned date has the format 'YYYY', 'YYYY-MM', or
420 'YYYY-MM-DD', depending on how much detail is known.
421
422 @return: a string containing the date, or None
423
424 @see: L{getType}
425 """
426 return self._beginDate
427
429 """Sets the begin/foundation date.
430
431 @param dateStr: a date string
432
433 @see: L{getBeginDate}
434 """
435 self._beginDate = dateStr
436
437 beginDate = property(getBeginDate, setBeginDate,
438 doc="The begin/foundation date.")
439
441 """Returns the death/dissolving date.
442
443 The definition of the I{end date} depends on the artist's
444 type. For persons, this is the day of death, for groups it
445 is the day the group was dissolved.
446
447 @return: a string containing a date, or None
448
449 @see: L{getBeginDate}
450 """
451 return self._endDate
452
454 """Sets the death/dissolving date.
455
456 @param dateStr: a string containing a date
457
458 @see: L{setEndDate}, L{getBeginDate}
459 """
460 self._endDate = dateStr
461
462 endDate = property(getEndDate, setEndDate,
463 doc="The death/dissolving date.")
464
466 """Returns the list of aliases for this artist.
467
468 @return: a list of L{ArtistAlias} objects
469 """
470 return self._aliases
471
472 aliases = property(getAliases, doc='The list of aliases.')
473
475 """Adds an alias for this artist.
476
477 @param alias: an L{ArtistAlias} object
478 """
479 self._aliases.append(alias)
480
482 """Returns a list of releases from this artist.
483
484 This may also include releases where this artist isn't the
485 I{main} artist but has just contributed one or more tracks
486 (aka VA-Releases).
487
488 @return: a list of L{Release} objects
489 """
490 return self._releases
491
492 releases = property(getReleases, doc='The list of releases')
493
495 """Adds a release to this artist's list of releases.
496
497 @param release: a L{Release} object
498 """
499 self._release.append(release)
500
502 """Returns the offset of the release list.
503
504 This is used if the release list is incomplete (ie. the web
505 service only returned part of the release for this artist).
506 Note that the offset value is zero-based, which means release
507 C{0} is the first release.
508
509 @return: an integer containing the offset, or None
510
511 @see: L{getReleases}, L{getReleasesCount}
512 """
513 return self._releasesOffset
514
516 """Sets the offset of the release list.
517
518 @param offset: an integer containing the offset, or None
519
520 @see: L{getReleasesOffset}
521 """
522 self._releasesOffset = offset
523
524 releasesOffset = property(getReleasesOffset, setReleasesOffset,
525 doc='The offset of the release list.')
526
528 """Returns the number of existing releases.
529
530 This may or may not match with the number of elements that
531 L{getReleases} returns. If the count is higher than
532 the list, it indicates that the list is incomplete.
533
534 @return: an integer containing the count, or None
535
536 @see: L{setReleasesCount}, L{getReleasesOffset}
537 """
538 return self._releasesCount
539
541 """Sets the number of existing releases.
542
543 @param value: an integer containing the count, or None
544
545 @see: L{getReleasesCount}, L{setReleasesOffset}
546 """
547 self._releasesCount = value
548
549 releasesCount = property(getReleasesCount, setReleasesCount,
550 doc='The total number of releases')
551
553 """Returns a list of release groups from this artist.
554
555 @return: a list of L{ReleaseGroup} objects
556 """
557 return self._releaseGroups
558
559 releaseGroups = property(getReleaseGroups, doc='The list of release groups')
560
562 """Adds a release group to this artist's list of release groups.
563
564 @param releaseGroup: a L{ReleaseGroup} object
565 """
566 self._releaseGroups.append(releaseGroup)
567
569 """Returns the offset of the release group list.
570
571 This is used if the release group list is incomplete (ie. the
572 web service only returned part of the result for this artist).
573 Note that the offset value is zero-based, which means release
574 group C{0} is the first release group.
575
576 @return: an integer containing the offset, or None
577
578 @see: L{getReleaseGroups}, L{getReleaseGroupsCount}
579 """
580 return self._releaseGroupsOffset
581
583 """Sets the offset of the release group list.
584
585 @param offset: an integer containing the offset, or None
586
587 @see: L{getReleaseGroupsOffset}
588 """
589 self._releaseGroupsOffset = offset
590
591 releaseGroupsOffset = property(getReleaseGroupsOffset, setReleaseGroupsOffset,
592 doc='The offset of the release group list.')
593
595 """Returns the number of existing release groups.
596
597 This may or may not match with the number of elements that
598 L{getReleaseGroups} returns. If the count is higher than
599 the list, it indicates that the list is incomplete.
600
601 @return: an integer containing the count, or None
602
603 @see: L{setReleaseGroupsCount}, L{getReleaseGroupsOffset}
604 """
605 return self._releaseGroupsCount
606
608 """Sets the number of existing release groups.
609
610 @param value: an integer containing the count, or None
611
612 @see: L{getReleaseGroupsCount}, L{setReleaseGroupsOffset}
613 """
614 self._releaseGroupsCount = value
615
616 releasesCount = property(getReleaseGroupsCount, setReleaseGroupsCount,
617 doc='The total number of release groups')
618
619
621 """The representation of a MusicBrain rating.
622
623 The rating can have the following values:
624
625 0 = Unrated
626 [1..5] = Rating
627 """
628 - def __init__(self, value=None, count=None):
629 """Constructor.
630
631 @param value: a string containing the tag's value
632 @param count: the number of users who added this tag
633 """
634 self._value = value
635 self._count = count
636
638 """Returns a string with the tag's value.
639
640 @return: an integer containing the rating's value, or None
641 """
642 return self._value
643
645 """ Set the value of this rating.
646
647 0 or None = Clear your rating
648 1 - 5 = Rating
649
650 @param value: the rating to apply
651
652 @raise ValueError: if value is not a double or not in the
653 range 0 - 5 or None.
654 """
655 if value == None:
656 value = 0
657 try:
658 value = float(value)
659 except ValueError, e:
660 raise ValueError("Value for rating needs to be an" \
661 "float.")
662 if value < 0.0 or value > 5.0:
663 raise ValueError("Value needs to be in the range [0..5]")
664 self._value = value
665
666 value = property(getValue, setValue, doc='The value of the rating.')
667
669 """Returns an integer containing the rating's frequency count.
670
671 @return: an integer containing the rating's frequency count,
672 or None
673 """
674 return self._count
675
677 """Sets the frequency count of this rating.
678
679 @param count: an integer containing the tag's frequency count
680 """
681 self._count = count
682
683 count = property(getCount, setCount, doc="This tag's frequency count.")
684
686 return str(self._value)
687
689 return unicode(self._value)
690
691
693 """The representation of a MusicBrainz folksonomy tag.
694
695 The tag's value is the text that's displayed in the tag cloud.
696 The count attribute keeps track of how many users added the tag
697 to its owning entity.
698 """
699 - def __init__(self, value=None, count=None):
700 """Constructor.
701
702 @param value: a string containing the tag's value
703 @param count: the number of users who added this tag
704 """
705 self._value = value
706 self._count = count
707
709 """Returns a string with the tag's value.
710
711 @return: a string containing the tags's value, or None
712 """
713 return self._value
714
716 """Sets the value of this tag.
717
718 @param value: A string containing the value of the tag
719 """
720 self._value = value
721
722 value = property(getValue, setValue, doc='The value of the text.')
723
725 """Returns an integer containing the tag's frequency count.
726
727 @return: an integer containing the tags's frequency count, or None
728 """
729 return self._count
730
732 """Sets the frequency count of this tag.
733
734 @param count: an integer containing the tag's frequency count
735 """
736 self._count = count
737
738 count = property(getCount, setCount, doc="This tag's frequency count.")
739
741 return str(self._value)
742
744 return unicode(self._value)
745
746
748 """Represents a record label.
749
750 A label within MusicBrainz is an L{Entity}. It contains information
751 about the label like when it was established, its name, label code and
752 other relationships. All release events may be assigned a label.
753 """
754 TYPE_UNKNOWN = NS_MMD_1 + 'Unknown'
755
756 TYPE_DISTRIBUTOR = NS_MMD_1 + 'Distributor'
757 TYPE_HOLDING = NS_MMD_1 + 'Holding'
758 TYPE_PRODUCTION = NS_MMD_1 + 'Production'
759
760 TYPE_ORIGINAL = NS_MMD_1 + 'OriginalProduction'
761 TYPE_BOOTLEG = NS_MMD_1 + 'BootlegProduction'
762 TYPE_REISSUE = NS_MMD_1 + 'ReissueProduction'
763
765 """Constructor.
766
767 @param id_: a string containing an absolute URI
768 """
769 Entity.__init__(self, id_)
770 self._type = None
771 self._name = None
772 self._sortName = None
773 self._disambiguation = None
774 self._countryId = None
775 self._code = None
776 self._beginDate = None
777 self._endDate = None
778 self._aliases = [ ]
779
781 """Returns the type of this label.
782
783 @return: a string containing an absolute URI
784 """
785 return self._type
786
788 """Sets the type of this label.
789
790 @param type_: A string containing the absolute URI of the type of label.
791 """
792 self._type = type_
793
794 type = property(getType, setType, doc='The type of label')
795
797 """Returns a string with the name of the label.
798
799 @return: a string containing the label's name, or None
800 """
801 return self._name
802
804 """Sets the name of this label.
805
806 @param name: A string containing the name of the label
807 """
808 self._name = name
809
810 name = property(getName, setName, doc='The name of the label.')
811
813 """Returns the label's sort name.
814
815 The sort name is the label's name in a special format which
816 is better suited for lexicographic sorting. The MusicBrainz
817 style guide specifies this format.
818
819 @see: U{The MusicBrainz Style Guidelines
820 <http://musicbrainz.org/style.html>}
821 """
822 return self._sortName
823
825 """Sets the label's sort name.
826
827 @param sortName: a string containing the label's sort name
828
829 @see: L{getSortName}
830 """
831 self._sortName = sortName
832
833 sortName = property(getSortName, setSortName,
834 doc="The label's sort name.")
835
837 """Returns the disambiguation attribute.
838
839 This attribute may be used if there is more than one label
840 with the same name. In this case, disambiguation attributes
841 are added to the labels' names to keep them apart.
842
843 @return: a disambiguation string, or None
844
845 @see: L{getUniqueName}
846 """
847 return self._disambiguation
848
850 """Sets the disambiguation attribute.
851
852 @param disambiguation: a disambiguation string
853
854 @see: L{getDisambiguation}, L{getUniqueName}
855 """
856 self._disambiguation = disambiguation
857
858 disambiguation = property(getDisambiguation, setDisambiguation,
859 doc="The disambiguation comment.")
860
862 """Returns a unique label name (using disambiguation).
863
864 This method returns the label's name together with the
865 disambiguation attribute in parenthesis if it exists.
866
867 @return: a string containing the unique name
868
869 @see: L{getDisambiguation}
870 """
871 d = self.getDisambiguation()
872 if d is not None and d.strip() != '':
873 return '%s (%s)' % (self.getName(), d)
874 else:
875 return self.getName()
876
878 """Returns the date this label was established.
879
880 @return: A string contained the start date, or None
881 """
882 return self._beginDate
883
885 """Set the date this label was established.
886
887 @param date: A string in the format of YYYY-MM-DD
888 """
889 self._beginDate = date
890
891 beginDate = property(getBeginDate, setBeginDate,
892 doc='The date this label was established.')
893
895 """Returns the date this label closed.
896
897 The returned date has the format 'YYYY', 'YYYY-MM', or
898 'YYYY-MM-DD', depending on how much detail is known.
899
900 @return: A string containing the date, or None
901 """
902 return self._endDate
903
905 """Set the date this label closed.
906
907 The date may have the format 'YYYY', 'YYYY-MM', or
908 'YYYY-MM-DD', depending on how much detail is known.
909
910 @param date: A string containing the date, or None
911 """
912 self._endDate = date
913
914 endDate = property(getEndDate, setEndDate,
915 doc='The date this label closed.')
916
918 """Returns the country the label is located.
919
920 @return: a string containing an ISO-3166 country code, or None
921
922 @see: L{musicbrainz2.utils.getCountryName}
923 """
924 return self._countryId
925
927 """Sets the country the label is located.
928
929 @param country: a string containing an ISO-3166 country code
930 """
931 self._countryId = country
932
933 country = property(getCountry, setCountry,
934 doc='The country the label is located.')
935
937 """Returns the label code.
938
939 Label codes have been introduced by the IFPI (International
940 Federation of Phonogram and Videogram Industries) to uniquely
941 identify record labels. The label code consists of 'LC-' and 4
942 figures (currently being extended to 5 figures).
943
944 @return: a string containing the label code, or None
945 """
946 return self._code
947
949 """Sets the label code.
950
951 @param code: a string containing the label code
952 """
953 self._code = code
954
955 code = property(getCode, setCode,
956 doc='The label code.')
957
959 """Returns the list of aliases for this label.
960
961 @return: a list of L{LabelAlias} objects
962 """
963 return self._aliases
964
965 aliases = property(getAliases, doc='The list of aliases.')
966
968 """Adds an alias for this label.
969
970 @param alias: a L{LabelAlias} object
971 """
972 self._aliases.append(alias)
973
974
976 """Represents a Release.
977
978 A release within MusicBrainz is an L{Entity} which contains L{Track}
979 objects. Releases may be of more than one type: There can be albums,
980 singles, compilations, live recordings, official releases, bootlegs
981 etc.
982
983 @note: The current MusicBrainz server implementation supports only a
984 limited set of types.
985 """
986 TYPE_NONE = NS_MMD_1 + 'None'
987 TYPE_NON_ALBUM_TRACKS = NS_MMD_1 + "NonAlbum Track"
988
989 TYPE_ALBUM = NS_MMD_1 + 'Album'
990 TYPE_SINGLE = NS_MMD_1 + 'Single'
991 TYPE_EP = NS_MMD_1 + 'EP'
992 TYPE_COMPILATION = NS_MMD_1 + 'Compilation'
993 TYPE_SOUNDTRACK = NS_MMD_1 + 'Soundtrack'
994 TYPE_SPOKENWORD = NS_MMD_1 + 'Spokenword'
995 TYPE_INTERVIEW = NS_MMD_1 + 'Interview'
996 TYPE_AUDIOBOOK = NS_MMD_1 + 'Audiobook'
997 TYPE_LIVE = NS_MMD_1 + 'Live'
998 TYPE_REMIX = NS_MMD_1 + 'Remix'
999 TYPE_OTHER = NS_MMD_1 + 'Other'
1000
1001 TYPE_OFFICIAL = NS_MMD_1 + 'Official'
1002 TYPE_PROMOTION = NS_MMD_1 + 'Promotion'
1003 TYPE_BOOTLEG = NS_MMD_1 + 'Bootleg'
1004 TYPE_PSEUDO_RELEASE = NS_MMD_1 + 'Pseudo-Release'
1005
1006 - def __init__(self, id_=None, title=None):
1007 """Constructor.
1008
1009 @param id_: a string containing an absolute URI
1010 @param title: a string containing the title
1011 """
1012 Entity.__init__(self, id_)
1013 self._types = [ ]
1014 self._title = title
1015 self._textLanguage = None
1016 self._textScript = None
1017 self._asin = None
1018 self._artist = None
1019 self._releaseEvents = [ ]
1020
1021 self._releaseGroup = None
1022 self._discs = [ ]
1023
1024 self._tracks = [ ]
1025 self._tracksOffset = None
1026 self._tracksCount = None
1027
1028
1030 """Returns the types of this release.
1031
1032 To test for release types, you can use the constants
1033 L{TYPE_ALBUM}, L{TYPE_SINGLE}, etc.
1034
1035 @return: a list of strings containing absolute URIs
1036
1037 @see: L{musicbrainz2.utils.getReleaseTypeName}
1038 """
1039 return self._types
1040
1041 types = property(getTypes, doc='The list of types for this release.')
1042
1044 """Add a type to the list of types.
1045
1046 @param type_: a string containing absolute URIs
1047
1048 @see: L{getTypes}
1049 """
1050 self._types.append(type_)
1051
1053 """Returns the release's title.
1054
1055 @return: a string containing the release's title
1056 """
1057 return self._title
1058
1060 """Sets the release's title.
1061
1062 @param title: a string containing the release's title, or None
1063 """
1064 self._title = title
1065
1066 title = property(getTitle, setTitle, doc='The title of this release.')
1067
1068 - def getTextLanguage(self):
1069 """Returns the language used in release and track titles.
1070
1071 To represent the language, the ISO-639-2/T standard is used,
1072 which provides three-letter terminological language codes like
1073 'ENG', 'DEU', 'JPN', 'KOR', 'ZHO' or 'YID'.
1074
1075 Note that this refers to release and track I{titles}, not
1076 lyrics.
1077
1078 @return: a string containing the language code, or None
1079
1080 @see: L{musicbrainz2.utils.getLanguageName}
1081 """
1082 return self._textLanguage
1083
1084 - def setTextLanguage(self, language):
1085 """Sets the language used in releaes and track titles.
1086
1087 @param language: a string containing a language code
1088
1089 @see: L{getTextLanguage}
1090 """
1091 self._textLanguage = language
1092
1093 textLanguage = property(getTextLanguage, setTextLanguage,
1094 doc='The language used in release and track titles.')
1095
1096 - def getTextScript(self):
1097 """Returns the script used in release and track titles.
1098
1099 To represent the script, ISO-15924 script codes are used.
1100 Valid codes are, among others: 'Latn', 'Cyrl', 'Hans', 'Hebr'
1101
1102 Note that this refers to release and track I{titles}, not
1103 lyrics.
1104
1105 @return: a string containing the script code, or None
1106
1107 @see: L{musicbrainz2.utils.getScriptName}
1108 """
1109 return self._textScript
1110
1111 - def setTextScript(self, script):
1112 """Sets the script used in releaes and track titles.
1113
1114 @param script: a string containing a script code
1115
1116 @see: L{getTextScript}
1117 """
1118 self._textScript = script
1119
1120 textScript = property(getTextScript, setTextScript,
1121 doc='The script used in release and track titles.')
1122
1124 """Returns the amazon shop identifier (ASIN).
1125
1126 The ASIN is a 10-letter code (except for books) assigned
1127 by Amazon, which looks like 'B000002IT2' or 'B00006I4YD'.
1128
1129 @return: a string containing the ASIN, or None
1130 """
1131 return self._asin
1132
1134 """Sets the amazon shop identifier (ASIN).
1135
1136 @param asin: a string containing the ASIN
1137
1138 @see: L{getAsin}
1139 """
1140 self._asin = asin
1141
1142 asin = property(getAsin, setAsin, doc='The amazon shop identifier.')
1143
1145 """Returns the main artist of this release.
1146
1147 @return: an L{Artist} object, or None
1148 """
1149 return self._artist
1150
1152 """Sets this release's main artist.
1153
1154 @param artist: an L{Artist} object
1155 """
1156 self._artist = artist
1157
1158 artist = property(getArtist, setArtist,
1159 doc='The main artist of this release.')
1160
1162 """Returns the release group to which this release belongs.
1163
1164 @return: a L{ReleaseGroup} object, or None.
1165 """
1166 return self._releaseGroup
1167
1169 """Sets the release's release group.
1170
1171 @param releaseGroup: a L{ReleaseGroup} object, or None.
1172 """
1173 self._releaseGroup = releaseGroup
1174
1175 releaseGroup = property(getReleaseGroup, setReleaseGroup,
1176 doc='The release group this release belongs to.')
1177
1179 """Checks if this is a single artist's release.
1180
1181 Returns C{True} if the release's main artist (L{getArtist}) is
1182 also the main artist for all of the tracks. This is checked by
1183 comparing the artist IDs.
1184
1185 Note that the release's artist has to be set (see L{setArtist})
1186 for this. The track artists may be unset.
1187
1188 @return: True, if this is a single artist's release
1189 """
1190 releaseArtist = self.getArtist()
1191 assert releaseArtist is not None, 'Release Artist may not be None!'
1192 for track in self.getTracks():
1193 if track.getArtist() is None:
1194 continue
1195 if track.getArtist().getId() != releaseArtist.getId():
1196 return False
1197
1198 return True
1199
1201 """Returns the tracks this release contains.
1202
1203 @return: a list containing L{Track} objects
1204
1205 @see: L{getTracksOffset}, L{getTracksCount}
1206 """
1207 return self._tracks
1208
1209 tracks = property(getTracks, doc='The list of tracks.')
1210
1212 """Adds a track to this release.
1213
1214 This appends a track at the end of this release's track list.
1215
1216 @param track: a L{Track} object
1217 """
1218 self._tracks.append(track)
1219
1221 """Returns the offset of the track list.
1222
1223 This is used if the track list is incomplete (ie. the web
1224 service only returned part of the tracks on this release).
1225 Note that the offset value is zero-based, which means track
1226 C{0} is the first track.
1227
1228 @return: an integer containing the offset, or None
1229
1230 @see: L{getTracks}, L{getTracksCount}
1231 """
1232 return self._tracksOffset
1233
1235 """Sets the offset of the track list.
1236
1237 @param offset: an integer containing the offset, or None
1238
1239 @see: L{getTracksOffset}, L{setTracksCount}
1240 """
1241 self._tracksOffset = offset
1242
1243 tracksOffset = property(getTracksOffset, setTracksOffset,
1244 doc='The offset of the track list.')
1245
1247 """Returns the number of tracks on this release.
1248
1249 This may or may not match with the number of elements that
1250 L{getTracks} returns. If the count is higher than
1251 the list, it indicates that the list is incomplete.
1252
1253 @return: an integer containing the count, or None
1254
1255 @see: L{setTracksCount}, L{getTracks}, L{getTracksOffset}
1256 """
1257 return self._tracksCount
1258
1260 """Sets the number of tracks on this release.
1261
1262 @param value: an integer containing the count, or None
1263
1264 @see: L{getTracksCount}, L{setTracksOffset}
1265 """
1266 self._tracksCount = value
1267
1268 tracksCount = property(getTracksCount, setTracksCount,
1269 doc='The total number of releases')
1270
1271
1273 """Returns the list of release events.
1274
1275 A L{Release} may contain a list of so-called release events,
1276 each represented using a L{ReleaseEvent} object. Release
1277 evens specify where and when this release was, well, released.
1278
1279 @return: a list of L{ReleaseEvent} objects
1280
1281 @see: L{getReleaseEventsAsDict}
1282 """
1283 return self._releaseEvents
1284
1285 releaseEvents = property(getReleaseEvents,
1286 doc='The list of release events.')
1287
1289 """Adds a release event to this release.
1290
1291 @param event: a L{ReleaseEvent} object
1292
1293 @see: L{getReleaseEvents}
1294 """
1295 self._releaseEvents.append(event)
1296
1298 """Returns the release events represented as a dict.
1299
1300 Keys are ISO-3166 country codes like 'DE', 'UK', 'FR' etc.
1301 Values are dates in 'YYYY', 'YYYY-MM' or 'YYYY-MM-DD' format.
1302
1303 @return: a dict containing (countryCode, date) entries
1304
1305 @see: L{getReleaseEvents}, L{musicbrainz2.utils.getCountryName}
1306 """
1307 d = { }
1308 for event in self.getReleaseEvents():
1309 d[event.getCountry()] = event.getDate()
1310 return d
1311
1313 """Returns the earliest release date.
1314
1315 This favours complete dates. For example, '2006-09' is
1316 returned if there is '2000', too. If there is no release
1317 event associated with this release, None is returned.
1318
1319 @return: a string containing the date, or None
1320
1321 @see: L{getReleaseEvents}, L{getReleaseEventsAsDict}
1322 """
1323 event = self.getEarliestReleaseEvent()
1324
1325 if event is None:
1326 return None
1327 else:
1328 return event.getDate()
1329
1331 """Returns the earliest release event.
1332
1333 This works like L{getEarliestReleaseDate}, but instead of
1334 just the date, this returns a L{ReleaseEvent} object.
1335
1336 @return: a L{ReleaseEvent} object, or None
1337
1338 @see: L{getReleaseEvents}, L{getEarliestReleaseDate}
1339 """
1340 dates = [ ]
1341 for event in self.getReleaseEvents():
1342 date = event.getDate()
1343 if len(date) == 10:
1344 dates.append( (date, event) )
1345 elif len(date) == 7:
1346 dates.append( (date + '-99', event) )
1347 else:
1348 dates.append( (date + '-99-99', event) )
1349
1350 dates.sort(lambda x, y: cmp(x[0], y[0]))
1351
1352 if len(dates) > 0:
1353 return dates[0][1]
1354 else:
1355 return None
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1371 """Returns the discs associated with this release.
1372
1373 Discs are currently containers for MusicBrainz DiscIDs.
1374 Note that under rare circumstances (identical TOCs), a
1375 DiscID could be associated with more than one release.
1376
1377 @return: a list of L{Disc} objects
1378 """
1379 return self._discs
1380
1381 discs = property(getDiscs, doc='The list of associated discs.')
1382
1384 """Adds a disc to this release.
1385
1386 @param disc: a L{Disc} object
1387 """
1388 self._discs.append(disc)
1389
1390
1391
1392
1393
1394
1395
1396
1398 """Represents a ReleaseGroup.
1399
1400 A ReleaseGroup in MusicBrainz is an L{Entity} which groups several different
1401 versions of L{Release} objects (e.g., different editions of the same album).
1402
1403 @see: L{Release}
1404 @see: L{Entity}
1405 """
1406
1407 - def __init__(self, id_=None, title=None):
1408 """Constructor.
1409
1410 @param id_: a string containing an absolute URI
1411 @param title: a string containing the title
1412 """
1413 Entity.__init__(self, id_)
1414 self._title = title
1415 self._id = id_
1416 self._type = None
1417 self._releases = [ ]
1418 self._artist = None
1419 self._releasesOffset = 0
1420 self._releasesCount = 0
1421
1423 """Returns the type of this release group.
1424
1425 To test for release types, you can use the constants
1426 L{Release.TYPE_ALBUM}, L{Release.TYPE_SINGLE}, etc.
1427
1428 @return: a string containing an absolute URI, or None.
1429
1430 @see: L{musicbrainz2.utils.getReleaseTypeName}
1431 """
1432 return self._type
1433
1435 """Sets the type of this release group.
1436
1437 Use a constant from the L{Release} class, such as
1438 L{Release.TYPE_ALBUM} or L{Release.TYPE_SINGLE} to
1439 set the value.
1440
1441 @param type_: a string containing an absolute URI, or None.
1442
1443 @see: L{musicbrainz2.utils.getReleaseTypeName}
1444 """
1445 self._type = type_
1446
1447 type = property(getType, setType,
1448 doc = 'The type of this release group.')
1449
1451 """Gets the releases in this release group.
1452
1453 @return: a list of L{Release} objects
1454 @see: L{Release}
1455 """
1456 return self._releases
1457
1458 releases = property(getReleases,
1459 doc = 'The list of releases in this release group.')
1460
1462 """Adds a L{Release} to this release group.
1463
1464 @param release: a L{Release} object
1465 """
1466 self._releases.append(release)
1467
1469 """Returns the offset of the release list.
1470
1471 This is used if the release list is incomplete (i.e., the web
1472 service only returned a portion of the releases in this release
1473 group).
1474
1475 @return: an integer containing the offset, or None.
1476 @see: L{getReleases}, L{getReleasesCount}
1477 """
1478 return self._releasesOffset
1479
1481 """Sets the offset of the release list.
1482
1483 @param offset: an integer containing the offset, or None.
1484 @see: L{getReleases}, L{getReleasesOffset}
1485 """
1486 self._releasesOffset = offset
1487
1488 releasesOffset = property(getReleasesOffset, setReleasesOffset,
1489 doc='The offset of the release list.')
1490
1492 """Returns the number of releases in this release group.
1493
1494 This may or may not match the number of elements returned by
1495 L{getReleases}. If the count is higher than the length of that
1496 list, then the list is incomplete.
1497
1498 @return: an integer containing the count, or None
1499 @see: L{getReleases}, L{setReleasesCount}, L{getReleasesOffset}
1500 """
1501 return self._releasesCount
1502
1504 """Sets the number of releases in this release group.
1505
1506 @param value: an integer containing the count, or None.
1507 @see: L{getReleases}, L{getReleasesCount}, L{getReleasesOffset}
1508 """
1509 self._releasesCount = value
1510
1511 releasesCount = property(getReleasesCount, setReleasesCount,
1512 doc = 'The total number of releases')
1513
1515 """Returns this release group's title.
1516
1517 @return: a string containing the release group's title
1518 """
1519 return self._title
1520
1522 """Sets the release group's title.
1523
1524 @param title: a string containing the release group's title.
1525 """
1526 self._title = title
1527
1528 title = property(getTitle, setTitle,
1529 doc = 'The title of this release group.')
1530
1532 """Returns the main artist of this release group.
1533
1534 @return: an L{Artist} object, or None
1535 """
1536 return self._artist
1537
1539 """Sets the release group's main artist.
1540
1541 @param artist: an L{Artist} object
1542 """
1543 self._artist = artist
1544
1545 artist = property(getArtist, setArtist,
1546 doc = 'The main artist of this release group')
1547
1548
1550 """Represents a track.
1551
1552 This class represents a track which may appear on one or more releases.
1553 A track may be associated with exactly one artist (the I{main} artist).
1554
1555 Using L{getReleases}, you can find out on which releases this track
1556 appears. To get the track number, too, use the
1557 L{Release.getTracksOffset} method.
1558
1559 @note: Currently, the MusicBrainz server doesn't support tracks to
1560 be on more than one release.
1561
1562 @see: L{Release}, L{Artist}
1563 """
1564 - def __init__(self, id_=None, title=None):
1565 """Constructor.
1566
1567 @param id_: a string containing an absolute URI
1568 @param title: a string containing the title
1569 """
1570 Entity.__init__(self, id_)
1571 self._title = title
1572 self._artist = None
1573 self._duration = None
1574 self._puids = [ ]
1575 self._releases = [ ]
1576 self._isrcs = [ ]
1577
1579 """Returns the track's title.
1580
1581 The style and format of this attribute is specified by the
1582 style guide.
1583
1584 @return: a string containing the title, or None
1585
1586 @see: U{The MusicBrainz Style Guidelines
1587 <http://musicbrainz.org/style.html>}
1588 """
1589 return self._title
1590
1592 """Sets the track's title.
1593
1594 @param title: a string containing the title
1595
1596 @see: L{getTitle}
1597 """
1598 self._title = title
1599
1600 title = property(getTitle, setTitle, doc="The track's title.")
1601
1603 """Returns the main artist of this track.
1604
1605 @return: an L{Artist} object, or None
1606 """
1607 return self._artist
1608
1610 """Sets this track's main artist.
1611
1612 @param artist: an L{Artist} object
1613 """
1614 self._artist = artist
1615
1616 artist = property(getArtist, setArtist, doc="The track's main artist.")
1617
1619 """Returns the duration of this track in milliseconds.
1620
1621 @return: an int containing the duration in milliseconds, or None
1622 """
1623 return self._duration
1624
1626 """Sets the duration of this track in milliseconds.
1627
1628 @param duration: an int containing the duration in milliseconds
1629 """
1630 self._duration = duration
1631
1632 duration = property(getDuration, setDuration,
1633 doc='The duration in milliseconds.')
1634
1636 """Returns the duration as a (minutes, seconds) tuple.
1637
1638 If no duration is set, (0, 0) is returned. Seconds are
1639 rounded towards the ceiling if at least 500 milliseconds
1640 are left.
1641
1642 @return: a (minutes, seconds) tuple, both entries being ints
1643 """
1644 duration = self.getDuration()
1645 if duration is None:
1646 return (0, 0)
1647 else:
1648 seconds = int( round(duration / 1000.0) )
1649 return (seconds / 60, seconds % 60)
1650
1652 """Returns the PUIDs associated with this track.
1653
1654 Please note that a PUID may be associated with more than one
1655 track.
1656
1657 @return: a list of strings, each containing one PUID
1658 """
1659 return self._puids
1660
1661 puids = property(getPuids, doc='The list of associated PUIDs.')
1662
1664 """Add a PUID to this track.
1665
1666 @param puid: a string containing a PUID
1667 """
1668 self._puids.append(puid)
1669
1671 """Returns the ISRCs associated with this track.
1672
1673 @return: a list of strings, each containing one ISRC
1674 """
1675 return self._isrcs
1676
1677 isrcs = property(getISRCs, doc='The list of associated ISRCs')
1678
1680 """Add a ISRC to this track.
1681
1682 @param isrc: a string containing an ISRC
1683 """
1684 self._isrcs.append(isrc)
1685
1687 """Returns the list of releases this track appears on.
1688
1689 @return: a list of L{Release} objects
1690 """
1691 return self._releases
1692
1693 releases = property(getReleases,
1694 doc='The releases on which this track appears.')
1695
1697 """Add a release on which this track appears.
1698
1699 @param release: a L{Release} object
1700 """
1701 self._releases.append(release)
1702
1703
1705 """Represents a relation between two Entities.
1706
1707 There may be an arbitrary number of relations between all first
1708 class objects in MusicBrainz. The Relation itself has multiple
1709 attributes, which may or may not be used for a given relation
1710 type.
1711
1712 Note that a L{Relation} object only contains the target but not
1713 the source end of the relation.
1714
1715 @todo: Add some examples.
1716
1717 @cvar TO_ARTIST: Identifies relations linking to an artist.
1718 @cvar TO_RELEASE: Identifies relations linking to a release.
1719 @cvar TO_TRACK: Identifies relations linking to a track.
1720 @cvar TO_URL: Identifies relations linking to an URL.
1721
1722 @cvar DIR_NONE: Relation reading direction doesn't matter.
1723 @cvar DIR_FORWARD: Relation reading direction is from source to target.
1724 @cvar DIR_BACKWARD: Relation reading direction is from target to source.
1725 @cvar DIR_BOTH: Relation reading direction doesn't matter (no longer used!).
1726 """
1727
1728
1729 TO_ARTIST = NS_REL_1 + 'Artist'
1730 TO_RELEASE = NS_REL_1 + 'Release'
1731 TO_TRACK = NS_REL_1 + 'Track'
1732 TO_URL = NS_REL_1 + 'Url'
1733
1734
1735
1736 DIR_BOTH = 'both'
1737 DIR_FORWARD = 'forward'
1738 DIR_BACKWARD = 'backward'
1739 DIR_NONE = 'none'
1740
1741 - def __init__(self, relationType=None, targetType=None, targetId=None,
1742 direction=DIR_NONE, attributes=None,
1743 beginDate=None, endDate=None, target=None):
1744 """Constructor.
1745
1746 @param relationType: a string containing an absolute URI
1747 @param targetType: a string containing an absolute URI
1748 @param targetId: a string containing an absolute URI
1749 @param direction: one of C{Relation.DIR_FORWARD},
1750 C{Relation.DIR_BACKWARD}, or C{Relation.DIR_NONE}
1751 @param attributes: a list of strings containing absolute URIs
1752 @param beginDate: a string containing a date
1753 @param endDate: a string containing a date
1754 @param target: an instance of a subclass of L{Entity}
1755 """
1756 self._relationType = relationType
1757 self._targetType = targetType
1758 self._targetId = targetId
1759 self._direction = direction
1760 self._beginDate = beginDate
1761 self._endDate = endDate
1762 self._target = target
1763 self._attributes = attributes
1764 if self._attributes is None:
1765 self._attributes = [ ]
1766
1768 """Returns this relation's type.
1769
1770 @return: a string containing an absolute URI, or None
1771 """
1772 return self._relationType
1773
1775 """Sets this relation's type.
1776
1777 @param type_: a string containing an absolute URI
1778 """
1779 self._relationType = type_
1780
1781 type = property(getType, setType, doc="The relation's type.")
1782
1784 """Returns the target's ID.
1785
1786 This is the ID the relation points to. It is an absolute
1787 URI, and in case of an URL relation, it is a URL.
1788
1789 @return: a string containing an absolute URI
1790 """
1791 return self._targetId
1792
1794 """Sets the target's ID.
1795
1796 @param targetId: a string containing an absolute URI
1797
1798 @see: L{getTargetId}
1799 """
1800 self._targetId = targetId
1801
1802 targetId = property(getTargetId, setTargetId, doc="The target's ID.")
1803
1805 """Returns the target's type.
1806
1807 For MusicBrainz data, the following target types are defined:
1808 - artists: L{Relation.TO_ARTIST}
1809 - releases: L{Relation.TO_RELEASE}
1810 - tracks: L{Relation.TO_TRACK}
1811 - urls: L{Relation.TO_URL}
1812
1813 @return: a string containing an absolute URI
1814 """
1815 return self._targetType
1816
1818 """Sets the target's type.
1819
1820 @param targetType: a string containing an absolute URI
1821
1822 @see: L{getTargetType}
1823 """
1824 self._targetType = targetType
1825
1826 targetId = property(getTargetId, setTargetId,
1827 doc="The type of target this relation points to.")
1828
1830 """Returns a list of attributes describing this relation.
1831
1832 The attributes permitted depend on the relation type.
1833
1834 @return: a list of strings containing absolute URIs
1835 """
1836 return self._attributes
1837
1838 attributes = property(getAttributes,
1839 doc='The list of attributes describing this relation.')
1840
1842 """Adds an attribute to the list.
1843
1844 @param attribute: a string containing an absolute URI
1845 """
1846 self._attributes.append(attribute)
1847
1849 """Returns the begin date.
1850
1851 The definition depends on the relation's type. It may for
1852 example be the day of a marriage or the year an artist
1853 joined a band. For other relation types this may be
1854 undefined.
1855
1856 @return: a string containing a date
1857 """
1858 return self._beginDate
1859
1861 """Sets the begin date.
1862
1863 @param dateStr: a string containing a date
1864
1865 @see: L{getBeginDate}
1866 """
1867 self._beginDate = dateStr
1868
1869 beginDate = property(getBeginDate, setBeginDate, doc="The begin date.")
1870
1872 """Returns the end date.
1873
1874 As with the begin date, the definition depends on the
1875 relation's type. Depending on the relation type, this may
1876 or may not be defined.
1877
1878 @return: a string containing a date
1879
1880 @see: L{getBeginDate}
1881 """
1882 return self._endDate
1883
1885 """Sets the end date.
1886
1887 @param dateStr: a string containing a date
1888
1889 @see: L{getBeginDate}
1890 """
1891 self._endDate = dateStr
1892
1893 endDate = property(getEndDate, setEndDate, doc="The end date.")
1894
1896 """Returns the reading direction.
1897
1898 The direction may be one of L{Relation.DIR_FORWARD},
1899 L{Relation.DIR_BACKWARD}, or L{Relation.DIR_NONE},
1900 depending on how the relation should be read. For example,
1901 if direction is L{Relation.DIR_FORWARD} for a cover relation,
1902 it is read as "X is a cover of Y". For some relations there is
1903 no reading direction (like marriages) and the web service doesn't
1904 send a direction. In these cases, the direction is set to
1905 L{Relation.DIR_NONE}.
1906
1907 @return: L{Relation.DIR_FORWARD}, L{Relation.DIR_BACKWARD},
1908 or L{Relation.DIR_NONE}
1909 """
1910 return self._direction
1911
1913 """Sets the reading direction.
1914
1915 @param direction: L{Relation.DIR_FORWARD},
1916 L{Relation.DIR_BACKWARD}, or L{Relation.DIR_NONE}
1917
1918 @see: L{getDirection}
1919 """
1920 self._direction = direction
1921
1922 direction = property(getDirection, setDirection,
1923 doc="The reading direction.")
1924
1926 """Returns this relation's target object.
1927
1928 Note that URL relations never have a target object. Use the
1929 L{getTargetId} method to get the URL.
1930
1931 @return: a subclass of L{Entity}, or None
1932 """
1933 return self._target
1934
1936 """Sets this relation's target object.
1937
1938 Note that URL relations never have a target object, they
1939 are set using L{setTargetId}.
1940
1941 @param target: a subclass of L{Entity}
1942 """
1943 self._target = target
1944
1945 target = property(getTarget, setTarget,
1946 doc="The relation's target object.")
1947
1948
1950 """A release event, indicating where and when a release took place.
1951
1952 All country codes used must be valid ISO-3166 country codes (i.e. 'DE',
1953 'UK' or 'FR'). The dates are strings and must have the format 'YYYY',
1954 'YYYY-MM' or 'YYYY-MM-DD'.
1955
1956 The format of the release medium is a URI that can be compared to the
1957 constants on this class (L{FORMAT_CD}, L{FORMAT_DVD} and others).
1958 """
1959 FORMAT_CD = NS_MMD_1 + 'CD'
1960 FORMAT_DVD = NS_MMD_1 + 'DVD'
1961 FORMAT_SACD = NS_MMD_1 + 'SACD'
1962 FORMAT_DUALDISC = NS_MMD_1 + 'DualDisc'
1963 FORMAT_LASERDISC = NS_MMD_1 + 'LaserDisc'
1964 FORMAT_MINIDISC = NS_MMD_1 + 'MiniDisc'
1965 FORMAT_VINYL = NS_MMD_1 + 'Vinyl'
1966 FORMAT_CASSETTE = NS_MMD_1 + 'Cassette'
1967 FORMAT_CARTRIDGE = NS_MMD_1 + 'Cartridge'
1968 FORMAT_REEL_TO_REEL = NS_MMD_1 + 'ReelToReel'
1969 FORMAT_DAT = NS_MMD_1 + 'DAT'
1970 FORMAT_DIGITAL = NS_MMD_1 + 'Digital'
1971 FORMAT_WAX_CYLINDER = NS_MMD_1 + 'WaxCylinder'
1972 FORMAT_PIANO_ROLL = NS_MMD_1 + 'PianoRoll'
1973 FORMAT_OTHER = NS_MMD_1 + 'Other'
1974
1975 - def __init__(self, country=None, dateStr=None):
1976 """Constructor.
1977
1978 @param country: a string containing an ISO-3166 country code
1979 @param dateStr: a string containing a date string
1980 """
1981 self._countryId = country
1982 self._dateStr = dateStr
1983 self._catalogNumber = None
1984 self._barcode = None
1985 self._label = None
1986 self._format = None
1987
1989 """Returns the country a release took place.
1990
1991 @note: Due to a server limitation, the web service does not
1992 return country IDs for release collection queries. This only
1993 affects the L{musicbrainz2.webservice.Query.getReleases} query.
1994
1995 @return: a string containing an ISO-3166 country code, or None
1996
1997 @see: L{musicbrainz2.utils.getCountryName}
1998 """
1999 return self._countryId
2000
2002 """Sets the country a release took place.
2003
2004 @param country: a string containing an ISO-3166 country code
2005 """
2006 self._countryId = country
2007
2008 country = property(getCountry, setCountry,
2009 doc='The country a release took place.')
2010
2012 """Returns the catalog number of this release event.
2013
2014 @return: A string containing the catalog number, or None
2015 """
2016 return self._catalogNumber
2017
2019 """Sets the catalog number of this release event.
2020
2021 @param catalogNumber: A string containing the catalog number
2022 """
2023 self._catalogNumber = catalogNumber
2024
2025 catalogNumber = property(getCatalogNumber, setCatalogNumber,
2026 doc='The catalog number of the release event')
2027
2029 """Returns the barcode of this release event.
2030
2031 @return: A string containing the barcode, or None
2032 """
2033 return self._barcode
2034
2036 """Sets the barcode of this release event.
2037
2038 @param barcode: A string containing the barcode
2039 """
2040 self._barcode = barcode
2041
2042 barcode = property(getBarcode, setBarcode,
2043 doc='The barcode of the release event')
2044
2046 """Returns a L{Label} object for the label associated with this release.
2047
2048 @return: a L{Label} object, or None
2049 """
2050 return self._label
2051
2053 """Sets the label of this release event.
2054
2055 @param label: A L{Label} object
2056 """
2057 self._label = label
2058
2059 label = property(getLabel, setLabel, doc='The label of the release')
2060
2062 """Returns the date a release took place.
2063
2064 @return: a string containing a date
2065 """
2066 return self._dateStr
2067
2069 """Sets the date a release took place.
2070
2071 @param dateStr: a string containing a date
2072 """
2073 self._dateStr = dateStr
2074
2075 date = property(getDate, setDate, doc='The date a release took place.')
2076
2083
2090
2091 format = property(getFormat, setFormat,
2092 doc='The format of the release medium.')
2093
2094
2096 """Represents a CD Stub"""
2097
2099 """Constructor.
2100
2101 @param disc: a L{Disc} object to create this CD Stub from
2102 """
2103 assert isinstance(disc, Disc), 'musicbrainz2.model.Disc expected'
2104 self._disc = disc
2105 self._tracks = [ ]
2106 self._title = ""
2107 self._artist = ""
2108 self._barcode = ""
2109 self._comment = ""
2110
2112 """Sets the title of this release.
2113
2114 @param title: a string containing the title
2115 """
2116 self._title = title
2117
2119 """Returns the title of this release.
2120
2121 @return: a string containing the title
2122 """
2123 return self._title
2124
2125 title = property(getTitle, setTitle,
2126 doc='The title of the release')
2127
2129 """Sets the artist of this release.
2130
2131 @param artist: a string containing the artist
2132 """
2133 self._artist = artist
2134
2136 """Returns the artist of this release.
2137
2138 @return: a string containing the artist
2139 """
2140 return self._artist
2141
2142 artist = property(getArtist, setArtist,
2143 doc='The artist of the release')
2144
2151
2158
2159 comment = property(getComment, setComment,
2160 doc='Comment for the release (optional)')
2161
2163 """Sets the barcode of this release.
2164
2165 @param barcode: a string containing the barcode
2166 """
2167 self._barcode = barcode
2168
2170 """Returns the barcode of this release.
2171
2172 @return: a string containing the barcode
2173 """
2174 return self._barcode
2175
2176 barcode = property(getBarcode, setBarcode,
2177 doc='Barcode for the release (optional)')
2178
2180 """Add a track to this release
2181
2182 @param title: a string containing the title of the track
2183 @param artist: a string containing the artist of the track,
2184 if different to the album artist
2185 """
2186 self._tracks.append((title, artist))
2187
2189 """Return all the tracks on the release.
2190
2191 @return: a list of tuples containing (title, artist) pairs
2192 for each track
2193 """
2194 return self._tracks
2195
2196 tracks = property(getTracks, doc='The tracks of the release.')
2197
2198 -class Disc(object):
2199 """Represents an Audio CD.
2200
2201 This class represents an Audio CD. A disc can have an ID (the
2202 MusicBrainz DiscID), which is calculated from the CD's table of
2203 contents (TOC). There may also be data from the TOC like the length
2204 of the disc in sectors, as well as position and length of the tracks.
2205
2206 Note that different TOCs, maybe due to different pressings, lead to
2207 different DiscIDs. Conversely, if two different discs have the same
2208 TOC, they also have the same DiscID (which is unlikely but not
2209 impossible). DiscIDs are always 28 characters long and look like this:
2210 C{'J68I_CDcUFdCRCIbHSEbTBCbooA-'}. Sometimes they are also referred
2211 to as CDIndex IDs.
2212
2213 The L{MusicBrainz web service <musicbrainz2.webservice>} only returns
2214 the DiscID and the number of sectors. The DiscID calculation function
2215 L{musicbrainz2.disc.readDisc}, however, can retrieve the other
2216 attributes of L{Disc} from an Audio CD in the disc drive.
2217 """
2219 """Constructor.
2220
2221 @param id_: a string containing a 28-character DiscID
2222 """
2223 self._id = id_
2224 self._sectors = None
2225 self._firstTrackNum = None
2226 self._lastTrackNum = None
2227 self._tracks = [ ]
2228
2230 """Returns the MusicBrainz DiscID.
2231
2232 @return: a string containing a 28-character DiscID
2233 """
2234 return self._id
2235
2237 """Sets the MusicBrainz DiscId.
2238
2239 @param id_: a string containing a 28-character DiscID
2240 """
2241 self._id = id_
2242
2243 id = property(getId, setId, doc="The MusicBrainz DiscID.")
2244
2246 """Returns the length of the disc in sectors.
2247
2248 @return: the length in sectors as an integer, or None
2249 """
2250 return self._sectors
2251
2253 """Sets the length of the disc in sectors.
2254
2255 @param sectors: the length in sectors as an integer
2256 """
2257 self._sectors = sectors
2258
2259 sectors = property(getSectors, setSectors,
2260 doc="The length of the disc in sectors.")
2261
2263 """Returns the number of the first track on this disc.
2264
2265 @return: an int containing the track number, or None
2266 """
2267 return self._firstTrackNum
2268
2270 """Sets the number of the first track on this disc.
2271
2272 @param trackNum: an int containing the track number, or None
2273 """
2274 self._firstTrackNum = trackNum
2275
2276 firstTrackNum = property(getFirstTrackNum, setFirstTrackNum,
2277 doc="The number of the first track on this disc.")
2278
2280 """Returns the number of the last track on this disc.
2281
2282 @return: an int containing the track number, or None
2283 """
2284 return self._lastTrackNum
2285
2287 """Sets the number of the last track on this disc.
2288
2289 @param trackNum: an int containing the track number, or None
2290 """
2291 self._lastTrackNum = trackNum
2292
2293 lastTrackNum = property(getLastTrackNum, setLastTrackNum,
2294 doc="The number of the last track on this disc.")
2295
2297 """Returns the sector offset and length of this disc.
2298
2299 This method returns a list of tuples containing the track
2300 offset and length in sectors for all tracks on this disc.
2301 The track offset is measured from the beginning of the disc,
2302 the length is relative to the track's offset. Note that the
2303 leadout track is I{not} included.
2304
2305 @return: a list of (offset, length) tuples (values are ints)
2306 """
2307 return self._tracks
2308
2309 tracks = property(getTracks,
2310 doc='Sector offset and length of all tracks.')
2311
2313 """Adds a track to the list.
2314
2315 This method adds an (offset, length) tuple to the list of
2316 tracks. The leadout track must I{not} be added. The total
2317 length of the disc can be set using L{setSectors}.
2318
2319 @param track: an (offset, length) tuple (values are ints)
2320
2321 @see: L{getTracks}
2322 """
2323 self._tracks.append(track)
2324
2325
2327 """An abstract super class for all alias classes."""
2328 - def __init__(self, value=None, type_=None, script=None):
2329 """Constructor.
2330
2331 @param value: a string containing the alias
2332 @param type_: a string containing an absolute URI
2333 @param script: a string containing an ISO-15924 script code
2334 """
2335 self._value = value
2336 self._type = type_
2337 self._script = script
2338
2340 """Returns the alias.
2341
2342 @return: a string containing the alias
2343 """
2344 return self._value
2345
2347 """Sets the alias.
2348
2349 @param value: a string containing the alias
2350 """
2351 self._value = value
2352
2353 value = property(getValue, setValue, doc='The alias value.')
2354
2356 """Returns the alias type.
2357
2358 @return: a string containing an absolute URI, or None
2359 """
2360 return self._type
2361
2363 """Sets the alias type.
2364
2365 @param type_: a string containing an absolute URI, or None
2366 """
2367 self._type = type_
2368
2369 type = property(getType, setType, doc='The alias type.')
2370
2372 """Returns the alias script.
2373
2374 @return: a string containing an ISO-15924 script code
2375 """
2376 return self._script
2377
2379 """Sets the alias script.
2380
2381 @param script: a string containing an ISO-15924 script code
2382 """
2383 self._script = script
2384
2385 script = property(getScript, setScript, doc='The alias script.')
2386
2387
2389 """Represents an artist alias.
2390
2391 An alias (the I{alias value}) is a different representation of an
2392 artist's name. This may be a common misspelling or a transliteration
2393 (the I{alias type}).
2394
2395 The I{alias script} is interesting mostly for transliterations and
2396 indicates which script is used for the alias value. To represent the
2397 script, ISO-15924 script codes like 'Latn', 'Cyrl', or 'Hebr' are used.
2398 """
2399 pass
2400
2401
2403 """Represents a label alias.
2404
2405 An alias (the I{alias value}) is a different representation of a
2406 label's name. This may be a common misspelling or a transliteration
2407 (the I{alias type}).
2408
2409 The I{alias script} is interesting mostly for transliterations and
2410 indicates which script is used for the alias value. To represent the
2411 script, ISO-15924 script codes like 'Latn', 'Cyrl', or 'Hebr' are used.
2412 """
2413 pass
2414
2415
2416 -class User(object):
2417 """Represents a MusicBrainz user."""
2418
2420 """Constructor."""
2421 self._name = None
2422 self._types = [ ]
2423 self._showNag = None
2424
2426 """Returns the user name.
2427
2428 @return: a string containing the user name
2429 """
2430 return self._name
2431
2433 """Sets the user name.
2434
2435 @param name: a string containing the user name
2436 """
2437 self._name = name
2438
2439 name = property(getName, setName, doc='The MusicBrainz user name.')
2440
2442 """Returns the types of this user.
2443
2444 Most users' type list is empty. Currently, the following types
2445 are defined:
2446
2447 - 'http://musicbrainz.org/ns/ext-1.0#AutoEditor'
2448 - 'http://musicbrainz.org/ns/ext-1.0#RelationshipEditor'
2449 - 'http://musicbrainz.org/ns/ext-1.0#Bot'
2450 - 'http://musicbrainz.org/ns/ext-1.0#NotNaggable'
2451
2452 @return: a list of strings containing absolute URIs
2453 """
2454 return self._types
2455
2456 types = property(getTypes, doc="The user's types.")
2457
2459 """Add a type to the list of types.
2460
2461 @param type_: a string containing absolute URIs
2462
2463 @see: L{getTypes}
2464 """
2465 self._types.append(type_)
2466
2468 """Returns true if a nag screen should be displayed to the user.
2469
2470 @return: C{True}, C{False}, or None
2471 """
2472 return self._showNag
2473
2475 """Sets the value of the nag screen flag.
2476
2477 If set to C{True},
2478
2479 @param value: C{True} or C{False}
2480
2481 @see: L{getShowNag}
2482 """
2483 self._showNag = value
2484
2485 showNag = property(getShowNag, setShowNag,
2486 doc='The value of the nag screen flag.')
2487
2488
2489