Browse Source

New source (unfinished)

inorichi 9 years ago
parent
commit
e74f81d41a

+ 7 - 2
app/src/main/java/eu/kanade/mangafeed/data/helpers/SourceManager.java

@@ -7,13 +7,15 @@ import java.util.HashMap;
 import java.util.List;
 
 import eu.kanade.mangafeed.sources.Batoto;
-import eu.kanade.mangafeed.sources.MangaHere;
+import eu.kanade.mangafeed.sources.Mangahere;
+import eu.kanade.mangafeed.sources.Mangafox;
 import eu.kanade.mangafeed.sources.base.Source;
 
 public class SourceManager {
 
     public static final int BATOTO = 1;
     public static final int MANGAHERE = 2;
+    public static final int MANGAFOX = 3;
 
     private HashMap<Integer, Source> mSourcesMap;
     private Context context;
@@ -37,7 +39,9 @@ public class SourceManager {
             case BATOTO:
                 return new Batoto(context);
             case MANGAHERE:
-                return new MangaHere(context);
+                return new Mangahere(context);
+            case MANGAFOX:
+                return new Mangafox(context);
         }
 
         return null;
@@ -46,6 +50,7 @@ public class SourceManager {
     private void initializeSources() {
         mSourcesMap.put(BATOTO, createSource(BATOTO));
         mSourcesMap.put(MANGAHERE, createSource(MANGAHERE));
+        mSourcesMap.put(MANGAFOX, createSource(MANGAFOX));
     }
 
     public List<Source> getSources() {

+ 18 - 22
app/src/main/java/eu/kanade/mangafeed/presenter/CataloguePresenter.java

@@ -4,7 +4,6 @@ import android.os.Bundle;
 
 import com.pushtorefresh.storio.sqlite.operations.put.PutResult;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
@@ -40,8 +39,8 @@ public class CataloguePresenter extends BasePresenter<CatalogueFragment> {
 
     private Subscription mQueryDebouncerSubscription;
     private Subscription mMangaDetailFetchSubscription;
-    private PublishSubject<Observable<String>> mQueryDebouncerSubject;
-    private PublishSubject<Observable<List<Manga>>> mMangaDetailPublishSubject;
+    private PublishSubject<String> mQueryDebouncerSubject;
+    private PublishSubject<List<Manga>> mMangaDetailPublishSubject;
 
     private static final int GET_MANGA_LIST = 1;
 
@@ -59,7 +58,7 @@ public class CataloguePresenter extends BasePresenter<CatalogueFragment> {
                     view.hideProgressBar();
                     view.onAddPage(page);
                     if (mMangaDetailPublishSubject != null)
-                        mMangaDetailPublishSubject.onNext(Observable.just(page.data));
+                        mMangaDetailPublishSubject.onNext(page.data);
                 });
 
         initializeSearch();
@@ -130,7 +129,7 @@ public class CataloguePresenter extends BasePresenter<CatalogueFragment> {
         mSearchMode = false;
         mQueryDebouncerSubject = PublishSubject.create();
 
-        add(mQueryDebouncerSubscription = Observable.switchOnNext(mQueryDebouncerSubject)
+        add(mQueryDebouncerSubscription = mQueryDebouncerSubject
                 .debounce(SEARCH_TIMEOUT, TimeUnit.MILLISECONDS)
                 .subscribeOn(Schedulers.io())
                 .observeOn(AndroidSchedulers.mainThread())
@@ -143,25 +142,12 @@ public class CataloguePresenter extends BasePresenter<CatalogueFragment> {
 
         mMangaDetailPublishSubject = PublishSubject.create();
 
-        add(mMangaDetailFetchSubscription = Observable.switchOnNext(mMangaDetailPublishSubject)
+        add(mMangaDetailFetchSubscription = mMangaDetailPublishSubject
                 .subscribeOn(Schedulers.io())
                 .flatMap(Observable::from)
                 .filter(manga -> !manga.initialized)
-                .buffer(3)
-                .concatMap(localMangas -> {
-                    List<Observable<Manga>> mangaObservables = new ArrayList<>();
-                    for (Manga manga : localMangas) {
-                        Observable<Manga> tempObs = selectedSource.pullMangaFromNetwork(manga.url)
-                                .subscribeOn(Schedulers.io())
-                                .flatMap(networkManga -> {
-                                    Manga.copyFromNetwork(manga, networkManga);
-                                    db.insertManga(manga).executeAsBlocking();
-                                    return Observable.just(manga);
-                                });
-                        mangaObservables.add(tempObs);
-                    }
-                    return Observable.merge(mangaObservables);
-                })
+                .window(3)
+                .concatMap(pack -> pack.concatMap(this::getMangaDetails))
                 .filter(manga -> manga.initialized)
                 .onBackpressureBuffer()
                 .observeOn(AndroidSchedulers.mainThread())
@@ -171,12 +157,22 @@ public class CataloguePresenter extends BasePresenter<CatalogueFragment> {
                 }));
     }
 
+    private Observable<Manga> getMangaDetails(final Manga manga) {
+        return selectedSource.pullMangaFromNetwork(manga.url)
+                .subscribeOn(Schedulers.io())
+                .flatMap(networkManga -> {
+                    Manga.copyFromNetwork(manga, networkManga);
+                    db.insertManga(manga).executeAsBlocking();
+                    return Observable.just(manga);
+                });
+    }
+
     public void onSearchEvent(String query, boolean now) {
         // If the query is empty or not debounced, resolve it instantly
         if (now || query.equals(""))
             queryFromSearch(query);
         else if (mQueryDebouncerSubject != null)
-            mQueryDebouncerSubject.onNext(Observable.just(query));
+            mQueryDebouncerSubject.onNext(query);
     }
 
     private void queryFromSearch(String query) {

+ 179 - 0
app/src/main/java/eu/kanade/mangafeed/sources/Mangafox.java

@@ -0,0 +1,179 @@
+package eu.kanade.mangafeed.sources;
+
+import android.content.Context;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import eu.kanade.mangafeed.data.helpers.SourceManager;
+import eu.kanade.mangafeed.data.models.Chapter;
+import eu.kanade.mangafeed.data.models.Manga;
+import eu.kanade.mangafeed.sources.base.Source;
+
+public class Mangafox extends Source {
+
+    public static final String NAME = "Mangafox (EN)";
+
+    private static final String INITIAL_UPDATE_URL = "http://mangafox.me/directory/";
+    private static final String INITIAL_SEARCH_URL =
+            "http://mangafox.me/search.php?name_method=cw&advopts=1&order=az&sort=name";
+
+    public Mangafox(Context context) {
+        super(context);
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    @Override
+    public int getSourceId() {
+        return SourceManager.MANGAFOX;
+    }
+
+    @Override
+    public boolean isLoginRequired() {
+        return false;
+    }
+
+    @Override
+    protected String getUrlFromPageNumber(int page) {
+        return INITIAL_UPDATE_URL + page + ".htm";
+    }
+
+    @Override
+    public List<Manga> parsePopularMangasFromHtml(String unparsedHtml) {
+        Document parsedDocument = Jsoup.parse(unparsedHtml);
+
+        List<Manga> mangaList = new ArrayList<>();
+
+        Elements mangaHtmlBlocks = parsedDocument.select("div#mangalist > ul.list > li");
+        for (Element currentHtmlBlock : mangaHtmlBlocks) {
+            Manga currentManga = constructPopularMangaFromHtmlBlock(currentHtmlBlock);
+            mangaList.add(currentManga);
+        }
+
+        return mangaList;
+    }
+
+    private Manga constructPopularMangaFromHtmlBlock(Element htmlBlock) {
+        Manga mangaFromHtmlBlock = new Manga();
+        mangaFromHtmlBlock.source = getSourceId();
+
+        Element urlElement = htmlBlock.select("a.title").first();
+
+        if (urlElement != null) {
+            mangaFromHtmlBlock.url = urlElement.attr("href");
+            mangaFromHtmlBlock.title = urlElement.text();
+        }
+
+        return mangaFromHtmlBlock;
+    }
+
+    @Override
+    protected String getSearchUrl(String query, int page) {
+        return INITIAL_SEARCH_URL + "&name=" + query + "&page=" + page;
+    }
+
+    @Override
+    protected List<Manga> parseSearchFromHtml(String unparsedHtml) {
+        Document parsedDocument = Jsoup.parse(unparsedHtml);
+
+        List<Manga> mangaList = new ArrayList<>();
+
+        Elements mangaHtmlBlocks = parsedDocument.select("table#listing > tbody > tr:gt(0)");
+        for (Element currentHtmlBlock : mangaHtmlBlocks) {
+            Manga currentManga = constructSearchMangaFromHtmlBlock(currentHtmlBlock);
+            mangaList.add(currentManga);
+        }
+
+        return mangaList;
+    }
+
+    private Manga constructSearchMangaFromHtmlBlock(Element htmlBlock) {
+        Manga mangaFromHtmlBlock = new Manga();
+        mangaFromHtmlBlock.source = getSourceId();
+
+        Element urlElement = htmlBlock.select("a.series_preview").first();
+
+        if (urlElement != null) {
+            mangaFromHtmlBlock.url = urlElement.attr("href");
+            mangaFromHtmlBlock.title = urlElement.text();
+        }
+
+        return mangaFromHtmlBlock;
+    }
+
+    @Override
+    protected Manga parseHtmlToManga(String mangaUrl, String unparsedHtml) {
+        Document parsedDocument = Jsoup.parse(unparsedHtml);
+
+        Element infoElement = parsedDocument.select("div#title").first();
+        Element titleElement = infoElement.select("h2 > a").first();
+        Element rowElement = infoElement.select("table > tbody > tr:eq(1)").first();
+        Element authorElement = rowElement.select("td:eq(1)").first();
+        Element artistElement = rowElement.select("td:eq(2)").first();
+        Element genreElement = rowElement.select("td:eq(3)").first();
+        Element descriptionElement = infoElement.select("p.summary").first();
+        Element thumbnailUrlElement = parsedDocument.select("div.cover > img").first();
+
+        Manga newManga = new Manga();
+        newManga.url = mangaUrl;
+
+        if (titleElement != null) {
+            String title = titleElement.text();
+            // Strip the last word
+            title = title.substring(0, title.lastIndexOf(" "));
+            newManga.title = title;
+        }
+        if (artistElement != null) {
+            String fieldArtist = artistElement.text();
+            newManga.artist = fieldArtist;
+        }
+        if (authorElement != null) {
+            String fieldAuthor = authorElement.text();
+            newManga.author = fieldAuthor;
+        }
+        if (descriptionElement != null) {
+            String fieldDescription = descriptionElement.text();
+            newManga.description = fieldDescription;
+        }
+        if (genreElement != null) {
+            String fieldGenre = genreElement.text();
+            newManga.genre = fieldGenre;
+        }
+        if (thumbnailUrlElement != null) {
+            String fieldThumbnailUrl = thumbnailUrlElement.attr("src");
+            newManga.thumbnail_url = fieldThumbnailUrl;
+        }
+//        if (statusElement != null) {
+//            boolean fieldCompleted = statusElement.text().contains("Completed");
+//            newManga.status = fieldCompleted + "";
+//        }
+
+        newManga.initialized = true;
+
+        return newManga;
+    }
+
+    @Override
+    protected List<Chapter> parseHtmlToChapters(String unparsedHtml) {
+        return null;
+    }
+
+    @Override
+    protected List<String> parseHtmlToPageUrls(String unparsedHtml) {
+        return null;
+    }
+
+    @Override
+    protected String parseHtmlToImageUrl(String unparsedHtml) {
+        return null;
+    }
+}

+ 38 - 25
app/src/main/java/eu/kanade/mangafeed/sources/MangaHere.java → app/src/main/java/eu/kanade/mangafeed/sources/Mangahere.java

@@ -21,15 +21,15 @@ import eu.kanade.mangafeed.data.models.Manga;
 import eu.kanade.mangafeed.sources.base.Source;
 import rx.Observable;
 
-public class MangaHere extends Source {
+public class Mangahere extends Source {
 
-    public static final String NAME = "MangaHere (EN)";
+    public static final String NAME = "Mangahere (EN)";
     public static final String BASE_URL = "www.mangahere.co";
 
-    private static final String INITIAL_UPDATE_URL = "http://www.mangahere.co/latest/";
+    private static final String INITIAL_UPDATE_URL = "http://www.mangahere.co/directory/";
     private static final String INITIAL_SEARCH_URL = "http://www.mangahere.co/search.php?";
 
-    public MangaHere(Context context) {
+    public Mangahere(Context context) {
         super(context);
     }
 
@@ -45,7 +45,7 @@ public class MangaHere extends Source {
 
     @Override
     protected String getUrlFromPageNumber(int page) {
-        return INITIAL_UPDATE_URL + page + "/";
+        return INITIAL_UPDATE_URL + page + ".htm?views.za";
     }
 
     @Override
@@ -101,42 +101,55 @@ public class MangaHere extends Source {
     public List<Manga> parsePopularMangasFromHtml(String unparsedHtml) {
         Document parsedDocument = Jsoup.parse(unparsedHtml);
 
-        List<Manga> updatedMangaList = new ArrayList<>();
+        List<Manga> mangaList = new ArrayList<>();
 
-        Elements updatedHtmlBlocks = parsedDocument.select("div.manga_updates dl");
-        for (Element currentHtmlBlock : updatedHtmlBlocks) {
-            Manga currentlyUpdatedManga = constructMangaFromHtmlBlock(currentHtmlBlock);
+        Elements mangaHtmlBlocks = parsedDocument.select("div.directory_list > ul > li");
+        for (Element currentHtmlBlock : mangaHtmlBlocks) {
+            Manga currentManga = constructPopularMangaFromHtmlBlock(currentHtmlBlock);
+            mangaList.add(currentManga);
+        }
+
+        return mangaList;
+    }
+
+    private Manga constructPopularMangaFromHtmlBlock(Element htmlBlock) {
+        Manga mangaFromHtmlBlock = new Manga();
+        mangaFromHtmlBlock.source = getSourceId();
+
+        Element urlElement = htmlBlock.select("div.title > a").first();
 
-            updatedMangaList.add(currentlyUpdatedManga);
+        if (urlElement != null) {
+            mangaFromHtmlBlock.url = urlElement.attr("href");
+            mangaFromHtmlBlock.title = urlElement.attr("title");
         }
 
-        return updatedMangaList;
+        return mangaFromHtmlBlock;
     }
 
     @Override
     protected List<Manga> parseSearchFromHtml(String unparsedHtml) {
-        return null;
+        Document parsedDocument = Jsoup.parse(unparsedHtml);
+
+        List<Manga> mangaList = new ArrayList<>();
+
+        Elements mangaHtmlBlocks = parsedDocument.select("div.result_search > dl");
+        for (Element currentHtmlBlock : mangaHtmlBlocks) {
+            Manga currentManga = constructSearchMangaFromHtmlBlock(currentHtmlBlock);
+            mangaList.add(currentManga);
+        }
+
+        return mangaList;
     }
 
-    private Manga constructMangaFromHtmlBlock(Element htmlBlock) {
+    private Manga constructSearchMangaFromHtmlBlock(Element htmlBlock) {
         Manga mangaFromHtmlBlock = new Manga();
         mangaFromHtmlBlock.source = getSourceId();
 
         Element urlElement = htmlBlock.select("a.manga_info").first();
-        Element nameElement = htmlBlock.select("a.manga_info").first();
-        Element updateElement = htmlBlock.select("span.time").first();
 
         if (urlElement != null) {
-            String fieldUrl = urlElement.attr("href");
-            mangaFromHtmlBlock.url = fieldUrl;
-        }
-        if (nameElement != null) {
-            String fieldName = nameElement.text();
-            mangaFromHtmlBlock.title = fieldName;
-        }
-        if (updateElement != null) {
-            long fieldUpdate = parseUpdateFromElement(updateElement);
-            mangaFromHtmlBlock.last_update = fieldUpdate;
+            mangaFromHtmlBlock.url = urlElement.attr("href");
+            mangaFromHtmlBlock.title = urlElement.text();
         }
 
         return mangaFromHtmlBlock;

+ 1 - 3
app/src/main/java/eu/kanade/mangafeed/sources/base/Source.java

@@ -85,9 +85,7 @@ public abstract class Source extends BaseSource {
         return Observable.from(pages)
                 .filter(page -> page.getImageUrl() == null)
                 .window(overrideNumberOfConcurrentPageDownloads())
-                .concatMap(batchedPages ->
-                                batchedPages.concatMap(this::getImageUrlFromPage)
-                );
+                .concatMap(batchedPages -> batchedPages.concatMap(this::getImageUrlFromPage));
     }
 
     private Observable<Page> getImageUrlFromPage(final Page page) {

+ 3 - 3
app/src/main/java/eu/kanade/mangafeed/ui/activity/MainActivity.java

@@ -46,9 +46,9 @@ public class MainActivity extends BaseActivity {
                         new PrimaryDrawerItem()
                                 .withName(R.string.library_title)
                                 .withIdentifier(R.id.nav_drawer_library),
-                        new PrimaryDrawerItem()
-                                .withName(R.string.recent_updates_title)
-                                .withIdentifier(R.id.nav_drawer_recent_updates),
+//                        new PrimaryDrawerItem()
+//                                .withName(R.string.recent_updates_title)
+//                                .withIdentifier(R.id.nav_drawer_recent_updates),
                         new PrimaryDrawerItem()
                                 .withName(R.string.catalogues_title)
                                 .withIdentifier(R.id.nav_drawer_catalogues),