def addContributor(self, c): r''' Assign a :class:`~music21.metadata.Contributor` object to this Metadata. >>> md = metadata.Metadata(title='Gaelic Symphony') >>> c = metadata.Contributor() >>> c.name = 'Beach, Amy' >>> c.role = 'composer' >>> md.addContributor(c) >>> md.composer 'Beach, Amy' Add maiden name as an alternative composer name: >>> md.composer = 'Cheney, Amy Marcy' >>> md.composers ['Beach, Amy', 'Cheney, Amy Marcy'] All contributor roles are searchable, even if they are not standard roles: >>> md.search('Beach') (True, 'composer') >>> dancer = metadata.Contributor() >>> dancer.names = ['Mark Gotham', 'I. Quinn'] >>> dancer.role = 'interpretive dancer' >>> md.addContributor(dancer) >>> md.search('Gotham') (True, 'interpretive dancer') ''' if not isinstance(c, Contributor): raise exceptions21.MetadataException( 'supplied object is not a Contributor: %s' % c) self.contributors.append(c)
def read(self, filePath=None): r''' Load cached metadata from the file path suggested by the name of this MetadataBundle ('core', 'local', or a name). If a specific filepath is given with the `filePath` keyword, attempt to load cached metadata from the file at that location. If `filePath` is None, and `self.filePath` is also None, do nothing. >>> #_DOCS_SHOW coreBundle = metadata.bundles.MetadataBundle('core').read() If a metadata is unnamed, and no file path is specified, an exception will be thrown: >>> anonymousBundle = metadata.bundles.MetadataBundle().read() Traceback (most recent call last): music21.exceptions21.MetadataException: Unnamed MetadataBundles have no default file path to read from. ''' timer = common.Timer() timer.start() if filePath is None: filePath = self.filePath if filePath is None and self.name is None: raise exceptions21.MetadataException( 'Unnamed MetadataBundles have no default file path to read ' 'from.') if not isinstance(filePath, pathlib.Path): filePath = pathlib.Path(filePath) if not filePath.exists(): environLocal.printDebug('no metadata found for: {0!r}; ' 'try building cache with corpus.cacheMetadata({1!r})'.format( self.name, self.name)) return self with gzip.open(str(filePath), 'rb') as pickledFile: try: uncompressed = pickledFile.read() newMdb = pickle.loads(uncompressed) except Exception as e: # pylint: disable=broad-except # pickle exceptions cannot be caught directly # because they might come from pickle or _pickle and the latter cannot # be caught. raise MetadataBundleException('Cannot load file ' + str(filePath)) from e self._metadataEntries = newMdb._metadataEntries environLocal.printDebug([ 'MetadataBundle: loading time:', self.name, timer(), 'md items:', len(self._metadataEntries) ]) return self
def workIdToAbbreviation(value): '''Get a work abbreviation from a string representation. :: >>> from music21 import metadata >>> metadata.Metadata.workIdToAbbreviation('localeOfComposition') 'opc' :: >>> for n in metadata.Metadata.workIdAbbreviationDict.values(): ... result = metadata.Metadata.workIdToAbbreviation(n) ... ''' # NOTE: this is a performance critical function try: # try direct access, where keys are already lower case return Metadata.workIdLookupDict[value] except KeyError: pass # slow approach for workId in Metadata.workIdAbbreviationDict.keys(): if value.lower() == \ Metadata.workIdAbbreviationDict[workId].lower(): return workId raise exceptions21.MetadataException('no such work id: %s' % value)
def addContributor(self, c): r''' Assign a :class:`~music21.metadata.Contributor` object to this Metadata. :: >>> from music21 import metadata >>> md = metadata.Metadata(title='Third Symphony') >>> c = metadata.Contributor() >>> c.name = 'Beethoven, Ludwig van' >>> c.role = 'composer' >>> md.addContributor(c) >>> md.composer 'Beethoven, Ludwig van' :: >>> md.composer = 'frank' >>> md.composers ['Beethoven, Ludwig van', 'frank'] ''' if not isinstance(c, Contributor): raise exceptions21.MetadataException( 'supplied object is not a Contributor: %s' % c) self._contributors.append(c)
def names(self, values): if not common.isIterable(values): raise exceptions21.MetadataException( '.names must be a list -- do you mean .name instead?') self._names = [] # reset for n in values: self._names.append(Text(n))
def relevance(self, value): if value == 'before': value = 'prior' if value.lower() not in ('prior', 'after', 'onorbefore', 'onorafter'): raise exceptions21.MetadataException( f'Relevance value is not supported by this object: {value!r}') self._relevance = value.lower()
def role(self, value): if value is None or value in self.roleAbbreviationsDict.values(): self._role = value elif value in self.roleAbbreviationsDict.keys(): self._role = self.roleAbbreviationsDict[value] else: raise exceptions21.MetadataException( 'Role value is not supported by this object: ' '{0!r}'.format(value))
def relevance(self, value): if value in ('certain', 'approximate', 'uncertain'): self._relevance = value self._dataError = [] # only here is dataError the same as relevance self._dataError.append(value) else: raise exceptions21.MetadataException( f'Relevance value is not supported by this object: {value!r}')
def roleToAbbreviation(roleName): '''Convert `roleName` to role abbreviation: >>> metadata.Contributor.roleToAbbreviation('composer') 'com' ''' # note: probably not the fastest way to do this for role_id in Contributor.roleAbbreviationsDict: if roleName.lower() == Contributor.roleAbbreviationsDict[role_id].lower(): return role_id raise exceptions21.MetadataException('No such role: %s' % roleName)
def setWorkId(self, idStr, value): r''' Directly set a workd id, given either as a full string name or as a three character abbreviation. The following work id abbreviations and their full id string are given as follows. In many cases the Metadata object support properties for convenient access to these work ids. Id abbreviations and strings: otl / title, otp / popularTitle, ota / alternativeTitle, opr / parentTitle, oac / actNumber, osc / sceneNumber, omv / movementNumber, omd / movementName, ops / opusNumber, onm / number, ovm / volume, ode / dedication, oco / commission, gtl / groupTitle, gaw / associatedWork, gco / collectionDesignation, txo / textOriginalLanguage, txl / textLanguage, ocy / countryOfComposition, opc / localeOfComposition. :: >>> from music21 import metadata >>> md = metadata.Metadata(title='Quartet') >>> md.title 'Quartet' :: >>> md.setWorkId('otl', 'Trio') >>> md.title 'Trio' :: >>> md.setWorkId('sdf', None) Traceback (most recent call last): MetadataException: no work id available with id: sdf ''' idStr = idStr.lower() match = False for abbreviation, workId in self.workIdAbbreviationDict.items(): #for id in WORK_IDS: #abbreviation = workIdToAbbreviation(id) if workId.lower() == idStr: self._workIds[workId] = Text(value) match = True break elif abbreviation == idStr: self._workIds[workId] = Text(value) match = True break if not match: raise exceptions21.MetadataException( 'no work id available with id: %s' % idStr)
def read(self, filePath=None): r''' Load cached metadata from the file path suggested by the name of this MetadataBundle ('core', 'local', or a name). If a specific filepath is given with the `filePath` keyword, attempt to load cached metadata from the file at that location. If `filePath` is None, and `self.filePath` is also None, do nothing. >>> #_DOCS_SHOW coreBundle = metadata.bundles.MetadataBundle('core').read() If a metadata is unnamed, and no file path is specified, an exception will be thrown: >>> anonymousBundle = metadata.bundles.MetadataBundle().read() Traceback (most recent call last): music21.exceptions21.MetadataException: Unnamed MetadataBundles have no default file path to read from. ''' timer = common.Timer() timer.start() if filePath is None: filePath = self.filePath if filePath is None and self.name is None: raise exceptions21.MetadataException( 'Unnamed MetadataBundles have no default file path to read ' 'from.') if not isinstance(filePath, pathlib.Path): filePath = pathlib.Path(filePath) if not filePath.exists(): environLocal.printDebug('no metadata found for: {0!r}; ' 'try building cache with corpus.cacheMetadata({1!r})'.format( self.name, self.name)) return self newMdb = readPickleGzip(filePath) self._metadataEntries = newMdb._metadataEntries environLocal.printDebug([ 'MetadataBundle: loading time:', self.name, timer(), 'md items:', len(self._metadataEntries) ]) return self
def abbreviationToWorkId(abbreviation): '''Get work id abbreviations. >>> metadata.Metadata.abbreviationToWorkId('otl') 'title' >>> for work_id in metadata.Metadata.workIdAbbreviationDict: ... result = metadata.Metadata.abbreviationToWorkId(work_id) ''' abbreviation = abbreviation.lower() if abbreviation not in Metadata.workIdAbbreviationDict: raise exceptions21.MetadataException('no such work id: %s' % abbreviation) return Metadata.workIdAbbreviationDict[abbreviation]
def abbreviationToRole(abbreviation): r''' Convert `abbreviation` to role name: >>> metadata.Contributor.abbreviationToRole('com') 'composer' >>> metadata.Contributor.abbreviationToRole('lib') 'librettist' ''' abbreviation = abbreviation.lower() if abbreviation in Contributor.roleAbbreviationsDict: return Contributor.roleAbbreviationsDict[abbreviation] else: raise exceptions21.MetadataException( 'no such role: {0!r}'.format(abbreviation))
def read(self, filePath=None): r''' Load cached metadata from the file path suggested by the name of this MetadataBundle ('core', 'local', or 'virtual'). If a specific filepath is given with the `filePath` keyword, attempt to load cached metadata from the file at that location. If `filePath` is None, and `self.filePath` is also None, do nothing. :: >>> from music21 import metadata >>> virtualBundle = metadata.MetadataBundle('virtual').read() If a metadata is unnamed, and no file path is specified, an exception will be thrown: :: >>> anonymousBundle = metadata.MetadataBundle().read() Traceback (most recent call last): MetadataException: Unnamed MetadataBundles have no default file path to read from. ''' timer = common.Timer() timer.start() if filePath is None: filePath = self.filePath if filePath is None and self.name is None: raise exceptions21.MetadataException( 'Unnamed MetadataBundles have no default file path to read ' 'from.') if not os.path.exists(filePath): environLocal.printDebug( 'no metadata found for: {0!r}; ' 'try building cache with corpus.cacheMetadata({1!r})'.format( self.name, self.name)) return self jst = freezeThaw.JSONThawer(self) jst.jsonRead(filePath) environLocal.printDebug([ 'MetadataBundle: loading time:', self.name, timer, 'md items:', len(self._metadataEntries) ]) return self
def load(self, value): r''' Load values by string, datetime object, or Date object: >>> a = metadata.Date(year=1843, month=3, day=3) >>> b = metadata.Date() >>> b.load(a) >>> b.year 1843 ''' if isinstance(value, datetime.datetime): self.loadDatetime(value) elif isinstance(value, six.string_types): self.loadStr(value) elif isinstance(value, Date): self.loadOther(value) else: raise exceptions21.MetadataException('Cannot load data: %s' % value)
def addContributor(self, c): r''' Assign a :class:`~music21.metadata.Contributor` object to this Metadata. >>> md = metadata.Metadata(title='Gaelic Symphony') >>> c = metadata.Contributor() >>> c.name = 'Beach, Amy' >>> c.role = 'composer' >>> md.addContributor(c) >>> md.composer 'Beach, Amy' Add maiden name as an alternative composer name: >>> c_alt = metadata.Contributor() >>> c_alt.name = 'Cheney, Amy Marcy' >>> c_alt.role = 'composer' >>> md.addContributor(c_alt) >>> md.composers ['Beach, Amy', 'Cheney, Amy Marcy'] >>> md.search('Beach') (True, 'composer') >>> md.search('Cheney') (True, 'composer') Note that in this case, a "composerAlias" would probably be a more appropriate role than a second composer. All contributor roles are searchable, even if they are not standard roles: >>> dancer = metadata.Contributor() >>> dancer.names = ['Merce Cunningham', 'Martha Graham'] >>> dancer.role = 'interpretive dancer' >>> md.addContributor(dancer) >>> md.search('Cunningham') (True, 'interpretive dancer') ''' if not isinstance(c, Contributor): raise exceptions21.MetadataException( 'supplied object is not a Contributor: %s' % c) self.contributors.append(c)
def abbreviationToWorkId(abbreviation): '''Get work id abbreviations. :: >>> from music21 import metadata >>> metadata.Metadata.abbreviationToWorkId('otl') 'title' :: >>> for id in metadata.Metadata.workIdAbbreviationDict.keys(): ... result = metadata.Metadata.abbreviationToWorkId(id) ... ''' abbreviation = abbreviation.lower() if abbreviation not in Metadata.workIdAbbreviationDict: raise exceptions21.MetadataException('no such work id: %s' % abbreviation) return Metadata.workIdAbbreviationDict[abbreviation]
def workIdToAbbreviation(value): '''Get a work abbreviation from a string representation. >>> metadata.Metadata.workIdToAbbreviation('localeOfComposition') 'opc' Static method. ''' # NOTE: this is a performance critical function try: # try direct access, where keys are already lower case return Metadata.workIdLookupDict[value] except KeyError: pass vl = value.lower() # slow approach for workId in Metadata.workIdAbbreviationDict: if vl == Metadata.workIdAbbreviationDict[workId].lower(): return workId raise exceptions21.MetadataException('no such work id: %s' % value)
def addContributor(self, c): r''' Assign a :class:`~music21.metadata.Contributor` object to this Metadata. >>> md = metadata.Metadata(title='Gaelic Symphony') >>> c = metadata.Contributor() >>> c.name = 'Beach, Amy' >>> c.role = 'composer' >>> md.addContributor(c) >>> md.composer 'Beach, Amy' Add maiden name as an alternative composer name: >>> md.composer = 'Cheney, Amy Marcy' >>> md.composers ['Beach, Amy', 'Cheney, Amy Marcy'] ''' if not isinstance(c, Contributor): raise exceptions21.MetadataException( 'supplied object is not a Contributor: %s' % c) self.contributors.append(c)
def relevance(self, value): if value != 'or': raise exceptions21.MetadataException( f'Relevance value is not supported by this object: {value!r}') self._relevance = value
def relevance(self, value): if value != 'or': raise exceptions21.MetadataException( 'Relevance value is not supported by this object: ' '{0!r}'.format(value)) self._relevance = value