Browse Source

Use interfaces for database managers, create a source manager

inorichi 9 years ago
parent
commit
67a2e99cc1

+ 6 - 0
app/src/main/java/eu/kanade/mangafeed/data/DataModule.java

@@ -10,6 +10,7 @@ import eu.kanade.mangafeed.data.caches.CacheManager;
 import eu.kanade.mangafeed.data.helpers.DatabaseHelper;
 import eu.kanade.mangafeed.data.helpers.NetworkHelper;
 import eu.kanade.mangafeed.data.helpers.PreferencesHelper;
+import eu.kanade.mangafeed.data.helpers.SourceManager;
 import rx.Scheduler;
 import rx.schedulers.Schedulers;
 
@@ -49,4 +50,9 @@ public class DataModule {
         return new NetworkHelper();
     }
 
+    @Provides
+    @Singleton
+    SourceManager provideSourceManager(NetworkHelper networkHelper, CacheManager cacheManager) {
+        return new SourceManager(networkHelper, cacheManager);
+    }
 }

+ 75 - 7
app/src/main/java/eu/kanade/mangafeed/data/helpers/DatabaseHelper.java

@@ -5,9 +5,17 @@ import android.content.Context;
 import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping;
 import com.pushtorefresh.storio.sqlite.StorIOSQLite;
 import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite;
+import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
+import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
+import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
+import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
+
+import java.util.List;
 
 import eu.kanade.mangafeed.data.managers.ChapterManager;
+import eu.kanade.mangafeed.data.managers.ChapterManagerImpl;
 import eu.kanade.mangafeed.data.managers.MangaManager;
+import eu.kanade.mangafeed.data.managers.MangaManagerImpl;
 import eu.kanade.mangafeed.data.models.Chapter;
 import eu.kanade.mangafeed.data.models.ChapterStorIOSQLiteDeleteResolver;
 import eu.kanade.mangafeed.data.models.ChapterStorIOSQLiteGetResolver;
@@ -16,16 +24,17 @@ import eu.kanade.mangafeed.data.models.Manga;
 import eu.kanade.mangafeed.data.models.MangaStorIOSQLiteDeleteResolver;
 import eu.kanade.mangafeed.data.models.MangaStorIOSQLitePutResolver;
 import eu.kanade.mangafeed.data.resolvers.MangaWithUnreadGetResolver;
+import rx.Observable;
 
-public class DatabaseHelper {
+public class DatabaseHelper implements MangaManager, ChapterManager {
 
-    private StorIOSQLite db;
-    public MangaManager manga;
-    public ChapterManager chapter;
+    private StorIOSQLite mDb;
+    private MangaManagerImpl mMangaManager;
+    private ChapterManagerImpl mChapterManager;
 
     public DatabaseHelper(Context context) {
 
-        db = DefaultStorIOSQLite.builder()
+        mDb = DefaultStorIOSQLite.builder()
                 .sqliteOpenHelper(new DbOpenHelper(context))
                 .addTypeMapping(Manga.class, SQLiteTypeMapping.<Manga>builder()
                         .putResolver(new MangaStorIOSQLitePutResolver())
@@ -39,8 +48,67 @@ public class DatabaseHelper {
                         .build())
                 .build();
 
-        manga = new MangaManager(db);
-        chapter = new ChapterManager(db);
+        mMangaManager = new MangaManagerImpl(mDb);
+        mChapterManager = new ChapterManagerImpl(mDb);
+    }
+
+    @Override
+    public Observable<List<Chapter>> getChapters(Manga manga) {
+        return mChapterManager.getChapters(manga);
+    }
+
+    @Override
+    public Observable<PutResult> insertChapter(Chapter chapter) {
+        return mChapterManager.insertChapter(chapter);
+    }
+
+    @Override
+    public Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters) {
+        return mChapterManager.insertChapters(chapters);
+    }
+
+    @Override
+    public Observable insertOrRemoveChapters(Manga manga, List<Chapter> chapters) {
+        return mChapterManager.insertOrRemoveChapters(manga, chapters);
+    }
+
+    @Override
+    public Observable<DeleteResult> deleteChapter(Chapter chapter) {
+        return mChapterManager.deleteChapter(chapter);
+    }
+
+    @Override
+    public Observable<DeleteResults<Chapter>> deleteChapters(List<Chapter> chapters) {
+        return mChapterManager.deleteChapters(chapters);
+    }
+
+    @Override
+    public Observable<List<Manga>> getMangas() {
+        return mMangaManager.getMangas();
+    }
+
+    @Override
+    public Observable<List<Manga>> getMangasWithUnread() {
+        return mMangaManager.getMangasWithUnread();
+    }
+
+    @Override
+    public Observable<PutResult> insertManga(Manga manga) {
+        return mMangaManager.insertManga(manga);
+    }
+
+    @Override
+    public Observable<PutResults<Manga>> insertMangas(List<Manga> mangas) {
+        return mMangaManager.insertMangas(mangas);
     }
 
+    @Override
+    public Observable<DeleteResult> deleteManga(Manga manga) {
+        return mMangaManager.deleteManga(manga);
+    }
+
+    @Override
+    public Observable<DeleteResults<Manga>> deleteMangas(List<Manga> mangas) {
+        return mMangaManager.deleteMangas(mangas);
+    }
 }

+ 38 - 0
app/src/main/java/eu/kanade/mangafeed/data/helpers/SourceManager.java

@@ -0,0 +1,38 @@
+package eu.kanade.mangafeed.data.helpers;
+
+import java.util.HashMap;
+
+import eu.kanade.mangafeed.data.caches.CacheManager;
+import eu.kanade.mangafeed.sources.Batoto;
+import eu.kanade.mangafeed.sources.Source;
+
+public class SourceManager {
+
+    public static final int BATOTO = 1;
+
+    private HashMap<Integer, Source> mSourcesMap;
+    private NetworkHelper mNetworkHelper;
+    private CacheManager mCacheManager;
+
+    public SourceManager(NetworkHelper networkHelper, CacheManager cacheManager) {
+        mSourcesMap = new HashMap<>();
+        mNetworkHelper = networkHelper;
+        mCacheManager = cacheManager;
+    }
+
+    public Source get(int sourceKey) {
+        if (!mSourcesMap.containsKey(sourceKey)) {
+            mSourcesMap.put(sourceKey, createSource(sourceKey));
+        }
+        return mSourcesMap.get(sourceKey);
+    }
+
+    private Source createSource(int sourceKey) {
+        switch (sourceKey) {
+            case BATOTO:
+                return new Batoto(mNetworkHelper, mCacheManager);
+        }
+
+        return null;
+    }
+}

+ 7 - 86
app/src/main/java/eu/kanade/mangafeed/data/managers/ChapterManager.java

@@ -1,107 +1,28 @@
 package eu.kanade.mangafeed.data.managers;
 
-import com.pushtorefresh.storio.sqlite.StorIOSQLite;
 import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
 import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
-import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetListOfObjects;
 import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
 import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
-import com.pushtorefresh.storio.sqlite.queries.Query;
 
 import java.util.List;
 
 import eu.kanade.mangafeed.data.models.Chapter;
 import eu.kanade.mangafeed.data.models.Manga;
-import eu.kanade.mangafeed.data.tables.ChaptersTable;
 import rx.Observable;
 
-public class ChapterManager extends BaseManager {
+public interface ChapterManager {
 
-    public ChapterManager(StorIOSQLite db) {
-        super(db);
-    }
+    Observable<List<Chapter>> getChapters(Manga manga);
 
-    private PreparedGetListOfObjects<Chapter> prepareGet(Manga manga) {
-        return db.get()
-                .listOfObjects(Chapter.class)
-                .withQuery(Query.builder()
-                        .table(ChaptersTable.TABLE)
-                        .where(ChaptersTable.COLUMN_MANGA_ID + "=?")
-                        .whereArgs(manga.id)
-                        .build())
-                .prepare();
-    }
+    Observable<PutResult> insertChapter(Chapter chapter);
 
-    public Observable<List<Chapter>> get(Manga manga) {
-        return prepareGet(manga).createObservable();
-    }
+    Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters);
 
-    public Observable<PutResult> insert(Chapter chapter) {
-        return db.put()
-                .object(chapter)
-                .prepare()
-                .createObservable();
-    }
+    Observable insertOrRemoveChapters(Manga manga, List<Chapter> chapters);
 
-    public Observable<PutResults<Chapter>> insert(List<Chapter> chapters) {
-        return db.put()
-                .objects(chapters)
-                .prepare()
-                .createObservable();
-    }
+    Observable<DeleteResult> deleteChapter(Chapter chapter);
 
-    // Add new chapters or delete if the source deletes them
-    public Observable insertOrRemove(Manga manga, List<Chapter> chapters) {
-        // I don't know a better approach
-        // TODO Fix this method
-        return Observable.create(subscriber -> {
-            List<Chapter> dbChapters = prepareGet(manga).executeAsBlocking();
+    Observable<DeleteResults<Chapter>> deleteChapters(List<Chapter> chapters);
 
-            Observable<List<Chapter>> newChaptersObs =
-                    Observable.from(chapters)
-                    .filter(c -> !dbChapters.contains(c))
-                    .toList();
-
-            Observable<List<Chapter>> deletedChaptersObs =
-                    Observable.from(dbChapters)
-                    .filter(c -> !chapters.contains(c))
-                    .toList();
-
-            Observable.zip(newChaptersObs, deletedChaptersObs,
-                    (newChapters, deletedChapters) -> {
-                        insert(newChapters).subscribe();
-                        delete(deletedChapters).subscribe();
-                        subscriber.onCompleted();
-                        return null;
-                    }).subscribe();
-        });
-
-    }
-
-    public void createDummyChapters() {
-        Chapter c;
-
-        for (int i = 1; i < 100; i++) {
-            c = new Chapter();
-            c.manga_id = 1L;
-            c.name = "Chapter " + i;
-            c.url = "http://example.com/1";
-            insert(c).subscribe();
-        }
-
-    }
-
-    public Observable<DeleteResults<Chapter>> delete(List<Chapter> chapters) {
-        return db.delete()
-                .objects(chapters)
-                .prepare()
-                .createObservable();
-    }
-
-    public Observable<DeleteResult> delete(Chapter chapter) {
-        return db.delete()
-                .object(chapter)
-                .prepare()
-                .createObservable();
-    }
 }

+ 101 - 0
app/src/main/java/eu/kanade/mangafeed/data/managers/ChapterManagerImpl.java

@@ -0,0 +1,101 @@
+package eu.kanade.mangafeed.data.managers;
+
+import com.pushtorefresh.storio.sqlite.StorIOSQLite;
+import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
+import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
+import com.pushtorefresh.storio.sqlite.operations.get.PreparedGetListOfObjects;
+import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
+import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
+import com.pushtorefresh.storio.sqlite.queries.Query;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.kanade.mangafeed.data.models.Chapter;
+import eu.kanade.mangafeed.data.models.Manga;
+import eu.kanade.mangafeed.data.tables.ChaptersTable;
+import rx.Observable;
+
+public class ChapterManagerImpl extends BaseManager implements ChapterManager {
+
+    public ChapterManagerImpl(StorIOSQLite db) {
+        super(db);
+    }
+
+    private PreparedGetListOfObjects<Chapter> prepareGet(Manga manga) {
+        return db.get()
+                .listOfObjects(Chapter.class)
+                .withQuery(Query.builder()
+                        .table(ChaptersTable.TABLE)
+                        .where(ChaptersTable.COLUMN_MANGA_ID + "=?")
+                        .whereArgs(manga.id)
+                        .build())
+                .prepare();
+    }
+
+    @Override
+    public Observable<List<Chapter>> getChapters(Manga manga) {
+        return prepareGet(manga).createObservable();
+    }
+
+    @Override
+    public Observable<PutResult> insertChapter(Chapter chapter) {
+        return db.put()
+                .object(chapter)
+                .prepare()
+                .createObservable();
+    }
+
+    @Override
+    public Observable<PutResults<Chapter>> insertChapters(List<Chapter> chapters) {
+        return db.put()
+                .objects(chapters)
+                .prepare()
+                .createObservable();
+    }
+
+    // Add new chapters or delete if the source deletes them
+    @Override
+    public Observable insertOrRemoveChapters(Manga manga, List<Chapter> chapters) {
+        // I don't know a better approach
+        // TODO Fix this method
+        return Observable.create(subscriber -> {
+            List<Chapter> dbChapters = prepareGet(manga).executeAsBlocking();
+
+            Observable<List<Chapter>> newChaptersObs =
+                    Observable.from(chapters)
+                            .filter(c -> !dbChapters.contains(c))
+                            .toList();
+
+            Observable<List<Chapter>> deletedChaptersObs =
+                    Observable.from(dbChapters)
+                            .filter(c -> !chapters.contains(c))
+                            .toList();
+
+            Observable.zip(newChaptersObs, deletedChaptersObs,
+                    (newChapters, deletedChapters) -> {
+                        insertChapters(newChapters).subscribe();
+                        deleteChapters(deletedChapters).subscribe();
+                        subscriber.onCompleted();
+                        return null;
+                    }).subscribe();
+        });
+    }
+
+    @Override
+    public Observable<DeleteResult> deleteChapter(Chapter chapter) {
+        return db.delete()
+                .object(chapter)
+                .prepare()
+                .createObservable();
+    }
+
+    @Override
+    public Observable<DeleteResults<Chapter>> deleteChapters(List<Chapter> chapters) {
+        return db.delete()
+                .objects(chapters)
+                .prepare()
+                .createObservable();
+    }
+
+}

+ 8 - 78
app/src/main/java/eu/kanade/mangafeed/data/managers/MangaManager.java

@@ -1,97 +1,27 @@
 package eu.kanade.mangafeed.data.managers;
 
-import com.pushtorefresh.storio.sqlite.StorIOSQLite;
 import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
 import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
 import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
-import com.pushtorefresh.storio.sqlite.queries.Query;
-import com.pushtorefresh.storio.sqlite.queries.RawQuery;
+import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
 
 import java.util.List;
 
 import eu.kanade.mangafeed.data.models.Manga;
-import eu.kanade.mangafeed.data.tables.ChaptersTable;
-import eu.kanade.mangafeed.data.tables.MangasTable;
 import rx.Observable;
 
-public class MangaManager extends BaseManager {
+public interface MangaManager {
 
-    public MangaManager(StorIOSQLite db) {
-        super(db);
-    }
+    Observable<List<Manga>> getMangas();
 
-    private final String mangasWithUnreadQuery = String.format(
-            "SELECT %1$s.*, COUNT(C.%4$s) AS %5$s FROM %1$s LEFT JOIN " +
-            "(SELECT %4$s FROM %2$s WHERE %6$s = 0) AS C ON %3$s = C.%4$s " +
-            "GROUP BY %3$s",
-            MangasTable.TABLE,
-            ChaptersTable.TABLE,
-            MangasTable.TABLE + "." + MangasTable.COLUMN_ID,
-            ChaptersTable.COLUMN_MANGA_ID,
-            MangasTable.COLUMN_UNREAD,
-            ChaptersTable.COLUMN_READ
-    );
+    Observable<List<Manga>> getMangasWithUnread();
 
-    public Observable<List<Manga>> get() {
-        return db.get()
-                .listOfObjects(Manga.class)
-                .withQuery(Query.builder()
-                        .table(MangasTable.TABLE)
-                        .build())
-                .prepare()
-                .createObservable();
-    }
+    Observable<PutResult> insertManga(Manga manga);
 
-    public Observable<List<Manga>> getWithUnread() {
-        return db.get()
-                .listOfObjects(Manga.class)
-                .withQuery(RawQuery.builder()
-                        .query(mangasWithUnreadQuery)
-                        .observesTables(MangasTable.TABLE, ChaptersTable.TABLE)
-                        .build())
-                .prepare()
-                .createObservable();
-    }
+    Observable<PutResults<Manga>> insertMangas(List<Manga> mangas);
 
-    public Observable<PutResult> insert(Manga manga) {
-        return db.put()
-                .object(manga)
-                .prepare()
-                .createObservable();
-    }
+    Observable<DeleteResult> deleteManga(Manga manga);
 
-    public void createDummyManga() {
-        insert(createDummyManga("One Piece")).subscribe();
-        insert(createDummyManga("Übel Blatt")).subscribe();
-        insert(createDummyManga("Berserk")).subscribe();
-        insert(createDummyManga("Horimiya")).subscribe();
-    }
-
-    private Manga createDummyManga(String title) {
-        Manga m = new Manga();
-        m.title = title;
-        m.url="http://example.com";
-        m.artist="Eiichiro Oda";
-        m.author="Eiichiro Oda";
-        m.description="...";
-        m.genre="Action, Drama";
-        m.status="Ongoing";
-        m.thumbnail_url="http://example.com/pic.png";
-        return m;
-    }
-
-    public Observable<DeleteResult> delete(Manga manga) {
-        return db.delete()
-                .object(manga)
-                .prepare()
-                .createObservable();
-    }
-
-    public Observable<DeleteResults<Manga>> delete(List<Manga> mangas) {
-        return db.delete()
-                .objects(mangas)
-                .prepare()
-                .createObservable();
-    }
+    Observable<DeleteResults<Manga>> deleteMangas(List<Manga> mangas);
 
 }

+ 85 - 0
app/src/main/java/eu/kanade/mangafeed/data/managers/MangaManagerImpl.java

@@ -0,0 +1,85 @@
+package eu.kanade.mangafeed.data.managers;
+
+import com.pushtorefresh.storio.sqlite.StorIOSQLite;
+import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResult;
+import com.pushtorefresh.storio.sqlite.operations.delete.DeleteResults;
+import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
+import com.pushtorefresh.storio.sqlite.operations.put.PutResults;
+import com.pushtorefresh.storio.sqlite.queries.Query;
+import com.pushtorefresh.storio.sqlite.queries.RawQuery;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.kanade.mangafeed.data.models.Manga;
+import eu.kanade.mangafeed.data.tables.ChaptersTable;
+import eu.kanade.mangafeed.data.tables.MangasTable;
+import rx.Observable;
+
+public class MangaManagerImpl extends BaseManager implements MangaManager {
+
+    public MangaManagerImpl(StorIOSQLite db) {
+        super(db);
+    }
+
+    private final String mangasWithUnreadQuery = String.format(
+            "SELECT %1$s.*, COUNT(C.%4$s) AS %5$s FROM %1$s LEFT JOIN " +
+            "(SELECT %4$s FROM %2$s WHERE %6$s = 0) AS C ON %3$s = C.%4$s " +
+            "GROUP BY %3$s",
+            MangasTable.TABLE,
+            ChaptersTable.TABLE,
+            MangasTable.TABLE + "." + MangasTable.COLUMN_ID,
+            ChaptersTable.COLUMN_MANGA_ID,
+            MangasTable.COLUMN_UNREAD,
+            ChaptersTable.COLUMN_READ
+    );
+
+    public Observable<List<Manga>> getMangas() {
+        return db.get()
+                .listOfObjects(Manga.class)
+                .withQuery(Query.builder()
+                        .table(MangasTable.TABLE)
+                        .build())
+                .prepare()
+                .createObservable();
+    }
+
+    public Observable<List<Manga>> getMangasWithUnread() {
+        return db.get()
+                .listOfObjects(Manga.class)
+                .withQuery(RawQuery.builder()
+                        .query(mangasWithUnreadQuery)
+                        .observesTables(MangasTable.TABLE, ChaptersTable.TABLE)
+                        .build())
+                .prepare()
+                .createObservable();
+    }
+
+    public Observable<PutResult> insertManga(Manga manga) {
+        return db.put()
+                .object(manga)
+                .prepare()
+                .createObservable();
+    }
+
+    public Observable<PutResults<Manga>> insertMangas(List<Manga> mangas) {
+        return db.put()
+                .objects(mangas)
+                .prepare()
+                .createObservable();
+    }
+
+    public Observable<DeleteResult> deleteManga(Manga manga) {
+        return db.delete()
+                .object(manga)
+                .prepare()
+                .createObservable();
+    }
+
+    public Observable<DeleteResults<Manga>> deleteMangas(List<Manga> mangas) {
+        return db.delete()
+                .objects(mangas)
+                .prepare()
+                .createObservable();
+    }
+}

+ 2 - 1
app/src/main/java/eu/kanade/mangafeed/data/tables/ChaptersTable.java

@@ -40,7 +40,8 @@ public class ChaptersTable {
 				+ COLUMN_DATE_UPLOAD + " LONG NOT NULL, "
 				+ "FOREIGN KEY(" + COLUMN_MANGA_ID + ") REFERENCES " + MangasTable.TABLE + "(" + MangasTable.COLUMN_ID + ") "
 				+ "ON DELETE CASCADE"
-				+ ");";
+				+ ");"
+				+ "CREATE INDEX " + TABLE + "_" + COLUMN_MANGA_ID + "_index ON " + TABLE + "(" + COLUMN_MANGA_ID + ");";
 	}
 	
 }

+ 6 - 4
app/src/main/java/eu/kanade/mangafeed/presenter/LibraryPresenter.java

@@ -11,6 +11,7 @@ import eu.kanade.mangafeed.data.helpers.PreferencesHelper;
 import eu.kanade.mangafeed.data.models.Manga;
 import eu.kanade.mangafeed.ui.activity.MangaDetailActivity;
 import eu.kanade.mangafeed.ui.adapter.LibraryAdapter;
+import eu.kanade.mangafeed.util.DummyDataUtil;
 import eu.kanade.mangafeed.view.LibraryView;
 import rx.Observable;
 import rx.schedulers.Schedulers;
@@ -32,8 +33,8 @@ public class LibraryPresenter extends BasePresenter {
 
         //TODO remove, only for testing
         if (prefs.isFirstRun()) {
-            db.manga.createDummyManga();
-            db.chapter.createDummyChapters();
+            db.insertMangas(DummyDataUtil.createDummyManga()).toBlocking().single();
+            db.insertChapters(DummyDataUtil.createDummyChapters()).subscribe();
             prefs.setNotFirstRun();
         }
 
@@ -52,10 +53,11 @@ public class LibraryPresenter extends BasePresenter {
         view.setAdapter(adapter);
         view.setMangaClickListener();
 
-        subscriptions.add(db.manga.getWithUnread()
+        subscriptions.add(db.getMangasWithUnread()
                         .observeOn(mainThread())
                         .subscribe(adapter::setNewItems)
         );
+
     }
 
     public void onQueryTextChange(String query) {
@@ -68,7 +70,7 @@ public class LibraryPresenter extends BasePresenter {
                 .map(checkedItems::keyAt)
                 .map(adapter::getItem)
                 .toList()
-                .flatMap(db.manga::delete)
+                .flatMap(db::deleteMangas)
                 .subscribe();
     }
 

+ 1 - 1
app/src/main/java/eu/kanade/mangafeed/presenter/MangaDetailPresenter.java

@@ -30,7 +30,7 @@ public class MangaDetailPresenter extends BasePresenter {
     }
 
     public void initializeChapters(Manga manga) {
-        db.chapter.get(manga)
+        db.getChapters(manga)
                 .subscribe(view::setChapters);
     }
 }

+ 28 - 36
app/src/main/java/eu/kanade/mangafeed/sources/Batoto.java

@@ -1,7 +1,6 @@
 package eu.kanade.mangafeed.sources;
 
 import com.squareup.okhttp.Headers;
-import com.squareup.okhttp.Response;
 
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
@@ -18,18 +17,17 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import eu.kanade.mangafeed.data.caches.CacheManager;
 import eu.kanade.mangafeed.data.helpers.NetworkHelper;
+import eu.kanade.mangafeed.data.helpers.SourceManager;
 import eu.kanade.mangafeed.data.models.Chapter;
 import eu.kanade.mangafeed.data.models.Manga;
 import rx.Observable;
-import rx.functions.Func1;
 import rx.schedulers.Schedulers;
-import timber.log.Timber;
 
-public class Batoto {
+public class Batoto extends Source {
 
     public static final String NAME = "Batoto (EN)";
     public static final String BASE_URL = "www.bato.to";
-    public static final String INITIAL_UPDATE_URL = "http://bato.to/search_ajax?order_cond=update&order=desc&p=1";
+    public static final String INITIAL_UPDATE_URL = "http://bato.to/search_ajax?order_cond=views&order=desc&p=1";
 
     private static final Headers REQUEST_HEADERS = constructRequestHeaders();
     private static Headers constructRequestHeaders() {
@@ -105,38 +103,32 @@ public class Batoto {
         return Observable.just(genres);
     }
 
-    /*
-    public Observable<UpdatePageMarker> pullLatestUpdatesFromNetwork(final UpdatePageMarker newUpdate) {
+    public String getUrlFromPageNumber(int page) {
+        if (page == 1)
+            return INITIAL_UPDATE_URL;
+
+        return INITIAL_UPDATE_URL.substring(0, INITIAL_UPDATE_URL.length() - 1) + page;
+    }
+
+    public Observable<List<Manga>> pullPopularMangasFromNetwork(int page) {
+        String url = getUrlFromPageNumber(page);
         return mNetworkService
-                .getResponse(newUpdate.getNextPageUrl(), NetworkModule.NULL_CACHE_CONTROL, REQUEST_HEADERS)
-                .flatMap(new Func1<Response, Observable<String>>() {
-                    @Override
-                    public Observable<String> call(Response response) {
-                        return mNetworkService.mapResponseToString(response);
-                    }
-                })
-                .flatMap(new Func1<String, Observable<UpdatePageMarker>>() {
-                    @Override
-                    public Observable<UpdatePageMarker> call(String unparsedHtml) {
-                        return Observable.just(parseHtmlToLatestUpdates(newUpdate.getNextPageUrl(), unparsedHtml));
-                    }
-                });
+                .getStringResponse(url, mNetworkService.NULL_CACHE_CONTROL, REQUEST_HEADERS)
+                .flatMap(response -> Observable.just(parseHtmlToLatestUpdates(response)));
     }
 
-    private UpdatePageMarker parseHtmlToLatestUpdates(String requestUrl, String unparsedHtml) {
+    private List<Manga> parseHtmlToLatestUpdates(String unparsedHtml) {
         Document parsedDocument = Jsoup.parse(unparsedHtml);
 
         List<Manga> updatedMangaList = scrapeUpdateMangasFromParsedDocument(parsedDocument);
-        updateLibraryInDatabase(updatedMangaList);
-
-        String nextPageUrl = findNextUrlFromParsedDocument(requestUrl, unparsedHtml);
-        int lastMangaPostion = updatedMangaList.size();
+        //updateLibraryInDatabase(updatedMangaList);
 
-        return new UpdatePageMarker(nextPageUrl, lastMangaPostion);
+        return updatedMangaList;
     }
 
+
     private List<Manga> scrapeUpdateMangasFromParsedDocument(Document parsedDocument) {
-        List<Manga> updatedMangaList = new ArrayList<Manga>();
+        List<Manga> updatedMangaList = new ArrayList<>();
 
         Elements updatedHtmlBlocks = parsedDocument.select("tr:not([id]):not([class])");
         for (Element currentHtmlBlock : updatedHtmlBlocks) {
@@ -149,29 +141,27 @@ public class Batoto {
     }
 
     private Manga constructMangaFromHtmlBlock(Element htmlBlock) {
-        Manga mangaFromHtmlBlock = DefaultFactory.Manga.constructDefault();
-        mangaFromHtmlBlock.setSource(NAME);
+        Manga mangaFromHtmlBlock = new Manga();
 
         Element urlElement = htmlBlock.select("a[href^=http://bato.to]").first();
         Element nameElement = urlElement;
         Element updateElement = htmlBlock.select("td").get(5);
 
+        mangaFromHtmlBlock.source = SourceManager.BATOTO;
+
         if (urlElement != null) {
             String fieldUrl = urlElement.attr("href");
-            mangaFromHtmlBlock.setUrl(fieldUrl);
+            mangaFromHtmlBlock.url = fieldUrl;
         }
         if (nameElement != null) {
             String fieldName = nameElement.text().trim();
-            mangaFromHtmlBlock.setName(fieldName);
+            mangaFromHtmlBlock.title = fieldName;
         }
         if (updateElement != null) {
             long fieldUpdate = parseUpdateFromElement(updateElement);
-            mangaFromHtmlBlock.setUpdated(fieldUpdate);
+            mangaFromHtmlBlock.last_update = fieldUpdate;
         }
 
-        int updateCount = 1;
-        mangaFromHtmlBlock.setUpdateCount(updateCount);
-
         return mangaFromHtmlBlock;
     }
 
@@ -186,9 +176,11 @@ public class Batoto {
             // Do Nothing.
         }
 
-        return DefaultFactory.Manga.DEFAULT_UPDATED;
+        return 0;
     }
 
+    /*
+
     private void updateLibraryInDatabase(List<Manga> mangaList) {
         mQueryManager.beginLibraryTransaction();
         try {

+ 5 - 0
app/src/main/java/eu/kanade/mangafeed/sources/Source.java

@@ -0,0 +1,5 @@
+package eu.kanade.mangafeed.sources;
+
+
+public class Source {
+}

+ 52 - 0
app/src/main/java/eu/kanade/mangafeed/util/DummyDataUtil.java

@@ -0,0 +1,52 @@
+package eu.kanade.mangafeed.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.kanade.mangafeed.data.models.Chapter;
+import eu.kanade.mangafeed.data.models.Manga;
+
+/**
+ * Created by len on 8/10/15.
+ */
+public class DummyDataUtil {
+
+    public static List<Manga> createDummyManga() {
+        ArrayList<Manga> mangas = new ArrayList<>();
+        mangas.add(createDummyManga("One Piece"));
+        mangas.add(createDummyManga("Berserk"));
+        mangas.add(createDummyManga("Horimiya"));
+        mangas.add(createDummyManga("Übel Blatt"));
+
+        return mangas;
+    }
+
+    private static Manga createDummyManga(String title) {
+        Manga m = new Manga();
+        m.title = title;
+        m.url="http://example.com";
+        m.artist="Eiichiro Oda";
+        m.author="Eiichiro Oda";
+        m.description="...";
+        m.genre="Action, Drama";
+        m.status="Ongoing";
+        m.thumbnail_url="http://example.com/pic.png";
+        return m;
+    }
+
+    public static List<Chapter> createDummyChapters() {
+        List<Chapter> chapters = new ArrayList<>();
+        Chapter c;
+
+        for (int i = 1; i < 50; i++) {
+            c = new Chapter();
+            c.manga_id = 1L;
+            c.name = "Chapter " + i;
+            c.url = "http://example.com/1";
+            chapters.add(c);
+        }
+
+        return chapters;
+    }
+
+}