annotate musixmatch-master/build/lib/musixmatch/track.py @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 8c29444cb5fd
children
rev   line source
yading@7 1 """
yading@7 2 This module contains higher level classes to query Musixmatch API and build
yading@7 3 simple dictionary-like objects representing a Track or a TracksCollection.
yading@7 4
yading@7 5 >>> from musixmatch.track import Track, TracksCollection
yading@7 6 >>> import musixmatch.api
yading@7 7 >>>
yading@7 8 >>> try:
yading@7 9 ... track = Track(track_mbid=8976)
yading@7 10 ... collection = TracksCollection.fromChart(country='us', page=1)
yading@7 11 ... except musixmatch.api.Error, e:
yading@7 12 ... pass
yading@7 13 """
yading@7 14 import musixmatch
yading@7 15 __license__ = musixmatch.__license__
yading@7 16 __author__ = musixmatch.__author__
yading@7 17
yading@7 18 from musixmatch import api, lyrics, subtitle
yading@7 19 from musixmatch.base import Item, ItemsCollection
yading@7 20 from musixmatch.ws import track, matcher, album
yading@7 21
yading@7 22 _marker=object()
yading@7 23
yading@7 24 class Track(Item):
yading@7 25 """
yading@7 26 This class builds a :py:class:`dict` like object representing a track. It
yading@7 27 can get track information through the :py:class:`musixmatch.api.Method`
yading@7 28 **track.get** or from an already well-formed :py:class:`dict`. Create a
yading@7 29 Track object based on a given keyword argument:
yading@7 30
yading@7 31 :param track_id: musiXmatch track ID
yading@7 32 :param musicbrainz_id: Musicbrainz track ID
yading@7 33 :param track_echonest_id: Echonest track ID
yading@7 34 :param track_data: an already well-formed :py:class:`dict` of track data
yading@7 35 :raises: :py:exc:`musixmatch.api.Error` if :py:class:`musixmatch.api.ResponseStatusCode` is not 200
yading@7 36
yading@7 37 Once information are collected, the following keys are available:
yading@7 38
yading@7 39 :keyword track_id: musiXmatch track ID
yading@7 40 :keyword track_mbid: Musicbrainz track ID
yading@7 41 :keyword lyrics_id: musiXmatch lyrics ID
yading@7 42 :keyword instrumental: wether the track is instrumental or not
yading@7 43 :keyword subtitle_id: musiXmatch subtitle ID
yading@7 44 :keyword track_name: track name
yading@7 45 :keyword album_coverart_100x100: album cover URL
yading@7 46 :keyword artist_id: musiXmatch artist ID
yading@7 47 :keyword artist_mbid: Musicbrainz artist ID
yading@7 48 :keyword artist_name: artist name
yading@7 49
yading@7 50 Keyword access have been overloaded thanks to the :py:meth:`get` method
yading@7 51 which will eventually fetch the matching lyrics or subtitle.
yading@7 52 """
yading@7 53 __api_method__ = track.get
yading@7 54
yading@7 55 @classmethod
yading@7 56 def fromMatcher(cls, **keywords):
yading@7 57 """
yading@7 58 Returns a :py:class:`Track` based on the result of the
yading@7 59 :py:class:`musiXmatch.api.Method` **matcher.track.get**. Accepts the
yading@7 60 following keywords:
yading@7 61
yading@7 62 :param q_track: words to be searched among track titles
yading@7 63 :param q_artist: words to be searched among artist names
yading@7 64 """
yading@7 65 return cls.fromResponseMessage(matcher.track.get(**keywords))
yading@7 66
yading@7 67 def get(self, key, default=_marker):
yading@7 68 """
yading@7 69 If key is *lyrics* or *subtitle* try to query api for proper value,
yading@7 70 and build an :py:class:`musixmatch.lyrics.Lyrics` or
yading@7 71 :py:class:`musixmatch.subtitle.Subtitle`. Access to the above mentioned
yading@7 72 keys may fail with :py:exc:`musixmatch.api.Error`. Once fetched, the
yading@7 73 result is saved.
yading@7 74 """
yading@7 75 special = {
yading@7 76 'lyrics': lyrics.Lyrics,
yading@7 77 'subtitle': subtitle.Subtitle,
yading@7 78 }
yading@7 79 if key in special and not key in self:
yading@7 80 self[key] = special[key](track_id=self['track_id'])
yading@7 81 value = dict.get(self, key, default)
yading@7 82 if value == _marker:
yading@7 83 raise KeyError, key
yading@7 84 return value
yading@7 85
yading@7 86 def __getitem__(self, key):
yading@7 87 return self.get(key)
yading@7 88
yading@7 89 def postFeedback(self, feedback):
yading@7 90 """
yading@7 91 Post feedback about lyrics for this track. **feedback** can be one of:
yading@7 92
yading@7 93 :keyword wrong_attribution: the lyrics shown are not by the artist that
yading@7 94 I selected.
yading@7 95 :keyword bad_characters: there are strange characters and/or words
yading@7 96 that are partially scrambled.
yading@7 97 :keyword lines_too_long: the text for each verse is too long!
yading@7 98 :keyword wrong_verses: there are some verses missing from the
yading@7 99 beginning or at the end.
yading@7 100 :keyword wrong_formatting: the text looks horrible, please fix it!
yading@7 101 """
yading@7 102 accepted = [
yading@7 103 'wrong_attribution', 'bad_characters', 'lines_too_long',
yading@7 104 'wrong_verses', 'wrong_formatting' ]
yading@7 105 if feedback in accepted:
yading@7 106 message = track.lyrics.feedback.post(
yading@7 107 track_id=self['track_id'],
yading@7 108 lyrics_id=self['track_id']['lyrics']['lyrics_id'],
yading@7 109 feedback=feedback
yading@7 110 )
yading@7 111 if not message.status_code:
yading@7 112 raise api.Error(str(message.status_code))
yading@7 113 else:
yading@7 114 raise TypeError, '%r not in %r' % (feedback, accepted)
yading@7 115
yading@7 116 class TracksCollection(ItemsCollection):
yading@7 117 """
yading@7 118 This class build a :py:class:`list` like object representing a tracks
yading@7 119 collection. It accepts :py:class:`dict` or :py:class:`Track` objects.
yading@7 120 """
yading@7 121 __allowedin__ = Track
yading@7 122
yading@7 123 @classmethod
yading@7 124 def fromAlbum(cls, **keywords):
yading@7 125 """
yading@7 126 This classmethod builds an :py:class:`TracksCollection` from a
yading@7 127 **album.tracks.get** :py:class:`musixmatch.api.Method` call.
yading@7 128
yading@7 129 :param album_id: musiXmatch album ID
yading@7 130 """
yading@7 131 return cls.fromResponseMessage(album.tracks.get(**keywords))
yading@7 132
yading@7 133 @classmethod
yading@7 134 def fromSearch(cls, **keywords):
yading@7 135 """
yading@7 136 This classmethod builds an :py:class:`TracksCollection` from a
yading@7 137 **track.search** :py:class:`musixmatch.api.Method` call.
yading@7 138
yading@7 139 :param q: a string that will be searched in every data field
yading@7 140 (q_track, q_artist, q_lyrics)
yading@7 141 :param q_track: words to be searched among track titles
yading@7 142 :param q_artist: words to be searched among artist names
yading@7 143 :param q_track_artist: words to be searched among track titles or
yading@7 144 artist names
yading@7 145 :param q_lyrics: words to be searched into the lyrics
yading@7 146 :param page: requested page of results
yading@7 147 :param page_size: desired number of items per result page
yading@7 148 :param f_has_lyrics: exclude tracks without an available lyrics
yading@7 149 (automatic if q_lyrics is set)
yading@7 150 :param f_artist_id: filter the results by the artist_id
yading@7 151 :param f_artist_mbid: filter the results by the artist_mbid
yading@7 152 :param quorum_factor: only works together with q and q_track_artist
yading@7 153 parameter. Possible values goes from 0.1 to
yading@7 154 0.9. A value of 0.9 means: 'match at least 90
yading@7 155 percent of the words'.
yading@7 156 """
yading@7 157 return cls.fromResponseMessage(track.search(**keywords))
yading@7 158
yading@7 159 @classmethod
yading@7 160 def fromChart(cls, **keywords):
yading@7 161 """
yading@7 162 This classmethod builds an :py:class:`TracksCollection` from a
yading@7 163 **track.chart.get** :py:class:`musixmatch.api.Method` call.
yading@7 164
yading@7 165 :param page: requested page of results
yading@7 166 :param page_size: desired number of items per result page
yading@7 167 :param country: the country code of the desired country chart
yading@7 168 :param f_has_lyrics: exclude tracks without an available lyrics
yading@7 169 (automatic if q_lyrics is set)
yading@7 170 """
yading@7 171 return cls.fromResponseMessage(track.chart.get(**keywords))