diff --git a/data/com.github.artemanufrij.playmymusic.appdata.xml b/data/com.github.artemanufrij.playmymusic.appdata.xml
index 8e73f47..55c44d1 100644
--- a/data/com.github.artemanufrij.playmymusic.appdata.xml
+++ b/data/com.github.artemanufrij.playmymusic.appdata.xml
@@ -64,6 +64,7 @@
New:
- List View for all music content
+ - Grab album cover from MusicBrainz
diff --git a/schemas/com.github.artemanufrij.playmymusic.gschema.xml b/schemas/com.github.artemanufrij.playmymusic.gschema.xml
index bd125ec..a9a21eb 100644
--- a/schemas/com.github.artemanufrij.playmymusic.gschema.xml
+++ b/schemas/com.github.artemanufrij.playmymusic.gschema.xml
@@ -100,10 +100,10 @@
Last choosed view.
Last choosed view.
-
+
true
- Load Artist data like Artwork from MusicBrainz.
- Load Artist data like Artwork from MusicBrainz.
+ Load Artwork and Cover from MusicBrainz.
+ Load Artwork and Cover from MusicBrainz.
false
diff --git a/src/Dialogs/Preferences.vala b/src/Dialogs/Preferences.vala
index b1b5c4d..7831074 100644
--- a/src/Dialogs/Preferences.vala
+++ b/src/Dialogs/Preferences.vala
@@ -81,12 +81,12 @@ namespace PlayMyMusic.Dialogs {
settings.sync_files = sync_files.active;
});
- var load_artist_data_label = new Gtk.Label (_("Load Artist data from MusicBrainz"));
- load_artist_data_label.halign = Gtk.Align.START;
- var load_artist_data = new Gtk.Switch ();
- load_artist_data.active = settings.load_artist_from_musicbrainz;
- load_artist_data.notify["active"].connect (() => {
- settings.load_artist_from_musicbrainz = load_artist_data.active;
+ var load_content_label = new Gtk.Label (_("Load Content from MusicBrainz"));
+ load_content_label.halign = Gtk.Align.START;
+ var load_content = new Gtk.Switch ();
+ load_content.active = settings.load_content_from_musicbrainz;
+ load_content.notify["active"].connect (() => {
+ settings.load_content_from_musicbrainz = load_content.active;
});
var save_custom_covers_label = new Gtk.Label (_("Save custom Covers in Library folder"));
@@ -113,8 +113,8 @@ namespace PlayMyMusic.Dialogs {
grid.attach (sync_files_label, 0, 3);
grid.attach (sync_files, 1, 3);
grid.attach (new Gtk.Separator (Gtk.Orientation.HORIZONTAL), 0, 4, 2, 1);
- grid.attach (load_artist_data_label, 0, 5);
- grid.attach (load_artist_data, 1, 5);
+ grid.attach (load_content_label, 0, 5);
+ grid.attach (load_content, 1, 5);
grid.attach (save_custom_covers_label, 0, 6);
grid.attach (save_custom_covers, 1, 6);
grid.attach (save_id3_tags_label, 0, 7);
diff --git a/src/Objects/Album.vala b/src/Objects/Album.vala
index f9b6422..9f30057 100644
--- a/src/Objects/Album.vala
+++ b/src/Objects/Album.vala
@@ -133,7 +133,7 @@ namespace PlayMyMusic.Objects {
}
// COVER REGION
- private async void load_cover_async () {
+ public async void load_cover_async () {
if (is_cover_loading || cover != null || this.ID == 0 || this.tracks.length () == 0) {
return;
}
@@ -142,6 +142,8 @@ namespace PlayMyMusic.Objects {
Gdk.Pixbuf? return_value = load_or_create_cover.end (res);
if (return_value != null) {
this.cover = return_value;
+ } else if (settings.load_content_from_musicbrainz) {
+ Services.MusicBrainzManager.instance.fill_album_cover_queue (this);
}
is_cover_loading = false;
});
diff --git a/src/Objects/Artist.vala b/src/Objects/Artist.vala
index 60bbdae..d8c1bfa 100644
--- a/src/Objects/Artist.vala
+++ b/src/Objects/Artist.vala
@@ -142,6 +142,16 @@ namespace PlayMyMusic.Objects {
}
}
+ public bool has_empty_album_covers () {
+ foreach (var album in albums) {
+ if (album.cover == null) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
public void merge (GLib.List artists) {
foreach (var artist in artists) {
if (artist.ID == ID) {
@@ -194,7 +204,7 @@ namespace PlayMyMusic.Objects {
Gdk.Pixbuf? return_value = load_or_create_cover.end (res);
if (return_value != null) {
this.cover = return_value;
- } else if (settings.load_artist_from_musicbrainz && !this.name.down ().contains ("various") && !this.name.down ().contains ("artist")) {
+ } else if (settings.load_content_from_musicbrainz && !this.name.down ().contains ("various") && !this.name.down ().contains ("artist")) {
Services.MusicBrainzManager.instance.fill_artist_cover_queue (this);
}
is_cover_loading = false;
diff --git a/src/Objects/Track.vala b/src/Objects/Track.vala
index b6e10fb..973f617 100644
--- a/src/Objects/Track.vala
+++ b/src/Objects/Track.vala
@@ -33,7 +33,7 @@ namespace PlayMyMusic.Objects {
public signal void album_changed (Album album);
public signal void tags_saved ();
- Album? _album = null;
+ Album ? _album = null;
public Album album {
get {
if (_album == null) {
@@ -43,8 +43,8 @@ namespace PlayMyMusic.Objects {
}
}
- Playlist? _playlist = null;
- public Playlist? playlist {
+ Playlist ? _playlist = null;
+ public Playlist ? playlist {
get {
return _playlist;
}
@@ -74,24 +74,25 @@ namespace PlayMyMusic.Objects {
}
}
- public File? original_file { get; set; }
+ public File ? original_file { get; set; }
public signal void path_not_found ();
construct {
library_manager = Services.LibraryManager.instance;
- removed.connect (() => {
- if (album != null) {
- album.track_removed (this);
- album.artist.track_removed (this);
- }
- if (playlist != null) {
- playlist.track_removed (this);
- }
- });
+ removed.connect (
+ () => {
+ if (album != null) {
+ album.track_removed (this);
+ album.artist.track_removed (this);
+ }
+ if (playlist != null) {
+ playlist.track_removed (this);
+ }
+ });
}
- public Track (TracksContainer? container = null) {
+ public Track (TracksContainer ? container = null) {
if (container != null && container is Album) {
set_album (container as Album);
} else if (container != null && container is Playlist) {
@@ -126,10 +127,8 @@ namespace PlayMyMusic.Objects {
}
public void save_id3_tags () {
-
var path = File.new_for_uri (uri);
- stdout.printf ("ID3 Start\n");
var file = new TagLib.File (path.get_path ());
if (file.tag.album == this.album.title && file.tag.artist == this.album.artist.name && file.tag.year == this.album.year && file.tag.genre == genre) {
return;
@@ -141,8 +140,6 @@ namespace PlayMyMusic.Objects {
file.tag.genre = genre;
if (file.save ()) {
tags_saved ();
-
- stdout.printf ("ID3 SAVED year:%u \n", file.tag.year);
}
path.dispose ();
}
diff --git a/src/Services/MusicBrainzManager.vala b/src/Services/MusicBrainzManager.vala
index b5af47c..d7c7dcc 100644
--- a/src/Services/MusicBrainzManager.vala
+++ b/src/Services/MusicBrainzManager.vala
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2017-2017 Artem Anufrij
+ * Copyright (c) 2017-2018 Artem Anufrij
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -31,20 +31,23 @@ namespace PlayMyMusic.Services {
public static MusicBrainzManager instance {
get {
if (_instance == null) {
- _instance = new MusicBrainzManager();
+ _instance = new MusicBrainzManager ();
}
return _instance;
}
}
GLib.List artists = new GLib.List ();
+ GLib.List albums = new GLib.List ();
bool artist_thread_running = false;
+ bool album_thread_running = false;
- private MusicBrainzManager () {}
+ private MusicBrainzManager () {
+ }
- private static string? get_body_from_url (string url) {
- string? return_value = null;
+ private static string ? get_body_from_url (string url) {
+ string ? return_value = null;
var session = new Soup.Session.with_options ("user_agent", "PlayMyMusic/0.1.0 (https://github.com/artemanufrij/playmymusic)");
var msg = new Soup.Message ("GET", url);
session.send_message (msg);
@@ -65,53 +68,110 @@ namespace PlayMyMusic.Services {
read_artists_queue ();
}
- private void read_artists_queue () {
- if (artist_thread_running) {
+ public void fill_album_cover_queue (Objects.Album album) {
+ lock (albums) {
+ if (albums.index (album) == -1) {
+ albums.append (album);
+ }
+ }
+ read_albums_queue ();
+ }
+
+ private void read_albums_queue () {
+ if (album_thread_running) {
return;
}
artist_thread_running = true;
- new Thread (null, () => {
- Objects.Artist? first = null;
- while (artists.length () > 0) {
- lock (artists) {
- first = artists.first ().data;
- if (first != null) {
- artists.remove (first);
+ new Thread (
+ "read_albums_queue",
+ () => {
+ Objects.Album ? first = null;
+
+ while (albums.length () > 0) {
+ lock (albums) {
+ first = albums.first ().data;
+ if (first != null) {
+ albums.remove (first);
+ }
+ }
+ Thread.usleep (1000000);
+ string url = "http://musicbrainz.org/ws/2/release/?query=release:%s AND artist:%s&fmt=json".printf (first.title.replace ("&", "%26").replace ("/", "_"), first.artist.name.replace ("&", "%26").replace ("/", "_"));
+ var body = get_body_from_url (url);
+ if (body != null) {
+ var release_id = Utils.MusicBrainz.get_release_id_from_artist_ws_2 (body);
+ stdout.printf ("RELEASE ID: %s (%s / %s)\n", release_id, first.title, first.artist.name);
+ var pixbuf = get_pixbuf_by_release_id (release_id);
+ if (pixbuf != null) {
+ pixbuf = LibraryManager.instance.align_and_scale_pixbuf (pixbuf, 256);
+ try {
+ if (pixbuf.save (first.cover_path, "jpeg", "quality", "100")) {
+ if (Settings.get_default ().save_custom_covers) {
+ first.set_custom_cover_file (first.cover_path);
+ }
+ first.load_cover_async.begin ();
+ break;
+ }
+ } catch (Error err) {
+ warning (err.message);
+ }
+ }
}
}
- if (first != null && first.cover == null) {
- var albums = first.albums_title.copy ();
- foreach (var album in albums) {
- Thread.usleep (1000000);
- string url = "http://musicbrainz.org/ws/2/release/?query=release:%s AND artist:%s&fmt=json".printf (album.replace ("&", "%26").replace("/", "_"), first.name.replace ("&", "%26").replace("/", "_"));
- var body = get_body_from_url (url);
- if (body != null) {
- var artist_id = Utils.MusicBrainz.get_artist_id_from_artist_ws_2 (body);
- stdout.printf ("ARTIST ID: %s (%s / %s)\n", artist_id, album, first.name);
- var pixbuf = get_pixbuf_by_artist_id (artist_id);
- if (pixbuf != null) {
- pixbuf = LibraryManager.instance.align_and_scale_pixbuf (pixbuf, 256);
- try {
- if (pixbuf.save (first.cover_path, "jpeg", "quality", "100")) {
- if (Settings.get_default ().save_custom_covers) {
- first.set_custom_cover_file (first.cover_path);
+ return null;
+ });
+ }
+
+ private void read_artists_queue () {
+ if (artist_thread_running) {
+ return;
+ }
+ artist_thread_running = true;
+ new Thread (
+ "read_artists_queue",
+ () => {
+ Objects.Artist ? first = null;
+ while (artists.length () > 0) {
+ lock (artists) {
+ first = artists.first ().data;
+ if (first != null) {
+ artists.remove (first);
+ }
+ }
+
+ if (first != null && (first.cover == null || first.has_empty_album_covers ())) {
+ var albums = first.albums_title.copy ();
+ foreach (var album in albums) {
+ Thread.usleep (1000000);
+ string url = "http://musicbrainz.org/ws/2/release/?query=release:%s AND artist:%s&fmt=json".printf (album.replace ("&", "%26").replace ("/", "_"), first.name.replace ("&", "%26").replace ("/", "_"));
+ var body = get_body_from_url (url);
+ if (body != null) {
+ var artist_id = Utils.MusicBrainz.get_artist_id_from_artist_ws_2 (body);
+ var release_id = Utils.MusicBrainz.get_release_id_from_artist_ws_2 (body);
+ stdout.printf ("ARTIST ID: %s; RELEASE ID: %s (%s / %s)\n", artist_id, release_id, album, first.name);
+ var pixbuf = get_pixbuf_by_artist_id (artist_id);
+ if (pixbuf != null) {
+ pixbuf = LibraryManager.instance.align_and_scale_pixbuf (pixbuf, 256);
+ try {
+ if (pixbuf.save (first.cover_path, "jpeg", "quality", "100")) {
+ if (Settings.get_default ().save_custom_covers) {
+ first.set_custom_cover_file (first.cover_path);
+ }
+ first.load_cover_async.begin ();
+ break;
}
- first.load_cover_async.begin ();
- break;
+ } catch (Error err) {
+ warning (err.message);
}
- } catch (Error err) {
- warning (err.message);
}
}
}
}
}
- }
- artist_thread_running = false;
- return null;
- });
+ artist_thread_running = false;
+ return null;
+ });
}
public static void fill_audio_cd (PlayMyMusic.Objects.AudioCD audio_cd) {
@@ -125,7 +185,7 @@ namespace PlayMyMusic.Services {
parser.load_from_data (body);
root = parser.get_root ();
} catch (Error err) {
- warning (err.message);
+ warning (err.message);
}
if (root != null) {
var o = root.get_object ();
@@ -164,7 +224,7 @@ namespace PlayMyMusic.Services {
pixbuf.save (audio_cd.cover_path, "jpeg", "quality", "100");
audio_cd.load_cover_async.begin ();
} catch (Error err) {
- warning (err.message);
+ warning (err.message);
}
}
}
@@ -172,7 +232,38 @@ namespace PlayMyMusic.Services {
}
}
- public Gdk.Pixbuf? get_pixbuf_by_artist_id (string id) {
+ public Gdk.Pixbuf ? get_pixbuf_by_release_id (string id) {
+ if (id == "") {
+ return null;
+ }
+ string url = "https://coverartarchive.org/release/%s".printf (id);
+ var body = get_body_from_url (url);
+ if (body != null) {
+ var parser = new Json.Parser ();
+ Json.Node root = null;
+ try {
+ parser.load_from_data (body);
+ root = parser.get_root ();
+ } catch (Error err) {
+ warning (err.message);
+ }
+ if (root != null && root.get_object ().has_member ("images")) {
+ var images = root.get_object ().get_member ("images").get_array ();
+ foreach (unowned Json.Node item in images.get_elements ()) {
+ var o = item.get_object ();
+ if (o.get_boolean_member ("front") && o.has_member ("thumbnails")) {
+ var thumb = o.get_member ("thumbnails").get_object ();
+ if (thumb.has_member ("large")) {
+ return get_pixbuf_from_url (thumb.get_string_member ("large"));
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public Gdk.Pixbuf ? get_pixbuf_by_artist_id (string id) {
if (id == "") {
return null;
}
@@ -185,7 +276,7 @@ namespace PlayMyMusic.Services {
parser.load_from_data (body);
root = parser.get_root ();
} catch (Error err) {
- warning (err.message);
+ warning (err.message);
}
if (root != null && root.get_object ().has_member ("relations")) {
var relations = root.get_object ().get_member ("relations").get_array ();
@@ -222,7 +313,7 @@ namespace PlayMyMusic.Services {
try {
regex = new Regex ("(?<=/wiki/)[^<]*");
} catch (Error err) {
- warning (err.message);
+ warning (err.message);
return "";
}
@@ -234,7 +325,7 @@ namespace PlayMyMusic.Services {
try {
regex = new Regex ("(?<=\"source\":\")[^\"]*");
} catch (Error err) {
- warning (err.message);
+ warning (err.message);
return "";
}
if (regex.match (body, 0, out match_info)) {
@@ -252,7 +343,7 @@ namespace PlayMyMusic.Services {
try {
regex = new Regex ("(?<=/File:)[^<]*");
} catch (Error err) {
- warning (err.message);
+ warning (err.message);
return "";
}
@@ -264,7 +355,7 @@ namespace PlayMyMusic.Services {
try {
regex = new Regex ("(?<=\"thumburl\":\")[^\"]*");
} catch (Error err) {
- warning (err.message);
+ warning (err.message);
return "";
}
if (regex.match (body, 0, out match_info)) {
@@ -276,22 +367,22 @@ namespace PlayMyMusic.Services {
return "";
}
- public static Gdk.Pixbuf? get_pixbuf_from_url (string url) {
+ public static Gdk.Pixbuf ? get_pixbuf_from_url (string url) {
if (!url.has_prefix ("http")) {
return null;
}
- Gdk.Pixbuf? return_value = null;
+ Gdk.Pixbuf ? return_value = null;
var session = new Soup.Session.with_options ("user_agent", "PlayMyMusic/0.1.0 (https://github.com/artemanufrij/playmymusic)");
var msg = new Soup.Message ("GET", url);
session.send_message (msg);
if (msg.status_code == 200) {
string tmp_file = GLib.Path.build_filename (GLib.Environment.get_user_cache_dir (), Random.next_int ().to_string () + ".jpg");
- var fs = FileStream.open(tmp_file, "w");
+ var fs = FileStream.open (tmp_file, "w");
fs.write (msg.response_body.data, (size_t)msg.response_body.length);
try {
return_value = new Gdk.Pixbuf.from_file (tmp_file);
} catch (Error err) {
- warning (err.message);
+ warning (err.message);
}
File f = File.new_for_path (tmp_file);
f.delete_async.begin ();
diff --git a/src/Settings.vala b/src/Settings.vala
index f373b6c..48cff02 100644
--- a/src/Settings.vala
+++ b/src/Settings.vala
@@ -59,7 +59,7 @@ namespace PlayMyMusic {
public string [] covers { get; set; }
public string library_location { get; set; }
public int view_index { get; set; }
- public bool load_artist_from_musicbrainz { get; set; }
+ public bool load_content_from_musicbrainz { get; set; }
public bool use_dark_theme { get; set; }
public bool save_custom_covers { get; set; }
public bool save_id3_tags { get; set; }
diff --git a/src/Utils/MusicBrainz.vala b/src/Utils/MusicBrainz.vala
index 01040a8..811b29e 100644
--- a/src/Utils/MusicBrainz.vala
+++ b/src/Utils/MusicBrainz.vala
@@ -52,6 +52,27 @@ namespace PlayMyMusic.Utils {
return "";
}
+ public static string get_release_id_from_artist_ws_2 (string body) {
+ var parser = new Json.Parser ();
+ Json.Node root = null;
+ try {
+ parser.load_from_data (body);
+ root = parser.get_root ();
+ } catch (Error err) {
+ warning (err.message);
+ }
+ if (root != null) {
+ if (root.get_object ().has_member ("releases")) {
+ var releases = root.get_object ().get_member ("releases").get_array ();
+ if (releases.get_length () > 0) {
+ var release = releases.get_element (0).get_object ();
+ return release.get_string_member ("id");
+ }
+ }
+ }
+ return "";
+ }
+
public static string get_large_thumbnail_from_release (string body) {
var parser = new Json.Parser ();
Json.Node root = null;