From e702be1a8d17f62ecbf88107305a544c763bb6b5 Mon Sep 17 00:00:00 2001 From: inorichi Date: Sun, 10 Jan 2016 19:49:26 +0100 Subject: [PATCH] Rewrite the chapter insertion method. Create a wakelock until the library updates. Move custom preferences to widget package. --- .../data/database/DatabaseHelper.java | 71 +++++++++++-------- .../data/source/online/english/Batoto.java | 2 - .../data/source/online/english/Kissmanga.java | 3 - .../data/source/online/english/Mangafox.java | 2 - .../data/source/online/english/Mangahere.java | 2 - .../data/sync/LibraryUpdateService.java | 46 +++++++----- .../ui/manga/chapter/ChaptersPresenter.java | 4 +- .../ui/setting/SettingsAccountsFragment.java | 4 +- .../ui/setting/SettingsGeneralFragment.java | 4 +- .../eu/kanade/mangafeed/util/PostResult.java | 33 --------- .../preference/IntListPreference.java | 2 +- .../preference/LibraryColumnsDialog.java | 2 +- .../preference/LoginDialogPreference.java | 2 +- .../preference/MangaSyncLoginDialog.java | 2 +- .../preference/SourceLoginDialog.java | 2 +- app/src/main/res/xml/pref_downloads.xml | 2 +- app/src/main/res/xml/pref_general.xml | 4 +- app/src/main/res/xml/pref_reader.xml | 4 +- 18 files changed, 84 insertions(+), 107 deletions(-) delete mode 100644 app/src/main/java/eu/kanade/mangafeed/util/PostResult.java rename app/src/main/java/eu/kanade/mangafeed/{ui/setting => widget}/preference/IntListPreference.java (94%) rename app/src/main/java/eu/kanade/mangafeed/{ui/setting => widget}/preference/LibraryColumnsDialog.java (97%) rename app/src/main/java/eu/kanade/mangafeed/{ui/setting => widget}/preference/LoginDialogPreference.java (97%) rename app/src/main/java/eu/kanade/mangafeed/{ui/setting => widget}/preference/MangaSyncLoginDialog.java (98%) rename app/src/main/java/eu/kanade/mangafeed/{ui/setting => widget}/preference/SourceLoginDialog.java (97%) diff --git a/app/src/main/java/eu/kanade/mangafeed/data/database/DatabaseHelper.java b/app/src/main/java/eu/kanade/mangafeed/data/database/DatabaseHelper.java index bd10f528f7..50aab278f4 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/database/DatabaseHelper.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/database/DatabaseHelper.java @@ -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 insertOrRemoveChapters(Manga manga, List chapters) { - for (Chapter chapter : chapters) { - chapter.manga_id = manga.id; - } + public Observable> insertOrRemoveChapters(Manga manga, List sourceChapters) { + List dbChapters = getChapters(manga).executeAsBlocking(); - Observable> chapterList = Observable.create(subscriber -> { - subscriber.onNext(getChapters(manga).executeAsBlocking()); - subscriber.onCompleted(); + Observable> 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> 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 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 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 deleteChapter(Chapter chapter) { diff --git a/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Batoto.java b/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Batoto.java index 8b4b8e0fbe..b222264d6b 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Batoto.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Batoto.java @@ -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; } diff --git a/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Kissmanga.java b/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Kissmanga.java index e1e67a9f5f..73851cba7b 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Kissmanga.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Kissmanga.java @@ -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; } diff --git a/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Mangafox.java b/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Mangafox.java index a7a148ef9d..364f5b388b 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Mangafox.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Mangafox.java @@ -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; } diff --git a/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Mangahere.java b/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Mangahere.java index 829c8967f5..76bcaa26cc 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Mangahere.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/source/online/english/Mangahere.java @@ -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; } diff --git a/app/src/main/java/eu/kanade/mangafeed/data/sync/LibraryUpdateService.java b/app/src/main/java/eu/kanade/mangafeed/data/sync/LibraryUpdateService.java index 114b136c0a..267ed5d13f 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/sync/LibraryUpdateService.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/sync/LibraryUpdateService.java @@ -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 updateManga(Manga manga) { + private Observable> 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; } } diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java b/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java index 95ce8d9f64..370c9c9a7b 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/manga/chapter/ChaptersPresenter.java @@ -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 { chaptersSubject.onNext(chapters); } - private Observable getOnlineChaptersObs() { + private Observable> getOnlineChaptersObs() { return source.pullChaptersFromNetwork(manga.url) .subscribeOn(Schedulers.io()) .flatMap(chapters -> db.insertOrRemoveChapters(manga, chapters)) diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsAccountsFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsAccountsFragment.java index b504080d38..bb6392e7c0 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsAccountsFragment.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsAccountsFragment.java @@ -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 { diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsGeneralFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsGeneralFragment.java index a411ddd102..ac40f9066b 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsGeneralFragment.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/setting/SettingsGeneralFragment.java @@ -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 { diff --git a/app/src/main/java/eu/kanade/mangafeed/util/PostResult.java b/app/src/main/java/eu/kanade/mangafeed/util/PostResult.java deleted file mode 100644 index f76bacdd1c..0000000000 --- a/app/src/main/java/eu/kanade/mangafeed/util/PostResult.java +++ /dev/null @@ -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; - } -} diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/IntListPreference.java b/app/src/main/java/eu/kanade/mangafeed/widget/preference/IntListPreference.java similarity index 94% rename from app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/IntListPreference.java rename to app/src/main/java/eu/kanade/mangafeed/widget/preference/IntListPreference.java index 7f2f172084..02dfe7c12c 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/IntListPreference.java +++ b/app/src/main/java/eu/kanade/mangafeed/widget/preference/IntListPreference.java @@ -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; diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/LibraryColumnsDialog.java b/app/src/main/java/eu/kanade/mangafeed/widget/preference/LibraryColumnsDialog.java similarity index 97% rename from app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/LibraryColumnsDialog.java rename to app/src/main/java/eu/kanade/mangafeed/widget/preference/LibraryColumnsDialog.java index 78b769af42..5bb1b2e16c 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/LibraryColumnsDialog.java +++ b/app/src/main/java/eu/kanade/mangafeed/widget/preference/LibraryColumnsDialog.java @@ -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; diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/LoginDialogPreference.java b/app/src/main/java/eu/kanade/mangafeed/widget/preference/LoginDialogPreference.java similarity index 97% rename from app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/LoginDialogPreference.java rename to app/src/main/java/eu/kanade/mangafeed/widget/preference/LoginDialogPreference.java index ba7597d8f0..73ba9f804a 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/LoginDialogPreference.java +++ b/app/src/main/java/eu/kanade/mangafeed/widget/preference/LoginDialogPreference.java @@ -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; diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/MangaSyncLoginDialog.java b/app/src/main/java/eu/kanade/mangafeed/widget/preference/MangaSyncLoginDialog.java similarity index 98% rename from app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/MangaSyncLoginDialog.java rename to app/src/main/java/eu/kanade/mangafeed/widget/preference/MangaSyncLoginDialog.java index 663e12b936..ec2d35d400 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/MangaSyncLoginDialog.java +++ b/app/src/main/java/eu/kanade/mangafeed/widget/preference/MangaSyncLoginDialog.java @@ -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; diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/SourceLoginDialog.java b/app/src/main/java/eu/kanade/mangafeed/widget/preference/SourceLoginDialog.java similarity index 97% rename from app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/SourceLoginDialog.java rename to app/src/main/java/eu/kanade/mangafeed/widget/preference/SourceLoginDialog.java index 96df2d04ba..5984ab1ab2 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/setting/preference/SourceLoginDialog.java +++ b/app/src/main/java/eu/kanade/mangafeed/widget/preference/SourceLoginDialog.java @@ -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; diff --git a/app/src/main/res/xml/pref_downloads.xml b/app/src/main/res/xml/pref_downloads.xml index b05bfbb4df..217fe896ca 100644 --- a/app/src/main/res/xml/pref_downloads.xml +++ b/app/src/main/res/xml/pref_downloads.xml @@ -5,7 +5,7 @@ android:title="@string/pref_download_directory" android:key="@string/pref_download_directory_key"/> - - - - -