From 6d79fdf64d0c00b0d3a201491d22e1f98bfdd170 Mon Sep 17 00:00:00 2001 From: Shinokuni Date: Sun, 12 Jan 2020 15:14:27 +0100 Subject: [PATCH] Add adapter for Nextcloud News items api call --- .../app/repositories/NextNewsRepository.java | 29 ++++---- .../services/nextcloudnews/NextNewsAPI.java | 17 +++-- .../nextcloudnews/NextNewsService.java | 6 +- .../nextcloudnews/NextNewsSyncResult.java | 8 +-- .../adapters/NextNewsItemsAdapter.kt | 67 +++++++++++++++++++ .../nextcloudnews/json/NextNewsItems.java | 16 ----- .../readropslibrary/utils/LibUtils.java | 6 ++ 7 files changed, 104 insertions(+), 45 deletions(-) create mode 100644 readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/adapters/NextNewsItemsAdapter.kt delete mode 100644 readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/json/NextNewsItems.java diff --git a/app/src/main/java/com/readrops/app/repositories/NextNewsRepository.java b/app/src/main/java/com/readrops/app/repositories/NextNewsRepository.java index 4a84e681..5710cd18 100644 --- a/app/src/main/java/com/readrops/app/repositories/NextNewsRepository.java +++ b/app/src/main/java/com/readrops/app/repositories/NextNewsRepository.java @@ -10,7 +10,6 @@ import androidx.annotation.Nullable; import com.readrops.app.utils.FeedInsertionResult; import com.readrops.app.utils.ParsingResult; import com.readrops.app.utils.Utils; -import com.readrops.app.utils.matchers.ItemMatcher; import com.readrops.readropsdb.entities.Feed; import com.readrops.readropsdb.entities.Folder; import com.readrops.readropsdb.entities.Item; @@ -24,7 +23,6 @@ import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeed; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeeds; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolder; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolders; -import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItem; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsRenameFeed; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsUser; import com.readrops.readropslibrary.utils.UnknownFormatException; @@ -118,8 +116,8 @@ public class NextNewsRepository extends ARepository { insertFeeds(syncResult.getFeeds()); timings.addSplit("insert feeds"); - /*insertItems(syncResult.getItems(), syncType == SyncType.INITIAL_SYNC); - timings.addSplit("insert items");*/ + insertItems(syncResult.getItems(), syncType == SyncType.INITIAL_SYNC); + timings.addSplit("insert items"); timings.dumpToLog(); account.setLastModified(lastModified); @@ -292,26 +290,27 @@ public class NextNewsRepository extends ARepository { database.folderDao().foldersUpsert(nextNewsFolders, account); } - private void insertItems(List items, boolean initialSync) { - List newItems = new ArrayList<>(); + private void insertItems(List items, boolean initialSync) { + List itemsToInsert = new ArrayList<>(); - for (NextNewsItem nextNewsItem : items) { - int feedId = database.feedDao().getFeedIdByRemoteId(String.valueOf(nextNewsItem.getFeedId()), account.getId()); + for (Item item : items) { + int feedId = database.feedDao().getFeedIdByRemoteId(item.getFeedRemoteId(), account.getId()); - if (!initialSync && feedId > 0 && database.itemDao().remoteItemExists(String.valueOf(nextNewsItem.getId()), feedId)) { - database.itemDao().setReadState(String.valueOf(nextNewsItem.getId()), !nextNewsItem.isUnread()); + //if the item already exists, update only its read state + if (!initialSync && feedId > 0 && database.itemDao().remoteItemExists(String.valueOf(item.getRemoteId()), feedId)) { + database.itemDao().setReadState(item.getRemoteId(), item.isRead()); break; } - Item item = ItemMatcher.nextNewsItemToItem(nextNewsItem, feedId); + item.setFeedId(feedId); item.setReadTime(Utils.readTimeFromString(item.getContent())); - newItems.add(item); + itemsToInsert.add(item); } - if (!newItems.isEmpty()) { - Collections.sort(newItems, Item::compareTo); - database.itemDao().insert(newItems); + if (!itemsToInsert.isEmpty()) { + Collections.sort(itemsToInsert, Item::compareTo); + database.itemDao().insert(itemsToInsert); } } } diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsAPI.java b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsAPI.java index d0850375..37fad5f7 100644 --- a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsAPI.java +++ b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsAPI.java @@ -7,23 +7,25 @@ import androidx.annotation.Nullable; import com.readrops.readropsdb.entities.Feed; import com.readrops.readropsdb.entities.Folder; +import com.readrops.readropsdb.entities.Item; import com.readrops.readropslibrary.services.API; import com.readrops.readropslibrary.services.Credentials; import com.readrops.readropslibrary.services.SyncType; import com.readrops.readropslibrary.services.nextcloudnews.adapters.NextNewsFeedsAdapter; import com.readrops.readropslibrary.services.nextcloudnews.adapters.NextNewsFoldersAdapter; +import com.readrops.readropslibrary.services.nextcloudnews.adapters.NextNewsItemsAdapter; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeed; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeeds; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolder; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolders; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItemIds; -import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItems; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsRenameFeed; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsUser; import com.readrops.readropslibrary.utils.ConflictException; import com.readrops.readropslibrary.utils.LibUtils; import com.readrops.readropslibrary.utils.UnknownFormatException; import com.squareup.moshi.Moshi; +import com.squareup.moshi.Types; import java.io.IOException; import java.util.HashMap; @@ -45,6 +47,7 @@ public class NextNewsAPI extends API { return new Moshi.Builder() .add(new NextNewsFeedsAdapter()) .add(new NextNewsFoldersAdapter()) + .add(Types.newParameterizedType(List.class, Item.class), new NextNewsItemsAdapter()) .build(); } @@ -93,28 +96,28 @@ public class NextNewsAPI extends API { private void initialSync(NextNewsSyncResult syncResult) throws IOException { getFeedsAndFolders(syncResult); - /*Response itemsResponse = api.getItems(3, false, MAX_ITEMS).execute(); - NextNewsItems itemList = itemsResponse.body(); + Response> itemsResponse = api.getItems(3, false, MAX_ITEMS).execute(); + List itemList = itemsResponse.body(); if (!itemsResponse.isSuccessful()) syncResult.setError(true); if (itemList != null) - syncResult.setItems(itemList.getItems());*/ + syncResult.setItems(itemList); } private void classicSync(NextNewsSyncResult syncResult, NextNewsSyncData data) throws IOException { putModifiedItems(data, syncResult); getFeedsAndFolders(syncResult); - Response itemsResponse = api.getNewItems(data.getLastModified(), 3).execute(); - NextNewsItems itemList = itemsResponse.body(); + Response> itemsResponse = api.getNewItems(data.getLastModified(), 3).execute(); + List itemList = itemsResponse.body(); if (!itemsResponse.isSuccessful()) syncResult.setError(true); if (itemList != null) - syncResult.setItems(itemList.getItems()); + syncResult.setItems(itemList); } private void getFeedsAndFolders(NextNewsSyncResult syncResult) throws IOException { diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsService.java b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsService.java index 0bd0da61..6c491e51 100644 --- a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsService.java +++ b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsService.java @@ -2,11 +2,11 @@ package com.readrops.readropslibrary.services.nextcloudnews; import com.readrops.readropsdb.entities.Feed; import com.readrops.readropsdb.entities.Folder; +import com.readrops.readropsdb.entities.Item; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeeds; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolder; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolders; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItemIds; -import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItems; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsRenameFeed; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsUser; @@ -37,10 +37,10 @@ public interface NextNewsService { Call> getFeeds(); @GET("items") - Call getItems(@Query("type") int type, @Query("getRead") boolean read, @Query("batchSize") int batchSize); + Call> getItems(@Query("type") int type, @Query("getRead") boolean read, @Query("batchSize") int batchSize); @GET("items/updated") - Call getNewItems(@Query("lastModified") long lastModified, @Query("type") int type); + Call> getNewItems(@Query("lastModified") long lastModified, @Query("type") int type); @PUT("items/{stateType}/multiple") Call setArticlesState(@Path("stateType") String stateType, @Body NextNewsItemIds items); diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsSyncResult.java b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsSyncResult.java index cda15e8f..2af97bce 100644 --- a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsSyncResult.java +++ b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/NextNewsSyncResult.java @@ -2,7 +2,7 @@ package com.readrops.readropslibrary.services.nextcloudnews; import com.readrops.readropsdb.entities.Feed; import com.readrops.readropsdb.entities.Folder; -import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItem; +import com.readrops.readropsdb.entities.Item; import java.util.List; @@ -12,7 +12,7 @@ public class NextNewsSyncResult { private List feeds; - private List items; + private List items; private boolean error; @@ -36,11 +36,11 @@ public class NextNewsSyncResult { this.feeds = feeds; } - public List getItems() { + public List getItems() { return items; } - public void setItems(List items) { + public void setItems(List items) { this.items = items; } diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/adapters/NextNewsItemsAdapter.kt b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/adapters/NextNewsItemsAdapter.kt new file mode 100644 index 00000000..f5fbffca --- /dev/null +++ b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/adapters/NextNewsItemsAdapter.kt @@ -0,0 +1,67 @@ +package com.readrops.readropslibrary.services.nextcloudnews.adapters + +import com.readrops.readropsdb.entities.Item +import com.readrops.readropslibrary.utils.LibUtils +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import org.joda.time.DateTimeZone +import org.joda.time.LocalDateTime + +class NextNewsItemsAdapter : JsonAdapter>() { + + override fun toJson(writer: JsonWriter, value: List?) { + // no need of this + } + + @Override + override fun fromJson(reader: JsonReader): List { + val items = mutableListOf() + + reader.beginObject() + reader.nextName() // "items", beginning of items array + reader.beginArray() + + while (reader.hasNext()) { + val item = Item() + reader.beginObject() + + var enclosureMime: String? = null + var enclosureLink: String? = null + + while (reader.hasNext()) { + with(item) { + when (reader.selectName(NAMES)) { + 0 -> remoteId = reader.nextInt().toString() + 1 -> link = reader.nextString() + 2 -> title = reader.nextString() + 3 -> author = reader.nextString() + 4 -> pubDate = LocalDateTime(reader.nextLong() * 1000L, DateTimeZone.getDefault()) + 5 -> content = reader.nextString() + 6 -> enclosureMime = if (reader.peek() != JsonReader.Token.NULL) reader.nextString() else reader.nextNull() + 7 -> enclosureLink = if (reader.peek() != JsonReader.Token.NULL) reader.nextString() else reader.nextNull() + 8 -> feedRemoteId = reader.nextInt().toString() + 9 -> isRead = !reader.nextBoolean() + else -> reader.skipValue() + } + } + } + + if (enclosureMime != null && LibUtils.isMimeImage(enclosureMime!!)) + item.imageLink = enclosureLink + + items += item + reader.endObject() + } + + reader.endArray() + reader.endObject() + + return items + } + + companion object { + val NAMES: JsonReader.Options = JsonReader.Options.of("id", "url", "title", "author", + "pubDate", "body", "enclosureMime", "enclosureLink", "feedId", "unread") + } +} \ No newline at end of file diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/json/NextNewsItems.java b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/json/NextNewsItems.java deleted file mode 100644 index bf238dda..00000000 --- a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/nextcloudnews/json/NextNewsItems.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.readrops.readropslibrary.services.nextcloudnews.json; - -import java.util.List; - -public class NextNewsItems { - - private List items; - - public NextNewsItems(List items) { - this.items = items; - } - - public List getItems() { - return items; - } -} diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/utils/LibUtils.java b/readropslibrary/src/main/java/com/readrops/readropslibrary/utils/LibUtils.java index b0830e35..d34f1483 100644 --- a/readropslibrary/src/main/java/com/readrops/readropslibrary/utils/LibUtils.java +++ b/readropslibrary/src/main/java/com/readrops/readropslibrary/utils/LibUtils.java @@ -3,6 +3,8 @@ package com.readrops.readropslibrary.utils; import android.content.Context; import android.net.Uri; +import androidx.annotation.NonNull; + import java.io.FileNotFoundException; import java.io.InputStream; import java.util.Scanner; @@ -38,4 +40,8 @@ public final class LibUtils { return inputStreamToString(inputStream); } + public static boolean isMimeImage(@NonNull String type) { + return type.equals("image") || type.equals("image/jpeg") || type.equals("image/jpg") + || type.equals("image/png"); + } }