From dadabd09c52a9700a108091d5d80c7dc6247011e Mon Sep 17 00:00:00 2001 From: Martijn Brekhof Date: Mon, 26 Sep 2016 19:31:22 +0200 Subject: [PATCH] Implemented recursion fix for movies and tv shows (#283) This applies the fix for issue #219 Incomplete libraries for movies and TV shows. For music items this was already fixed in PR #236 See commit 7330f85241920e0ae9a5bec7719c497998fb070c --- .../org/xbmc/kore/testhelpers/Database.java | 11 +++++----- .../org/xbmc/kore/testhelpers/TestUtils.java | 4 ---- .../kore/tests/mediaprovider/TestValues.java | 12 ---------- .../kore/jsonrpc/method/VideoLibrary.java | 22 +++++++++++-------- .../xbmc/kore/service/library/SyncMovies.java | 20 +++++++++++------ .../xbmc/kore/service/library/SyncMusic.java | 14 +++--------- .../kore/service/library/SyncTVShows.java | 9 ++++---- .../xbmc/kore/service/library/SyncUtils.java | 13 +++++++++++ 8 files changed, 53 insertions(+), 52 deletions(-) diff --git a/app/src/androidTest/java/org/xbmc/kore/testhelpers/Database.java b/app/src/androidTest/java/org/xbmc/kore/testhelpers/Database.java index d4f938d..bd3188c 100644 --- a/app/src/androidTest/java/org/xbmc/kore/testhelpers/Database.java +++ b/app/src/androidTest/java/org/xbmc/kore/testhelpers/Database.java @@ -23,6 +23,7 @@ import android.content.Context; import org.xbmc.kore.host.HostInfo; import org.xbmc.kore.host.HostManager; import org.xbmc.kore.jsonrpc.ApiException; +import org.xbmc.kore.jsonrpc.ApiList; import org.xbmc.kore.jsonrpc.method.AudioLibrary; import org.xbmc.kore.jsonrpc.method.VideoLibrary; import org.xbmc.kore.jsonrpc.type.AudioType; @@ -68,15 +69,15 @@ public class Database { private static void insertMovies(Context context, int hostId) throws ApiException, IOException { VideoLibrary.GetMovies getMovies = new VideoLibrary.GetMovies(); String result = Utils.readFile(context, "Video.Details.Movie.json"); - ArrayList movieList = (ArrayList) getMovies.resultFromJson(result); + ApiList movieList = getMovies.resultFromJson(result); - ContentValues movieValuesBatch[] = new ContentValues[movieList.size()]; + ContentValues movieValuesBatch[] = new ContentValues[movieList.items.size()]; int castCount = 0; // Iterate on each movie - for (int i = 0; i < movieList.size(); i++) { - VideoType.DetailsMovie movie = movieList.get(i); + for (int i = 0; i < movieList.items.size(); i++) { + VideoType.DetailsMovie movie = movieList.items.get(i); movieValuesBatch[i] = SyncUtils.contentValuesFromMovie(hostId, movie); castCount += movie.cast.size(); } @@ -86,7 +87,7 @@ public class Database { ContentValues movieCastValuesBatch[] = new ContentValues[castCount]; int count = 0; // Iterate on each movie/cast - for (VideoType.DetailsMovie movie : movieList) { + for (VideoType.DetailsMovie movie : movieList.items) { for (VideoType.Cast cast : movie.cast) { movieCastValuesBatch[count] = SyncUtils.contentValuesFromCast(hostId, cast); movieCastValuesBatch[count].put(MediaContract.MovieCastColumns.MOVIEID, movie.movieid); diff --git a/app/src/androidTest/java/org/xbmc/kore/testhelpers/TestUtils.java b/app/src/androidTest/java/org/xbmc/kore/testhelpers/TestUtils.java index 1cf9d31..4b24c06 100644 --- a/app/src/androidTest/java/org/xbmc/kore/testhelpers/TestUtils.java +++ b/app/src/androidTest/java/org/xbmc/kore/testhelpers/TestUtils.java @@ -18,13 +18,9 @@ package org.xbmc.kore.testhelpers; import android.database.Cursor; -import org.xbmc.kore.ui.SongsListFragment; - import java.util.HashMap; import java.util.Map; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; public class TestUtils { diff --git a/app/src/androidTest/java/org/xbmc/kore/tests/mediaprovider/TestValues.java b/app/src/androidTest/java/org/xbmc/kore/tests/mediaprovider/TestValues.java index 393b0f9..76bc71d 100644 --- a/app/src/androidTest/java/org/xbmc/kore/tests/mediaprovider/TestValues.java +++ b/app/src/androidTest/java/org/xbmc/kore/tests/mediaprovider/TestValues.java @@ -19,18 +19,6 @@ package org.xbmc.kore.tests.mediaprovider; import android.database.Cursor; import org.xbmc.kore.provider.MediaContract; -import org.xbmc.kore.provider.MediaDatabase; -import org.xbmc.kore.provider.MediaProvider; -import org.xbmc.kore.ui.AlbumListFragment; -import org.xbmc.kore.ui.ArtistListFragment; -import org.xbmc.kore.ui.ArtistOverviewFragment; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; import static org.junit.Assert.assertEquals; diff --git a/app/src/main/java/org/xbmc/kore/jsonrpc/method/VideoLibrary.java b/app/src/main/java/org/xbmc/kore/jsonrpc/method/VideoLibrary.java index 68b4f17..bcbed88 100644 --- a/app/src/main/java/org/xbmc/kore/jsonrpc/method/VideoLibrary.java +++ b/app/src/main/java/org/xbmc/kore/jsonrpc/method/VideoLibrary.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.xbmc.kore.jsonrpc.ApiException; +import org.xbmc.kore.jsonrpc.ApiList; import org.xbmc.kore.jsonrpc.ApiMethod; import org.xbmc.kore.jsonrpc.type.ListType; import org.xbmc.kore.jsonrpc.type.VideoType; @@ -82,7 +83,7 @@ public class VideoLibrary { /** * Retrieve all movies */ - public static class GetMovies extends ApiMethod> { + public static class GetMovies extends ApiMethod> { public final static String METHOD_NAME = "VideoLibrary.GetMovies"; private final static String LIST_NODE = "movies"; @@ -118,13 +119,15 @@ public class VideoLibrary { } @Override - public List resultFromJson(ObjectNode jsonObject) + public ApiList resultFromJson(ObjectNode jsonObject) throws ApiException { + ListType.LimitsReturned limits = new ListType.LimitsReturned(jsonObject); + JsonNode resultNode = jsonObject.get(RESULT_NODE); ArrayNode items = resultNode.has(LIST_NODE) ? (ArrayNode)resultNode.get(LIST_NODE) : null; if (items == null) { - return new ArrayList(0); + return new ApiList<>(new ArrayList(0), limits); } ArrayList result = new ArrayList(items.size()); @@ -132,7 +135,7 @@ public class VideoLibrary { result.add(new VideoType.DetailsMovie(item)); } - return result; + return new ApiList<>(result, limits); } } @@ -200,7 +203,7 @@ public class VideoLibrary { /** * Retrieve all TV Shows */ - public static class GetTVShows extends ApiMethod> { + public static class GetTVShows extends ApiMethod> { public final static String METHOD_NAME = "VideoLibrary.GetTVShows"; private final static String LIST_NODE = "tvshows"; @@ -235,21 +238,22 @@ public class VideoLibrary { } @Override - public List resultFromJson(ObjectNode jsonObject) + public ApiList resultFromJson(ObjectNode jsonObject) throws ApiException { + ListType.LimitsReturned limits = new ListType.LimitsReturned(jsonObject); JsonNode resultNode = jsonObject.get(RESULT_NODE); ArrayNode items = resultNode.has(LIST_NODE) ? (ArrayNode)resultNode.get(LIST_NODE) : null; if (items == null) { - return new ArrayList(0); + return new ApiList<>(new ArrayList(0), limits); } - ArrayList result = new ArrayList(items.size()); + ArrayList result = new ArrayList<>(items.size()); for (JsonNode item : items) { result.add(new VideoType.DetailsTVShow(item)); } - return result; + return new ApiList<>(result, limits); } } diff --git a/app/src/main/java/org/xbmc/kore/service/library/SyncMovies.java b/app/src/main/java/org/xbmc/kore/service/library/SyncMovies.java index b0965e0..3f8f83f 100644 --- a/app/src/main/java/org/xbmc/kore/service/library/SyncMovies.java +++ b/app/src/main/java/org/xbmc/kore/service/library/SyncMovies.java @@ -22,6 +22,7 @@ import android.os.Bundle; import android.os.Handler; import org.xbmc.kore.jsonrpc.ApiCallback; +import org.xbmc.kore.jsonrpc.ApiList; import org.xbmc.kore.jsonrpc.HostConnection; import org.xbmc.kore.jsonrpc.method.VideoLibrary; import org.xbmc.kore.jsonrpc.type.ListType; @@ -146,19 +147,24 @@ public class SyncMovies extends SyncItem { // Call GetMovies with the current limits set ListType.Limits limits = new ListType.Limits(startIdx, startIdx + LIMIT_SYNC_MOVIES); VideoLibrary.GetMovies action = new VideoLibrary.GetMovies(limits, properties); - action.execute(hostConnection, new ApiCallback>() { + action.execute(hostConnection, new ApiCallback>() { @Override - public void onSuccess(List result) { + public void onSuccess(ApiList result) { + ListType.LimitsReturned limitsReturned = null; + if (result != null) { + limitsReturned = result.limits; + } + if (startIdx == 0) { // First call, delete movies from DB deleteMovies(contentResolver, hostId, -1); } - if (!result.isEmpty()) { - insertMovies(orchestrator, contentResolver, result); + if (!result.items.isEmpty()) { + insertMovies(orchestrator, contentResolver, result.items); } - LogUtils.LOGD(TAG, "syncAllMovies, movies gotten: " + result.size()); - if (result.size() == LIMIT_SYNC_MOVIES) { + LogUtils.LOGD(TAG, "syncAllMovies, movies gotten: " + result.items.size()); + if (SyncUtils.moreItemsAvailable(limitsReturned)) { // Max limit returned, there may be some more movies // As we're going to recurse, these result objects can add up, so // let's help the GC and indicate that we don't need this memory @@ -176,7 +182,7 @@ public class SyncMovies extends SyncItem { @Override public void onError(int errorCode, String description) { - // Ok, something bad happend, just quit + // Ok, something bad happened, just quit orchestrator.syncItemFailed(errorCode, description); } }, callbackHandler); diff --git a/app/src/main/java/org/xbmc/kore/service/library/SyncMusic.java b/app/src/main/java/org/xbmc/kore/service/library/SyncMusic.java index 258920b..1f2e247 100644 --- a/app/src/main/java/org/xbmc/kore/service/library/SyncMusic.java +++ b/app/src/main/java/org/xbmc/kore/service/library/SyncMusic.java @@ -118,7 +118,7 @@ public class SyncMusic extends SyncItem { insertArtists(items, contentResolver); - if (moreItemsAvailable(limitsReturned)) { + if (SyncUtils.moreItemsAvailable(limitsReturned)) { LogUtils.LOGD(TAG, "chainCallSyncArtists: More results on media center, recursing."); result = null; // Help the GC? chainCallSyncArtists(orchestrator, hostConnection, callbackHandler, contentResolver, @@ -235,7 +235,7 @@ public class SyncMusic extends SyncItem { LogUtils.LOGD(TAG, "Finished inserting artists and genres in: " + (System.currentTimeMillis() - albumSyncStartTime)); - if (moreItemsAvailable(limitsReturned)) { + if (SyncUtils.moreItemsAvailable(limitsReturned)) { LogUtils.LOGD(TAG, "chainCallSyncAlbums: More results on media center, recursing."); result = null; // Help the GC? chainCallSyncAlbums(orchestrator, hostConnection, callbackHandler, contentResolver, @@ -302,7 +302,7 @@ public class SyncMusic extends SyncItem { // Save partial results to DB insertSongsItems(items, contentResolver); - if (moreItemsAvailable(limitsReturned)) { + if (SyncUtils.moreItemsAvailable(limitsReturned)) { LogUtils.LOGD(TAG, "chainCallSyncSongs: More results on media center, recursing."); result = null; // Help the GC? chainCallSyncSongs(orchestrator, hostConnection, callbackHandler, contentResolver, @@ -407,12 +407,4 @@ public class SyncMusic extends SyncItem { contentResolver.bulkInsert(MediaContract.SongArtists.CONTENT_URI, songArtistsValuesBatch); } - - private boolean moreItemsAvailable(ListType.LimitsReturned limitsReturned) { - boolean moreItemsAvailable = false; - if (limitsReturned != null) { - moreItemsAvailable = ( limitsReturned.total - limitsReturned.end ) > 0; - } - return moreItemsAvailable; - } } diff --git a/app/src/main/java/org/xbmc/kore/service/library/SyncTVShows.java b/app/src/main/java/org/xbmc/kore/service/library/SyncTVShows.java index 4cca6db..e3701c9 100644 --- a/app/src/main/java/org/xbmc/kore/service/library/SyncTVShows.java +++ b/app/src/main/java/org/xbmc/kore/service/library/SyncTVShows.java @@ -23,6 +23,7 @@ import android.os.Bundle; import android.os.Handler; import org.xbmc.kore.jsonrpc.ApiCallback; +import org.xbmc.kore.jsonrpc.ApiList; import org.xbmc.kore.jsonrpc.HostConnection; import org.xbmc.kore.jsonrpc.method.VideoLibrary; import org.xbmc.kore.jsonrpc.type.ListType; @@ -143,11 +144,11 @@ public class SyncTVShows extends SyncItem { // Call GetTVShows with the current limits set ListType.Limits limits = new ListType.Limits(startIdx, startIdx + LIMIT_SYNC_TVSHOWS); VideoLibrary.GetTVShows action = new VideoLibrary.GetTVShows(limits, getTVShowsProperties); - action.execute(hostConnection, new ApiCallback>() { + action.execute(hostConnection, new ApiCallback>() { @Override - public void onSuccess(List result) { - allResults.addAll(result); - if (result.size() == LIMIT_SYNC_TVSHOWS) { + public void onSuccess(ApiList result) { + allResults.addAll(result.items); + if (SyncUtils.moreItemsAvailable(result.limits)) { // Max limit returned, there may be some more movies LogUtils.LOGD(TAG, "syncAllTVShows: More tv shows on media center, recursing."); syncAllTVShows(orchestrator, hostConnection, callbackHandler, contentResolver, diff --git a/app/src/main/java/org/xbmc/kore/service/library/SyncUtils.java b/app/src/main/java/org/xbmc/kore/service/library/SyncUtils.java index 2eb4233..32985ea 100644 --- a/app/src/main/java/org/xbmc/kore/service/library/SyncUtils.java +++ b/app/src/main/java/org/xbmc/kore/service/library/SyncUtils.java @@ -23,6 +23,7 @@ import android.content.ServiceConnection; import android.os.IBinder; import org.xbmc.kore.host.HostInfo; +import org.xbmc.kore.jsonrpc.type.ListType; import org.xbmc.kore.jsonrpc.type.VideoType; import org.xbmc.kore.jsonrpc.type.AudioType; import org.xbmc.kore.jsonrpc.type.LibraryType; @@ -476,4 +477,16 @@ public class SyncUtils { return false; } + + /** + * Checks if there are more items available according to the limits returned + * @param limitsReturned + * @return true if there are more items available, false otherwise + */ + public static boolean moreItemsAvailable(ListType.LimitsReturned limitsReturned) { + if (limitsReturned != null) { + return ( limitsReturned.total - limitsReturned.end ) > 0; + } + return false; + } }