1# Copyright (c) 2014-2017 Cedric Bellegarde <cedric.bellegarde@adishatz.org>
2# This program is free software: you can redistribute it and/or modify
3# it under the terms of the GNU General Public License as published by
4# the Free Software Foundation, either version 3 of the License, or
5# (at your option) any later version.
6# This program is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9# GNU General Public License for more details.
10# You should have received a copy of the GNU General Public License
11# along with this program. If not, see <http://www.gnu.org/licenses/>.
12
13from gi.repository import GLib
14
15import json
16import re
17from locale import getdefaultlocale
18
19from lollypop.logger import Logger
20from lollypop.define import App, LASTFM_API_KEY
21from lollypop.utils import get_network_available
22
23
24class LastFMWebHelper:
25    """
26        Web helper for Last.fm
27    """
28
29    def __init__(self):
30        """
31            Init helper
32        """
33        pass
34
35    def get_artist_id(self, artist_name, cancellable):
36        """
37            Get artist id
38            @param artist_name as str
39            @param cancellable as Gio.Cancellable
40            @return str/None
41        """
42        try:
43            uri = "http://ws.audioscrobbler.com/2.0/?method=artist.getinfo"
44            uri += "&artist=%s&api_key=%s&format=json" % (
45                artist_name, LASTFM_API_KEY)
46            (status, data) = App().task_helper.load_uri_content_sync(uri, None)
47            if status:
48                content = json.loads(data.decode("utf-8"))
49                return content["artist"]["mbid"]
50        except:
51            Logger.error(
52                "LastFMWebHelper::get_artist_id(): %s", uri)
53        return None
54
55    def get_artist_top_albums(self, artist, cancellable):
56        """
57            Get top albums for artist
58            @param artist as str
59            @param cancellable as Gio.Cancellable
60            @return [(str, str)]
61        """
62        artist = GLib.uri_escape_string(artist, None, True)
63        albums = []
64        try:
65            uri = "http://ws.audioscrobbler.com/2.0/"
66            uri += "?method=artist.gettopalbums"
67            uri += "&artist=%s&api_key=%s&format=json" % (
68                artist, LASTFM_API_KEY)
69            (status, data) = App().task_helper.load_uri_content_sync(uri, None)
70            if status:
71                content = json.loads(data.decode("utf-8"))
72                for album in content["topalbums"]["album"]:
73                    albums.append((album["name"], album["artist"]["name"]))
74        except:
75            Logger.error(
76                "LastFMWebHelper::get_artist_top_albums(): %s", uri)
77        return albums
78
79    def get_album_payload(self, album, artist, cancellable):
80        """
81            Get album payload for mbid
82            @param album as str
83            @param artist as str
84            @param cancellable as Gio.Cancellable
85            @return {}
86        """
87        artist = GLib.uri_escape_string(artist, None, True)
88        album = GLib.uri_escape_string(album, None, True)
89        try:
90            uri = "http://ws.audioscrobbler.com/2.0/"
91            uri += "?method=album.getInfo"
92            uri += "&album=%s&artist=%s&api_key=%s&format=json" % (
93                album, artist, LASTFM_API_KEY)
94            (status, data) = App().task_helper.load_uri_content_sync(uri, None)
95            if status:
96                return json.loads(data.decode("utf-8"))["album"]
97        except:
98            Logger.error(
99                "LastFMWebHelper::get_album_payload(): %s", uri)
100        return {}
101
102    def get_lollypop_payload(self, mbid, cancellable):
103        """
104            Get track payload for mbid
105            @param mbid as str
106            @param cancellable as Gio.Cancellable
107            @return {}/None
108        """
109        try:
110            uri = "http://ws.audioscrobbler.com/2.0/"
111            uri += "?method=track.getInfo"
112            uri += "&mbid=%s&api_key=%s&format=json" % (
113                mbid, LASTFM_API_KEY)
114            (status, data) = App().task_helper.load_uri_content_sync(uri, None)
115            if status:
116                return json.loads(data.decode("utf-8"))["track"]
117        except:
118            Logger.error(
119                "LastFMWebHelper::get_lollypop_payload(): %s", uri)
120        return None
121
122    def get_artist_bio(self, artist):
123        """
124            Get artist biography
125            @param artist as str
126            @return content as bytes/None
127        """
128        if not get_network_available("LASTFM"):
129            return None
130        artist = GLib.uri_escape_string(artist, None, True)
131        try:
132            language = getdefaultlocale()[0][0:2]
133            uri = "http://ws.audioscrobbler.com/2.0/?method=artist.getinfo"
134            uri += "&artist=%s&api_key=%s&format=json&lang=%s" % (
135                artist, LASTFM_API_KEY, language)
136            (status, data) = App().task_helper.load_uri_content_sync(uri, None)
137            if status:
138                content = json.loads(data.decode("utf-8"))
139                bio = content["artist"]["bio"]["content"]
140                bio = re.sub(r"<.*Last.fm.*>.", "", bio)
141                return bio.encode(encoding="UTF-8")
142        except:
143            Logger.error(
144                "LastFMWebHelper::get_artist_bio(): %s", uri)
145        return None
146
147    def lollypop_album_payload(self, payload):
148        """
149            Convert payload to Lollypop one
150            @param payload as {}
151            return {}
152        """
153        lollypop_payload = {}
154        lollypop_payload["mbid"] = None
155        lollypop_payload["name"] = payload["name"]
156        lollypop_payload["uri"] = ""
157        lollypop_payload["artists"] = payload["artist"]
158        lollypop_payload["track-count"] = len(payload["tracks"])
159        lollypop_payload["date"] = None
160        try:
161            artwork_uri = payload["image"][-1]["#text"]
162        except:
163            artwork_uri = None
164        lollypop_payload["artwork-uri"] = artwork_uri
165        return lollypop_payload
166
167    def lollypop_track_payload(self, payload, tracknumber):
168        """
169            Convert payload to Lollypop one
170            @param payload as {}
171            @param tracknumber as int
172            @return {}
173        """
174        lollypop_payload = {}
175        lollypop_payload["mbid"] = None
176        lollypop_payload["name"] = payload["name"]
177        lollypop_payload["uri"] = ""
178        lollypop_payload["artists"] = payload["artist"]["name"]
179        lollypop_payload["discnumber"] = "1"
180        lollypop_payload["tracknumber"] = tracknumber
181        lollypop_payload["duration"] = int(payload["duration"]) * 1000
182        return lollypop_payload
183
184#######################
185# PRIVATE             #
186#######################
187