From 3119d4426411dc697c1edcdff9bc1448e38f473f Mon Sep 17 00:00:00 2001 From: Shinokuni Date: Wed, 15 May 2019 22:45:43 +0200 Subject: [PATCH] Add account entity --- .../readrops/app/activities/MainActivity.java | 7 +- .../com/readrops/app/database/Converters.java | 23 ++++ .../com/readrops/app/database/Database.java | 18 ++- .../readrops/app/database/dao/AccountDao.java | 26 ++++ .../app/database/entities/Account.java | 123 ++++++++++++++++++ .../app/repositories/ARepository.java | 3 +- .../app/repositories/LocalFeedRepository.java | 3 +- .../app/repositories/NextNewsRepository.java | 46 +++++-- .../app/viewmodels/MainViewModel.java | 18 +-- .../services/nextcloudnews/NextNewsAPI.java | 4 +- 10 files changed, 239 insertions(+), 32 deletions(-) create mode 100644 app/src/main/java/com/readrops/app/database/dao/AccountDao.java create mode 100644 app/src/main/java/com/readrops/app/database/entities/Account.java diff --git a/app/src/main/java/com/readrops/app/activities/MainActivity.java b/app/src/main/java/com/readrops/app/activities/MainActivity.java index 4e5873a9..42df6b28 100644 --- a/app/src/main/java/com/readrops/app/activities/MainActivity.java +++ b/app/src/main/java/com/readrops/app/activities/MainActivity.java @@ -38,6 +38,7 @@ import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.SecondaryDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; import com.readrops.app.R; +import com.readrops.app.database.entities.Account; import com.readrops.app.database.entities.Feed; import com.readrops.app.database.entities.Folder; import com.readrops.app.database.pojo.ItemWithFeed; @@ -88,6 +89,8 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou private ActionMode actionMode; + private Account account; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -111,6 +114,8 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou adapter.submitList(itemWithFeeds); }); + viewModel.getAccounts().observe(this, accounts -> account = accounts.get(0)); + refreshLayout = findViewById(R.id.swipe_refresh_layout); refreshLayout.setOnRefreshListener(this); @@ -431,7 +436,7 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou } private void sync(List feeds) { - viewModel.sync(feeds) + viewModel.sync(feeds, account) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { diff --git a/app/src/main/java/com/readrops/app/database/Converters.java b/app/src/main/java/com/readrops/app/database/Converters.java index 496503a9..eef32c17 100644 --- a/app/src/main/java/com/readrops/app/database/Converters.java +++ b/app/src/main/java/com/readrops/app/database/Converters.java @@ -2,8 +2,14 @@ package com.readrops.app.database; import androidx.room.TypeConverter; +import com.readrops.app.database.entities.Account; + import org.joda.time.LocalDateTime; +import static com.readrops.app.database.entities.Account.AccountType.FEEDLY; +import static com.readrops.app.database.entities.Account.AccountType.FRESHRSS; +import static com.readrops.app.database.entities.Account.AccountType.NEXTCLOUD_NEWS; + public class Converters { @TypeConverter @@ -16,5 +22,22 @@ public class Converters { return localDateTime.toDateTime().getMillis(); } + @TypeConverter + public Account.AccountType fromAccountTypeCode(int code) { + if (code == NEXTCLOUD_NEWS.getCode()) + return NEXTCLOUD_NEWS; + else if (code == FEEDLY.getCode()) + return FEEDLY; + else if (code == FRESHRSS.getCode()) + return FRESHRSS; + + return null; + } + + @TypeConverter + public int getAccountTypeCode(Account.AccountType accountType) { + return accountType.getCode(); + } + } diff --git a/app/src/main/java/com/readrops/app/database/Database.java b/app/src/main/java/com/readrops/app/database/Database.java index c93613bc..30b384b8 100644 --- a/app/src/main/java/com/readrops/app/database/Database.java +++ b/app/src/main/java/com/readrops/app/database/Database.java @@ -1,21 +1,24 @@ package com.readrops.app.database; -import androidx.sqlite.db.SupportSQLiteDatabase; +import android.content.Context; + +import androidx.annotation.NonNull; import androidx.room.Room; import androidx.room.RoomDatabase; import androidx.room.TypeConverters; -import android.content.Context; -import androidx.annotation.NonNull; +import androidx.sqlite.db.SupportSQLiteDatabase; +import com.readrops.app.database.dao.AccountDao; import com.readrops.app.database.dao.FeedDao; import com.readrops.app.database.dao.FolderDao; import com.readrops.app.database.dao.ItemDao; +import com.readrops.app.database.entities.Account; import com.readrops.app.database.entities.Feed; import com.readrops.app.database.entities.Folder; import com.readrops.app.database.entities.Item; -@androidx.room.Database(entities = {Feed.class, Item.class, Folder.class}, version = 1, exportSchema = false) +@androidx.room.Database(entities = {Feed.class, Item.class, Folder.class, Account.class}, version = 1, exportSchema = false) @TypeConverters({Converters.class}) public abstract class Database extends RoomDatabase { @@ -25,6 +28,8 @@ public abstract class Database extends RoomDatabase { public abstract FolderDao folderDao(); + public abstract AccountDao accountDao(); + private static Database database; public static Database getInstance(Context context) { @@ -41,6 +46,11 @@ public abstract class Database extends RoomDatabase { Folder folder = new Folder("reserved"); new Thread(() -> database.folderDao().insert(folder)).start(); + + Account account = new Account("", "Nextcloud News", + Account.AccountType.NEXTCLOUD_NEWS); + + new Thread(() -> database.accountDao().insert(account)).start(); } @Override diff --git a/app/src/main/java/com/readrops/app/database/dao/AccountDao.java b/app/src/main/java/com/readrops/app/database/dao/AccountDao.java new file mode 100644 index 00000000..2847bf41 --- /dev/null +++ b/app/src/main/java/com/readrops/app/database/dao/AccountDao.java @@ -0,0 +1,26 @@ +package com.readrops.app.database.dao; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.Query; + +import com.readrops.app.database.entities.Account; + +import java.util.List; + +@Dao +public interface AccountDao { + + @Query("Select * from Account") + LiveData> selectAll(); + + @Query("Select * from Account Where id = :id") + Account selectById(int id); + + @Insert + long insert(Account account); + + @Query("Update Account set last_modified = :lastModified Where id = :accountId") + void updateLastModified(int accountId, long lastModified); +} diff --git a/app/src/main/java/com/readrops/app/database/entities/Account.java b/app/src/main/java/com/readrops/app/database/entities/Account.java new file mode 100644 index 00000000..57fe1b79 --- /dev/null +++ b/app/src/main/java/com/readrops/app/database/entities/Account.java @@ -0,0 +1,123 @@ +package com.readrops.app.database.entities; + +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.Ignore; +import androidx.room.PrimaryKey; + +@Entity +public class Account { + + @PrimaryKey(autoGenerate = true) + private int id; + + private String url; + + @ColumnInfo(name = "account_name") + private String accountName; + + @ColumnInfo(name = "account_type") + private AccountType accountType; + + @ColumnInfo(name = "last_modified") + private long lastModified; + + @ColumnInfo(name = "current_account") + private boolean currentAccount; + + @Ignore + private String login; + + @Ignore + private String password; + + public Account() { + } + + @Ignore + public Account(String url, String accountName, AccountType accountType) { + this.url = url; + this.accountName = accountName; + this.accountType = accountType; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getAccountName() { + return accountName; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + public AccountType getAccountType() { + return accountType; + } + + public void setAccountType(AccountType accountType) { + this.accountType = accountType; + } + + public long getLastModified() { + return lastModified; + } + + public void setLastModified(long lastModified) { + this.lastModified = lastModified; + } + + public boolean isCurrentAccount() { + return currentAccount; + } + + public void setCurrentAccount(boolean currentAccount) { + this.currentAccount = currentAccount; + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public enum AccountType { + NEXTCLOUD_NEWS(0), + FEEDLY(1), + FRESHRSS(2); + + private int code; + + public int getCode() { + return code; + } + + AccountType(int code) { + this.code = code; + } + } +} diff --git a/app/src/main/java/com/readrops/app/repositories/ARepository.java b/app/src/main/java/com/readrops/app/repositories/ARepository.java index 4d671f68..fb25d172 100644 --- a/app/src/main/java/com/readrops/app/repositories/ARepository.java +++ b/app/src/main/java/com/readrops/app/repositories/ARepository.java @@ -7,6 +7,7 @@ import android.util.Patterns; import androidx.palette.graphics.Palette; import com.readrops.app.database.Database; +import com.readrops.app.database.entities.Account; import com.readrops.app.database.entities.Feed; import com.readrops.app.database.entities.Folder; import com.readrops.app.database.pojo.FeedWithFolder; @@ -35,7 +36,7 @@ public abstract class ARepository { this.database = Database.getInstance(application); } - public abstract Observable sync(List feeds); + public abstract Observable sync(List feeds, Account account); public abstract Single> addFeeds(List results); diff --git a/app/src/main/java/com/readrops/app/repositories/LocalFeedRepository.java b/app/src/main/java/com/readrops/app/repositories/LocalFeedRepository.java index bd2461d1..b04b4a13 100644 --- a/app/src/main/java/com/readrops/app/repositories/LocalFeedRepository.java +++ b/app/src/main/java/com/readrops/app/repositories/LocalFeedRepository.java @@ -5,6 +5,7 @@ import android.app.Application; import androidx.paging.PageKeyedDataSource; import androidx.annotation.Nullable; +import com.readrops.app.database.entities.Account; import com.readrops.app.database.entities.Folder; import com.readrops.app.database.pojo.FeedWithFolder; import com.readrops.app.database.pojo.ItemWithFeed; @@ -49,7 +50,7 @@ public class LocalFeedRepository extends ARepository { } @Override - public Observable sync(@Nullable List feeds) { + public Observable sync(@Nullable List feeds, Account account) { return Observable.create(emitter -> { List feedList; 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 74304e21..f2b3005b 100644 --- a/app/src/main/java/com/readrops/app/repositories/NextNewsRepository.java +++ b/app/src/main/java/com/readrops/app/repositories/NextNewsRepository.java @@ -3,6 +3,7 @@ package com.readrops.app.repositories; import android.app.Application; import android.util.TimingLogger; +import com.readrops.app.database.entities.Account; import com.readrops.app.database.entities.Feed; import com.readrops.app.database.entities.Folder; import com.readrops.app.database.entities.Item; @@ -21,6 +22,8 @@ import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolder; import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItem; import com.readrops.readropslibrary.utils.LibUtils; +import org.joda.time.LocalDateTime; + import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -40,13 +43,23 @@ public class NextNewsRepository extends ARepository { } @Override - public Observable sync(List feeds) { + public Observable sync(List feeds, Account account) { return Observable.create(emitter -> { try { NextNewsAPI newsAPI = new NextNewsAPI(); + long lastModified = LocalDateTime.now().toDateTime().getMillis(); + NextNewsAPI.SyncType syncType; - Credentials credentials = new Credentials("", LibUtils.NEXTCLOUD_PASSWORD, ""); - SyncResult syncResult = newsAPI.sync(credentials, NextNewsAPI.SyncType.INITIAL_SYNC, new SyncData()); + if (account.getLastModified() != 0) + syncType = NextNewsAPI.SyncType.CLASSIC_SYNC; + else + syncType = NextNewsAPI.SyncType.INITIAL_SYNC; + + SyncData syncData = new SyncData(); + syncData.setLastModified(account.getLastModified() / 1000L); + + Credentials credentials = new Credentials("Lucas", LibUtils.NEXTCLOUD_PASSWORD, account.getUrl()); + SyncResult syncResult = newsAPI.sync(credentials, syncType, syncData); if (!syncResult.isError()) { TimingLogger timings = new TimingLogger(TAG, "sync"); @@ -56,10 +69,12 @@ public class NextNewsRepository extends ARepository { insertFeeds(syncResult.getFeeds()); timings.addSplit("insert feeds"); - insertItems(syncResult.getItems()); + insertItems(syncResult.getItems(), syncType == NextNewsAPI.SyncType.INITIAL_SYNC); timings.addSplit("insert items"); timings.dumpToLog(); + database.accountDao().updateLastModified(account.getId(), lastModified); + emitter.onComplete(); } else emitter.onError(new Throwable()); @@ -142,22 +157,25 @@ public class NextNewsRepository extends ARepository { database.folderDao().insert(newFolders); } - private void insertItems(List items) { + private void insertItems(List items, boolean initialSync) { List newItems = new ArrayList<>(); for (NextNewsItem nextNewsItem : items) { - if (!database.itemDao().remoteItemExists(nextNewsItem.getId())) { - try { - Feed feed = database.feedDao().getFeedByRemoteId(nextNewsItem.getFeedId()); - Item item = ItemMatcher.nextNewsItemToItem(nextNewsItem, feed); + if (!initialSync) { + if (database.itemDao().remoteItemExists(nextNewsItem.getId())) + continue; // skip the current item if it exists in the db + } - item.setReadTime(Utils.readTimeFromString(item.getContent())); + try { + Feed feed = database.feedDao().getFeedByRemoteId(nextNewsItem.getFeedId()); + Item item = ItemMatcher.nextNewsItemToItem(nextNewsItem, feed); - newItems.add(item); - } catch (Exception e) { - e.printStackTrace(); - } + item.setReadTime(Utils.readTimeFromString(item.getContent())); + + newItems.add(item); + } catch (Exception e) { + e.printStackTrace(); } } diff --git a/app/src/main/java/com/readrops/app/viewmodels/MainViewModel.java b/app/src/main/java/com/readrops/app/viewmodels/MainViewModel.java index d46aca53..4444bcc4 100644 --- a/app/src/main/java/com/readrops/app/viewmodels/MainViewModel.java +++ b/app/src/main/java/com/readrops/app/viewmodels/MainViewModel.java @@ -1,22 +1,18 @@ package com.readrops.app.viewmodels; import android.app.Application; -import androidx.arch.core.util.Function; + +import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; -import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LiveData; import androidx.lifecycle.MediatorLiveData; -import androidx.lifecycle.Observer; -import androidx.lifecycle.Transformations; -import androidx.paging.DataSource; import androidx.paging.LivePagedListBuilder; import androidx.paging.PagedList; -import androidx.sqlite.db.SupportSQLiteQuery; -import androidx.annotation.NonNull; import com.readrops.app.activities.MainActivity; import com.readrops.app.database.Database; import com.readrops.app.database.ItemsListQueryBuilder; +import com.readrops.app.database.entities.Account; import com.readrops.app.database.entities.Feed; import com.readrops.app.database.entities.Folder; import com.readrops.app.database.pojo.ItemWithFeed; @@ -106,8 +102,8 @@ public class MainViewModel extends AndroidViewModel { return itemsWithFeed; } - public Observable sync(List feeds) { - return repository.sync(feeds); + public Observable sync(List feeds, Account account) { + return repository.sync(feeds, account); } public Single getFeedCount() { @@ -134,6 +130,10 @@ public class MainViewModel extends AndroidViewModel { }); } + public LiveData> getAccounts() { + return db.accountDao().selectAll(); + } + public Completable setItemReadState(int itemId, boolean read) { return Completable.create(emitter -> { db.itemDao().setReadState(itemId, read ? 1 : 0); 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 99653088..2c23d1be 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 @@ -104,10 +104,10 @@ public class NextNewsAPI { } private void putModifiedItems(SyncData data, SyncResult syncResult) throws IOException { - Response readItemsResponse = api.setArticlesState(StateType.READ.name(), + Response readItemsResponse = api.setArticlesState(StateType.READ.name().toLowerCase(), data.getReadItems()).execute(); - Response unreadItemsResponse = api.setArticlesState(StateType.UNREAD.toString(), + Response unreadItemsResponse = api.setArticlesState(StateType.UNREAD.toString().toLowerCase(), data.getUnreadItems()).execute(); if (!readItemsResponse.isSuccessful())