Package musicbrainz2 :: Module model
[frames] | no frames]

Source Code for Module musicbrainz2.model

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