Add new synchronization process for FreshRSS with read state and starred items sync

This commit is contained in:
Shinokuni 2020-12-28 15:48:32 +01:00
parent 03c806b9a5
commit 0c9c601d41
3 changed files with 66 additions and 47 deletions

View File

@ -4,17 +4,10 @@ import com.readrops.db.entities.Feed
import com.readrops.db.entities.Folder
import com.readrops.db.entities.Item
class SyncResult {
var items: List<Item> = mutableListOf()
var starredItems: List<Item> = mutableListOf()
var feeds: List<Feed> = listOf()
var folders: List<Folder> = listOf()
var starredIds: List<String>? = null
var isError: Boolean = false
}
class SyncResult(var items: List<Item> = mutableListOf(),
var starredItems: List<Item> = mutableListOf(),
var feeds: List<Feed> = listOf(),
var folders: List<Folder> = listOf(),
var unreadIds: List<String>? = null,
var isError: Boolean = false
)

View File

@ -24,7 +24,8 @@ import okhttp3.RequestBody;
public class FreshRSSDataSource {
private static final int MAX_ITEMS = 5000;
private static final int MAX_STARRED_ITEMS = 999;
private static final int MAX_UNREAD_ITEMS_IDS = 5000;
private static final int MAX_STARRED_ITEMS = 1000;
public static final String GOOGLE_READ = "user/-/state/com.google/read";
public static final String GOOGLE_STARRED = "user/-/state/com.google/starred";
@ -111,14 +112,14 @@ public class FreshRSSDataSource {
.flatMap(freshRSSItems -> {
syncResult.setItems(freshRSSItems);
return getItemsIds(GOOGLE_READ, GOOGLE_READING_LIST, MAX_UNREAD_ITEMS_IDS);
}).flatMap(unreadItemsIds -> {
syncResult.setUnreadIds(unreadItemsIds);
return getStarredItems(MAX_STARRED_ITEMS);
}).flatMap(starredItems -> {
syncResult.setStarredItems(starredItems);
return getItemsIds(null, GOOGLE_STARRED, MAX_STARRED_ITEMS);
}).flatMap(starredIds -> {
syncResult.setStarredIds(starredIds);
return Single.just(syncResult);
}));
}

View File

@ -17,13 +17,18 @@ import com.readrops.db.Database;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
import com.readrops.db.entities.StarredItem;
import com.readrops.db.entities.UnreadItemsIds;
import com.readrops.db.entities.account.Account;
import org.joda.time.DateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import io.reactivex.Completable;
import io.reactivex.Observable;
@ -104,25 +109,18 @@ public class FreshRSSRepository extends ARepository {
insertFeeds(syncResult.getFeeds());
logger.addSplit("feeds insertion");
insertItems(syncResult.getItems(), syncType == SyncType.INITIAL_SYNC);
insertItems(syncResult.getItems());
logger.addSplit("items insertion");
insertItems(syncResult.getStarredItems(), syncType == SyncType.INITIAL_SYNC);
insertStarredItems(syncResult.getStarredItems());
logger.addSplit("starred items insertion");
updateItemsStarState(syncResult.getStarredIds());
insertUnreadItemsIds(syncResult.getUnreadIds());
logger.addSplit("insert and update items ids");
account.setLastModified(newLastModified);
database.accountDao().updateLastModified(account.getId(), newLastModified);
if (!syncData.getReadItemsIds().isEmpty() || !syncData.getUnreadItemsIds().isEmpty()) {
database.itemDao().resetReadChanges(account.getId());
}
if (!syncData.getStarredItemsIds().isEmpty() || !syncData.getUnstarredItemsIds().isEmpty()) {
database.itemDao().resetStarChanges(account.getId());
}
logger.addSplit("reset read changes");
logger.dumpToLog();
this.syncResult = syncResult;
@ -199,9 +197,7 @@ public class FreshRSSRepository extends ARepository {
}
private void insertFeeds(List<Feed> freshRSSFeeds) {
for (Feed feed : freshRSSFeeds) {
feed.setAccountId(account.getId());
}
freshRSSFeeds.stream().forEach(feed -> feed.setAccountId(account.getId()));
List<Long> insertedFeedsIds = database.feedDao().feedsUpsert(freshRSSFeeds, account);
@ -212,22 +208,22 @@ public class FreshRSSRepository extends ARepository {
}
private void insertFolders(List<Folder> freshRSSFolders) {
for (Folder folder : freshRSSFolders) {
folder.setAccountId(account.getId());
}
freshRSSFolders.stream().forEach(folder -> folder.setAccountId(account.getId()));
database.folderDao().foldersUpsert(freshRSSFolders, account);
}
private void insertItems(List<Item> items, boolean initialSync) {
private void insertItems(List<Item> items) {
List<Item> itemsToInsert = new ArrayList<>();
Map<String, Integer> itemsFeedsIds = new HashMap<>();
for (Item item : items) {
int feedId = database.feedDao().getFeedIdByRemoteId(item.getFeedRemoteId(), account.getId());
if (!initialSync && feedId > 0 && database.itemDao().remoteItemExists(item.getRemoteId(), feedId)) {
database.itemDao().setReadAndStarState(item.getRemoteId(), item.isRead(), item.isStarred());
continue;
Integer feedId;
if (itemsFeedsIds.containsKey(item.getFeedRemoteId())) {
feedId = itemsFeedsIds.get(item.getFeedRemoteId());
} else {
feedId = database.feedDao().getFeedIdByRemoteId(item.getFeedRemoteId(), account.getId());
itemsFeedsIds.put(item.getFeedRemoteId(), feedId);
}
item.setFeedId(feedId);
@ -241,12 +237,41 @@ public class FreshRSSRepository extends ARepository {
}
}
private void updateItemsStarState(List<String> itemsIds) {
if (itemsIds != null && !itemsIds.isEmpty()) {
database.itemDao().unstarItems(itemsIds, account.getId());
database.itemDao().starItems(itemsIds, account.getId());
private void insertStarredItems(List<Item> items) {
List<StarredItem> starredItems = items.stream().map(StarredItem::new).collect(Collectors.toList());
List<StarredItem> itemsToInsert = new ArrayList<>();
Map<String, Integer> itemsFeedsIds = new HashMap<>();
for (StarredItem item : starredItems) {
int feedId;
if (itemsFeedsIds.containsKey(item.getFeedRemoteId())) {
feedId = itemsFeedsIds.get(item.getFeedRemoteId());
} else {
feedId = database.feedDao().getFeedIdByRemoteId(item.getFeedRemoteId(), account.getId());
itemsFeedsIds.put(item.getFeedRemoteId(), feedId);
}
item.setFeedId(feedId);
item.setReadTime(Utils.readTimeFromString(item.getContent()));
itemsToInsert.add(item);
}
if (!itemsToInsert.isEmpty()) {
Collections.sort(itemsToInsert, Item::compareTo);
database.starredItemDao().deleteStarredItems(account.getId());
database.starredItemDao().insert(itemsToInsert);
}
}
private void insertUnreadItemsIds(List<String> ids) {
database.itemsIdsDao().deleteUnreadItemsIds(account.getId());
database.itemsIdsDao().insertUnreadItemsIds(ids.stream().map(id ->
new UnreadItemsIds(0, id, account.getId())).collect(Collectors.toList()));
database.itemDao().updateUnreadState(account.getId());
database.itemDao().updateReadState(account.getId());
}
}