121 lines
4.1 KiB
Vala
121 lines
4.1 KiB
Vala
using Soup;
|
|
|
|
namespace MpdNotify {
|
|
|
|
class AlbumArt {
|
|
private const string LASTFM_API_KEY =
|
|
"929dc7a1779b10b09f9c3e375b43463c";
|
|
private const string LASTFM_API_URL =
|
|
"http://ws.audioscrobbler.com/2.0";
|
|
|
|
private static static Mutex mtx = Mutex();
|
|
private static string cache_dir = Path.build_path(
|
|
Path.DIR_SEPARATOR_S,
|
|
Environment.get_user_cache_dir(),
|
|
"album-art"
|
|
);
|
|
|
|
public signal void download_complete(bool success);
|
|
|
|
public string artist { get; private set; }
|
|
public string album { get; private set; }
|
|
public string filename { get; private set; }
|
|
public bool cached {
|
|
get {
|
|
return FileUtils.test(filename, FileTest.EXISTS);
|
|
}
|
|
}
|
|
|
|
public AlbumArt(string artist, string album) {
|
|
this.artist = artist;
|
|
this.album = album;
|
|
var key = string.join(":", artist, album);
|
|
this.filename = Path.build_filename(
|
|
cache_dir,
|
|
Checksum.compute_for_string(ChecksumType.SHA1, key)
|
|
);
|
|
}
|
|
|
|
public void fetch() {
|
|
uint response;
|
|
URI url;
|
|
Soup.Session session;
|
|
Soup.Message message;
|
|
|
|
if (!mtx.trylock()) {
|
|
return;
|
|
}
|
|
|
|
session = new Soup.Session();
|
|
url = new URI(LASTFM_API_URL);
|
|
var data = Datalist<string>();
|
|
data.set_data("method", "album.getInfo");
|
|
data.set_data("api_key", LASTFM_API_KEY);
|
|
data.set_data("artist", artist);
|
|
data.set_data("album", album);
|
|
data.set_data("format", "json");
|
|
url.set_query(Form.encode_datalist(data));
|
|
message = new Soup.Message("GET", url.to_string(false));
|
|
response = session.send_message(message);
|
|
if (response < 200 || response >= 300) {
|
|
stderr.printf("Last.fm API call failed with status %u\b",
|
|
response);
|
|
finish(false);
|
|
return;
|
|
}
|
|
|
|
var parser = new Json.Parser();
|
|
try {
|
|
parser.load_from_data((string) message.response_body.data);
|
|
} catch {
|
|
stderr.printf("Failed to parse Last.fm album info response\n");
|
|
finish(false);
|
|
return;
|
|
}
|
|
unowned Json.Object root = parser.get_root().get_object();
|
|
unowned Json.Object alb = root.get_object_member("album");
|
|
unowned Json.Array images = alb.get_array_member("image");
|
|
string img_url = null;
|
|
foreach (unowned Json.Node n in images.get_elements()) {
|
|
unowned Json.Object img = n.get_object();
|
|
unowned string size = img.get_string_member("size");
|
|
unowned string text = img.get_string_member("#text");
|
|
if (size != "large" || text == null || text == "") {
|
|
continue;
|
|
} else {
|
|
img_url = text;
|
|
break;
|
|
}
|
|
}
|
|
if (img_url == null || img_url == "") {
|
|
stderr.printf("No album art available for %s - %s\n",
|
|
artist, album);
|
|
finish(false);
|
|
return;
|
|
}
|
|
message = new Soup.Message("GET", img_url);
|
|
response = session.send_message(message);
|
|
if (response < 200 || response >= 300) {
|
|
stderr.printf("Fetching album art failed with status %u\n",
|
|
response);
|
|
finish(false);
|
|
return;
|
|
}
|
|
|
|
var stream = FileStream.open(filename, "w");
|
|
stream.write(message.response_body.data);
|
|
finish(true);
|
|
}
|
|
|
|
private void finish(bool success) {
|
|
Idle.add(() => {
|
|
download_complete(success);
|
|
return false;
|
|
});
|
|
mtx.unlock();
|
|
}
|
|
|
|
}
|
|
|
|
}
|