Create an util class to write less code on sources. Save status from sources.

This commit is contained in:
inorichi 2016-01-01 21:02:13 +01:00
parent 4d9cd6cb6e
commit 986572f6cb
10 changed files with 297 additions and 464 deletions

View File

@ -60,8 +60,19 @@ public class Manga implements Serializable {
public int category; public int category;
public static final int UNKNOWN = 0;
public static final int ONGOING = 1;
public static final int COMPLETED = 2;
public static final int LICENSED = 3;
public Manga() {} public Manga() {}
public static Manga create(String pathUrl) {
Manga m = new Manga();
m.url = pathUrl;
return m;
}
public void setUrl(String url) { public void setUrl(String url) {
this.url = UrlUtil.getPath(url); this.url = UrlUtil.getPath(url);
} }

View File

@ -2,6 +2,7 @@ package eu.kanade.mangafeed.data.network;
import com.squareup.okhttp.CacheControl; import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.Headers; import com.squareup.okhttp.Headers;
import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request; import com.squareup.okhttp.Request;
@ -21,6 +22,7 @@ public final class NetworkHelper {
public final CacheControl NULL_CACHE_CONTROL = new CacheControl.Builder().noCache().build(); public final CacheControl NULL_CACHE_CONTROL = new CacheControl.Builder().noCache().build();
public final Headers NULL_HEADERS = new Headers.Builder().build(); public final Headers NULL_HEADERS = new Headers.Builder().build();
public final RequestBody NULL_REQUEST_BODY = new FormEncodingBuilder().build();
public NetworkHelper() { public NetworkHelper() {
client = new OkHttpClient(); client = new OkHttpClient();
@ -65,7 +67,7 @@ public final class NetworkHelper {
try { try {
Request request = new Request.Builder() Request request = new Request.Builder()
.url(url) .url(url)
.post(formBody) .post(formBody != null ? formBody : NULL_REQUEST_BODY)
.headers(headers != null ? headers : NULL_HEADERS) .headers(headers != null ? headers : NULL_HEADERS)
.build(); .build();
return Observable.just(client.newCall(request).execute()); return Observable.just(client.newCall(request).execute());

View File

@ -0,0 +1,17 @@
package eu.kanade.mangafeed.data.source.base;
import android.content.Context;
public abstract class LoginSource extends Source {
public LoginSource() {}
public LoginSource(Context context) {
super(context);
}
@Override
public boolean isLoginRequired() {
return true;
}
}

View File

@ -42,6 +42,11 @@ public abstract class Source extends BaseSource {
glideHeaders = glideHeadersBuilder().build(); glideHeaders = glideHeadersBuilder().build();
} }
@Override
public boolean isLoginRequired() {
return false;
}
// Get the most popular mangas from the source // Get the most popular mangas from the source
public Observable<MangasPage> pullPopularMangasFromNetwork(MangasPage page) { public Observable<MangasPage> pullPopularMangasFromNetwork(MangasPage page) {
if (page.page == 1) if (page.page == 1)
@ -95,8 +100,8 @@ public abstract class Source extends BaseSource {
return networkService return networkService
.getStringResponse(getBaseUrl() + overrideChapterUrl(chapterUrl), requestHeaders, null) .getStringResponse(getBaseUrl() + overrideChapterUrl(chapterUrl), requestHeaders, null)
.flatMap(unparsedHtml -> { .flatMap(unparsedHtml -> {
List<String> pageUrls = parseHtmlToPageUrls(unparsedHtml); List<Page> pages = convertToPages(parseHtmlToPageUrls(unparsedHtml));
return Observable.just(getFirstImageFromPageUrls(pageUrls, unparsedHtml)); return Observable.just(parseFirstPage(pages, unparsedHtml));
}); });
} }
@ -182,8 +187,7 @@ public abstract class Source extends BaseSource {
return pages; return pages;
} }
protected List<Page> getFirstImageFromPageUrls(List<String> pageUrls, String unparsedHtml) { protected List<Page> parseFirstPage(List<Page> pages, String unparsedHtml) {
List<Page> pages = convertToPages(pageUrls);
String firstImage = parseHtmlToImageUrl(unparsedHtml); String firstImage = parseHtmlToImageUrl(unparsedHtml);
pages.get(0).setImageUrl(firstImage); pages.get(0).setImageUrl(firstImage);
return pages; return pages;

View File

@ -2,6 +2,7 @@ package eu.kanade.mangafeed.data.source.online.english;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.text.TextUtils;
import com.squareup.okhttp.FormEncodingBuilder; import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.Headers; import com.squareup.okhttp.Headers;
@ -30,12 +31,13 @@ import java.util.regex.Pattern;
import eu.kanade.mangafeed.data.database.models.Chapter; import eu.kanade.mangafeed.data.database.models.Chapter;
import eu.kanade.mangafeed.data.database.models.Manga; import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.data.source.SourceManager; import eu.kanade.mangafeed.data.source.SourceManager;
import eu.kanade.mangafeed.data.source.base.Source; import eu.kanade.mangafeed.data.source.base.LoginSource;
import eu.kanade.mangafeed.data.source.model.MangasPage; import eu.kanade.mangafeed.data.source.model.MangasPage;
import eu.kanade.mangafeed.data.source.model.Page; import eu.kanade.mangafeed.data.source.model.Page;
import eu.kanade.mangafeed.util.Parser;
import rx.Observable; import rx.Observable;
public class Batoto extends Source { public class Batoto extends LoginSource {
public static final String NAME = "Batoto (EN)"; public static final String NAME = "Batoto (EN)";
public static final String BASE_URL = "http://bato.to"; public static final String BASE_URL = "http://bato.to";
@ -87,56 +89,6 @@ public class Batoto extends Source {
return builder; return builder;
} }
public Observable<List<String>> getGenres() {
List<String> genres = new ArrayList<>(38);
genres.add("4-Koma");
genres.add("Action");
genres.add("Adventure");
genres.add("Award Winning");
genres.add("Comedy");
genres.add("Cooking");
genres.add("Doujinshi");
genres.add("Drama");
genres.add("Ecchi");
genres.add("Fantasy");
genres.add("Gender Bender");
genres.add("Harem");
genres.add("Historical");
genres.add("Horror");
genres.add("Josei");
genres.add("Martial Arts");
genres.add("Mecha");
genres.add("Medical");
genres.add("Music");
genres.add("Mystery");
genres.add("One Shot");
genres.add("Psychological");
genres.add("Romance");
genres.add("School Life");
genres.add("Sci-fi");
genres.add("Seinen");
genres.add("Shoujo");
genres.add("Shoujo Ai");
genres.add("Shounen");
genres.add("Shounen Ai");
genres.add("Slice of Life");
genres.add("Smut");
genres.add("Sports");
genres.add("Supernatural");
genres.add("Tragedy");
genres.add("Webtoon");
genres.add("Yaoi");
genres.add("Yuri");
return Observable.just(genres);
}
@Override
public boolean isLoginRequired() {
return true;
}
@Override @Override
public String getInitialPopularMangasUrl() { public String getInitialPopularMangasUrl() {
return String.format(POPULAR_MANGAS_URL, 1); return String.format(POPULAR_MANGAS_URL, 1);
@ -167,140 +119,88 @@ public class Batoto extends Source {
return String.format(PAGE_URL, id, defaultPageUrl.substring(end+1)); return String.format(PAGE_URL, id, defaultPageUrl.substring(end+1));
} }
@Override private List<Manga> parseMangasFromHtml(Document parsedHtml) {
protected List<Manga> parsePopularMangasFromHtml(Document parsedHtml) {
if (parsedHtml.text().contains("No (more) comics found!")) {
return new ArrayList<>();
}
List<Manga> mangaList = new ArrayList<>(); List<Manga> mangaList = new ArrayList<>();
Elements updatedHtmlBlocks = parsedHtml.select("tr:not([id]):not([class])"); if (!parsedHtml.text().contains("No (more) comics found!")) {
for (Element currentHtmlBlock : updatedHtmlBlocks) { for (Element currentHtmlBlock : parsedHtml.select("tr:not([id]):not([class])")) {
Manga currentlyUpdatedManga = constructMangaFromHtmlBlock(currentHtmlBlock); Manga manga = constructMangaFromHtmlBlock(currentHtmlBlock);
mangaList.add(manga);
mangaList.add(currentlyUpdatedManga); }
}
return mangaList;
} }
return mangaList; @Override
protected List<Manga> parsePopularMangasFromHtml(Document parsedHtml) {
return parseMangasFromHtml(parsedHtml);
} }
@Override @Override
protected String parseNextPopularMangasUrl(Document parsedHtml, MangasPage page) { protected String parseNextPopularMangasUrl(Document parsedHtml, MangasPage page) {
Element next = parsedHtml.select("#show_more_row").first(); Element next = Parser.element(parsedHtml, "#show_more_row");
if (next == null) return next != null ? String.format(POPULAR_MANGAS_URL, page.page + 1) : null;
return null;
return String.format(POPULAR_MANGAS_URL, page.page + 1);
} }
@Override @Override
protected List<Manga> parseSearchFromHtml(Document parsedHtml) { protected List<Manga> parseSearchFromHtml(Document parsedHtml) {
if (parsedHtml.text().contains("No (more) comics found!")) { return parseMangasFromHtml(parsedHtml);
return new ArrayList<>();
}
List<Manga> mangaList = new ArrayList<>();
Elements updatedHtmlBlocks = parsedHtml.select("tr:not([id]):not([class])");
for (Element currentHtmlBlock : updatedHtmlBlocks) {
Manga currentlyUpdatedManga = constructMangaFromHtmlBlock(currentHtmlBlock);
mangaList.add(currentlyUpdatedManga);
}
return mangaList;
} }
private Manga constructMangaFromHtmlBlock(Element htmlBlock) { private Manga constructMangaFromHtmlBlock(Element htmlBlock) {
Manga mangaFromHtmlBlock = new Manga(); Manga manga = new Manga();
manga.source = getId();
Element urlElement = htmlBlock.select("a[href^=http://bato.to]").first();
Element updateElement = htmlBlock.select("td").get(5);
mangaFromHtmlBlock.source = getId();
Element urlElement = Parser.element(htmlBlock, "a[href^=http://bato.to]");
if (urlElement != null) { if (urlElement != null) {
mangaFromHtmlBlock.setUrl(urlElement.attr("href")); manga.setUrl(urlElement.attr("href"));
mangaFromHtmlBlock.title = urlElement.text().trim(); manga.title = urlElement.text().trim();
} }
if (updateElement != null) { return manga;
mangaFromHtmlBlock.last_update = parseUpdateFromElement(updateElement);
}
return mangaFromHtmlBlock;
} }
@Override @Override
protected String parseNextSearchUrl(Document parsedHtml, MangasPage page, String query) { protected String parseNextSearchUrl(Document parsedHtml, MangasPage page, String query) {
Element next = parsedHtml.select("#show_more_row").first(); Element next = Parser.element(parsedHtml, "#show_more_row");
if (next == null) return next != null ? String.format(SEARCH_URL, query, page.page + 1) : null;
return null;
return String.format(SEARCH_URL, query, page.page + 1);
}
private long parseUpdateFromElement(Element updateElement) {
String updatedDateAsString = updateElement.text();
try {
Date specificDate = new SimpleDateFormat("dd MMMMM yyyy - hh:mm a", Locale.ENGLISH).parse(updatedDateAsString);
return specificDate.getTime();
} catch (ParseException e) {
// Do Nothing.
}
return 0;
} }
@Override @Override
protected Manga parseHtmlToManga(String mangaUrl, String unparsedHtml) { protected Manga parseHtmlToManga(String mangaUrl, String unparsedHtml) {
Document parsedDocument = Jsoup.parse(unparsedHtml); Document parsedDocument = Jsoup.parse(unparsedHtml);
Elements artistElements = parsedDocument.select("a[href^=http://bato.to/search?artist_name]"); Element tbody = parsedDocument.select("tbody").first();
Element descriptionElement = parsedDocument.select("tr").get(5); Element artistElement = tbody.select("tr:contains(Author/Artist:)").first();
Elements genreElements = parsedDocument.select("img[src=http://bato.to/forums/public/style_images/master/bullet_black.png]"); Elements genreElements = tbody.select("tr:contains(Genres:) img");
Element thumbnailUrlElement = parsedDocument.select("img[src^=http://img.bato.to/forums/uploads/]").first();
Manga newManga = new Manga(); Manga manga = Manga.create(mangaUrl);
newManga.url = mangaUrl; manga.author = Parser.text(artistElement, "td:eq(1)");
manga.artist = Parser.text(artistElement, "td:eq(2)", manga.author);
manga.description = Parser.text(tbody, "tr:contains(Description:) > td:eq(1)");
manga.thumbnail_url = Parser.src(parsedDocument, "img[src^=http://img.bato.to/forums/uploads/]");
manga.status = parseStatus(Parser.text(parsedDocument, "tr:contains(Status:) > td:eq(1)"));
if (artistElements != null) { if (!genreElements.isEmpty()) {
newManga.author = artistElements.get(0).text(); List<String> genres = new ArrayList<>();
if (artistElements.size() > 1) { for (Element element : genreElements) {
newManga.artist = artistElements.get(1).text(); genres.add(element.attr("alt"));
} else {
newManga.artist = newManga.author;
} }
} manga.genre = TextUtils.join(", ", genres);
if (descriptionElement != null) {
newManga.description = descriptionElement.text().substring("Description:".length()).trim();
}
if (genreElements != null) {
String fieldGenres = "";
for (int index = 0; index < genreElements.size(); index++) {
String currentGenre = genreElements.get(index).attr("alt");
if (index < genreElements.size() - 1) {
fieldGenres += currentGenre + ", ";
} else {
fieldGenres += currentGenre;
}
}
newManga.genre = fieldGenres;
}
if (thumbnailUrlElement != null) {
newManga.thumbnail_url = thumbnailUrlElement.attr("src");
} }
boolean fieldCompleted = unparsedHtml.contains("<td>Complete</td>"); manga.initialized = true;
//TODO fix return manga;
newManga.status = 0; }
newManga.initialized = true; private int parseStatus(String status) {
switch (status) {
return newManga; case "Ongoing":
return Manga.ONGOING;
case "Complete":
return Manga.COMPLETED;
default:
return Manga.UNKNOWN;
}
} }
@Override @Override
@ -311,34 +211,30 @@ public class Batoto extends Source {
Elements chapterElements = parsedDocument.select("tr.row.lang_English.chapter_row"); Elements chapterElements = parsedDocument.select("tr.row.lang_English.chapter_row");
for (Element chapterElement : chapterElements) { for (Element chapterElement : chapterElements) {
Chapter currentChapter = constructChapterFromHtmlBlock(chapterElement); Chapter chapter = constructChapterFromHtmlBlock(chapterElement);
chapterList.add(currentChapter); chapterList.add(chapter);
} }
//saveChaptersToDatabase(chapterList, mangaUrl);
return chapterList; return chapterList;
} }
private Chapter constructChapterFromHtmlBlock(Element chapterElement) { private Chapter constructChapterFromHtmlBlock(Element chapterElement) {
Chapter newChapter = Chapter.create(); Chapter chapter = Chapter.create();
Element urlElement = chapterElement.select("a[href^=http://bato.to/reader").first(); Element urlElement = chapterElement.select("a[href^=http://bato.to/reader").first();
Element dateElement = chapterElement.select("td").get(4); Element dateElement = chapterElement.select("td").get(4);
if (urlElement != null) { if (urlElement != null) {
String fieldUrl = urlElement.attr("href"); String fieldUrl = urlElement.attr("href");
newChapter.setUrl(fieldUrl); chapter.setUrl(fieldUrl);
newChapter.name = urlElement.text().trim(); chapter.name = urlElement.text().trim();
} }
if (dateElement != null) { if (dateElement != null) {
newChapter.date_upload = parseDateFromElement(dateElement); chapter.date_upload = parseDateFromElement(dateElement);
} }
newChapter.date_fetch = new Date().getTime(); chapter.date_fetch = new Date().getTime();
return newChapter; return chapter;
} }
private long parseDateFromElement(Element dateElement) { private long parseDateFromElement(Element dateElement) {
@ -372,8 +268,7 @@ public class Batoto extends Source {
List<String> pageUrlList = new ArrayList<>(); List<String> pageUrlList = new ArrayList<>();
Element selectElement = parsedDocument.select("#page_select").first(); Element selectElement = Parser.element(parsedDocument, "#page_select");
if (selectElement != null) { if (selectElement != null) {
for (Element pageUrlElement : selectElement.select("option")) { for (Element pageUrlElement : selectElement.select("option")) {
pageUrlList.add(pageUrlElement.attr("value")); pageUrlList.add(pageUrlElement.attr("value"));
@ -389,8 +284,7 @@ public class Batoto extends Source {
} }
@Override @Override
protected List<Page> getFirstImageFromPageUrls(List<String> pageUrls, String unparsedHtml) { protected List<Page> parseFirstPage(List<Page> pages, String unparsedHtml) {
List<Page> pages = convertToPages(pageUrls);
if (!unparsedHtml.contains("Want to see this chapter per page instead?")) { if (!unparsedHtml.contains("Want to see this chapter per page instead?")) {
String firstImage = parseHtmlToImageUrl(unparsedHtml); String firstImage = parseHtmlToImageUrl(unparsedHtml);
pages.get(0).setImageUrl(firstImage); pages.get(0).setImageUrl(firstImage);
@ -412,9 +306,7 @@ public class Batoto extends Source {
String trimmedHtml = unparsedHtml.substring(beginIndex, endIndex); String trimmedHtml = unparsedHtml.substring(beginIndex, endIndex);
Document parsedDocument = Jsoup.parse(trimmedHtml); Document parsedDocument = Jsoup.parse(trimmedHtml);
Element imageElement = parsedDocument.getElementById("comic_page"); Element imageElement = parsedDocument.getElementById("comic_page");
return imageElement.attr("src"); return imageElement.attr("src");
} }
@ -431,7 +323,7 @@ public class Batoto extends Source {
String postUrl = form.attr("action"); String postUrl = form.attr("action");
FormEncodingBuilder formBody = new FormEncodingBuilder(); FormEncodingBuilder formBody = new FormEncodingBuilder();
Element authKey = form.select("input[name=auth_key").first(); Element authKey = form.select("input[name=auth_key]").first();
formBody.add(authKey.attr("name"), authKey.attr("value")); formBody.add(authKey.attr("name"), authKey.attr("value"));
formBody.add("ips_username", username); formBody.add("ips_username", username);

View File

@ -10,7 +10,6 @@ import com.squareup.okhttp.Response;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -27,6 +26,7 @@ import eu.kanade.mangafeed.data.source.SourceManager;
import eu.kanade.mangafeed.data.source.base.Source; import eu.kanade.mangafeed.data.source.base.Source;
import eu.kanade.mangafeed.data.source.model.MangasPage; import eu.kanade.mangafeed.data.source.model.MangasPage;
import eu.kanade.mangafeed.data.source.model.Page; import eu.kanade.mangafeed.data.source.model.Page;
import eu.kanade.mangafeed.util.Parser;
import rx.Observable; import rx.Observable;
public class Kissmanga extends Source { public class Kissmanga extends Source {
@ -64,11 +64,6 @@ public class Kissmanga extends Source {
return BASE_URL; return BASE_URL;
} }
@Override
public boolean isLoginRequired() {
return false;
}
@Override @Override
protected String getInitialPopularMangasUrl() { protected String getInitialPopularMangasUrl() {
return String.format(POPULAR_MANGAS_URL, 1); return String.format(POPULAR_MANGAS_URL, 1);
@ -83,36 +78,32 @@ public class Kissmanga extends Source {
protected List<Manga> parsePopularMangasFromHtml(Document parsedHtml) { protected List<Manga> parsePopularMangasFromHtml(Document parsedHtml) {
List<Manga> mangaList = new ArrayList<>(); List<Manga> mangaList = new ArrayList<>();
Elements mangaHtmlBlocks = parsedHtml.select("table.listing tr:gt(1)"); for (Element currentHtmlBlock : parsedHtml.select("table.listing tr:gt(1)")) {
for (Element currentHtmlBlock : mangaHtmlBlocks) { Manga manga = constructPopularMangaFromHtml(currentHtmlBlock);
Manga currentManga = constructPopularMangaFromHtmlBlock(currentHtmlBlock); mangaList.add(manga);
mangaList.add(currentManga);
} }
return mangaList; return mangaList;
} }
private Manga constructPopularMangaFromHtmlBlock(Element htmlBlock) { private Manga constructPopularMangaFromHtml(Element htmlBlock) {
Manga mangaFromHtmlBlock = new Manga(); Manga manga = new Manga();
mangaFromHtmlBlock.source = getId(); manga.source = getId();
Element urlElement = htmlBlock.select("td a:eq(0)").first(); Element urlElement = Parser.element(htmlBlock, "td a:eq(0)");
if (urlElement != null) { if (urlElement != null) {
mangaFromHtmlBlock.setUrl(urlElement.attr("href")); manga.setUrl(urlElement.attr("href"));
mangaFromHtmlBlock.title = urlElement.text(); manga.title = urlElement.text();
} }
return mangaFromHtmlBlock; return manga;
} }
@Override @Override
protected String parseNextPopularMangasUrl(Document parsedHtml, MangasPage page) { protected String parseNextPopularMangasUrl(Document parsedHtml, MangasPage page) {
Element next = parsedHtml.select("li > a:contains( Next)").first(); String path = Parser.href(parsedHtml, "li > a:contains( Next)");
if (next == null) return path != null ? BASE_URL + path : null;
return null;
return BASE_URL + next.attr("href");
} }
public Observable<MangasPage> searchMangasFromNetwork(MangasPage page, String query) { public Observable<MangasPage> searchMangasFromNetwork(MangasPage page, String query) {
@ -147,90 +138,75 @@ public class Kissmanga extends Source {
@Override @Override
protected Manga parseHtmlToManga(String mangaUrl, String unparsedHtml) { protected Manga parseHtmlToManga(String mangaUrl, String unparsedHtml) {
Document parsedDocument = Jsoup.parse(unparsedHtml); Document parsedDocument = Jsoup.parse(unparsedHtml);
Element infoElement = parsedDocument.select("div.barContent").first(); Element infoElement = parsedDocument.select("div.barContent").first();
Element titleElement = infoElement.select("a.bigChar").first();
Element authorElement = infoElement.select("p:has(span:contains(Author:)) > a").first();
Elements genreElement = infoElement.select("p:has(span:contains(Genres:)) > *:gt(0)");
Elements descriptionElement = infoElement.select("p:has(span:contains(Summary:)) ~ p");
Element thumbnailUrlElement = parsedDocument.select(".rightBox:eq(0) img").first();
Manga newManga = new Manga(); Manga manga = Manga.create(mangaUrl);
newManga.url = mangaUrl; manga.title = Parser.text(infoElement, "a.bigChar");
manga.author = Parser.text(infoElement, "p:has(span:contains(Author:)) > a");
manga.genre = Parser.allText(infoElement, "p:has(span:contains(Genres:)) > *:gt(0)");
manga.description = Parser.allText(infoElement, "p:has(span:contains(Summary:)) ~ p");
manga.status = parseStatus(Parser.text(infoElement, "p:has(span:contains(Status:))"));
if (titleElement != null) { String thumbnail = Parser.src(parsedDocument, ".rightBox:eq(0) img");
newManga.title = titleElement.text(); if (thumbnail != null) {
manga.thumbnail_url = Uri.parse(thumbnail).buildUpon().authority(IP).toString();
} }
if (authorElement != null) {
newManga.author = authorElement.text();
}
if (descriptionElement != null) {
newManga.description = descriptionElement.text();
}
if (genreElement != null) {
newManga.genre = genreElement.text();
}
if (thumbnailUrlElement != null) {
newManga.thumbnail_url = Uri.parse(thumbnailUrlElement.attr("src"))
.buildUpon().authority(IP).toString();
}
// if (statusElement != null) {
// boolean fieldCompleted = statusElement.text().contains("Completed");
// newManga.status = fieldCompleted + "";
// }
newManga.initialized = true; manga.initialized = true;
return manga;
}
return newManga; private int parseStatus(String status) {
if (status.contains("Ongoing")) {
return Manga.ONGOING;
}
if (status.contains("Completed")) {
return Manga.COMPLETED;
}
return Manga.UNKNOWN;
} }
@Override @Override
protected List<Chapter> parseHtmlToChapters(String unparsedHtml) { protected List<Chapter> parseHtmlToChapters(String unparsedHtml) {
Document parsedDocument = Jsoup.parse(unparsedHtml); Document parsedDocument = Jsoup.parse(unparsedHtml);
List<Chapter> chapterList = new ArrayList<>(); List<Chapter> chapterList = new ArrayList<>();
Elements chapterElements = parsedDocument.select("table.listing tr:gt(1)"); for (Element chapterElement : parsedDocument.select("table.listing tr:gt(1)")) {
for (Element chapterElement : chapterElements) { Chapter chapter = constructChapterFromHtmlBlock(chapterElement);
Chapter currentChapter = constructChapterFromHtmlBlock(chapterElement); chapterList.add(chapter);
chapterList.add(currentChapter);
} }
return chapterList; return chapterList;
} }
private Chapter constructChapterFromHtmlBlock(Element chapterElement) { private Chapter constructChapterFromHtmlBlock(Element chapterElement) {
Chapter newChapter = Chapter.create(); Chapter chapter = Chapter.create();
Element urlElement = chapterElement.select("a").first(); Element urlElement = Parser.element(chapterElement, "a");
Element dateElement = chapterElement.select("td:eq(1)").first(); String date = Parser.text(chapterElement, "td:eq(1)");
if (urlElement != null) { if (urlElement != null) {
newChapter.setUrl(urlElement.attr("href")); chapter.setUrl(urlElement.attr("href"));
newChapter.name = urlElement.text(); chapter.name = urlElement.text();
} }
if (dateElement != null) { if (date != null) {
try { try {
newChapter.date_upload = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH).parse(dateElement.text()).getTime(); chapter.date_upload = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH).parse(date).getTime();
} catch (ParseException e) { } catch (ParseException e) { /* Ignore */ }
// Do Nothing.
}
} }
newChapter.date_fetch = new Date().getTime(); chapter.date_fetch = new Date().getTime();
return chapter;
return newChapter;
} }
@Override
public Observable<List<Page>> pullPageListFromNetwork(final String chapterUrl) { public Observable<List<Page>> pullPageListFromNetwork(final String chapterUrl) {
FormEncodingBuilder builder = new FormEncodingBuilder();
return networkService return networkService
.postData(getBaseUrl() + overrideChapterUrl(chapterUrl), builder.build(), requestHeaders) .postData(getBaseUrl() + overrideChapterUrl(chapterUrl), null, requestHeaders)
.flatMap(networkService::mapResponseToString) .flatMap(networkService::mapResponseToString)
.flatMap(unparsedHtml -> { .flatMap(unparsedHtml -> {
List<String> pageUrls = parseHtmlToPageUrls(unparsedHtml); List<Page> pages = convertToPages(parseHtmlToPageUrls(unparsedHtml));
return Observable.just(getFirstImageFromPageUrls(pageUrls, unparsedHtml)); return Observable.just(parseFirstPage(pages, unparsedHtml));
}); });
} }
@ -248,18 +224,13 @@ public class Kissmanga extends Source {
} }
@Override @Override
protected List<Page> getFirstImageFromPageUrls(List<String> pageUrls, String unparsedHtml) { protected List<Page> parseFirstPage(List<Page> pages, String unparsedHtml) {
List<Page> pages = convertToPages(pageUrls);
Pattern p = Pattern.compile("lstImages.push\\(\"(.+?)\""); Pattern p = Pattern.compile("lstImages.push\\(\"(.+?)\"");
Matcher m = p.matcher(unparsedHtml); Matcher m = p.matcher(unparsedHtml);
List<String> imageUrls = new ArrayList<>();
while (m.find()) {
imageUrls.add(m.group(1));
}
for (int i = 0; i < pages.size(); i++) { int i = 0;
pages.get(i).setImageUrl(imageUrls.get(i)); while (m.find()) {
pages.get(i++).setImageUrl(m.group(1));
} }
return pages; return pages;
} }

View File

@ -21,6 +21,7 @@ import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.data.source.SourceManager; import eu.kanade.mangafeed.data.source.SourceManager;
import eu.kanade.mangafeed.data.source.base.Source; import eu.kanade.mangafeed.data.source.base.Source;
import eu.kanade.mangafeed.data.source.model.MangasPage; import eu.kanade.mangafeed.data.source.model.MangasPage;
import eu.kanade.mangafeed.util.Parser;
public class Mangafox extends Source { public class Mangafox extends Source {
@ -49,11 +50,6 @@ public class Mangafox extends Source {
return BASE_URL; return BASE_URL;
} }
@Override
public boolean isLoginRequired() {
return false;
}
@Override @Override
protected String getInitialPopularMangasUrl() { protected String getInitialPopularMangasUrl() {
return String.format(POPULAR_MANGAS_URL, ""); return String.format(POPULAR_MANGAS_URL, "");
@ -68,48 +64,39 @@ public class Mangafox extends Source {
protected List<Manga> parsePopularMangasFromHtml(Document parsedHtml) { protected List<Manga> parsePopularMangasFromHtml(Document parsedHtml) {
List<Manga> mangaList = new ArrayList<>(); List<Manga> mangaList = new ArrayList<>();
Elements mangaHtmlBlocks = parsedHtml.select("div#mangalist > ul.list > li"); for (Element currentHtmlBlock : parsedHtml.select("div#mangalist > ul.list > li")) {
for (Element currentHtmlBlock : mangaHtmlBlocks) {
Manga currentManga = constructPopularMangaFromHtmlBlock(currentHtmlBlock); Manga currentManga = constructPopularMangaFromHtmlBlock(currentHtmlBlock);
mangaList.add(currentManga); mangaList.add(currentManga);
} }
return mangaList; return mangaList;
} }
private Manga constructPopularMangaFromHtmlBlock(Element htmlBlock) { private Manga constructPopularMangaFromHtmlBlock(Element htmlBlock) {
Manga mangaFromHtmlBlock = new Manga(); Manga manga = new Manga();
mangaFromHtmlBlock.source = getId(); manga.source = getId();
Element urlElement = htmlBlock.select("a.title").first();
Element urlElement = Parser.element(htmlBlock, "a.title");
if (urlElement != null) { if (urlElement != null) {
mangaFromHtmlBlock.setUrl(urlElement.attr("href")); manga.setUrl(urlElement.attr("href"));
mangaFromHtmlBlock.title = urlElement.text(); manga.title = urlElement.text();
} }
return manga;
return mangaFromHtmlBlock;
} }
@Override @Override
protected String parseNextPopularMangasUrl(Document parsedHtml, MangasPage page) { protected String parseNextPopularMangasUrl(Document parsedHtml, MangasPage page) {
Element next = parsedHtml.select("a:has(span.next)").first(); Element next = Parser.element(parsedHtml, "a:has(span.next)");
if (next == null) return next != null ? String.format(POPULAR_MANGAS_URL, next.attr("href")) : null;
return null;
return String.format(POPULAR_MANGAS_URL, next.attr("href"));
} }
@Override @Override
protected List<Manga> parseSearchFromHtml(Document parsedHtml) { protected List<Manga> parseSearchFromHtml(Document parsedHtml) {
List<Manga> mangaList = new ArrayList<>(); List<Manga> mangaList = new ArrayList<>();
Elements mangaHtmlBlocks = parsedHtml.select("table#listing > tbody > tr:gt(0)"); for (Element currentHtmlBlock : parsedHtml.select("table#listing > tbody > tr:gt(0)")) {
for (Element currentHtmlBlock : mangaHtmlBlocks) {
Manga currentManga = constructSearchMangaFromHtmlBlock(currentHtmlBlock); Manga currentManga = constructSearchMangaFromHtmlBlock(currentHtmlBlock);
mangaList.add(currentManga); mangaList.add(currentManga);
} }
return mangaList; return mangaList;
} }
@ -117,23 +104,18 @@ public class Mangafox extends Source {
Manga mangaFromHtmlBlock = new Manga(); Manga mangaFromHtmlBlock = new Manga();
mangaFromHtmlBlock.source = getId(); mangaFromHtmlBlock.source = getId();
Element urlElement = htmlBlock.select("a.series_preview").first(); Element urlElement = Parser.element(htmlBlock, "a.series_preview");
if (urlElement != null) { if (urlElement != null) {
mangaFromHtmlBlock.setUrl(urlElement.attr("href")); mangaFromHtmlBlock.setUrl(urlElement.attr("href"));
mangaFromHtmlBlock.title = urlElement.text(); mangaFromHtmlBlock.title = urlElement.text();
} }
return mangaFromHtmlBlock; return mangaFromHtmlBlock;
} }
@Override @Override
protected String parseNextSearchUrl(Document parsedHtml, MangasPage page, String query) { protected String parseNextSearchUrl(Document parsedHtml, MangasPage page, String query) {
Element next = parsedHtml.select("a:has(span.next)").first(); Element next = Parser.element(parsedHtml, "a:has(span.next)");
if (next == null) return next != null ? BASE_URL + next.attr("href") : null;
return null;
return BASE_URL + next.attr("href");
} }
@Override @Override
@ -141,84 +123,60 @@ public class Mangafox extends Source {
Document parsedDocument = Jsoup.parse(unparsedHtml); Document parsedDocument = Jsoup.parse(unparsedHtml);
Element infoElement = parsedDocument.select("div#title").first(); 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 rowElement = infoElement.select("table > tbody > tr:eq(1)").first();
Element authorElement = rowElement.select("td:eq(1)").first(); Element sideInfoElement = parsedDocument.select("#series_info").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(); Manga manga = Manga.create(mangaUrl);
newManga.url = mangaUrl; manga.author = Parser.text(rowElement, "td:eq(1)");
manga.artist = Parser.text(rowElement, "td:eq(2)");
manga.description = Parser.text(infoElement, "p.summary");
manga.genre = Parser.text(rowElement, "td:eq(3)");
manga.thumbnail_url = Parser.src(sideInfoElement, "div.cover > img");
manga.status = parseStatus(Parser.text(sideInfoElement, ".data"));
if (titleElement != null) { manga.initialized = true;
String title = titleElement.text(); return manga;
// Strip the last word
title = title.substring(0, title.lastIndexOf(" "));
newManga.title = title;
} }
if (artistElement != null) {
newManga.artist = artistElement.text();
}
if (authorElement != null) {
newManga.author = authorElement.text();
}
if (descriptionElement != null) {
newManga.description = descriptionElement.text();
}
if (genreElement != null) {
newManga.genre = genreElement.text();
}
if (thumbnailUrlElement != null) {
newManga.thumbnail_url = thumbnailUrlElement.attr("src");
}
// if (statusElement != null) {
// boolean fieldCompleted = statusElement.text().contains("Completed");
// newManga.status = fieldCompleted + "";
// }
newManga.initialized = true; private int parseStatus(String status) {
if (status.contains("Ongoing")) {
return newManga; return Manga.ONGOING;
}
if (status.contains("Completed")) {
return Manga.COMPLETED;
}
return Manga.UNKNOWN;
} }
@Override @Override
protected List<Chapter> parseHtmlToChapters(String unparsedHtml) { protected List<Chapter> parseHtmlToChapters(String unparsedHtml) {
Document parsedDocument = Jsoup.parse(unparsedHtml); Document parsedDocument = Jsoup.parse(unparsedHtml);
List<Chapter> chapterList = new ArrayList<Chapter>(); List<Chapter> chapterList = new ArrayList<>();
Elements chapterElements = parsedDocument.select("div#chapters li div"); for (Element chapterElement : parsedDocument.select("div#chapters li div")) {
for (Element chapterElement : chapterElements) {
Chapter currentChapter = constructChapterFromHtmlBlock(chapterElement); Chapter currentChapter = constructChapterFromHtmlBlock(chapterElement);
chapterList.add(currentChapter); chapterList.add(currentChapter);
} }
return chapterList; return chapterList;
} }
private Chapter constructChapterFromHtmlBlock(Element chapterElement) { private Chapter constructChapterFromHtmlBlock(Element chapterElement) {
Chapter newChapter = Chapter.create(); Chapter chapter = Chapter.create();
Element urlElement = chapterElement.select("a.tips").first(); Element urlElement = chapterElement.select("a.tips").first();
Element nameElement = chapterElement.select("a.tips").first();
Element dateElement = chapterElement.select("span.date").first(); Element dateElement = chapterElement.select("span.date").first();
if (urlElement != null) { if (urlElement != null) {
newChapter.setUrl(urlElement.attr("href")); chapter.setUrl(urlElement.attr("href"));
} chapter.name = urlElement.text();
if (nameElement != null) {
newChapter.name = nameElement.text();
} }
if (dateElement != null) { if (dateElement != null) {
newChapter.date_upload = parseUpdateFromElement(dateElement); chapter.date_upload = parseUpdateFromElement(dateElement);
} }
chapter.date_fetch = new Date().getTime();
newChapter.date_fetch = new Date().getTime(); return chapter;
return newChapter;
} }
private long parseUpdateFromElement(Element updateElement) { private long parseUpdateFromElement(Element updateElement) {

View File

@ -21,7 +21,7 @@ import eu.kanade.mangafeed.data.database.models.Manga;
import eu.kanade.mangafeed.data.source.SourceManager; import eu.kanade.mangafeed.data.source.SourceManager;
import eu.kanade.mangafeed.data.source.base.Source; import eu.kanade.mangafeed.data.source.base.Source;
import eu.kanade.mangafeed.data.source.model.MangasPage; import eu.kanade.mangafeed.data.source.model.MangasPage;
import rx.Observable; import eu.kanade.mangafeed.util.Parser;
public class Mangahere extends Source { public class Mangahere extends Source {
@ -49,11 +49,6 @@ public class Mangahere extends Source {
return BASE_URL; return BASE_URL;
} }
@Override
public boolean isLoginRequired() {
return false;
}
@Override @Override
protected String getInitialPopularMangasUrl() { protected String getInitialPopularMangasUrl() {
return String.format(POPULAR_MANGAS_URL, ""); return String.format(POPULAR_MANGAS_URL, "");
@ -64,78 +59,33 @@ public class Mangahere extends Source {
return String.format(SEARCH_URL, Uri.encode(query), 1); return String.format(SEARCH_URL, Uri.encode(query), 1);
} }
public Observable<List<String>> getGenres() {
List<String> genres = new ArrayList<>(30);
genres.add("Action");
genres.add("Adventure");
genres.add("Comedy");
genres.add("Drama");
genres.add("Ecchi");
genres.add("Fantasy");
genres.add("Gender Bender");
genres.add("Harem");
genres.add("Historical");
genres.add("Horror");
genres.add("Josei");
genres.add("Martial Arts");
genres.add("Mature");
genres.add("Mecha");
genres.add("Mystery");
genres.add("One Shot");
genres.add("Psychological");
genres.add("Romance");
genres.add("School Life");
genres.add("Sci-fi");
genres.add("Seinen");
genres.add("Shoujo");
genres.add("Shoujo Ai");
genres.add("Shounen");
genres.add("Shounen Ai");
genres.add("Slice of Life");
genres.add("Sports");
genres.add("Supernatural");
genres.add("Tragedy");
genres.add("Yaoi");
genres.add("Yuri");
return Observable.just(genres);
}
@Override @Override
public List<Manga> parsePopularMangasFromHtml(Document parsedHtml) { public List<Manga> parsePopularMangasFromHtml(Document parsedHtml) {
List<Manga> mangaList = new ArrayList<>(); List<Manga> mangaList = new ArrayList<>();
Elements mangaHtmlBlocks = parsedHtml.select("div.directory_list > ul > li"); for (Element currentHtmlBlock : parsedHtml.select("div.directory_list > ul > li")) {
for (Element currentHtmlBlock : mangaHtmlBlocks) {
Manga currentManga = constructPopularMangaFromHtmlBlock(currentHtmlBlock); Manga currentManga = constructPopularMangaFromHtmlBlock(currentHtmlBlock);
mangaList.add(currentManga); mangaList.add(currentManga);
} }
return mangaList; return mangaList;
} }
private Manga constructPopularMangaFromHtmlBlock(Element htmlBlock) { private Manga constructPopularMangaFromHtmlBlock(Element htmlBlock) {
Manga mangaFromHtmlBlock = new Manga(); Manga manga = new Manga();
mangaFromHtmlBlock.source = getId(); manga.source = getId();
Element urlElement = htmlBlock.select("div.title > a").first();
Element urlElement = Parser.element(htmlBlock, "div.title > a");
if (urlElement != null) { if (urlElement != null) {
mangaFromHtmlBlock.setUrl(urlElement.attr("href")); manga.setUrl(urlElement.attr("href"));
mangaFromHtmlBlock.title = urlElement.attr("title"); manga.title = urlElement.attr("title");
} }
return manga;
return mangaFromHtmlBlock;
} }
@Override @Override
protected String parseNextPopularMangasUrl(Document parsedHtml, MangasPage page) { protected String parseNextPopularMangasUrl(Document parsedHtml, MangasPage page) {
Element next = parsedHtml.select("div.next-page > a.next").first(); Element next = Parser.element(parsedHtml, "div.next-page > a.next");
if (next == null) return next != null ? String.format(POPULAR_MANGAS_URL, next.attr("href")) : null;
return null;
return String.format(POPULAR_MANGAS_URL, next.attr("href"));
} }
@Override @Override
@ -147,31 +97,25 @@ public class Mangahere extends Source {
Manga currentManga = constructSearchMangaFromHtmlBlock(currentHtmlBlock); Manga currentManga = constructSearchMangaFromHtmlBlock(currentHtmlBlock);
mangaList.add(currentManga); mangaList.add(currentManga);
} }
return mangaList; return mangaList;
} }
private Manga constructSearchMangaFromHtmlBlock(Element htmlBlock) { private Manga constructSearchMangaFromHtmlBlock(Element htmlBlock) {
Manga mangaFromHtmlBlock = new Manga(); Manga manga = new Manga();
mangaFromHtmlBlock.source = getId(); manga.source = getId();
Element urlElement = htmlBlock.select("a.manga_info").first();
Element urlElement = Parser.element(htmlBlock, "a.manga_info");
if (urlElement != null) { if (urlElement != null) {
mangaFromHtmlBlock.setUrl(urlElement.attr("href")); manga.setUrl(urlElement.attr("href"));
mangaFromHtmlBlock.title = urlElement.text(); manga.title = urlElement.text();
} }
return manga;
return mangaFromHtmlBlock;
} }
@Override @Override
protected String parseNextSearchUrl(Document parsedHtml, MangasPage page, String query) { protected String parseNextSearchUrl(Document parsedHtml, MangasPage page, String query) {
Element next = parsedHtml.select("div.next-page > a.next").first(); Element next = Parser.element(parsedHtml, "div.next-page > a.next");
if (next == null) return next != null ? BASE_URL + next.attr("href") : null;
return null;
return BASE_URL + next.attr("href");
} }
private long parseUpdateFromElement(Element updateElement) { private long parseUpdateFromElement(Element updateElement) {
@ -223,49 +167,41 @@ public class Mangahere extends Source {
String trimmedHtml = unparsedHtml.substring(beginIndex, endIndex); String trimmedHtml = unparsedHtml.substring(beginIndex, endIndex);
Document parsedDocument = Jsoup.parse(trimmedHtml); Document parsedDocument = Jsoup.parse(trimmedHtml);
Element detailElement = parsedDocument.select("ul.detail_topText").first();
Elements detailElements = parsedDocument.select("ul.detail_topText li"); Manga manga = Manga.create(mangaUrl);
manga.author = Parser.text(parsedDocument, "a[href^=http://www.mangahere.co/author/]");
manga.artist = Parser.text(parsedDocument, "a[href^=http://www.mangahere.co/artist/]");
Element artistElement = parsedDocument.select("a[href^=http://www.mangahere.co/artist/]").first(); String description = Parser.text(detailElement, "#show");
Element authorElement = parsedDocument.select("a[href^=http://www.mangahere.co/author/]").first(); if (description != null) {
Element descriptionElement = detailElements.select("#show").first(); manga.description = description.substring(0, description.length() - "Show less".length());
Element genreElement = detailElements.get(3);
Element statusElement = detailElements.get(6);
Manga newManga = new Manga();
newManga.url = mangaUrl;
if (artistElement != null) {
newManga.artist = artistElement.text();
} }
if (authorElement != null) { String genres = Parser.text(detailElement, "li:eq(3)");
newManga.author = authorElement.text(); if (genres != null) {
} manga.genre = genres.substring("Genre(s):".length());
if (descriptionElement != null) {
newManga.description = descriptionElement.text().substring(0, descriptionElement.text().length() - "Show less".length());
}
if (genreElement != null) {
newManga.genre = genreElement.text().substring("Genre(s):".length());
}
if (statusElement != null) {
boolean fieldCompleted = statusElement.text().contains("Completed");
// TODO fix status
// newManga.status = fieldCompleted + "";
} }
manga.status = parseStatus(Parser.text(detailElement, "li:eq(6)"));
beginIndex = unparsedHtml.indexOf("<img"); beginIndex = unparsedHtml.indexOf("<img");
endIndex = unparsedHtml.indexOf("/>", beginIndex); endIndex = unparsedHtml.indexOf("/>", beginIndex);
trimmedHtml = unparsedHtml.substring(beginIndex, endIndex + 2); trimmedHtml = unparsedHtml.substring(beginIndex, endIndex + 2);
parsedDocument = Jsoup.parse(trimmedHtml);
Element thumbnailUrlElement = parsedDocument.select("img").first();
if (thumbnailUrlElement != null) { parsedDocument = Jsoup.parse(trimmedHtml);
newManga.thumbnail_url = thumbnailUrlElement.attr("src"); manga.thumbnail_url = Parser.src(parsedDocument, "img");
manga.initialized = true;
return manga;
} }
newManga.initialized = true; private int parseStatus(String status) {
if (status.contains("Ongoing")) {
return newManga; return Manga.ONGOING;
}
if (status.contains("Completed")) {
return Manga.COMPLETED;
}
return Manga.UNKNOWN;
} }
@Override @Override
@ -276,37 +212,31 @@ public class Mangahere extends Source {
Document parsedDocument = Jsoup.parse(trimmedHtml); Document parsedDocument = Jsoup.parse(trimmedHtml);
List<Chapter> chapterList = new ArrayList<Chapter>(); List<Chapter> chapterList = new ArrayList<>();
Elements chapterElements = parsedDocument.getElementsByTag("li"); for (Element chapterElement : parsedDocument.getElementsByTag("li")) {
for (Element chapterElement : chapterElements) {
Chapter currentChapter = constructChapterFromHtmlBlock(chapterElement); Chapter currentChapter = constructChapterFromHtmlBlock(chapterElement);
chapterList.add(currentChapter); chapterList.add(currentChapter);
} }
return chapterList; return chapterList;
} }
private Chapter constructChapterFromHtmlBlock(Element chapterElement) { private Chapter constructChapterFromHtmlBlock(Element chapterElement) {
Chapter newChapter = Chapter.create(); Chapter chapter = Chapter.create();
Element urlElement = chapterElement.select("a").first(); Element urlElement = chapterElement.select("a").first();
Element nameElement = chapterElement.select("a").first();
Element dateElement = chapterElement.select("span.right").first(); Element dateElement = chapterElement.select("span.right").first();
if (urlElement != null) { if (urlElement != null) {
newChapter.setUrl(urlElement.attr("href")); chapter.setUrl(urlElement.attr("href"));
} chapter.name = urlElement.text();
if (nameElement != null) {
newChapter.name = nameElement.text();
} }
if (dateElement != null) { if (dateElement != null) {
newChapter.date_upload = parseDateFromElement(dateElement); chapter.date_upload = parseDateFromElement(dateElement);
} }
newChapter.date_fetch = new Date().getTime(); chapter.date_fetch = new Date().getTime();
return newChapter; return chapter;
} }
private long parseDateFromElement(Element dateElement) { private long parseDateFromElement(Element dateElement) {
@ -348,7 +278,6 @@ public class Mangahere extends Source {
// Do Nothing. // Do Nothing.
} }
} }
return 0; return 0;
} }
@ -360,7 +289,7 @@ public class Mangahere extends Source {
Document parsedDocument = Jsoup.parse(trimmedHtml); Document parsedDocument = Jsoup.parse(trimmedHtml);
List<String> pageUrlList = new ArrayList<String>(); List<String> pageUrlList = new ArrayList<>();
Elements pageUrlElements = parsedDocument.select("select.wid60").first().getElementsByTag("option"); Elements pageUrlElements = parsedDocument.select("select.wid60").first().getElementsByTag("option");
for (Element pageUrlElement : pageUrlElements) { for (Element pageUrlElement : pageUrlElements) {

View File

@ -69,6 +69,7 @@ public class MyAnimeListPresenter extends BasePresenter<MyAnimeListFragment> {
for (MangaSync myManga : myList) { for (MangaSync myManga : myList) {
if (myManga.remote_id == mangaSync.remote_id) { if (myManga.remote_id == mangaSync.remote_id) {
mangaSync.copyPersonalFrom(myManga); mangaSync.copyPersonalFrom(myManga);
mangaSync.total_chapters = myManga.total_chapters;
return Observable.just(mangaSync); return Observable.just(mangaSync);
} }
} }

View File

@ -0,0 +1,48 @@
package eu.kanade.mangafeed.util;
import android.support.annotation.Nullable;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class Parser {
@Nullable
public static Element element(Element container, String pattern) {
return container.select(pattern).first();
}
@Nullable
public static String text(Element container, String pattern) {
return text(container, pattern, null);
}
@Nullable
public static String text(Element container, String pattern, String defValue) {
Element element = container.select(pattern).first();
return element != null ? element.text() : defValue;
}
@Nullable
public static String allText(Element container, String pattern) {
Elements elements = container.select(pattern);
return !elements.isEmpty() ? elements.text() : null;
}
@Nullable
public static String attr(Element container, String pattern, String attr) {
Element element = container.select(pattern).first();
return element != null ? element.attr(attr) : null;
}
@Nullable
public static String href(Element container, String pattern) {
return attr(container, pattern, "href");
}
@Nullable
public static String src(Element container, String pattern) {
return attr(container, pattern, "src");
}
}