def from_tracks(cls, tracks): def track_string(track, album_artist, metadata): if (track.track_number() in metadata.keys()): metadata = metadata[track.track_number()] if (metadata.artist_name == album_artist): return metadata.track_name else: return u"%s / %s" % (metadata.artist_name, metadata.track_name) else: return u"" audiofiles = [f for f in tracks if f.track_number() != 0] audiofiles.sort(lambda t1, t2: cmp(t1.track_number(), t2.track_number())) discid = DiscID([track.cd_frames() for track in audiofiles]) metadata = dict([(t.track_number(), t.get_metadata()) for t in audiofiles if (t.get_metadata() is not None)]) artist_names = [m.artist_name for m in metadata.values()] if (len(artist_names) == 0): album_artist = u"" elif ((len(artist_names) > 1) and (len(set(artist_names)) == len(artist_names))): #if all track artists are different, don't pick one album_artist = u"Various" else: album_artist = __most_numerous__(artist_names) return cls(dict([("DISCID", str(discid).decode('ascii')), ("DTITLE", u"%s / %s" % \ (album_artist, __most_numerous__([m.album_name for m in metadata.values()]))), ("DYEAR", __most_numerous__([m.year for m in metadata.values()])), ("EXTDD", u""), ("PLAYORDER", u"")] + \ [("TTITLE%d" % (track.track_number() - 1), track_string(track, album_artist, metadata)) for track in audiofiles] + \ [("EXTT%d" % (track.track_number() - 1), u"") for track in audiofiles]), [u"# xmcd", u"#", u"# Track frame offsets:"] + [u"#\t%d" % (offset) for offset in discid.offsets()] + [u"#", u"# Disc length: %d seconds" % ( (discid.length() / 75) + 2), u"#"])
def from_tracks(cls, tracks): def track_string(track, album_artist, metadata): if (track.track_number() in metadata.keys()): metadata = metadata[track.track_number()] if (metadata.artist_name == album_artist): return metadata.track_name else: return u"%s / %s" % (metadata.artist_name, metadata.track_name) else: return u"" audiofiles = [f for f in tracks if f.track_number() != 0] audiofiles.sort( lambda t1, t2: cmp(t1.track_number(), t2.track_number())) discid = DiscID([track.cd_frames() for track in audiofiles]) metadata = dict([(t.track_number(), t.get_metadata()) for t in audiofiles if (t.get_metadata() is not None)]) artist_names = [m.artist_name for m in metadata.values()] if (len(artist_names) == 0): album_artist = u"" elif ((len(artist_names) > 1) and (len(set(artist_names)) == len(artist_names))): #if all track artists are different, don't pick one album_artist = u"Various" else: album_artist = __most_numerous__(artist_names) return cls(dict([("DISCID", str(discid).decode('ascii')), ("DTITLE", u"%s / %s" % \ (album_artist, __most_numerous__([m.album_name for m in metadata.values()]))), ("DYEAR", __most_numerous__([m.year for m in metadata.values()])), ("EXTDD", u""), ("PLAYORDER", u"")] + \ [("TTITLE%d" % (track.track_number() - 1), track_string(track, album_artist, metadata)) for track in audiofiles] + \ [("EXTT%d" % (track.track_number() - 1), u"") for track in audiofiles]), [u"# xmcd", u"#", u"# Track frame offsets:"] + [u"#\t%d" % (offset) for offset in discid.offsets()] + [u"#", u"# Disc length: %d seconds" % ( (discid.length() / 75) + 2), u"#"])
def from_tracks(cls, tracks): """Returns a MusicBrainzReleaseXML from a list of AudioFile objects. These objects are presumably from the same album. If not, these heuristics may generate something unexpected. """ from xml.dom.minidom import parseString def make_text_node(document, tagname, text): node = document.createElement(tagname) node.appendChild(document.createTextNode(text)) return node tracks.sort(lambda x, y: cmp(x.track_number(), y.track_number())) #our base DOM to start with dom = parseString('<?xml version="1.0" encoding="UTF-8"?>' + '<metadata xmlns="http://musicbrainz.org/' + 'ns/mmd-1.0#" xmlns:ext="http://musicbrainz.org/' + 'ns/ext-1.0#"></metadata>') release = dom.createElement(u'release') track_metadata = [t.get_metadata() for t in tracks if (t.get_metadata() is not None)] #add album title release.appendChild(make_text_node( dom, u'title', unicode(__most_numerous__( [m.album_name for m in track_metadata])))) #add album artist if (len(set([m.artist_name for m in track_metadata])) < len(track_metadata)): artist = dom.createElement(u'artist') album_artist = unicode(__most_numerous__( [m.artist_name for m in track_metadata])) artist.appendChild(make_text_node(dom, u'name', album_artist)) release.appendChild(artist) else: album_artist = u'' # all track artist names differ artist = dom.createElement(u'artist') artist.appendChild(make_text_node(dom, u'name', album_artist)) release.appendChild(artist) #add release info (catalog number, release date, media, etc.) event_list = dom.createElement(u'release-event-list') event = dom.createElement(u'event') year = unicode(__most_numerous__( [m.year for m in track_metadata])) if (year != u""): event.setAttribute(u'date', year) catalog_number = unicode(__most_numerous__( [m.catalog for m in track_metadata])) if (catalog_number != u""): event.setAttribute(u'catalog-number', catalog_number) media = unicode(__most_numerous__( [m.media for m in track_metadata])) if (media != u""): event.setAttribute(u'format', media) event_list.appendChild(event) release.appendChild(event_list) #add tracks track_list = dom.createElement(u'track-list') for track in tracks: node = dom.createElement(u'track') track_metadata = track.get_metadata() if (track_metadata is not None): node.appendChild(make_text_node( dom, u'title', track_metadata.track_name)) else: node.appendChild(make_text_node( dom, u'title', u'')) node.appendChild(make_text_node( dom, u'duration', unicode((track.total_frames() * 1000) / track.sample_rate()))) if (track_metadata is not None): #add track artist, if different from album artist if (track_metadata.artist_name != album_artist): artist = dom.createElement(u'artist') artist.appendChild(make_text_node( dom, u'name', track_metadata.artist_name)) node.appendChild(artist) track_list.appendChild(node) release.appendChild(track_list) release_list = dom.createElement(u'release-list') release_list.appendChild(release) dom.getElementsByTagName(u'metadata')[0].appendChild(release_list) return cls(dom)