mirror of https://github.com/readrops/Readrops.git
Requesting folders, feeds and items from Nextcloud News now works
This commit is contained in:
parent
3903bb6eb1
commit
92ce491771
|
@ -5,7 +5,6 @@ import androidx.lifecycle.LiveData;
|
||||||
import androidx.room.Dao;
|
import androidx.room.Dao;
|
||||||
import androidx.room.Insert;
|
import androidx.room.Insert;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import androidx.room.Update;
|
|
||||||
|
|
||||||
import com.readrops.app.database.entities.Feed;
|
import com.readrops.app.database.entities.Feed;
|
||||||
import com.readrops.app.database.pojo.FeedWithFolder;
|
import com.readrops.app.database.pojo.FeedWithFolder;
|
||||||
|
@ -21,8 +20,8 @@ public interface FeedDao {
|
||||||
@Insert
|
@Insert
|
||||||
long insert(Feed feed);
|
long insert(Feed feed);
|
||||||
|
|
||||||
@Update
|
@Insert
|
||||||
void update(Feed feed);
|
long[] insert(List<Feed> feeds);
|
||||||
|
|
||||||
@Query("Delete From Feed Where id = :feedId")
|
@Query("Delete From Feed Where id = :feedId")
|
||||||
void delete(int feedId);
|
void delete(int feedId);
|
||||||
|
@ -30,12 +29,18 @@ public interface FeedDao {
|
||||||
@Query("Select case When :feedUrl In (Select url from Feed) Then 'true' else 'false' end")
|
@Query("Select case When :feedUrl In (Select url from Feed) Then 'true' else 'false' end")
|
||||||
String feedExists(String feedUrl);
|
String feedExists(String feedUrl);
|
||||||
|
|
||||||
|
@Query("Select case When :remoteId In (Select remoteId from Feed) Then 1 else 0 end")
|
||||||
|
boolean remoteFeedExists(int remoteId);
|
||||||
|
|
||||||
@Query("Select count(*) from Feed")
|
@Query("Select count(*) from Feed")
|
||||||
int getFeedCount();
|
int getFeedCount();
|
||||||
|
|
||||||
@Query("Select * from Feed Where url = :feedUrl")
|
@Query("Select * from Feed Where url = :feedUrl")
|
||||||
Feed getFeedByUrl(String feedUrl);
|
Feed getFeedByUrl(String feedUrl);
|
||||||
|
|
||||||
|
@Query("Select * from Feed Where remoteId = :remoteId")
|
||||||
|
Feed getFeedByRemoteId(int remoteId);
|
||||||
|
|
||||||
@Query("Select * from Feed Where folder_id = :folderId")
|
@Query("Select * from Feed Where folder_id = :folderId")
|
||||||
List<Feed> getFeedsByFolder(int folderId);
|
List<Feed> getFeedsByFolder(int folderId);
|
||||||
|
|
||||||
|
@ -48,9 +53,15 @@ public interface FeedDao {
|
||||||
@Query("Update Feed set name = :feedName, url = :feedUrl, folder_id = :folderId Where id = :feedId")
|
@Query("Update Feed set name = :feedName, url = :feedUrl, folder_id = :folderId Where id = :feedId")
|
||||||
void updateFeedFields(int feedId, String feedName, String feedUrl, int folderId);
|
void updateFeedFields(int feedId, String feedName, String feedUrl, int folderId);
|
||||||
|
|
||||||
|
@Query("Update Feed set text_color = :textColor, background_color = :bgColor Where id = :feedId")
|
||||||
|
void updateColors(int feedId, int textColor, int bgColor);
|
||||||
|
|
||||||
@Query("Select Feed.name as feed_name, Feed.id as feed_id, Folder.name as folder_name, Folder.id as folder_id," +
|
@Query("Select Feed.name as feed_name, Feed.id as feed_id, Folder.name as folder_name, Folder.id as folder_id," +
|
||||||
"Feed.description as feed_description, Feed.icon_url as feed_icon_url, Feed.url as feed_url, Feed.folder_id as feed_folder_id" +
|
"Feed.description as feed_description, Feed.icon_url as feed_icon_url, Feed.url as feed_url, Feed.folder_id as feed_folder_id" +
|
||||||
", Feed.siteUrl as feed_siteUrl from Feed Inner Join Folder on Feed.folder_id = Folder.id Order by Feed.name")
|
", Feed.siteUrl as feed_siteUrl from Feed Inner Join Folder on Feed.folder_id = Folder.id Order by Feed.name")
|
||||||
LiveData<List<FeedWithFolder>> getAllFeedsWithFolder();
|
LiveData<List<FeedWithFolder>> getAllFeedsWithFolder();
|
||||||
|
|
||||||
|
@Query("Select * From Feed Where id in (:ids)")
|
||||||
|
List<Feed> selectFromIdList(long[] ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,15 @@ public interface FolderDao {
|
||||||
@Insert
|
@Insert
|
||||||
long insert(Folder folder);
|
long insert(Folder folder);
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
long[] insert(List<Folder> folders);
|
||||||
|
|
||||||
@Delete
|
@Delete
|
||||||
void delete(Folder folder);
|
void delete(Folder folder);
|
||||||
|
|
||||||
|
@Query("Select id From Folder Where remoteId = :remoteId")
|
||||||
|
int getRemoteFolderLocalId(int remoteId);
|
||||||
|
|
||||||
|
@Query("Select case When :remoteId In (Select remoteId from Folder) Then 1 else 0 end")
|
||||||
|
boolean remoteFolderExists(int remoteId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,19 @@ package com.readrops.app.database.dao;
|
||||||
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.paging.DataSource;
|
|
||||||
import androidx.paging.PageKeyedDataSource;
|
import androidx.paging.PageKeyedDataSource;
|
||||||
import androidx.sqlite.db.SupportSQLiteQuery;
|
|
||||||
import androidx.room.Dao;
|
import androidx.room.Dao;
|
||||||
import androidx.room.Insert;
|
import androidx.room.Insert;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import androidx.room.RawQuery;
|
import androidx.room.RawQuery;
|
||||||
|
import androidx.sqlite.db.SupportSQLiteQuery;
|
||||||
|
|
||||||
import com.readrops.app.database.entities.Feed;
|
import com.readrops.app.database.entities.Feed;
|
||||||
import com.readrops.app.database.entities.Folder;
|
import com.readrops.app.database.entities.Folder;
|
||||||
import com.readrops.app.database.pojo.ItemWithFeed;
|
|
||||||
import com.readrops.app.database.entities.Item;
|
import com.readrops.app.database.entities.Item;
|
||||||
|
import com.readrops.app.database.pojo.ItemWithFeed;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public interface ItemDao {
|
public interface ItemDao {
|
||||||
|
@ -24,9 +25,15 @@ public interface ItemDao {
|
||||||
@Query("Select case When :guid In (Select guid from Item) Then 'true' else 'false' end")
|
@Query("Select case When :guid In (Select guid from Item) Then 'true' else 'false' end")
|
||||||
String guidExist(String guid);
|
String guidExist(String guid);
|
||||||
|
|
||||||
|
@Query("Select case When :remoteId In (Select remoteId from Item) Then 1 else 0 end")
|
||||||
|
boolean remoteItemExists(int remoteId);
|
||||||
|
|
||||||
@Insert
|
@Insert
|
||||||
long insert(Item item);
|
long insert(Item item);
|
||||||
|
|
||||||
|
@Insert
|
||||||
|
long[] insert(List<Item> items);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an item read or unread
|
* Set an item read or unread
|
||||||
* @param itemId id of the item to update
|
* @param itemId id of the item to update
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
package com.readrops.app.database.entities;
|
package com.readrops.app.database.entities;
|
||||||
|
|
||||||
|
|
||||||
import androidx.room.*;
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import androidx.annotation.ColorInt;
|
import androidx.annotation.ColorInt;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.room.ColumnInfo;
|
||||||
|
import androidx.room.Entity;
|
||||||
|
import androidx.room.ForeignKey;
|
||||||
|
import androidx.room.Ignore;
|
||||||
|
import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
import com.readrops.readropslibrary.localfeed.atom.ATOMFeed;
|
import com.readrops.readropslibrary.localfeed.atom.ATOMFeed;
|
||||||
import com.readrops.readropslibrary.localfeed.json.JSONFeed;
|
import com.readrops.readropslibrary.localfeed.json.JSONFeed;
|
||||||
|
@ -14,8 +18,6 @@ import com.readrops.readropslibrary.localfeed.rss.RSSFeed;
|
||||||
|
|
||||||
import org.jsoup.Jsoup;
|
import org.jsoup.Jsoup;
|
||||||
|
|
||||||
import static androidx.room.ForeignKey.NO_ACTION;
|
|
||||||
|
|
||||||
@Entity(foreignKeys = @ForeignKey(entity = Folder.class, parentColumns = "id", childColumns = "folder_id", onDelete = ForeignKey.SET_NULL))
|
@Entity(foreignKeys = @ForeignKey(entity = Folder.class, parentColumns = "id", childColumns = "folder_id", onDelete = ForeignKey.SET_NULL))
|
||||||
public class Feed implements Parcelable {
|
public class Feed implements Parcelable {
|
||||||
|
|
||||||
|
@ -33,7 +35,7 @@ public class Feed implements Parcelable {
|
||||||
private String lastUpdated;
|
private String lastUpdated;
|
||||||
|
|
||||||
@ColumnInfo(name = "text_color")
|
@ColumnInfo(name = "text_color")
|
||||||
private @ColorInt int textColor;
|
private @ColorInt int textColor;
|
||||||
|
|
||||||
@ColumnInfo(name = "background_color")
|
@ColumnInfo(name = "background_color")
|
||||||
private @ColorInt int backgroundColor;
|
private @ColorInt int backgroundColor;
|
||||||
|
@ -46,9 +48,11 @@ public class Feed implements Parcelable {
|
||||||
@ColumnInfo(name = "last_modified")
|
@ColumnInfo(name = "last_modified")
|
||||||
private String lastModified;
|
private String lastModified;
|
||||||
|
|
||||||
@ColumnInfo(name = "folder_id")
|
@ColumnInfo(name = "folder_id", index = true)
|
||||||
private int folderId;
|
private int folderId;
|
||||||
|
|
||||||
|
private int remoteId;
|
||||||
|
|
||||||
@Ignore
|
@Ignore
|
||||||
private int unreadCount;
|
private int unreadCount;
|
||||||
|
|
||||||
|
@ -76,6 +80,7 @@ public class Feed implements Parcelable {
|
||||||
etag = in.readString();
|
etag = in.readString();
|
||||||
lastModified = in.readString();
|
lastModified = in.readString();
|
||||||
folderId = in.readInt();
|
folderId = in.readInt();
|
||||||
|
remoteId = in.readInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<Feed> CREATOR = new Creator<Feed>() {
|
public static final Creator<Feed> CREATOR = new Creator<Feed>() {
|
||||||
|
@ -194,6 +199,14 @@ public class Feed implements Parcelable {
|
||||||
this.unreadCount = unreadCount;
|
this.unreadCount = unreadCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getRemoteId() {
|
||||||
|
return remoteId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteId(int remoteId) {
|
||||||
|
this.remoteId = remoteId;
|
||||||
|
}
|
||||||
|
|
||||||
public static Feed feedFromRSS(RSSFeed rssFeed) {
|
public static Feed feedFromRSS(RSSFeed rssFeed) {
|
||||||
Feed feed = new Feed();
|
Feed feed = new Feed();
|
||||||
RSSChannel channel = rssFeed.getChannel();
|
RSSChannel channel = rssFeed.getChannel();
|
||||||
|
@ -270,5 +283,6 @@ public class Feed implements Parcelable {
|
||||||
dest.writeString(etag);
|
dest.writeString(etag);
|
||||||
dest.writeString(lastModified);
|
dest.writeString(lastModified);
|
||||||
dest.writeInt(folderId);
|
dest.writeInt(folderId);
|
||||||
|
dest.writeInt(remoteId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package com.readrops.app.database.entities;
|
package com.readrops.app.database.entities;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import androidx.room.Entity;
|
import androidx.room.Entity;
|
||||||
import androidx.room.Ignore;
|
import androidx.room.Ignore;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import android.os.Parcel;
|
|
||||||
import android.os.Parcelable;
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Folder implements Parcelable, Comparable<Folder> {
|
public class Folder implements Parcelable, Comparable<Folder> {
|
||||||
|
@ -14,6 +15,8 @@ public class Folder implements Parcelable, Comparable<Folder> {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
private int remoteId;
|
||||||
|
|
||||||
public Folder() {
|
public Folder() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,6 +49,14 @@ public class Folder implements Parcelable, Comparable<Folder> {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getRemoteId() {
|
||||||
|
return remoteId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteId(int remoteId) {
|
||||||
|
this.remoteId = remoteId;
|
||||||
|
}
|
||||||
|
|
||||||
public static final Creator<Folder> CREATOR = new Creator<Folder>() {
|
public static final Creator<Folder> CREATOR = new Creator<Folder>() {
|
||||||
@Override
|
@Override
|
||||||
public Folder createFromParcel(Parcel in) {
|
public Folder createFromParcel(Parcel in) {
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class Item implements Comparable<Item> {
|
||||||
|
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
@ColumnInfo(name = "feed_id")
|
@ColumnInfo(name = "feed_id", index = true)
|
||||||
private int feedId;
|
private int feedId;
|
||||||
|
|
||||||
@ColumnInfo(index = true)
|
@ColumnInfo(index = true)
|
||||||
|
@ -61,6 +61,8 @@ public class Item implements Comparable<Item> {
|
||||||
@ColumnInfo(name = "read_it_later")
|
@ColumnInfo(name = "read_it_later")
|
||||||
private boolean readItLater;
|
private boolean readItLater;
|
||||||
|
|
||||||
|
private int remoteId;
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -184,6 +186,14 @@ public class Item implements Comparable<Item> {
|
||||||
this.readItLater = readItLater;
|
this.readItLater = readItLater;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getRemoteId() {
|
||||||
|
return remoteId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteId(int remoteId) {
|
||||||
|
this.remoteId = remoteId;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<Item> itemsFromRSS(List<RSSItem> items, Feed feed) throws ParseException {
|
public static List<Item> itemsFromRSS(List<RSSItem> items, Feed feed) throws ParseException {
|
||||||
List<Item> dbItems = new ArrayList<>();
|
List<Item> dbItems = new ArrayList<>();
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,18 @@ package com.readrops.app.repositories;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import androidx.palette.graphics.Palette;
|
|
||||||
import android.util.Patterns;
|
import android.util.Patterns;
|
||||||
|
|
||||||
import com.readrops.app.database.pojo.FeedWithFolder;
|
import androidx.palette.graphics.Palette;
|
||||||
import com.readrops.app.utils.FeedInsertionResult;
|
|
||||||
import com.readrops.app.utils.HtmlParser;
|
|
||||||
import com.readrops.app.utils.Utils;
|
|
||||||
import com.readrops.app.database.Database;
|
import com.readrops.app.database.Database;
|
||||||
import com.readrops.app.database.entities.Feed;
|
import com.readrops.app.database.entities.Feed;
|
||||||
import com.readrops.app.database.entities.Folder;
|
import com.readrops.app.database.entities.Folder;
|
||||||
|
import com.readrops.app.database.pojo.FeedWithFolder;
|
||||||
|
import com.readrops.app.utils.FeedInsertionResult;
|
||||||
|
import com.readrops.app.utils.HtmlParser;
|
||||||
import com.readrops.app.utils.ParsingResult;
|
import com.readrops.app.utils.ParsingResult;
|
||||||
|
import com.readrops.app.utils.Utils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -79,13 +80,16 @@ public abstract class ARepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setFeedColors(String favUrl, Feed feed) throws IOException {
|
protected void setFeedColors(String favUrl, Feed feed) {
|
||||||
Bitmap favicon = Utils.getImageFromUrl(favUrl);
|
Bitmap favicon = Utils.getImageFromUrl(favUrl);
|
||||||
Palette palette = Palette.from(favicon).generate();
|
|
||||||
|
|
||||||
feed.setTextColor(palette.getDominantSwatch().getRgb());
|
if (favicon != null) {
|
||||||
|
Palette palette = Palette.from(favicon).generate();
|
||||||
|
|
||||||
if (palette.getMutedSwatch() != null)
|
feed.setTextColor(palette.getDominantSwatch().getRgb());
|
||||||
feed.setBackgroundColor(palette.getMutedSwatch().getRgb());
|
|
||||||
|
if (palette.getMutedSwatch() != null)
|
||||||
|
feed.setBackgroundColor(palette.getMutedSwatch().getRgb());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,6 +219,8 @@ public class LocalFeedRepository extends ARepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertItems(Collection<Item> items, Feed feed) {
|
private void insertItems(Collection<Item> items, Feed feed) {
|
||||||
|
List<Item> itemsToInsert = new ArrayList<>();
|
||||||
|
|
||||||
for (Item dbItem : items) {
|
for (Item dbItem : items) {
|
||||||
if (!Boolean.valueOf(database.itemDao().guidExist(dbItem.getGuid()))) {
|
if (!Boolean.valueOf(database.itemDao().guidExist(dbItem.getGuid()))) {
|
||||||
if (dbItem.getDescription() != null) {
|
if (dbItem.getDescription() != null) {
|
||||||
|
@ -247,9 +249,11 @@ public class LocalFeedRepository extends ARepository {
|
||||||
else if (dbItem.getDescription() != null)
|
else if (dbItem.getDescription() != null)
|
||||||
dbItem.setReadTime(Utils.readTimeFromString(dbItem.getCleanDescription()));
|
dbItem.setReadTime(Utils.readTimeFromString(dbItem.getCleanDescription()));
|
||||||
|
|
||||||
database.itemDao().insert(dbItem);
|
itemsToInsert.add(dbItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
database.itemDao().insert(itemsToInsert);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FeedInsertionResult.FeedInsertionError getErrorFromException(Exception e) {
|
private FeedInsertionResult.FeedInsertionError getErrorFromException(Exception e) {
|
||||||
|
|
|
@ -1,25 +1,38 @@
|
||||||
package com.readrops.app.repositories;
|
package com.readrops.app.repositories;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
import android.util.TimingLogger;
|
||||||
|
|
||||||
import com.readrops.app.database.entities.Feed;
|
import com.readrops.app.database.entities.Feed;
|
||||||
import com.readrops.app.database.entities.Folder;
|
import com.readrops.app.database.entities.Folder;
|
||||||
|
import com.readrops.app.database.entities.Item;
|
||||||
import com.readrops.app.database.pojo.FeedWithFolder;
|
import com.readrops.app.database.pojo.FeedWithFolder;
|
||||||
import com.readrops.app.utils.FeedInsertionResult;
|
import com.readrops.app.utils.FeedInsertionResult;
|
||||||
|
import com.readrops.app.utils.FeedMatcher;
|
||||||
|
import com.readrops.app.utils.ItemMatcher;
|
||||||
import com.readrops.app.utils.ParsingResult;
|
import com.readrops.app.utils.ParsingResult;
|
||||||
|
import com.readrops.app.utils.Utils;
|
||||||
import com.readrops.readropslibrary.services.nextcloudnews.Credentials;
|
import com.readrops.readropslibrary.services.nextcloudnews.Credentials;
|
||||||
import com.readrops.readropslibrary.services.nextcloudnews.NextNewsAPI;
|
import com.readrops.readropslibrary.services.nextcloudnews.NextNewsAPI;
|
||||||
|
import com.readrops.readropslibrary.services.nextcloudnews.SyncResults;
|
||||||
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeed;
|
||||||
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolder;
|
||||||
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItem;
|
||||||
import com.readrops.readropslibrary.utils.LibUtils;
|
import com.readrops.readropslibrary.utils.LibUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import io.reactivex.Completable;
|
import io.reactivex.Completable;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.Single;
|
import io.reactivex.Single;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
|
||||||
public class NextNewsRepository extends ARepository {
|
public class NextNewsRepository extends ARepository {
|
||||||
|
|
||||||
|
private static final String TAG = NextNewsRepository.class.getSimpleName();
|
||||||
|
|
||||||
public NextNewsRepository(Application application) {
|
public NextNewsRepository(Application application) {
|
||||||
super(application);
|
super(application);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +44,18 @@ public class NextNewsRepository extends ARepository {
|
||||||
NextNewsAPI newsAPI = new NextNewsAPI();
|
NextNewsAPI newsAPI = new NextNewsAPI();
|
||||||
|
|
||||||
Credentials credentials = new Credentials("", LibUtils.NEXTCLOUD_PASSWORD, "");
|
Credentials credentials = new Credentials("", LibUtils.NEXTCLOUD_PASSWORD, "");
|
||||||
newsAPI.sync(credentials, NextNewsAPI.SyncType.INITIAL_SYNC, null);
|
SyncResults results = newsAPI.sync(credentials, NextNewsAPI.SyncType.INITIAL_SYNC, null);
|
||||||
|
|
||||||
|
TimingLogger timings = new TimingLogger(TAG, "sync");
|
||||||
|
insertFolders(results.getFolders());
|
||||||
|
timings.addSplit("insert folders");
|
||||||
|
|
||||||
|
insertFeeds(results.getFeeds());
|
||||||
|
timings.addSplit("insert feeds");
|
||||||
|
|
||||||
|
insertItems(results.getItems());
|
||||||
|
timings.addSplit("insert items");
|
||||||
|
timings.dumpToLog();
|
||||||
|
|
||||||
emitter.onComplete();
|
emitter.onComplete();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -60,4 +84,77 @@ public class NextNewsRepository extends ARepository {
|
||||||
public Completable addFolder(Folder folder) {
|
public Completable addFolder(Folder folder) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void insertFeeds(List<NextNewsFeed> feeds) {
|
||||||
|
List<Feed> newFeeds = new ArrayList<>();
|
||||||
|
|
||||||
|
for (NextNewsFeed nextNewsFeed : feeds) {
|
||||||
|
|
||||||
|
if (!database.feedDao().remoteFeedExists(nextNewsFeed.getId())) {
|
||||||
|
Feed feed = FeedMatcher.nextNewsFeedToFeed(nextNewsFeed);
|
||||||
|
|
||||||
|
// if the Nextcloud feed has a folder, it is already inserted, so we have to get its local id
|
||||||
|
if (nextNewsFeed.getFolderId() != 0) {
|
||||||
|
int folderId = database.folderDao().getRemoteFolderLocalId(nextNewsFeed.getFolderId());
|
||||||
|
|
||||||
|
if (folderId != 0)
|
||||||
|
feed.setFolderId(folderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
newFeeds.add(feed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long[] ids = database.feedDao().insert(newFeeds);
|
||||||
|
|
||||||
|
List<Feed> insertedFeeds = database.feedDao().selectFromIdList(ids);
|
||||||
|
Observable.<Feed>create(emitter -> {
|
||||||
|
for (Feed feed : insertedFeeds) {
|
||||||
|
setFavIconUtils(feed);
|
||||||
|
emitter.onNext(feed);
|
||||||
|
}
|
||||||
|
}).subscribeOn(Schedulers.computation())
|
||||||
|
.observeOn(Schedulers.io())
|
||||||
|
.doOnNext(feed1 -> database.feedDao().updateColors(feed1.getId(),
|
||||||
|
feed1.getTextColor(), feed1.getBackgroundColor()))
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertFolders(List<NextNewsFolder> folders) {
|
||||||
|
List<Folder> newFolders = new ArrayList<>();
|
||||||
|
|
||||||
|
for (NextNewsFolder nextNewsFolder : folders) {
|
||||||
|
|
||||||
|
if (!database.folderDao().remoteFolderExists(nextNewsFolder.getId())) {
|
||||||
|
Folder folder = new Folder(nextNewsFolder.getName());
|
||||||
|
folder.setRemoteId(nextNewsFolder.getId());
|
||||||
|
|
||||||
|
newFolders.add(folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
database.folderDao().insert(newFolders);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertItems(List<NextNewsItem> items) {
|
||||||
|
List<Item> 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);
|
||||||
|
|
||||||
|
item.setReadTime(Utils.readTimeFromString(item.getContent()));
|
||||||
|
|
||||||
|
newItems.add(item);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
database.itemDao().insert(newItems);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.readrops.app.utils;
|
||||||
|
|
||||||
|
import com.readrops.app.database.entities.Feed;
|
||||||
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeed;
|
||||||
|
|
||||||
|
public final class FeedMatcher {
|
||||||
|
|
||||||
|
public static Feed nextNewsFeedToFeed(NextNewsFeed feed) {
|
||||||
|
Feed newFeed = new Feed();
|
||||||
|
|
||||||
|
newFeed.setName(feed.getTitle());
|
||||||
|
newFeed.setUrl(feed.getUrl());
|
||||||
|
newFeed.setSiteUrl(feed.getLink());
|
||||||
|
newFeed.setUnreadCount(feed.getUnreadCount());
|
||||||
|
|
||||||
|
newFeed.setFolderId(feed.getFolderId());
|
||||||
|
newFeed.setIconUrl(feed.getFaviconLink());
|
||||||
|
|
||||||
|
newFeed.setRemoteId(feed.getId());
|
||||||
|
|
||||||
|
return newFeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -100,7 +100,7 @@ public final class HtmlParser {
|
||||||
String head = body.substring(body.indexOf("<head>"), body.indexOf("</head>"));
|
String head = body.substring(body.indexOf("<head>"), body.indexOf("</head>"));
|
||||||
|
|
||||||
long end = System.currentTimeMillis();
|
long end = System.currentTimeMillis();
|
||||||
Log.d(TAG, "parsing time : " + String.valueOf(end - start));
|
Log.d(TAG, "parsing time : " + (end - start));
|
||||||
|
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.readrops.app.utils;
|
||||||
|
|
||||||
|
import com.readrops.app.database.entities.Feed;
|
||||||
|
import com.readrops.app.database.entities.Item;
|
||||||
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItem;
|
||||||
|
|
||||||
|
import org.joda.time.DateTimeZone;
|
||||||
|
import org.joda.time.LocalDateTime;
|
||||||
|
|
||||||
|
public final class ItemMatcher {
|
||||||
|
|
||||||
|
public static Item nextNewsItemToItem(NextNewsItem nextNewsItem, Feed feed) {
|
||||||
|
Item item = new Item();
|
||||||
|
|
||||||
|
item.setRemoteId(nextNewsItem.getId());
|
||||||
|
item.setTitle(nextNewsItem.getTitle());
|
||||||
|
|
||||||
|
if (!nextNewsItem.getAuthor().isEmpty())
|
||||||
|
item.setAuthor(nextNewsItem.getAuthor());
|
||||||
|
|
||||||
|
item.setPubDate(new LocalDateTime(nextNewsItem.getPubDate() * 1000L,
|
||||||
|
DateTimeZone.getDefault()));
|
||||||
|
item.setContent(nextNewsItem.getBody());
|
||||||
|
|
||||||
|
|
||||||
|
item.setLink(nextNewsItem.getUrl());
|
||||||
|
item.setGuid(nextNewsItem.getGuid());
|
||||||
|
item.setRead(!nextNewsItem.isUnread());
|
||||||
|
|
||||||
|
item.setFeedId(feed.getId());
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,14 +12,15 @@ import android.graphics.drawable.ShapeDrawable;
|
||||||
import android.graphics.drawable.shapes.OvalShape;
|
import android.graphics.drawable.shapes.OvalShape;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import androidx.annotation.ColorInt;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.io.IOException;
|
import androidx.annotation.ColorInt;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
|
@ -45,17 +46,23 @@ public final class Utils {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bitmap getImageFromUrl(String url) throws IOException {
|
public static Bitmap getImageFromUrl(String url) {
|
||||||
OkHttpClient okHttpClient = new OkHttpClient();
|
try {
|
||||||
Request request = new Request.Builder().url(url).build();
|
OkHttpClient okHttpClient = new OkHttpClient.Builder()
|
||||||
|
.callTimeout(5, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
Request request = new Request.Builder().url(url).build();
|
||||||
|
|
||||||
Response response = okHttpClient.newCall(request).execute();
|
Response response = okHttpClient.newCall(request).execute();
|
||||||
|
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
InputStream inputStream = response.body().byteStream();
|
InputStream inputStream = response.body().byteStream();
|
||||||
return BitmapFactory.decodeStream(inputStream);
|
return BitmapFactory.decodeStream(inputStream);
|
||||||
} else
|
} else
|
||||||
return null;
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null; // no way to get the favicon
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getDeviceWidth(Activity activity) {
|
public static int getDeviceWidth(Activity activity) {
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
package com.readrops.app.views;
|
package com.readrops.app.views;
|
||||||
|
|
||||||
import androidx.paging.PagedListAdapter;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.appcompat.content.res.AppCompatResources;
|
|
||||||
import androidx.recyclerview.widget.ListAdapter;
|
|
||||||
import androidx.recyclerview.widget.DiffUtil;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -20,6 +12,13 @@ import android.widget.ImageView;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.paging.PagedListAdapter;
|
||||||
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.bumptech.glide.ListPreloader;
|
import com.bumptech.glide.ListPreloader;
|
||||||
import com.bumptech.glide.RequestBuilder;
|
import com.bumptech.glide.RequestBuilder;
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
|
@ -30,8 +29,8 @@ import com.bumptech.glide.request.RequestOptions;
|
||||||
import com.bumptech.glide.request.transition.DrawableCrossFadeFactory;
|
import com.bumptech.glide.request.transition.DrawableCrossFadeFactory;
|
||||||
import com.bumptech.glide.util.ViewPreloadSizeProvider;
|
import com.bumptech.glide.util.ViewPreloadSizeProvider;
|
||||||
import com.readrops.app.R;
|
import com.readrops.app.R;
|
||||||
import com.readrops.app.database.pojo.ItemWithFeed;
|
|
||||||
import com.readrops.app.database.entities.Item;
|
import com.readrops.app.database.entities.Item;
|
||||||
|
import com.readrops.app.database.pojo.ItemWithFeed;
|
||||||
import com.readrops.app.utils.DateUtils;
|
import com.readrops.app.utils.DateUtils;
|
||||||
import com.readrops.app.utils.GlideRequests;
|
import com.readrops.app.utils.GlideRequests;
|
||||||
import com.readrops.app.utils.Utils;
|
import com.readrops.app.utils.Utils;
|
||||||
|
@ -40,8 +39,6 @@ import java.util.Collections;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.bumptech.glide.load.resource.bitmap.BitmapTransitionOptions.withCrossFade;
|
|
||||||
|
|
||||||
public class MainItemListAdapter extends PagedListAdapter<ItemWithFeed, MainItemListAdapter.ItemViewHolder> implements ListPreloader.PreloadModelProvider<String> {
|
public class MainItemListAdapter extends PagedListAdapter<ItemWithFeed, MainItemListAdapter.ItemViewHolder> implements ListPreloader.PreloadModelProvider<String> {
|
||||||
|
|
||||||
private GlideRequests glideRequests;
|
private GlideRequests glideRequests;
|
||||||
|
@ -73,7 +70,9 @@ public class MainItemListAdapter extends PagedListAdapter<ItemWithFeed, MainItem
|
||||||
itemWithFeed.getFeedName().equals(t1.getFeedName()) &&
|
itemWithFeed.getFeedName().equals(t1.getFeedName()) &&
|
||||||
itemWithFeed.getFolder().getName().equals(t1.getFolder().getName()) &&
|
itemWithFeed.getFolder().getName().equals(t1.getFolder().getName()) &&
|
||||||
item.isRead() == item1.isRead() &&
|
item.isRead() == item1.isRead() &&
|
||||||
item.isReadItLater() == item1.isReadItLater();
|
item.isReadItLater() == item1.isReadItLater() &&
|
||||||
|
itemWithFeed.getColor() == t1.getColor() &&
|
||||||
|
itemWithFeed.getBgColor() == t1.getBgColor();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,7 +122,8 @@ public class MainItemListAdapter extends PagedListAdapter<ItemWithFeed, MainItem
|
||||||
viewHolder.itemImage.setVisibility(View.GONE);
|
viewHolder.itemImage.setVisibility(View.GONE);
|
||||||
|
|
||||||
if (itemWithFeed.getFeedIconUrl() != null) {
|
if (itemWithFeed.getFeedIconUrl() != null) {
|
||||||
glideRequests.load(itemWithFeed.getFeedIconUrl())
|
glideRequests.
|
||||||
|
load(itemWithFeed.getFeedIconUrl())
|
||||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
.placeholder(R.drawable.ic_rss_feed)
|
.placeholder(R.drawable.ic_rss_feed)
|
||||||
.into(viewHolder.feedIcon);
|
.into(viewHolder.feedIcon);
|
||||||
|
@ -222,6 +222,7 @@ public class MainItemListAdapter extends PagedListAdapter<ItemWithFeed, MainItem
|
||||||
public RequestBuilder<Drawable> getPreloadRequestBuilder(@NonNull String url) {
|
public RequestBuilder<Drawable> getPreloadRequestBuilder(@NonNull String url) {
|
||||||
return glideRequests
|
return glideRequests
|
||||||
.load(url)
|
.load(url)
|
||||||
|
.centerCrop()
|
||||||
.apply(requestOptions)
|
.apply(requestOptions)
|
||||||
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
.transition(DrawableTransitionOptions.withCrossFade(FADE_FACTORY));
|
.transition(DrawableTransitionOptions.withCrossFade(FADE_FACTORY));
|
||||||
|
|
|
@ -2,12 +2,13 @@ package com.readrops.app;
|
||||||
|
|
||||||
import com.readrops.app.utils.DateUtils;
|
import com.readrops.app.utils.DateUtils;
|
||||||
|
|
||||||
|
import org.joda.time.DateTimeZone;
|
||||||
import org.joda.time.LocalDateTime;
|
import org.joda.time.LocalDateTime;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Example local unit test, which will execute on the development machine (host).
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
@ -39,4 +40,11 @@ public class ExampleUnitTest {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void timeStamptoDateTest() {
|
||||||
|
LocalDateTime localDateTime = new LocalDateTime(1367270544 * 1000L, DateTimeZone.getDefault());
|
||||||
|
|
||||||
|
assertEquals(0, localDateTime.compareTo(new LocalDateTime(2013, 4, 29, 21, 22, 24)));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,5 @@
|
||||||
package com.readrops.readropslibrary.services;
|
package com.readrops.readropslibrary.services;
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
|
||||||
|
|
||||||
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeed;
|
|
||||||
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeeds;
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeeds;
|
||||||
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolders;
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolders;
|
||||||
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItems;
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItems;
|
||||||
|
@ -11,9 +8,11 @@ import java.util.List;
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
import okhttp3.ResponseBody;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
|
import retrofit2.http.Body;
|
||||||
import retrofit2.http.GET;
|
import retrofit2.http.GET;
|
||||||
import retrofit2.http.PUT;
|
import retrofit2.http.PUT;
|
||||||
import retrofit2.http.Path;
|
import retrofit2.http.Path;
|
||||||
|
import retrofit2.http.Query;
|
||||||
|
|
||||||
public interface NextNewsService {
|
public interface NextNewsService {
|
||||||
|
|
||||||
|
@ -25,21 +24,24 @@ public interface NextNewsService {
|
||||||
@GET("feeds")
|
@GET("feeds")
|
||||||
Call<NextNewsFeeds> getFeeds();
|
Call<NextNewsFeeds> getFeeds();
|
||||||
|
|
||||||
@GET("items?type={type}&getRead={read}&batchSize={batchSize}")
|
@GET("items")
|
||||||
Call<NextNewsItems> getItems(@Path("type") int type, @Path("read") boolean read, @Path("batchSize") int batchSize);
|
Call<NextNewsItems> getItems(@Query("type") int type, @Query("getRead") boolean read, @Query("batchSize") int batchSize);
|
||||||
|
|
||||||
@GET("items/updated?lastModified={lastModified}&type=3")
|
@GET("items/updated?type=3")
|
||||||
Call<NextNewsItems> getNewItems(@Path("lastModified") long lastModified);
|
Call<NextNewsItems> getNewItems(@Query("lastModified") long lastModified);
|
||||||
|
|
||||||
@PUT("items/read/multiple")
|
@PUT("items/read/multiple")
|
||||||
Call<ResponseBody> setReadArticles();
|
Call<ResponseBody> setReadArticles(@Body List<Integer> itemsIds);
|
||||||
|
|
||||||
@PUT("items/unread/multiple")
|
@PUT("items/unread/multiple")
|
||||||
Call<ResponseBody> setUnreadArticles();
|
Call<ResponseBody> setUnreadArticles(@Body List<Integer> itemsIds);
|
||||||
|
|
||||||
@PUT("items/starred/multiple")
|
@PUT("items/starred/multiple")
|
||||||
Call<ResponseBody> setStarredArticles();
|
Call<ResponseBody> setStarredArticles(@Body List<Integer> itemsIds);
|
||||||
|
|
||||||
@PUT("items/unstarred/multiple")
|
@PUT("items/unstarred/multiple")
|
||||||
Call<ResponseBody> setUnstarredArticles();
|
Call<ResponseBody> setUnstarredArticles(@Body List<Integer> itemsIds);
|
||||||
|
|
||||||
|
@PUT("items/{stateType}/multiple")
|
||||||
|
Call<ResponseBody> setArticlesState(@Path("stateType") String stateType, @Body List<Integer> items);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,36 +2,17 @@ package com.readrops.readropslibrary.services.nextcloudnews;
|
||||||
|
|
||||||
public class Credentials {
|
public class Credentials {
|
||||||
|
|
||||||
private String login;
|
private String base64;
|
||||||
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
public Credentials(String login, String password, String url) {
|
public Credentials(String login, String password, String url) {
|
||||||
this.login = login;
|
this.base64 = okhttp3.Credentials.basic(login, password);
|
||||||
this.password = password;
|
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toBase64() {
|
public String getBase64() {
|
||||||
return okhttp3.Credentials.basic(login, password);
|
return base64;
|
||||||
}
|
|
||||||
|
|
||||||
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 String getUrl() {
|
public String getUrl() {
|
||||||
|
|
|
@ -1,21 +1,25 @@
|
||||||
package com.readrops.readropslibrary.services.nextcloudnews;
|
package com.readrops.readropslibrary.services.nextcloudnews;
|
||||||
|
|
||||||
|
import android.util.TimingLogger;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.readrops.readropslibrary.services.NextNewsService;
|
import com.readrops.readropslibrary.services.NextNewsService;
|
||||||
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeeds;
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeeds;
|
||||||
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolders;
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolders;
|
||||||
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItems;
|
||||||
import com.readrops.readropslibrary.utils.HttpManager;
|
import com.readrops.readropslibrary.utils.HttpManager;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import retrofit2.Response;
|
|
||||||
import retrofit2.Retrofit;
|
import retrofit2.Retrofit;
|
||||||
import retrofit2.converter.gson.GsonConverterFactory;
|
import retrofit2.converter.gson.GsonConverterFactory;
|
||||||
|
|
||||||
public class NextNewsAPI {
|
public class NextNewsAPI {
|
||||||
|
|
||||||
|
private static final String TAG = NextNewsAPI.class.getSimpleName();
|
||||||
|
|
||||||
public NextNewsAPI() {
|
public NextNewsAPI() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,15 +32,41 @@ public class NextNewsAPI {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sync(@NonNull Credentials credentials, @NonNull SyncType syncType, @Nullable SyncData data) throws IOException {
|
public SyncResults sync(@NonNull Credentials credentials, @NonNull SyncType syncType, @Nullable SyncData data) throws IOException {
|
||||||
HttpManager httpManager = new HttpManager(credentials);
|
HttpManager httpManager = new HttpManager(credentials);
|
||||||
Retrofit retrofit = getConfiguredRetrofitInstance(httpManager);
|
Retrofit retrofit = getConfiguredRetrofitInstance(httpManager);
|
||||||
|
|
||||||
NextNewsService api = retrofit.create(NextNewsService.class);
|
NextNewsService api = retrofit.create(NextNewsService.class);
|
||||||
|
|
||||||
|
TimingLogger timings = new TimingLogger(TAG, "sync");
|
||||||
|
|
||||||
|
NextNewsFeeds feedList = api.getFeeds().execute().body();
|
||||||
|
timings.addSplit("get feeds");
|
||||||
|
|
||||||
|
NextNewsFolders folderList = api.getFolders().execute().body();
|
||||||
|
timings.addSplit("get folders");
|
||||||
|
|
||||||
|
NextNewsItems itemList = api.getItems(3, false, 300).execute().body();
|
||||||
|
timings.addSplit("get items");
|
||||||
|
timings.dumpToLog();
|
||||||
|
|
||||||
|
SyncResults results = new SyncResults();
|
||||||
|
results.setFeeds(feedList.getFeeds());
|
||||||
|
results.setFolders(folderList.getFolders());
|
||||||
|
results.setItems(itemList.getItems());
|
||||||
|
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SyncType {
|
public enum SyncType {
|
||||||
INITIAL_SYNC,
|
INITIAL_SYNC,
|
||||||
CLASSIC_SYNC
|
CLASSIC_SYNC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum StateType {
|
||||||
|
READ,
|
||||||
|
UNREAD,
|
||||||
|
STARRED,
|
||||||
|
UNSTARRED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.readrops.readropslibrary.services.nextcloudnews;
|
||||||
|
|
||||||
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFeed;
|
||||||
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsFolder;
|
||||||
|
import com.readrops.readropslibrary.services.nextcloudnews.json.NextNewsItem;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SyncResults {
|
||||||
|
|
||||||
|
private List<NextNewsFolder> folders;
|
||||||
|
|
||||||
|
private List<NextNewsFeed> feeds;
|
||||||
|
|
||||||
|
private List<NextNewsItem> items;
|
||||||
|
|
||||||
|
public SyncResults() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NextNewsFolder> getFolders() {
|
||||||
|
return folders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFolders(List<NextNewsFolder> folders) {
|
||||||
|
this.folders = folders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NextNewsFeed> getFeeds() {
|
||||||
|
return feeds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeeds(List<NextNewsFeed> feeds) {
|
||||||
|
this.feeds = feeds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NextNewsItem> getItems() {
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItems(List<NextNewsItem> items) {
|
||||||
|
this.items = items;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,13 +10,13 @@ public class NextNewsFeed {
|
||||||
|
|
||||||
private String faviconLink;
|
private String faviconLink;
|
||||||
|
|
||||||
private float added;
|
private long added;
|
||||||
|
|
||||||
private float folderId;
|
private int folderId;
|
||||||
|
|
||||||
private float unreadCount;
|
private int unreadCount;
|
||||||
|
|
||||||
private float ordering;
|
private int ordering;
|
||||||
|
|
||||||
private String link;
|
private String link;
|
||||||
|
|
||||||
|
@ -54,35 +54,35 @@ public class NextNewsFeed {
|
||||||
this.faviconLink = faviconLink;
|
this.faviconLink = faviconLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAdded() {
|
public long getAdded() {
|
||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAdded(float added) {
|
public void setAdded(long added) {
|
||||||
this.added = added;
|
this.added = added;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getFolderId() {
|
public int getFolderId() {
|
||||||
return folderId;
|
return folderId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFolderId(float folderId) {
|
public void setFolderId(int folderId) {
|
||||||
this.folderId = folderId;
|
this.folderId = folderId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getUnreadCount() {
|
public int getUnreadCount() {
|
||||||
return unreadCount;
|
return unreadCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUnreadCount(float unreadCount) {
|
public void setUnreadCount(int unreadCount) {
|
||||||
this.unreadCount = unreadCount;
|
this.unreadCount = unreadCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getOrdering() {
|
public int getOrdering() {
|
||||||
return ordering;
|
return ordering;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOrdering(float ordering) {
|
public void setOrdering(int ordering) {
|
||||||
this.ordering = ordering;
|
this.ordering = ordering;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ public class NextNewsItem {
|
||||||
|
|
||||||
private String author;
|
private String author;
|
||||||
|
|
||||||
private float pubDate;
|
private long pubDate;
|
||||||
|
|
||||||
private String body;
|
private String body;
|
||||||
|
|
||||||
|
@ -22,13 +22,13 @@ public class NextNewsItem {
|
||||||
|
|
||||||
private String enclosureLink;
|
private String enclosureLink;
|
||||||
|
|
||||||
private float feedId;
|
private int feedId;
|
||||||
|
|
||||||
private boolean unread;
|
private boolean unread;
|
||||||
|
|
||||||
private boolean starred;
|
private boolean starred;
|
||||||
|
|
||||||
private float lastModified;
|
private long lastModified;
|
||||||
|
|
||||||
private String fingerprint;
|
private String fingerprint;
|
||||||
|
|
||||||
|
@ -80,11 +80,11 @@ public class NextNewsItem {
|
||||||
this.author = author;
|
this.author = author;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getPubDate() {
|
public long getPubDate() {
|
||||||
return pubDate;
|
return pubDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPubDate(float pubDate) {
|
public void setPubDate(long pubDate) {
|
||||||
this.pubDate = pubDate;
|
this.pubDate = pubDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,11 +112,11 @@ public class NextNewsItem {
|
||||||
this.enclosureLink = enclosureLink;
|
this.enclosureLink = enclosureLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getFeedId() {
|
public int getFeedId() {
|
||||||
return feedId;
|
return feedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFeedId(float feedId) {
|
public void setFeedId(int feedId) {
|
||||||
this.feedId = feedId;
|
this.feedId = feedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,11 +136,11 @@ public class NextNewsItem {
|
||||||
this.starred = starred;
|
this.starred = starred;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getLastModified() {
|
public long getLastModified() {
|
||||||
return lastModified;
|
return lastModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastModified(float lastModified) {
|
public void setLastModified(long lastModified) {
|
||||||
this.lastModified = lastModified;
|
this.lastModified = lastModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
package com.readrops.readropslibrary.services.nextcloudnews.json;
|
|
||||||
|
|
||||||
public class SyncResults {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -40,7 +40,7 @@ public class HttpManager {
|
||||||
Request request = chain.request();
|
Request request = chain.request();
|
||||||
|
|
||||||
request = request.newBuilder()
|
request = request.newBuilder()
|
||||||
.addHeader("Authorization", credentials.toBase64())
|
.addHeader("Authorization", credentials.getBase64())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return chain.proceed(request);
|
return chain.proceed(request);
|
||||||
|
|
Loading…
Reference in New Issue