mirror of
https://github.com/ultrasonic/ultrasonic
synced 2025-01-23 13:40:30 +01:00
Merge pull request #25 from ultrasonic/use-get-artists
Use getArtists new api implementation call
This commit is contained in:
commit
6b8d953751
@ -164,17 +164,18 @@ class SubsonicAPIClientTest {
|
||||
lastModified `should equal` 1491069027523
|
||||
ignoredArticles `should equal` "The El La Los Las Le Les"
|
||||
shortcutList `should equal` listOf(
|
||||
Artist(889L, "podcasts", null),
|
||||
Artist(890L, "audiobooks", null)
|
||||
Artist(id = 889L, name = "podcasts"),
|
||||
Artist(id = 890L, name = "audiobooks")
|
||||
)
|
||||
indexList `should equal` mutableListOf(
|
||||
Index("A", listOf(
|
||||
Artist(50L, "Ace Of Base", parseDate("2017-04-02T20:16:29.815Z")),
|
||||
Artist(379L, "A Perfect Circle", null)
|
||||
Artist(id = 50L, name = "Ace Of Base",
|
||||
starred = parseDate("2017-04-02T20:16:29.815Z")),
|
||||
Artist(id = 379L, name = "A Perfect Circle")
|
||||
)),
|
||||
Index("H", listOf(
|
||||
Artist(299, "Haddaway", null),
|
||||
Artist(297, "Halestorm", null)
|
||||
Artist(id = 299, name = "Haddaway"),
|
||||
Artist(id = 297, name = "Halestorm")
|
||||
))
|
||||
)
|
||||
}
|
||||
@ -271,6 +272,55 @@ class SubsonicAPIClientTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Should parse get artists error response`() {
|
||||
val response = checkErrorCallParsed { client.api.getArtists(null).execute() }
|
||||
|
||||
response.indexes `should not be` null
|
||||
with(response.indexes) {
|
||||
lastModified `should equal to` 0
|
||||
ignoredArticles `should equal to` ""
|
||||
indexList.size `should equal to` 0
|
||||
shortcutList.size `should equal to` 0
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Should parse get artists ok reponse`() {
|
||||
enqueueResponse("get_artists_ok.json")
|
||||
|
||||
val response = client.api.getArtists(null).execute()
|
||||
|
||||
assertResponseSuccessful(response)
|
||||
with(response.body().indexes) {
|
||||
lastModified `should equal to` 0L
|
||||
ignoredArticles `should equal to` "The El La Los Las Le Les"
|
||||
shortcutList `should equal` emptyList()
|
||||
indexList.size `should equal to` 2
|
||||
indexList `should equal` listOf(
|
||||
Index(name = "A", artists = listOf(
|
||||
Artist(id = 362L, name = "AC/DC", coverArt = "ar-362", albumCount = 2),
|
||||
Artist(id = 254L, name = "Acceptance", coverArt = "ar-254", albumCount = 1)
|
||||
)),
|
||||
Index(name = "T", artists = listOf(
|
||||
Artist(id = 516L, name = "Tangerine Dream", coverArt = "ar-516", albumCount = 1),
|
||||
Artist(id = 242L, name = "Taproot", coverArt = "ar-242", albumCount = 2)
|
||||
))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Should pass param on query for get artists call`() {
|
||||
enqueueResponse("get_artists_ok.json")
|
||||
val musicFolderId = 101L
|
||||
client.api.getArtists(musicFolderId).execute()
|
||||
|
||||
val request = mockWebServerRule.mockWebServer.takeRequest()
|
||||
|
||||
request.requestLine `should contain` "musicFolderId=$musicFolderId"
|
||||
}
|
||||
|
||||
private fun enqueueResponse(resourceName: String) {
|
||||
mockWebServerRule.mockWebServer.enqueue(MockResponse()
|
||||
.setBody(loadJsonResponse(resourceName)))
|
||||
|
@ -0,0 +1,43 @@
|
||||
{
|
||||
"subsonic-response": {
|
||||
"status": "ok",
|
||||
"version": "1.15.0",
|
||||
"artists": {
|
||||
"ignoredArticles": "The El La Los Las Le Les",
|
||||
"index": [
|
||||
{
|
||||
"name": "A",
|
||||
"artist": [
|
||||
{
|
||||
"id": "362",
|
||||
"name": "AC/DC",
|
||||
"coverArt": "ar-362",
|
||||
"albumCount": 2
|
||||
},
|
||||
{
|
||||
"id": "254",
|
||||
"name": "Acceptance",
|
||||
"coverArt": "ar-254",
|
||||
"albumCount": 1
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"name": "T",
|
||||
"artist": [
|
||||
{
|
||||
"id": "516",
|
||||
"name": "Tangerine Dream",
|
||||
"coverArt": "ar-516",
|
||||
"albumCount": 1
|
||||
},
|
||||
{
|
||||
"id": "242",
|
||||
"name": "Taproot",
|
||||
"coverArt": "ar-242",
|
||||
"albumCount": 2
|
||||
}
|
||||
]
|
||||
} ]
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package org.moire.ultrasonic.api.subsonic
|
||||
|
||||
import org.moire.ultrasonic.api.subsonic.response.GetArtistsResponse
|
||||
import org.moire.ultrasonic.api.subsonic.response.GetIndexesResponse
|
||||
import org.moire.ultrasonic.api.subsonic.response.GetMusicDirectoryResponse
|
||||
import org.moire.ultrasonic.api.subsonic.response.LicenseResponse
|
||||
@ -30,4 +31,7 @@ interface SubsonicAPIDefinition {
|
||||
|
||||
@GET("getMusicDirectory.view")
|
||||
fun getMusicDirectory(@Query("id") id: Long): Call<GetMusicDirectoryResponse>
|
||||
|
||||
@GET("getArtists.view")
|
||||
fun getArtists(@Query("musicFolderId") musicFolderId: Long?): Call<GetArtistsResponse>
|
||||
}
|
||||
|
@ -4,4 +4,6 @@ import java.util.Calendar
|
||||
|
||||
data class Artist(val id: Long = -1,
|
||||
val name: String = "",
|
||||
val starred: Calendar?)
|
||||
val coverArt: String = "",
|
||||
val albumCount: Int = 0,
|
||||
val starred: Calendar? = null)
|
||||
|
@ -0,0 +1,12 @@
|
||||
package org.moire.ultrasonic.api.subsonic.response
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions
|
||||
import org.moire.ultrasonic.api.subsonic.SubsonicError
|
||||
import org.moire.ultrasonic.api.subsonic.models.Indexes
|
||||
|
||||
class GetArtistsResponse(status: Status,
|
||||
version: SubsonicAPIVersions,
|
||||
error: SubsonicError?,
|
||||
@JsonProperty("artists") val indexes: Indexes = Indexes()) :
|
||||
SubsonicResponse(status, version, error)
|
@ -56,6 +56,7 @@ import org.apache.http.protocol.ExecutionContext;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.moire.ultrasonic.R;
|
||||
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient;
|
||||
import org.moire.ultrasonic.api.subsonic.response.GetArtistsResponse;
|
||||
import org.moire.ultrasonic.api.subsonic.response.GetIndexesResponse;
|
||||
import org.moire.ultrasonic.api.subsonic.response.LicenseResponse;
|
||||
import org.moire.ultrasonic.api.subsonic.response.MusicFoldersResponse;
|
||||
@ -81,7 +82,6 @@ import org.moire.ultrasonic.service.parser.BookmarkParser;
|
||||
import org.moire.ultrasonic.service.parser.ChatMessageParser;
|
||||
import org.moire.ultrasonic.service.parser.ErrorParser;
|
||||
import org.moire.ultrasonic.service.parser.GenreParser;
|
||||
import org.moire.ultrasonic.service.parser.IndexesParser;
|
||||
import org.moire.ultrasonic.service.parser.JukeboxStatusParser;
|
||||
import org.moire.ultrasonic.service.parser.LyricsParser;
|
||||
import org.moire.ultrasonic.service.parser.MusicDirectoryParser;
|
||||
@ -234,6 +234,21 @@ public class RESTMusicService implements MusicService
|
||||
return musicFolders;
|
||||
}
|
||||
|
||||
private static List<MusicFolder> readCachedMusicFolders(Context context) {
|
||||
String filename = getCachedMusicFoldersFilename(context);
|
||||
return FileUtil.deserialize(context, filename);
|
||||
}
|
||||
|
||||
private static void writeCachedMusicFolders(Context context, List<MusicFolder> musicFolders) {
|
||||
String filename = getCachedMusicFoldersFilename(context);
|
||||
FileUtil.serialize(context, new ArrayList<>(musicFolders), filename);
|
||||
}
|
||||
|
||||
private static String getCachedMusicFoldersFilename(Context context) {
|
||||
String s = Util.getRestUrl(context, null);
|
||||
return String.format(Locale.US, "musicFolders-%d.ser", Math.abs(s.hashCode()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Indexes getIndexes(String musicFolderId,
|
||||
boolean refresh,
|
||||
@ -269,68 +284,38 @@ public class RESTMusicService implements MusicService
|
||||
return String.format(Locale.US, "indexes-%d.ser", Math.abs(s.hashCode()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Indexes getArtists(boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
{
|
||||
checkServerVersion(context, "1.8", "Artists by ID3 tag not supported.");
|
||||
@Override
|
||||
public Indexes getArtists(boolean refresh,
|
||||
Context context,
|
||||
ProgressListener progressListener) throws Exception {
|
||||
Indexes cachedArtists = readCachedArtists(context);
|
||||
if (cachedArtists != null &&
|
||||
!refresh) {
|
||||
return cachedArtists;
|
||||
}
|
||||
|
||||
Indexes cachedArtists = readCachedArtists(context);
|
||||
if (cachedArtists != null && !refresh)
|
||||
{
|
||||
return cachedArtists;
|
||||
}
|
||||
Response<GetArtistsResponse> response = subsonicAPIClient.getApi().getArtists(null).execute();
|
||||
checkResponseSuccessful(response);
|
||||
|
||||
Reader reader = getReader(context, progressListener, "getArtists", null);
|
||||
try
|
||||
{
|
||||
Indexes indexes = new IndexesParser(context).parse(reader, progressListener);
|
||||
if (indexes != null)
|
||||
{
|
||||
writeCachedArtists(context, indexes);
|
||||
return indexes;
|
||||
}
|
||||
Indexes indexes = APIConverter.toDomainEntity(response.body().getIndexes());
|
||||
writeCachedArtists(context, indexes);
|
||||
return indexes;
|
||||
}
|
||||
|
||||
return cachedArtists != null ? cachedArtists : new Indexes(0, null, new ArrayList<org.moire.ultrasonic.domain.Artist>(), new ArrayList<org.moire.ultrasonic.domain.Artist>());
|
||||
}
|
||||
finally
|
||||
{
|
||||
Util.close(reader);
|
||||
}
|
||||
}
|
||||
|
||||
private static Indexes readCachedArtists(Context context)
|
||||
{
|
||||
String filename = getCachedArtistsFilename(context);
|
||||
return FileUtil.deserialize(context, filename);
|
||||
}
|
||||
|
||||
private static void writeCachedArtists(Context context, Indexes artists)
|
||||
{
|
||||
String filename = getCachedArtistsFilename(context);
|
||||
FileUtil.serialize(context, artists, filename);
|
||||
}
|
||||
|
||||
private static String getCachedArtistsFilename(Context context)
|
||||
{
|
||||
String s = Util.getRestUrl(context, null);
|
||||
return String.format("indexes-%d.ser", Math.abs(s.hashCode()));
|
||||
}
|
||||
|
||||
private static List<MusicFolder> readCachedMusicFolders(Context context) {
|
||||
String filename = getCachedMusicFoldersFilename(context);
|
||||
private static Indexes readCachedArtists(Context context) {
|
||||
String filename = getCachedArtistsFilename(context);
|
||||
return FileUtil.deserialize(context, filename);
|
||||
}
|
||||
|
||||
private static void writeCachedMusicFolders(Context context, List<MusicFolder> musicFolders) {
|
||||
String filename = getCachedMusicFoldersFilename(context);
|
||||
FileUtil.serialize(context, new ArrayList<>(musicFolders), filename);
|
||||
private static void writeCachedArtists(Context context, Indexes artists) {
|
||||
String filename = getCachedArtistsFilename(context);
|
||||
FileUtil.serialize(context, artists, filename);
|
||||
}
|
||||
|
||||
private static String getCachedMusicFoldersFilename(Context context)
|
||||
{
|
||||
String s = Util.getRestUrl(context, null);
|
||||
return String.format("musicFolders-%d.ser", Math.abs(s.hashCode()));
|
||||
}
|
||||
private static String getCachedArtistsFilename(Context context) {
|
||||
String s = Util.getRestUrl(context, null);
|
||||
return String.format(Locale.US, "indexes-%d.ser", Math.abs(s.hashCode()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void star(String id, String albumId, String artistId, Context context, ProgressListener progressListener) throws Exception
|
||||
|
@ -1,126 +0,0 @@
|
||||
/*
|
||||
This file is part of Subsonic.
|
||||
|
||||
Subsonic is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Subsonic is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Copyright 2009 (C) Sindre Mehus
|
||||
*/
|
||||
package org.moire.ultrasonic.service.parser;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import org.moire.ultrasonic.R;
|
||||
import org.moire.ultrasonic.domain.Artist;
|
||||
import org.moire.ultrasonic.domain.Indexes;
|
||||
import org.moire.ultrasonic.util.ProgressListener;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Sindre Mehus
|
||||
*/
|
||||
public class IndexesParser extends AbstractParser
|
||||
{
|
||||
private static final String TAG = IndexesParser.class.getSimpleName();
|
||||
private Context context;
|
||||
|
||||
public IndexesParser(Context context)
|
||||
{
|
||||
super(context);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public Indexes parse(Reader reader, ProgressListener progressListener) throws Exception
|
||||
{
|
||||
|
||||
long t0 = System.currentTimeMillis();
|
||||
updateProgress(progressListener, R.string.parser_reading);
|
||||
init(reader);
|
||||
|
||||
List<Artist> artists = new ArrayList<Artist>();
|
||||
List<Artist> shortcuts = new ArrayList<Artist>();
|
||||
Long lastModified = null;
|
||||
String ignoredArticles = null;
|
||||
int eventType;
|
||||
String index = "#";
|
||||
boolean changed = false;
|
||||
|
||||
do
|
||||
{
|
||||
eventType = nextParseEvent();
|
||||
if (eventType == XmlPullParser.START_TAG)
|
||||
{
|
||||
String name = getElementName();
|
||||
if ("indexes".equals(name) || "artists".equals(name))
|
||||
{
|
||||
changed = true;
|
||||
lastModified = getLong("lastModified");
|
||||
ignoredArticles = get("ignoredArticles");
|
||||
}
|
||||
else if ("index".equals(name))
|
||||
{
|
||||
index = get("name");
|
||||
}
|
||||
else if ("artist".equals(name))
|
||||
{
|
||||
Artist artist = new Artist();
|
||||
artist.setId(get("id"));
|
||||
artist.setName(get("name"));
|
||||
artist.setCoverArt(get("coverArt"));
|
||||
artist.setAlbumCount(getLong("albumCount"));
|
||||
artist.setIndex(index);
|
||||
artists.add(artist);
|
||||
|
||||
if (artists.size() % 10 == 0)
|
||||
{
|
||||
String msg = this.context.getResources().getString(R.string.parser_artist_count, artists.size());
|
||||
updateProgress(progressListener, msg);
|
||||
}
|
||||
}
|
||||
else if ("shortcut".equals(name))
|
||||
{
|
||||
Artist shortcut = new Artist();
|
||||
shortcut.setId(get("id"));
|
||||
shortcut.setName(get("name"));
|
||||
shortcut.setIndex("*");
|
||||
shortcuts.add(shortcut);
|
||||
}
|
||||
else if ("error".equals(name))
|
||||
{
|
||||
handleError();
|
||||
}
|
||||
}
|
||||
} while (eventType != XmlPullParser.END_DOCUMENT);
|
||||
|
||||
validate();
|
||||
|
||||
if (!changed)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
long t1 = System.currentTimeMillis();
|
||||
Log.d(TAG, "Got " + artists.size() + " artist(s) in " + (t1 - t0) + "ms.");
|
||||
|
||||
String msg = this.context.getResources().getString(R.string.parser_artist_count, artists.size());
|
||||
updateProgress(progressListener, msg);
|
||||
|
||||
return new Indexes(lastModified == null ? 0L : lastModified, ignoredArticles, shortcuts, artists);
|
||||
}
|
||||
}
|
@ -82,7 +82,7 @@ class APIConverterTest {
|
||||
MusicFolder(id, name)
|
||||
|
||||
private fun createArtist(id: Long = -1, name: String = "", starred: Calendar? = null): Artist
|
||||
= Artist(id, name, starred)
|
||||
= Artist(id = id, name = name, starred = starred)
|
||||
|
||||
private fun createIndex(name: String = "", artistList: List<Artist> = emptyList()): Index
|
||||
= Index(name, artistList)
|
||||
|
Loading…
Reference in New Issue
Block a user