Refresh button in library is now looking for new chapters in sources and notifying the user

This commit is contained in:
inorichi
2015-11-02 17:25:06 +01:00
parent faef785fc3
commit 04dfdba0b7
12 changed files with 301 additions and 6 deletions

View File

@@ -103,6 +103,11 @@ public class DatabaseHelper implements MangaManager, ChapterManager {
return mMangaManager.getMangasWithUnread();
}
@Override
public Observable<List<Manga>> getFavoriteMangas() {
return mMangaManager.getFavoriteMangas();
}
@Override
public Observable<List<Manga>> getManga(String url) {
return mMangaManager.getManga(url);

View File

@@ -6,7 +6,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import eu.kanade.mangafeed.data.caches.CacheManager;
import eu.kanade.mangafeed.sources.Batoto;
import eu.kanade.mangafeed.sources.MangaHere;
import eu.kanade.mangafeed.sources.base.Source;
@@ -17,8 +16,6 @@ public class SourceManager {
public static final int MANGAHERE = 2;
private HashMap<Integer, Source> mSourcesMap;
private NetworkHelper mNetworkHelper;
private CacheManager mCacheManager;
private Context context;
public SourceManager(Context context) {

View File

@@ -16,6 +16,8 @@ public interface MangaManager {
Observable<List<Manga>> getMangasWithUnread();
Observable<List<Manga>> getFavoriteMangas();
Observable<List<Manga>> getManga(String url);
Observable<List<Manga>> getManga(long id);

View File

@@ -55,6 +55,19 @@ public class MangaManagerImpl extends BaseManager implements MangaManager {
.createObservable();
}
@Override
public Observable<List<Manga>> getFavoriteMangas() {
return db.get()
.listOfObjects(Manga.class)
.withQuery(Query.builder()
.table(MangasTable.TABLE)
.where(MangasTable.COLUMN_FAVORITE + "=?")
.whereArgs(1)
.build())
.prepare()
.createObservable();
}
public Observable<List<Manga>> getManga(String url) {
return db.get()
.listOfObjects(Manga.class)

View File

@@ -0,0 +1,168 @@
package eu.kanade.mangafeed.data.services;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javax.inject.Inject;
import eu.kanade.mangafeed.App;
import eu.kanade.mangafeed.BuildConfig;
import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.helpers.DatabaseHelper;
import eu.kanade.mangafeed.data.helpers.SourceManager;
import eu.kanade.mangafeed.data.models.Manga;
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 timber.log.Timber;
public class LibraryUpdateService extends Service {
@Inject DatabaseHelper db;
@Inject SourceManager sourceManager;
private Subscription updateSubscription;
private Subscription favoriteMangasSubscription;
public static final int UPDATE_NOTIFICATION_ID = 1;
public static Intent getStartIntent(Context context) {
return new Intent(context, LibraryUpdateService.class);
}
public static boolean isRunning(Context context) {
return AndroidComponentUtil.isServiceRunning(context, LibraryUpdateService.class);
}
@Override
public void onCreate() {
super.onCreate();
App.get(this).getComponent().inject(this);
}
@Override
public void onDestroy() {
if (updateSubscription != null)
updateSubscription.unsubscribe();
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, final int startId) {
Timber.i("Starting sync...");
if (!NetworkUtil.isNetworkConnected(this)) {
Timber.i("Sync canceled, connection not available");
AndroidComponentUtil.toggleComponent(this, SyncOnConnectionAvailable.class, true);
stopSelf(startId);
return START_NOT_STICKY;
}
if (favoriteMangasSubscription != null && !favoriteMangasSubscription.isUnsubscribed())
favoriteMangasSubscription.unsubscribe();
favoriteMangasSubscription = db.getFavoriteMangas()
.subscribe(mangas -> {
// Don't receive further db updates
favoriteMangasSubscription.unsubscribe();
this.startUpdating(mangas, startId);
});
return START_STICKY;
}
private void startUpdating(final List<Manga> mangas, final int startId) {
if (updateSubscription != null && !updateSubscription.isUnsubscribed())
updateSubscription.unsubscribe();
final AtomicInteger count = new AtomicInteger(0);
List<MangaUpdate> updates = new ArrayList<>();
updateSubscription = Observable.from(mangas)
.doOnNext(manga -> {
NotificationUtil.create(this, UPDATE_NOTIFICATION_ID,
getString(R.string.notification_progress, count.incrementAndGet(), mangas.size()),
manga.title);
})
.concatMap(manga -> sourceManager.get(manga.source)
.pullChaptersFromNetwork(manga.url)
.flatMap(chapters -> db.insertOrRemoveChapters(manga, chapters))
.filter(result -> result.getNumberOfRowsInserted() > 0)
.flatMap(result -> Observable.just(new MangaUpdate(manga, result)))
)
.subscribe(update -> {
updates.add(update);
}, error -> {
Timber.e("Error syncing");
stopSelf(startId);
}, () -> {
NotificationUtil.createBigText(this, UPDATE_NOTIFICATION_ID,
getString(R.string.notification_completed), getUpdatedMangas(updates));
stopSelf(startId);
});
}
private String getUpdatedMangas(List<MangaUpdate> updates) {
final StringBuilder result = new StringBuilder();
if (updates.isEmpty()) {
result.append(getString(R.string.notification_no_new_chapters)).append("\n");
} else {
result.append(getString(R.string.notification_new_chapters));
for (MangaUpdate update : updates) {
result.append("\n").append(update.getManga().title);
}
}
return result.toString();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public static class SyncOnConnectionAvailable extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (NetworkUtil.isNetworkConnected(context)) {
if (BuildConfig.DEBUG) {
Timber.i("Connection is now available, triggering sync...");
}
AndroidComponentUtil.toggleComponent(context, this.getClass(), false);
context.startService(getStartIntent(context));
}
}
}
private static class MangaUpdate {
private Manga manga;
private PostResult result;
public MangaUpdate(Manga manga, PostResult result) {
this.manga = manga;
this.result = result;
}
public Manga getManga() {
return manga;
}
public PostResult getResult() {
return result;
}
}
}