Add adapter for FreshRSS items api call

This commit is contained in:
Shinokuni 2020-01-04 17:06:21 +01:00
parent fea6c78520
commit 03b6c9b986
9 changed files with 174 additions and 135 deletions

View File

@ -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<FreshRSSAPI> {
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<FreshRSSAPI> {
}
private void insertFeeds(List<Feed> freshRSSFeeds) {
for (Feed feed : freshRSSFeeds) {
feed.setAccountId(account.getId());
}
List<Long> insertedFeedsIds = database.feedDao().feedsUpsert(freshRSSFeeds, account);
if (!insertedFeedsIds.isEmpty()) {
@ -198,27 +200,27 @@ public class FreshRSSRepository extends ARepository<FreshRSSAPI> {
}
private void insertFolders(List<Folder> freshRSSFolders) {
for (Folder folder : freshRSSFolders) {
folder.setAccountId(account.getId());
}
database.folderDao().foldersUpsert(freshRSSFolders, account);
}
private void insertItems(List<FreshRSSItem> items, boolean initialSync) {
List<Item> newItems = new ArrayList<>();
private void insertItems(List<Item> 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);
}
}

View File

@ -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<Item> {
@PrimaryKey(autoGenerate = true)
@ -55,6 +55,9 @@ public class Item implements Comparable<Item> {
private String remoteId;
@Ignore
private String feedRemoteId;
public int getId() {
return id;
}
@ -194,6 +197,14 @@ public class Item implements Comparable<Item> {
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());

View File

@ -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<FreshRSSService> {
@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<FreshRSSService> {
public Single<FreshRSSSyncResult> 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<FreshRSSService> {
* @param lastModified fetch only items created after this timestamp
* @return the items
*/
public Single<FreshRSSItems> getItems(@Nullable String excludeTarget, int max, @Nullable Long lastModified) {
public Single<List<Item>> getItems(@Nullable String excludeTarget, int max, @Nullable Long lastModified) {
return api.getItems(excludeTarget, max, lastModified);
}

View File

@ -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<List<Feed>> getFeeds();
@GET("reader/api/0/stream/contents/user/-/state/com.google/reading-list")
Single<FreshRSSItems> getItems(@Query("xt") String excludeTarget, @Query("n") int max, @Query("ot") Long lastModified);
Single<List<Item>> getItems(@Query("xt") String excludeTarget, @Query("n") int max, @Query("ot") Long lastModified);
@GET("reader/api/0/tag/list?output=json")
Single<List<Folder>> getFolders();

View File

@ -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<Feed> feeds;
private List<FreshRSSItem> items;
private List<Item> items;
private long lastUpdated;
@ -30,11 +30,11 @@ public class FreshRSSSyncResult {
this.feeds = feeds;
}
public List<FreshRSSItem> getItems() {
public List<Item> getItems() {
return items;
}
public void setItems(List<FreshRSSItem> items) {
public void setItems(List<Item> items) {
this.items = items;
}

View File

@ -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<List<Item>>() {
override fun toJson(writer: JsonWriter, value: List<Item>?) {
// no need of this
}
override fun fromJson(reader: JsonReader): List<Item>? {
val logger = TimingLogger(TAG, "item parsing")
val items = mutableListOf<Item>()
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<Item>) {
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
}
}

View File

@ -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;
}
}

View File

@ -1,16 +0,0 @@
package com.readrops.readropslibrary.services.freshrss.json;
import java.util.List;
public class FreshRSSFolders {
private List<FreshRSSFolder> tags;
public List<FreshRSSFolder> getTags() {
return tags;
}
public void setTags(List<FreshRSSFolder> tags) {
this.tags = tags;
}
}

View File

@ -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<FreshRSSItem> 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<FreshRSSItem> getItems() {
return items;
}
public void setItems(List<FreshRSSItem> items) {
this.items = items;
}
}