Rewrite the chapter insertion method. Create a wakelock until the library updates. Move custom preferences to widget package.
This commit is contained in:
parent
fcb5bf4dd4
commit
e702be1a8d
@ -1,6 +1,7 @@
|
||||
package eu.kanade.mangafeed.data.database;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.pushtorefresh.storio.Queries;
|
||||
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
|
||||
@ -12,11 +13,11 @@ import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetListOfObjects;
|
||||
import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetObject;
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutCollectionOfObjects;
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PreparedPutObject;
|
||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
|
||||
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery;
|
||||
import com.pushtorefresh.storio.sqlite.queries.Query;
|
||||
import com.pushtorefresh.storio.sqlite.queries.RawQuery;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import eu.kanade.mangafeed.data.database.models.Category;
|
||||
@ -37,7 +38,6 @@ import eu.kanade.mangafeed.data.database.tables.MangaSyncTable;
|
||||
import eu.kanade.mangafeed.data.database.tables.MangaTable;
|
||||
import eu.kanade.mangafeed.data.mangasync.base.MangaSyncService;
|
||||
import eu.kanade.mangafeed.util.ChapterRecognition;
|
||||
import eu.kanade.mangafeed.util.PostResult;
|
||||
import rx.Observable;
|
||||
|
||||
public class DatabaseHelper {
|
||||
@ -246,37 +246,46 @@ public class DatabaseHelper {
|
||||
}
|
||||
|
||||
// Add new chapters or delete if the source deletes them
|
||||
public Observable<PostResult> insertOrRemoveChapters(Manga manga, List<Chapter> chapters) {
|
||||
for (Chapter chapter : chapters) {
|
||||
chapter.manga_id = manga.id;
|
||||
}
|
||||
public Observable<Pair<Integer, Integer>> insertOrRemoveChapters(Manga manga, List<Chapter> sourceChapters) {
|
||||
List<Chapter> dbChapters = getChapters(manga).executeAsBlocking();
|
||||
|
||||
Observable<List<Chapter>> chapterList = Observable.create(subscriber -> {
|
||||
subscriber.onNext(getChapters(manga).executeAsBlocking());
|
||||
subscriber.onCompleted();
|
||||
Observable<List<Chapter>> newChapters = Observable.from(sourceChapters)
|
||||
.filter(c -> !dbChapters.contains(c))
|
||||
.doOnNext(c -> {
|
||||
c.manga_id = manga.id;
|
||||
c.date_fetch = new Date().getTime();
|
||||
ChapterRecognition.parseChapterNumber(c, manga);
|
||||
})
|
||||
.toList();
|
||||
|
||||
Observable<List<Chapter>> deletedChapters = Observable.from(dbChapters)
|
||||
.filter(c -> !sourceChapters.contains(c))
|
||||
.toList();
|
||||
|
||||
return Observable.zip(newChapters, deletedChapters, (toAdd, toDelete) -> {
|
||||
int added = 0;
|
||||
int deleted = 0;
|
||||
db.internal().beginTransaction();
|
||||
try {
|
||||
if (!toAdd.isEmpty()) {
|
||||
// Set the date fetch for new items in reverse order to allow another sorting method.
|
||||
// Sources MUST return the chapters from most to less recent, which is common.
|
||||
for (int i = toAdd.size() - 1; i >= 0; i--) {
|
||||
toAdd.get(i).date_fetch = new Date().getTime();
|
||||
}
|
||||
added = insertChapters(toAdd).executeAsBlocking().numberOfInserts();
|
||||
}
|
||||
|
||||
if (!toDelete.isEmpty()) {
|
||||
deleted = deleteChapters(toDelete).executeAsBlocking().results().size();
|
||||
}
|
||||
|
||||
db.internal().setTransactionSuccessful();
|
||||
} finally {
|
||||
db.internal().endTransaction();
|
||||
}
|
||||
return Pair.create(added, deleted);
|
||||
});
|
||||
|
||||
Observable<Integer> newChaptersObs = chapterList
|
||||
.flatMap(dbChapters -> Observable.from(chapters)
|
||||
.filter(c -> !dbChapters.contains(c))
|
||||
.map(c -> {
|
||||
ChapterRecognition.parseChapterNumber(c, manga);
|
||||
return c;
|
||||
})
|
||||
.toList()
|
||||
.flatMap(newChapters -> insertChapters(newChapters).createObservable())
|
||||
.map(PutResults::numberOfInserts));
|
||||
|
||||
Observable<Integer> deletedChaptersObs = chapterList
|
||||
.flatMap(dbChapters -> Observable.from(dbChapters)
|
||||
.filter(c -> !chapters.contains(c))
|
||||
.toList()
|
||||
.flatMap(deletedChapters -> deleteChapters(deletedChapters).createObservable())
|
||||
.map(d -> d.results().size()));
|
||||
|
||||
return Observable.zip(newChaptersObs, deletedChaptersObs,
|
||||
(insertions, deletions) -> new PostResult(0, insertions, deletions)
|
||||
);
|
||||
}
|
||||
|
||||
public PreparedDeleteObject<Chapter> deleteChapter(Chapter chapter) {
|
||||
|
@ -232,8 +232,6 @@ public class Batoto extends LoginSource {
|
||||
if (dateElement != null) {
|
||||
chapter.date_upload = parseDateFromElement(dateElement);
|
||||
}
|
||||
chapter.date_fetch = new Date().getTime();
|
||||
|
||||
return chapter;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,6 @@ import org.jsoup.nodes.Element;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
@ -194,8 +193,6 @@ public class Kissmanga extends Source {
|
||||
chapter.date_upload = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH).parse(date).getTime();
|
||||
} catch (ParseException e) { /* Ignore */ }
|
||||
}
|
||||
|
||||
chapter.date_fetch = new Date().getTime();
|
||||
return chapter;
|
||||
}
|
||||
|
||||
|
@ -174,8 +174,6 @@ public class Mangafox extends Source {
|
||||
if (dateElement != null) {
|
||||
chapter.date_upload = parseUpdateFromElement(dateElement);
|
||||
}
|
||||
chapter.date_fetch = new Date().getTime();
|
||||
|
||||
return chapter;
|
||||
}
|
||||
|
||||
|
@ -234,8 +234,6 @@ public class Mangahere extends Source {
|
||||
if (dateElement != null) {
|
||||
chapter.date_upload = parseDateFromElement(dateElement);
|
||||
}
|
||||
chapter.date_fetch = new Date().getTime();
|
||||
|
||||
return chapter;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,8 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
import android.util.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -22,7 +24,6 @@ import eu.kanade.mangafeed.data.source.SourceManager;
|
||||
import eu.kanade.mangafeed.util.AndroidComponentUtil;
|
||||
import eu.kanade.mangafeed.util.NetworkUtil;
|
||||
import eu.kanade.mangafeed.util.NotificationUtil;
|
||||
import eu.kanade.mangafeed.util.PostResult;
|
||||
import rx.Observable;
|
||||
import rx.Subscription;
|
||||
import rx.schedulers.Schedulers;
|
||||
@ -34,6 +35,7 @@ public class LibraryUpdateService extends Service {
|
||||
@Inject SourceManager sourceManager;
|
||||
@Inject PreferencesHelper preferences;
|
||||
|
||||
private PowerManager.WakeLock wakeLock;
|
||||
private Subscription subscription;
|
||||
|
||||
public static final int UPDATE_NOTIFICATION_ID = 1;
|
||||
@ -56,6 +58,7 @@ public class LibraryUpdateService extends Service {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
App.get(this).getComponent().inject(this);
|
||||
createAndAcquireWakeLock();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -64,6 +67,7 @@ public class LibraryUpdateService extends Service {
|
||||
subscription.unsubscribe();
|
||||
// Reset the alarm
|
||||
LibraryUpdateAlarm.startAlarm(this);
|
||||
destroyWakeLock();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@ -111,17 +115,18 @@ public class LibraryUpdateService extends Service {
|
||||
.concatMap(manga -> updateManga(manga)
|
||||
.onErrorReturn(error -> {
|
||||
failedUpdates.add(manga);
|
||||
return new PostResult(0, 0, 0);
|
||||
return Pair.create(0, 0);
|
||||
})
|
||||
.filter(result -> result.getNumberOfRowsInserted() > 0)
|
||||
.map(result -> new MangaUpdate(manga, result)))
|
||||
// Filter out mangas without new chapters
|
||||
.filter(pair -> pair.first > 0)
|
||||
.map(pair -> new MangaUpdate(manga, pair.first)))
|
||||
.doOnNext(updates::add)
|
||||
.doOnCompleted(() -> NotificationUtil.createBigText(this, UPDATE_NOTIFICATION_ID,
|
||||
getString(R.string.notification_update_completed),
|
||||
getUpdatedMangas(updates, failedUpdates)));
|
||||
}
|
||||
|
||||
private Observable<PostResult> updateManga(Manga manga) {
|
||||
private Observable<Pair<Integer, Integer>> updateManga(Manga manga) {
|
||||
return sourceManager.get(manga.source)
|
||||
.pullChaptersFromNetwork(manga.url)
|
||||
.flatMap(chapters -> db.insertOrRemoveChapters(manga, chapters));
|
||||
@ -135,7 +140,7 @@ public class LibraryUpdateService extends Service {
|
||||
result.append(getString(R.string.notification_new_chapters));
|
||||
|
||||
for (MangaUpdate update : updates) {
|
||||
result.append("\n").append(update.getManga().title);
|
||||
result.append("\n").append(update.manga.title);
|
||||
}
|
||||
}
|
||||
if (!failedUpdates.isEmpty()) {
|
||||
@ -154,6 +159,19 @@ public class LibraryUpdateService extends Service {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void createAndAcquireWakeLock() {
|
||||
wakeLock = ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
|
||||
PowerManager.PARTIAL_WAKE_LOCK, "LibraryUpdateService:WakeLock");
|
||||
wakeLock.acquire();
|
||||
}
|
||||
|
||||
private void destroyWakeLock() {
|
||||
if (wakeLock != null && wakeLock.isHeld()) {
|
||||
wakeLock.release();
|
||||
wakeLock = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SyncOnConnectionAvailable extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
@ -169,20 +187,12 @@ public class LibraryUpdateService extends Service {
|
||||
}
|
||||
|
||||
private static class MangaUpdate {
|
||||
private Manga manga;
|
||||
private PostResult result;
|
||||
public Manga manga;
|
||||
public int newChapters;
|
||||
|
||||
public MangaUpdate(Manga manga, PostResult result) {
|
||||
public MangaUpdate(Manga manga, int newChapters) {
|
||||
this.manga = manga;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public Manga getManga() {
|
||||
return manga;
|
||||
}
|
||||
|
||||
public PostResult getResult() {
|
||||
return result;
|
||||
this.newChapters = newChapters;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package eu.kanade.mangafeed.ui.manga.chapter;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Pair;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -20,7 +21,6 @@ import eu.kanade.mangafeed.event.DownloadChaptersEvent;
|
||||
import eu.kanade.mangafeed.event.ReaderEvent;
|
||||
import eu.kanade.mangafeed.ui.base.presenter.BasePresenter;
|
||||
import eu.kanade.mangafeed.util.EventBusHook;
|
||||
import eu.kanade.mangafeed.util.PostResult;
|
||||
import rx.Observable;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.schedulers.Schedulers;
|
||||
@ -119,7 +119,7 @@ public class ChaptersPresenter extends BasePresenter<ChaptersFragment> {
|
||||
chaptersSubject.onNext(chapters);
|
||||
}
|
||||
|
||||
private Observable<PostResult> getOnlineChaptersObs() {
|
||||
private Observable<Pair<Integer, Integer>> getOnlineChaptersObs() {
|
||||
return source.pullChaptersFromNetwork(manga.url)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.flatMap(chapters -> db.insertOrRemoveChapters(manga, chapters))
|
||||
|
@ -16,8 +16,8 @@ import eu.kanade.mangafeed.data.mangasync.base.MangaSyncService;
|
||||
import eu.kanade.mangafeed.data.mangasync.MangaSyncManager;
|
||||
import eu.kanade.mangafeed.data.source.SourceManager;
|
||||
import eu.kanade.mangafeed.data.source.base.Source;
|
||||
import eu.kanade.mangafeed.ui.setting.preference.MangaSyncLoginDialog;
|
||||
import eu.kanade.mangafeed.ui.setting.preference.SourceLoginDialog;
|
||||
import eu.kanade.mangafeed.widget.preference.MangaSyncLoginDialog;
|
||||
import eu.kanade.mangafeed.widget.preference.SourceLoginDialog;
|
||||
import rx.Observable;
|
||||
|
||||
public class SettingsAccountsFragment extends SettingsNestedFragment {
|
||||
|
@ -8,8 +8,8 @@ import android.view.ViewGroup;
|
||||
import eu.kanade.mangafeed.R;
|
||||
import eu.kanade.mangafeed.data.preference.PreferencesHelper;
|
||||
import eu.kanade.mangafeed.data.sync.LibraryUpdateAlarm;
|
||||
import eu.kanade.mangafeed.ui.setting.preference.IntListPreference;
|
||||
import eu.kanade.mangafeed.ui.setting.preference.LibraryColumnsDialog;
|
||||
import eu.kanade.mangafeed.widget.preference.IntListPreference;
|
||||
import eu.kanade.mangafeed.widget.preference.LibraryColumnsDialog;
|
||||
|
||||
public class SettingsGeneralFragment extends SettingsNestedFragment {
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
package eu.kanade.mangafeed.util;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
public class PostResult {
|
||||
|
||||
@Nullable
|
||||
private final Integer numberOfRowsUpdated;
|
||||
|
||||
@Nullable
|
||||
private final Integer numberOfRowsInserted;
|
||||
|
||||
@Nullable
|
||||
private final Integer numberOfRowsDeleted;
|
||||
|
||||
public PostResult(Integer numberOfRowsUpdated, Integer numberOfRowsInserted, Integer numberOfRowsDeleted) {
|
||||
this.numberOfRowsUpdated = numberOfRowsUpdated;
|
||||
this.numberOfRowsInserted = numberOfRowsInserted;
|
||||
this.numberOfRowsDeleted = numberOfRowsDeleted;
|
||||
}
|
||||
|
||||
public Integer getNumberOfRowsUpdated() {
|
||||
return numberOfRowsUpdated;
|
||||
}
|
||||
|
||||
public Integer getNumberOfRowsInserted() {
|
||||
return numberOfRowsInserted;
|
||||
}
|
||||
|
||||
public Integer getNumberOfRowsDeleted() {
|
||||
return numberOfRowsDeleted;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.mangafeed.ui.setting.preference;
|
||||
package eu.kanade.mangafeed.widget.preference;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.ListPreference;
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.mangafeed.ui.setting.preference;
|
||||
package eu.kanade.mangafeed.widget.preference;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.DialogPreference;
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.mangafeed.ui.setting.preference;
|
||||
package eu.kanade.mangafeed.widget.preference;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.mangafeed.ui.setting.preference;
|
||||
package eu.kanade.mangafeed.widget.preference;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.mangafeed.ui.setting.preference;
|
||||
package eu.kanade.mangafeed.widget.preference;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
@ -5,7 +5,7 @@
|
||||
android:title="@string/pref_download_directory"
|
||||
android:key="@string/pref_download_directory_key"/>
|
||||
|
||||
<eu.kanade.mangafeed.ui.setting.preference.IntListPreference
|
||||
<eu.kanade.mangafeed.widget.preference.IntListPreference
|
||||
android:title="@string/pref_download_slots"
|
||||
android:key="@string/pref_download_slots_key"
|
||||
android:entries="@array/download_slots"
|
||||
|
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<eu.kanade.mangafeed.ui.setting.preference.LibraryColumnsDialog
|
||||
<eu.kanade.mangafeed.widget.preference.LibraryColumnsDialog
|
||||
android:key="@string/pref_library_columns_dialog_key"
|
||||
android:persistent="false"
|
||||
android:title="@string/pref_library_columns"/>
|
||||
|
||||
<eu.kanade.mangafeed.ui.setting.preference.IntListPreference
|
||||
<eu.kanade.mangafeed.widget.preference.IntListPreference
|
||||
android:key="@string/pref_library_update_interval_key"
|
||||
android:title="@string/pref_library_update_interval"
|
||||
android:entries="@array/library_update_interval"
|
||||
|
@ -28,7 +28,7 @@
|
||||
android:defaultValue="1"
|
||||
android:summary="%s"/>
|
||||
|
||||
<eu.kanade.mangafeed.ui.setting.preference.IntListPreference
|
||||
<eu.kanade.mangafeed.widget.preference.IntListPreference
|
||||
android:title="@string/pref_reader_theme"
|
||||
android:key="@string/pref_reader_theme_key"
|
||||
android:entries="@array/reader_themes"
|
||||
@ -36,7 +36,7 @@
|
||||
android:defaultValue="0"
|
||||
android:summary="%s"/>
|
||||
|
||||
<eu.kanade.mangafeed.ui.setting.preference.IntListPreference
|
||||
<eu.kanade.mangafeed.widget.preference.IntListPreference
|
||||
android:title="@string/pref_image_decoder"
|
||||
android:key="@string/pref_image_decoder_key"
|
||||
android:entries="@array/image_decoders"
|
||||
|
Loading…
Reference in New Issue
Block a user