예제 #1
0
    def _get_things(self,
                    method,
                    thing,
                    thing_type,
                    params=None,
                    cacheable=True):
        """Returns a list of the most played thing_types by this thing, in a
        tuple with the total number of pages of results. Includes an MBID, if
        found.
        """
        doc = self._request(self.ws_prefix + "." + method, cacheable, params)

        toptracks_node = doc.getElementsByTagName('toptracks')[0]
        total_pages = int(toptracks_node.getAttribute('totalPages'))

        seq = []
        for node in doc.getElementsByTagName(thing):
            title = _extract(node, "name")
            artist = _extract(node, "name", 1)
            mbid = _extract(node, "mbid")
            playcount = _number(_extract(node, "playcount"))

            thing = thing_type(artist, title, self.network)
            thing.mbid = mbid
            seq.append(TopItem(thing, playcount))

        return seq, total_pages
예제 #2
0
파일: crawl.py 프로젝트: cheungzq/MusicGene
def crawl_tag(song_hash_file):
    network = pylast.LastFMNetwork(api_key=API_KEY)
    taghash = {}
    tags = []
    taginfo = [] 
    with open(song_hash_file) as fin:
        for line in fin:
            [sid, title, artist] = line.strip().split('\t')
            #if int(sid)>3:
            #    break
            print line.strip()
            title = title.replace('\/','/')
            title = title.replace('w/ ','feat. ')
            tags.append({})
            track = network.get_track(artist, title)
            try:
                toptags = track.get_top_tags()
            except:
                if title.find('(feat.')!=-1:
                    track = network.get_track(artist, title[:title.find('(feat.')])
                elif title.find('feat.')!=-1:
                    track = network.get_track(artist, title[:title.find('feat.')])
                else:
                    print sid, ':', title, 'not found'
                    continue
                try:
                    toptags = track.get_top_tags()
                except:
                    print sid, ':', title, 'not found'
                    continue
            for tag in toptags:
                if tag.item.name is None or tag.weight is None:
                    continue
                if tag.item.name not in taghash:
                    taghash[tag.item.name] = len(taghash)
                tags[-1][taghash[tag.item.name]] = int(tag.weight)
    errlist = []
    for k in taghash:
        print k
        tag = network.get_tag(k)
        taginfo.append({'tid':taghash[k], 'name':k})
        try:
            info = tag._request('tag.getInfo', True)
            reach = pylast._extract(info, 'reach')
            taggings = pylast._extract(info, 'taggings')
            if reach is None or taggings is None:
                errlist.append(k)
            else:
                taginfo[-1]['reach'] = reach
                taginfo[-1]['taggings'] = taggings
        except:
            errlist.append(k)
    print 'errlist',len(errlist),errlist
    taginfo.sort(key=lambda k:k['tid'])
    return tags, taginfo
예제 #3
0
def _extract_track_data(track: Node):
    track_mbid = pylast._extract(track, "mbid")
    track_title = pylast._extract(track, "name")
    timestamp = dt.datetime.fromtimestamp(
        int(track.getElementsByTagName("date")[0].getAttribute("uts")))
    artist_name = pylast._extract(track, "artist")
    artist_mbid = track.getElementsByTagName("artist")[0].getAttribute("mbid")
    album_title = pylast._extract(track, "album")
    album_mbid = track.getElementsByTagName("album")[0].getAttribute("mbid")

    # TODO: could call track/album/artist.getInfo here, and get more info?

    # Handle missing titles
    if album_title is None:
        album_title = "(unknown album)"

    # If we don't have mbids, synthesize them
    if not artist_mbid:
        artist_mbid = "md5:" + hashlib.md5(
            artist_name.encode("utf8")).hexdigest()
    if not album_mbid:
        h = hashlib.md5()
        h.update(artist_mbid.encode("utf8"))
        h.update(album_title.encode("utf8"))
        album_mbid = "md5:" + h.hexdigest()
    if not track_mbid:
        h = hashlib.md5()
        h.update(album_mbid.encode("utf8"))
        h.update(track_title.encode("utf8"))
        track_mbid = "md5:" + h.hexdigest()

    return {
        "artist": {
            "id": artist_mbid,
            "name": artist_name
        },
        "album": {
            "id": album_mbid,
            "title": album_title,
            "artist_id": artist_mbid
        },
        "track": {
            "id": track_mbid,
            "album_id": album_mbid,
            "title": track_title
        },
        "play": {
            "track_id": track_mbid,
            "timestamp": timestamp
        },
    }
예제 #4
0
 def get_similar(self, limit=None):
     if limit:
         doc = self._request(self.ws_prefix + '.getSimilar', True, params={'artist': self.artist.name,
                                                                           'track': self.title,
                                                                           'limit': limit})
     else:
         doc = self._request(self.ws_prefix + '.getSimilar', True)
     seq = []
     for node in doc.getElementsByTagName(self.ws_prefix):
         title = pylast._extract(node, 'name')
         artist = pylast._extract(node, 'name', 1)
         match = pylast._number(pylast._extract(node, "match"))
         seq.append(pylast.SimilarItem(pylast.Track(artist, title, self.network), match))
     return seq
예제 #5
0
def check_album(artist, album):
    album_object = network.get_album(artist, album)
    corrected_album_name = pylast._extract(album_object._request(album_object.ws_prefix + ".getCorrection"), "name")
    if not corrected_album_name:
        print('No suggested album.')
        return album
    if (album == corrected_album_name):
        # No change, return immediately and don't waste server hits
        return album
    elif album == "" and not corrected_album_name:
        # Blank album
        return album
    corrected_album_object = network.get_album(artist, corrected_album_name)
    if (album_object != corrected_album_object):
        response = input(f'Should album {album} be {corrected_album_name}? (y/N)').lower()
        if (response == "y"):
            album = corrected_album_name
    elif (album != corrected_album_name):
        print(f"Suggested album name correction {corrected_album_name} does not affect scrobble, recommend changing.")
        response = input(f'Should album {album} be {corrected_album_name}? (Y/n)').lower()
        if (response == "n"):
            pass
        else:
            album = corrected_album_name
    return album
예제 #6
0
 def tag(self, irc, msg, args, tag):
     """<tag>
     
     Returns some info on the tag <tag>."""
     try:
         summaryLength = 260
         outputString = "%s%s%s%s"
         summaryString = "\"%s\" "
         artistsString = " Top artists: %s."
         #tracksString = " Top tracks: %s."
         #tagsString = " Similar tags: %s."
         sString = "'s%s"
         nothingString = " has no top artists."
         urlString = " %s"
         tagRef = network.get_tag(tag)
         tag = tagRef.get_name(properly_capitalized = True)
         tag = tag[0].upper() + tag[1:]
         summary = pylast._extract(tagRef._request("tag.getInfo", True), "summary")
         if summary != None and summary != "":
             summary = re.sub("\<[^<]+\>", "", summary)
             summary = re.sub("\s+", " ", summary)
             summary = summary[:summaryLength] + "..." if (summary[:summaryLength] != summary) else summary
         topArtists = tagRef.get_top_artists()
         if len(topArtists) > 3:
             topArtists = topArtists[:3]
         topArtistsText = commaAndify([x.item.get_name() for x in topArtists])
         if len(topArtistsText) > 0:
             topArtistsText = artistsString % topArtistsText
         
         #topTracks = tagRef.get_top_tracks()
         #if len(topTracks) > 3:
         #    topTracks = topTracks[:3]
         #topTracksText = commaAndify([x.item.get_artist().get_name() 
         #    + " - " + x.item.get_name() for x in topTracks]).encode("utf-8")
         #if len(topTracksText) > 0:
         #    topTracksText = tracksString % topTracksText
         
         #similarTags = tagRef.get_similar()
         #if len(similarTags) > 3:
         #    similarTags = similarTags[:3]
         #similarTagsText = commaAndify([x.get_name() for x in similarTags])
         #if len(similarTagsText) > 0:
         #    similarTagsText = tagsString % similarTagsText
         
         data = sString % (topArtistsText)
         if len(topArtistsText) is 0:
             data = nothingString
         else:
             data = data[:3] + data[3].lower() + data[4:]
         url = tagRef.get_url()
         if len(url) > 0:
             url = urlString % url
         summary = summaryString % summary if (summary != None and summary != "") else ""
         output = outputString % (summary, tag, data, url)
         irc.reply(output.encode("utf-8"))
     except pylast.WSError, e:
         irc.error(str(e))
예제 #7
0
파일: scrapefm.py 프로젝트: jta/scrapefm
    def get_child(cls, response, field):
        """ Retrieves child element from response and casts it according
            to field type in DB model.

            Parameters
            ----------
            response : XML string
                Response from Last.fm
            field : DB attribute.
                Attribute object contains name, which matches child in XML
                tree, and db_value, which casts string to appropriate type.
        """
        return field.db_value(pylast._extract(response, field.name))
예제 #8
0
    def _get_things(self, method, thing, thing_type, params=None, cacheable=True):
        """Returns a list of the most played thing_types by this thing, in a
        tuple with the total number of pages of results. Includes an MBID, if
        found.
        """
        doc = self._request(self.ws_prefix + "." + method, cacheable, params)

        toptracks_node = doc.getElementsByTagName("toptracks")[0]
        total_pages = int(toptracks_node.getAttribute("totalPages"))

        seq = []
        for node in doc.getElementsByTagName(thing):
            title = _extract(node, "name")
            artist = _extract(node, "name", 1)
            mbid = _extract(node, "mbid")
            playcount = _number(_extract(node, "playcount"))

            thing = thing_type(artist, title, self.network)
            thing.mbid = mbid
            seq.append(TopItem(thing, playcount))

        return seq, total_pages
예제 #9
0
파일: scrapefm.py 프로젝트: jta/scrapefm
    def scrape_artisttags(self, artist, doc = None):
        """ Iterator over top tags associated with artist

            Parameters
            ----------
            artist : pylast.Artist
                Artist object.
            doc : xml 
                Answer to artist.getInfo request. Used to aviod
                repeating request when underlying caching is disabled.
        """
        if not doc:
            doc = artist._request('artist.getInfo', True)
        for tag in doc.getElementsByTagName("tag"):
            yield pylast._extract(tag, "name")