diff --git a/README.org b/README.org index 5310377..97c42fb 100644 --- a/README.org +++ b/README.org @@ -43,7 +43,7 @@ The library is implemented around a set of entities. | *Name* | *Type* | *Fields* | *Description* | |------------------+-----------+----------------------+---------------------------------------------------------| | song | structure | name, album, file, … | | -| album | structure | name, date, artist | | +| album | structure | name, date, artists | | | artist | structure | name | | | genre | structure | name | | | directory | structure | name, path | | diff --git a/libmpdel.el b/libmpdel.el index b0c6209..f872aff 100644 --- a/libmpdel.el +++ b/libmpdel.el @@ -173,7 +173,7 @@ message from the server.") (:conc-name libmpdel--album-)) (name nil :read-only t) (date nil :read-only t) - (artist nil :read-only t)) + (artists nil :read-only t)) (cl-defstruct (libmpdel-song (:constructor libmpdel--song-create) @@ -184,6 +184,7 @@ message from the server.") (album nil :read-only t) (performers nil :read-only t) (genres nil :read-only t) + (artists nil :read-only t) (disc nil :read-only t) (date nil :read-only t) (id nil :read-only t) @@ -214,20 +215,28 @@ message from the server.") "Return artist name of ENTITY." (libmpdel--artist-name (libmpdel-artist entity))) +(defun libmpdel-artists-name (entity) + "Return semicolon separated string of artists names of ENTITY." + (string-join (mapcar #'libmpdel--artist-name + (libmpdel-artists entity)) + "; ")) + (cl-defgeneric libmpdel-artist (entity) - "Return artist of ENTITY.") + "Return artist of ENTITY." + (or (car (libmpdel-artists entity)) + libmpdel--unknown-artist)) -(cl-defmethod libmpdel-artist ((artist libmpdel-artist)) - "Return ARTIST." - artist) +(cl-defmethod libmpdel-artists ((artist libmpdel-artist)) + "Return singleton list containing ARTIST." + (list artist)) -(cl-defmethod libmpdel-artist ((album libmpdel-album)) +(cl-defmethod libmpdel-artists ((album libmpdel-album)) "Return the ALBUM's artist." - (libmpdel--album-artist album)) + (libmpdel--album-artists album)) -(cl-defmethod libmpdel-artist ((song libmpdel-song)) - "Return the SONG's artist." - (libmpdel-artist (libmpdel--song-album song))) +(cl-defmethod libmpdel-artists ((song libmpdel-song)) + "Return the SONG's artists." + (libmpdel--song-artists song)) (defun libmpdel-album-name (entity) "Return album name of ENTITY." @@ -399,6 +408,7 @@ If the SONG's name is nil, return the filename instead." :file (cdr (assq 'file song-data)) :performers (libmpdel--artists-create (libmpdel-entries song-data 'Performer)) :genres (libmpdel--genres-create (libmpdel-entries song-data 'Genre)) + :artists (libmpdel--artists-create (libmpdel-entries song-data 'Artist)) :album (libmpdel--create-album-from-data song-data) :date (cdr (assq 'Date song-data)) :disc (cdr (assq 'Disc song-data)) @@ -414,7 +424,7 @@ If the SONG's name is nil, return the filename instead." (libmpdel--album-create :name (cdr (assq 'Album song-data)) :date (cdr (assq 'Date song-data)) - :artist (libmpdel--artist-create :name (cdr (assq 'Artist song-data))))) + :artists (libmpdel--artists-create (libmpdel-entries song-data 'AlbumArtist)))) (defun libmpdel--create-albums-from-data (data) "Return a list of albums from DATA, a server's response." @@ -983,7 +993,11 @@ If HANDLER is nil, ignore response." (cl-defmethod libmpdel-entity-to-criteria ((album libmpdel-album)) "Return search query matching all songs from ALBUM." (format "%s album %S" - (libmpdel-entity-to-criteria (libmpdel-artist album)) + (string-join + (mapcar (lambda (artist) + (format "albumartist %S" (libmpdel-entity-name artist))) + (libmpdel-artists album)) + " ") (libmpdel-entity-name album))) (cl-defmethod libmpdel-entity-to-criteria ((genre libmpdel-genre)) @@ -993,7 +1007,12 @@ If HANDLER is nil, ignore response." (cl-defmethod libmpdel-entity-to-criteria ((song libmpdel-song)) "Return search query matching SONG." - (format "%s title %S" + (format "%s %s title %S" + (string-join + (mapcar (lambda (artist) + (format "artist %S" (libmpdel-entity-name artist))) + (libmpdel-artists song)) + " ") (libmpdel-entity-to-criteria (libmpdel-album song)) (libmpdel-entity-name song))) diff --git a/test/libmpdel-test.el b/test/libmpdel-test.el index 6b939c6..9c45489 100644 --- a/test/libmpdel-test.el +++ b/test/libmpdel-test.el @@ -54,23 +54,23 @@ (ert-deftest libmpdel-test-artist () (let* ((artist (libmpdel--artist-create :name "The Artist")) - (album (libmpdel--album-create :name "The Album" :artist artist)) - (song (libmpdel--song-create :name "The song" :album album))) + (album (libmpdel--album-create :name "The Album" :artists (list artist))) + (song (libmpdel--song-create :name "The song" :album album :artists (list artist)))) (should (equal artist (libmpdel-artist artist))) (should (equal artist (libmpdel-artist album))) (should (equal artist (libmpdel-artist song))))) (ert-deftest libmpdel-test-artist-name () (let* ((artist (libmpdel--artist-create :name "The Artist")) - (album (libmpdel--album-create :name "The Album" :artist artist)) - (song (libmpdel--song-create :name "The song" :album album))) + (album (libmpdel--album-create :name "The Album" :artists (list artist))) + (song (libmpdel--song-create :name "The song" :album album :artists (list artist)))) (should (equal "The Artist" (libmpdel-artist-name artist))) (should (equal "The Artist" (libmpdel-artist-name album))) (should (equal "The Artist" (libmpdel-artist-name song))))) (ert-deftest libmpdel-test-album-name () (let* ((artist (libmpdel--artist-create :name "The Artist")) - (album (libmpdel--album-create :name "The Album" :artist artist)) + (album (libmpdel--album-create :name "The Album" :artists (list artist))) (song (libmpdel--song-create :name "The song" :album album))) (should-error (libmpdel-album-name artist)) (should (equal "The Album" (libmpdel-album-name album))) @@ -78,7 +78,7 @@ (ert-deftest libmpdel-test-album () (let* ((artist (libmpdel--artist-create :name "The Artist")) - (album (libmpdel--album-create :name "The Album" :artist artist)) + (album (libmpdel--album-create :name "The Album" :artists (list artist))) (song (libmpdel--song-create :name "The song" :album album))) (should-error (libmpdel-album artist)) (should (equal album (libmpdel-album album))) @@ -86,7 +86,7 @@ (ert-deftest libmpdel-test-entity-name () (let* ((artist (libmpdel--artist-create :name "The Artist")) - (album (libmpdel--album-create :name "The Album" :artist artist)) + (album (libmpdel--album-create :name "The Album" :artists (list artist))) (song (libmpdel--song-create :name "The song" :album album)) (stored-playlist (libmpdel--stored-playlist-create :name "The playlist"))) (should (equal "The Artist" (libmpdel-entity-name artist))) @@ -101,7 +101,7 @@ (ert-deftest libmpdel-test-entity-parent () (let* ((artist (libmpdel--artist-create :name "The Artist")) - (album (libmpdel--album-create :name "The Album" :artist artist)) + (album (libmpdel--album-create :name "The Album" :artists (list artist))) (song (libmpdel--song-create :name "The song" :album album)) (stored-playlist (libmpdel--stored-playlist-create :name "The playlist"))) (should (equal 'artists (libmpdel-entity-parent artist))) @@ -122,6 +122,7 @@ (Performer . "The Pianist") (Performer . "The Singer") (Genre . "The Genre") + (AlbumArtist . "The Albumartist") (Artist . "The Artist"))))) (should (equal "The song" (libmpdel-entity-name song))) (should (equal "foo/song.ogg" (libmpdel-song-file song))) @@ -131,7 +132,8 @@ (should (equal "The Album" (libmpdel-entity-name (libmpdel-album song)))) (should (equal (list "The Violinist" "The Pianist" "The Singer") (mapcar #'libmpdel-entity-name (libmpdel-performers song)))) - (should (equal "The Artist" (libmpdel-entity-name (libmpdel-artist (libmpdel-album song))))))) + (should (equal "The Artist" (libmpdel-entity-name (libmpdel-artist song)))) + (should (equal "The Albumartist" (libmpdel-entity-name (libmpdel-artist (libmpdel-album song))))))) (ert-deftest libmpdel-test-current-playlist-p () (should (libmpdel-current-playlist-p 'current-playlist)) @@ -279,20 +281,22 @@ (ert-deftest libmpdel-test-playlist-add-no-string-id-sends-findadd () (let* ((artist (libmpdel--artist-create :name "The Artist")) - (album (libmpdel--album-create :name "The Album" :artist artist))) + (album (libmpdel--album-create :name "The Album" :artists (list artist)))) (libmpdel-test--with-connection (libmpdel-playlist-add album 'current-playlist) - (should (equal '("findadd artist \"The Artist\" album \"The Album\"") + (should (equal '("findadd albumartist \"The Artist\" album \"The Album\"") (last commands)))))) (ert-deftest libmpdel-test-playlist-add-sends-findadd () (let ((song (libmpdel--create-song-from-data '((Title . "S") (Album . "A") + (AlbumArtist . "Art") + (AlbumArtist . "Bart") (Artist . "Art"))))) (libmpdel-test--with-connection (libmpdel-playlist-add song 'current-playlist) - (should (equal '("findadd artist \"Art\" album \"A\" title \"S\"") + (should (equal '("findadd artist \"Art\" albumartist \"Art\" albumartist \"Bart\" album \"A\" title \"S\"") (last commands)))))) @@ -333,9 +337,9 @@ (let* ((artist1 (libmpdel--artist-create :name "artist1")) (artist1-bis (libmpdel--artist-create :name "artist1")) (artist2 (libmpdel--artist-create :name "artist2")) - (album1 (libmpdel--album-create :name "album1" :artist artist1)) - (album1-bis (libmpdel--album-create :name "album1" :artist artist1)) - (album2 (libmpdel--album-create :name "album2" :artist artist1)) + (album1 (libmpdel--album-create :name "album1" :artists (list artist1))) + (album1-bis (libmpdel--album-create :name "album1" :artists (list artist1))) + (album2 (libmpdel--album-create :name "album2" :artists (list artist1))) (song1 (libmpdel--song-create :name "name" :file "file"