mpdnotify/src/albumart.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();
}
}
}