diff --git a/app/src/main/java/com/readrops/app/repositories/FreshRSSRepository.java b/app/src/main/java/com/readrops/app/repositories/FreshRSSRepository.java index 1c8a85be..acfcbeef 100644 --- a/app/src/main/java/com/readrops/app/repositories/FreshRSSRepository.java +++ b/app/src/main/java/com/readrops/app/repositories/FreshRSSRepository.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; @@ -20,7 +19,6 @@ import com.readrops.readropslibrary.services.SyncType; import com.readrops.readropslibrary.services.freshrss.FreshRSSAPI; import com.readrops.readropslibrary.services.freshrss.FreshRSSCredentials; import com.readrops.readropslibrary.services.freshrss.FreshRSSSyncData; -import com.readrops.readropslibrary.services.freshrss.json.FreshRSSItem; import java.util.ArrayList; import java.util.Collections; @@ -111,10 +109,10 @@ public class FreshRSSRepository extends ARepository { insertItems(syncResult.getItems(), syncType == SyncType.INITIAL_SYNC); logger.addSplit("items insertion"); - account.setLastModified(syncResult.getLastUpdated()); - database.accountDao().updateLastModified(account.getId(), syncResult.getLastUpdated()); + //account.setLastModified(syncResult.getLastUpdated()); + //database.accountDao().updateLastModified(account.getId(), syncResult.getLastUpdated()); - database.itemDao().resetReadChanges(account.getId()); + //database.itemDao().resetReadChanges(account.getId()); logger.dumpToLog(); return Observable.empty(); @@ -189,6 +187,10 @@ public class FreshRSSRepository extends ARepository { } private void insertFeeds(List freshRSSFeeds) { + for (Feed feed : freshRSSFeeds) { + feed.setAccountId(account.getId()); + } + List insertedFeedsIds = database.feedDao().feedsUpsert(freshRSSFeeds, account); if (!insertedFeedsIds.isEmpty()) { @@ -198,27 +200,27 @@ public class FreshRSSRepository extends ARepository { } private void insertFolders(List freshRSSFolders) { + for (Folder folder : freshRSSFolders) { + folder.setAccountId(account.getId()); + } + database.folderDao().foldersUpsert(freshRSSFolders, account); } - private void insertItems(List items, boolean initialSync) { - List newItems = new ArrayList<>(); + private void insertItems(List items, boolean initialSync) { + for (Item item : items) { + int feedId = database.feedDao().getFeedIdByRemoteId(item.getFeedRemoteId(), account.getId()); - for (FreshRSSItem freshRSSItem : items) { - int feedId = database.feedDao().getFeedIdByRemoteId(String.valueOf(freshRSSItem.getOrigin().getStreamId()), account.getId()); - - if (!initialSync && feedId > 0 && database.itemDao().remoteItemExists(freshRSSItem.getId(), feedId)) { - database.itemDao().setReadState(freshRSSItem.getId(), freshRSSItem.isRead()); + if (!initialSync && feedId > 0 && database.itemDao().remoteItemExists(item.getRemoteId(), feedId)) { + database.itemDao().setReadState(item.getRemoteId(), item.isRead()); break; } - Item item = ItemMatcher.freshRSSItemtoItem(freshRSSItem, feedId); + item.setFeedId(feedId); item.setReadTime(Utils.readTimeFromString(item.getContent())); - - newItems.add(item); } - Collections.sort(newItems, Item::compareTo); - database.itemDao().insert(newItems); + Collections.sort(items, Item::compareTo); + database.itemDao().insert(items); } } diff --git a/readropsdb/src/main/java/com/readrops/readropsdb/entities/Item.java b/readropsdb/src/main/java/com/readrops/readropsdb/entities/Item.java index 0156f233..92738557 100644 --- a/readropsdb/src/main/java/com/readrops/readropsdb/entities/Item.java +++ b/readropsdb/src/main/java/com/readrops/readropsdb/entities/Item.java @@ -3,6 +3,7 @@ package com.readrops.readropsdb.entities; import androidx.room.ColumnInfo; import androidx.room.Entity; import androidx.room.ForeignKey; +import androidx.room.Ignore; import androidx.room.PrimaryKey; import org.joda.time.LocalDateTime; @@ -10,8 +11,7 @@ import org.joda.time.LocalDateTime; import static androidx.room.ForeignKey.CASCADE; -@Entity -(foreignKeys = @ForeignKey(entity = Feed.class, parentColumns = "id", childColumns = "feed_id", onDelete = CASCADE)) +@Entity(foreignKeys = @ForeignKey(entity = Feed.class, parentColumns = "id", childColumns = "feed_id", onDelete = CASCADE)) public class Item implements Comparable { @PrimaryKey(autoGenerate = true) @@ -55,6 +55,9 @@ public class Item implements Comparable { private String remoteId; + @Ignore + private String feedRemoteId; + public int getId() { return id; } @@ -194,6 +197,14 @@ public class Item implements Comparable { this.remoteId = remoteId; } + public String getFeedRemoteId() { + return feedRemoteId; + } + + public void setFeedRemoteId(String feedRemoteId) { + this.feedRemoteId = feedRemoteId; + } + @Override public int compareTo(Item o) { return this.pubDate.compareTo(o.getPubDate()); diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSAPI.java b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSAPI.java index f39a7656..07e61f0b 100644 --- a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSAPI.java +++ b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSAPI.java @@ -5,14 +5,16 @@ 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.freshrss.adapters.FreshRSSFeedsAdapter; import com.readrops.readropslibrary.services.freshrss.adapters.FreshRSSFoldersAdapter; -import com.readrops.readropslibrary.services.freshrss.json.FreshRSSItems; +import com.readrops.readropslibrary.services.freshrss.adapters.FreshRSSItemsAdapter; import com.readrops.readropslibrary.services.freshrss.json.FreshRSSUserInfo; import com.squareup.moshi.Moshi; +import com.squareup.moshi.Types; import java.io.StringReader; import java.util.List; @@ -36,6 +38,7 @@ public class FreshRSSAPI extends API { @Override protected Moshi buildMoshi() { return new Moshi.Builder() + .add(Types.newParameterizedType(List.class, Item.class), new FreshRSSItemsAdapter()) .add(new FreshRSSFeedsAdapter()) .add(new FreshRSSFoldersAdapter()) .build(); @@ -94,39 +97,23 @@ public class FreshRSSAPI extends API { public Single sync(@NonNull SyncType syncType, @NonNull FreshRSSSyncData syncData, @NonNull String writeToken) { FreshRSSSyncResult syncResult = new FreshRSSSyncResult(); - /*return setItemsReadState(syncData, writeToken) - .andThen(getFolders() - .flatMap(freshRSSFolders -> { - syncResult.setFolders(freshRSSFolders.getTags()); + return getFolders() + .flatMap(freshRSSFolders -> { + syncResult.setFolders(freshRSSFolders); - return getFeeds(); - }) - .flatMap(freshRSSFeeds -> { - syncResult.setFeeds(freshRSSFeeds.getSubscriptions()); - - switch (syncType) { - case INITIAL_SYNC: - return getItems(GOOGLE_READ, MAX_ITEMS, null); - case CLASSIC_SYNC: - return getItems(GOOGLE_READ, MAX_ITEMS, syncData.getLastModified()); - } - - return Single.error(new Exception("Unknown sync type")); - }) - .flatMap(freshRSSItems -> { - syncResult.setItems(freshRSSItems.getItems()); - syncResult.setLastUpdated(freshRSSItems.getUpdated()); - - return Single.just(syncResult); - }));*/ - - return getFeeds() + return getFeeds(); + }) .flatMap(freshRSSFeeds -> { syncResult.setFeeds(freshRSSFeeds); - return getFolders(); - }).flatMap(folders -> { - syncResult.setFolders(folders); + if (syncType == SyncType.INITIAL_SYNC) { + return getItems(GOOGLE_READ, MAX_ITEMS, null); + } else { + return getItems(GOOGLE_READ, MAX_ITEMS, syncData.getLastModified()); + } + }) + .flatMap(freshRSSItems -> { + syncResult.setItems(freshRSSItems); return Single.just(syncResult); }); @@ -158,7 +145,7 @@ public class FreshRSSAPI extends API { * @param lastModified fetch only items created after this timestamp * @return the items */ - public Single getItems(@Nullable String excludeTarget, int max, @Nullable Long lastModified) { + public Single> getItems(@Nullable String excludeTarget, int max, @Nullable Long lastModified) { return api.getItems(excludeTarget, max, lastModified); } diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSService.java b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSService.java index ad81d1fc..b49ce94c 100644 --- a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSService.java +++ b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSService.java @@ -2,7 +2,7 @@ package com.readrops.readropslibrary.services.freshrss; import com.readrops.readropsdb.entities.Feed; import com.readrops.readropsdb.entities.Folder; -import com.readrops.readropslibrary.services.freshrss.json.FreshRSSItems; +import com.readrops.readropsdb.entities.Item; import com.readrops.readropslibrary.services.freshrss.json.FreshRSSUserInfo; import java.util.List; @@ -35,7 +35,7 @@ public interface FreshRSSService { Single> getFeeds(); @GET("reader/api/0/stream/contents/user/-/state/com.google/reading-list") - Single getItems(@Query("xt") String excludeTarget, @Query("n") int max, @Query("ot") Long lastModified); + Single> getItems(@Query("xt") String excludeTarget, @Query("n") int max, @Query("ot") Long lastModified); @GET("reader/api/0/tag/list?output=json") Single> getFolders(); diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSSyncResult.java b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSSyncResult.java index 36966ae7..e3f4c300 100644 --- a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSSyncResult.java +++ b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/FreshRSSSyncResult.java @@ -2,7 +2,7 @@ package com.readrops.readropslibrary.services.freshrss; import com.readrops.readropsdb.entities.Feed; import com.readrops.readropsdb.entities.Folder; -import com.readrops.readropslibrary.services.freshrss.json.FreshRSSItem; +import com.readrops.readropsdb.entities.Item; import java.util.ArrayList; import java.util.List; @@ -13,7 +13,7 @@ public class FreshRSSSyncResult { private List feeds; - private List items; + private List items; private long lastUpdated; @@ -30,11 +30,11 @@ public class FreshRSSSyncResult { 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/freshrss/adapters/FreshRSSItemsAdapter.kt b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/adapters/FreshRSSItemsAdapter.kt new file mode 100644 index 00000000..7963c619 --- /dev/null +++ b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/adapters/FreshRSSItemsAdapter.kt @@ -0,0 +1,118 @@ +package com.readrops.readropslibrary.services.freshrss.adapters + +import android.util.TimingLogger +import com.readrops.readropsdb.entities.Item +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 FreshRSSItemsAdapter : JsonAdapter>() { + + override fun toJson(writer: JsonWriter, value: List?) { + // no need of this + } + + override fun fromJson(reader: JsonReader): List? { + val logger = TimingLogger(TAG, "item parsing") + val items = mutableListOf() + + reader.beginObject() + while (reader.hasNext()) { + if (reader.nextName() == "items") parseItems(reader, items) else reader.skipValue() + } + + reader.endObject() + + logger.addSplit("item parsing done") + logger.dumpToLog() + + return items + } + + private fun parseItems(reader: JsonReader, items: MutableList) { + reader.beginArray() + + while (reader.hasNext()) { + val item = Item() + reader.beginObject() + + while (reader.hasNext()) { + with(item) { + when (reader.selectName(NAMES)) { + 0 -> remoteId = reader.nextString() + 1 -> pubDate = LocalDateTime(reader.nextLong() * 1000L, + DateTimeZone.getDefault()) + 2 -> title = reader.nextString() + 3 -> content = getContent(reader) + 4 -> link = getLink(reader) + 5 -> feedRemoteId = getRemoteFeedId(reader) + 6 -> author = reader.nextString() + else -> reader.skipValue() + } + } + } + + items += item + reader.endObject() + } + + reader.endArray() + } + + private fun getContent(reader: JsonReader): String? { + var content: String? = null + reader.beginObject() + + while (reader.hasNext()) { + when (reader.nextName()) { + "content" -> content = reader.nextString() + else -> reader.skipValue() + } + } + + reader.endObject() + return content + } + + private fun getLink(reader: JsonReader): String? { + var href: String? = null + reader.beginArray() + + while (reader.hasNext()) { + reader.beginObject() + + when (reader.nextName()) { + "href" -> href = reader.nextString() + else -> reader.skipValue() + } + + reader.endObject() + } + + reader.endArray() + return href + } + + private fun getRemoteFeedId(reader: JsonReader): String? { + var remoteFeedId: String? = null + reader.beginObject() + + while (reader.hasNext()) { + when (reader.nextName()) { + "streamId" -> remoteFeedId = reader.nextString() + else -> reader.skipValue() + } + } + + reader.endObject() + return remoteFeedId + } + + companion object { + val NAMES: JsonReader.Options = JsonReader.Options.of("id", "published", "title", "summary", "alternate", "origin", "author") + + val TAG = FreshRSSItemsAdapter::class.java.simpleName + } +} \ No newline at end of file diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/json/FreshRSSFolder.java b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/json/FreshRSSFolder.java deleted file mode 100644 index 595a0f65..00000000 --- a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/json/FreshRSSFolder.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.readrops.readropslibrary.services.freshrss.json; - -public class FreshRSSFolder { - - private String id; - - private String type; - - public FreshRSSFolder() { - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } -} diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/json/FreshRSSFolders.java b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/json/FreshRSSFolders.java deleted file mode 100644 index 9e324596..00000000 --- a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/json/FreshRSSFolders.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.readrops.readropslibrary.services.freshrss.json; - -import java.util.List; - -public class FreshRSSFolders { - - private List tags; - - public List getTags() { - return tags; - } - - public void setTags(List tags) { - this.tags = tags; - } -} diff --git a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/json/FreshRSSItems.java b/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/json/FreshRSSItems.java deleted file mode 100644 index ab97ea85..00000000 --- a/readropslibrary/src/main/java/com/readrops/readropslibrary/services/freshrss/json/FreshRSSItems.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.readrops.readropslibrary.services.freshrss.json; - -import java.util.List; - -public class FreshRSSItems { - - private String id; - - private Long updated; - - private List items; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public Long getUpdated() { - return updated; - } - - public void setUpdated(Long updated) { - this.updated = updated; - } - - public List getItems() { - return items; - } - - public void setItems(List items) { - this.items = items; - } -}