mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/master'
This commit is contained in:
		| @@ -9,6 +9,7 @@ import eu.kanade.tachiyomi.data.source.online.english.Mangahere | ||||
| import eu.kanade.tachiyomi.data.source.online.russian.Mangachan; | ||||
| import eu.kanade.tachiyomi.data.source.online.russian.Mintmanga; | ||||
| import eu.kanade.tachiyomi.data.source.online.russian.Readmanga; | ||||
| import eu.kanade.tachiyomi.data.source.online.english.ReadMangaToday | ||||
| import java.util.* | ||||
|  | ||||
| open class SourceManager(private val context: Context) { | ||||
| @@ -22,8 +23,9 @@ open class SourceManager(private val context: Context) { | ||||
|     val READMANGA = 5 | ||||
|     val MINTMANGA = 6 | ||||
|     val MANGACHAN = 7 | ||||
|     val READMANGATODAY = 8 | ||||
|  | ||||
|     val LAST_SOURCE = 7 | ||||
|     val LAST_SOURCE = 8 | ||||
|  | ||||
|     init { | ||||
|         sourcesMap = createSourcesMap() | ||||
| @@ -41,6 +43,7 @@ open class SourceManager(private val context: Context) { | ||||
|         READMANGA -> Readmanga(context) | ||||
|         MINTMANGA -> Mintmanga(context) | ||||
|         MANGACHAN -> Mangachan(context) | ||||
|         READMANGATODAY -> ReadMangaToday(context) | ||||
|         else -> null | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -0,0 +1,278 @@ | ||||
| package eu.kanade.tachiyomi.data.source.online.english; | ||||
|  | ||||
| import android.content.Context; | ||||
| import android.net.Uri; | ||||
|  | ||||
| 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.Calendar; | ||||
| import java.util.List; | ||||
|  | ||||
| import eu.kanade.tachiyomi.data.database.models.Chapter; | ||||
| import eu.kanade.tachiyomi.data.database.models.Manga; | ||||
| import eu.kanade.tachiyomi.data.source.Language; | ||||
| import eu.kanade.tachiyomi.data.source.LanguageKt; | ||||
| import eu.kanade.tachiyomi.data.source.base.Source; | ||||
| import eu.kanade.tachiyomi.data.source.model.MangasPage; | ||||
| import eu.kanade.tachiyomi.util.Parser; | ||||
| import okhttp3.Headers; | ||||
| import rx.Observable; | ||||
|  | ||||
| import com.google.gson.Gson; | ||||
| import com.google.gson.JsonElement; | ||||
| import com.google.gson.JsonParser; | ||||
| import com.google.gson.JsonObject; | ||||
| import com.google.gson.JsonArray; | ||||
|  | ||||
| public class ReadMangaToday extends Source { | ||||
|     public static final String NAME = "ReadMangaToday"; | ||||
|     public static final String BASE_URL = "http://www.readmanga.today"; | ||||
|     public static final String POPULAR_MANGAS_URL = BASE_URL + "/hot-manga/%s"; | ||||
|     public static final String SEARCH_URL = BASE_URL + "/service/search?q=%s"; | ||||
|  | ||||
|     private static JsonParser parser = new JsonParser(); | ||||
|     private static Gson gson = new Gson(); | ||||
|  | ||||
|     public ReadMangaToday(Context context) { | ||||
|         super(context); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getName() { | ||||
|         return NAME; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getBaseUrl() { | ||||
|         return BASE_URL; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected String getInitialPopularMangasUrl() { | ||||
|         return String.format(POPULAR_MANGAS_URL, ""); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected String getInitialSearchUrl(String query) { | ||||
|         return String.format(SEARCH_URL, Uri.encode(query), 1); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Language getLang() { | ||||
|         return LanguageKt.getEN(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<Manga> parsePopularMangasFromHtml(Document parsedHtml) { | ||||
|         List<Manga> mangaList = new ArrayList<>(); | ||||
|  | ||||
|         for (Element currentHtmlBlock : parsedHtml.select("div.hot-manga > div.style-list > div.box")) { | ||||
|             Manga currentManga = constructPopularMangaFromHtmlBlock(currentHtmlBlock); | ||||
|             mangaList.add(currentManga); | ||||
|         } | ||||
|         return mangaList; | ||||
|     } | ||||
|  | ||||
|     private Manga constructPopularMangaFromHtmlBlock(Element htmlBlock) { | ||||
|         Manga manga = new Manga(); | ||||
|         manga.source = getId(); | ||||
|  | ||||
|         Element urlElement = Parser.element(htmlBlock, "div.title > h2 > a"); | ||||
|         if (urlElement != null) { | ||||
|             manga.setUrl(urlElement.attr("href")); | ||||
|             manga.title = urlElement.attr("title"); | ||||
|         } | ||||
|         return manga; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected String parseNextPopularMangasUrl(Document parsedHtml, MangasPage page) { | ||||
|         Element next = Parser.element(parsedHtml, "div.hot-manga > ul.pagination > li > a:contains(»)"); | ||||
|         return next != null ? next.attr("href") : null; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Observable<MangasPage> searchMangasFromNetwork(MangasPage page, String query) { | ||||
|         return networkService | ||||
|                 .requestBody(searchMangaRequest(page, query), true) | ||||
|                 .doOnNext(doc -> page.mangas = parseSearchFromJson(doc)) | ||||
|                 .map(response -> page); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected Headers.Builder headersBuilder() { | ||||
|         return super.headersBuilder().add("X-Requested-With", "XMLHttpRequest"); | ||||
|     } | ||||
|  | ||||
|     protected List<Manga> parseSearchFromJson(String unparsedJson) { | ||||
|         List<Manga> mangaList = new ArrayList<>(); | ||||
|  | ||||
|         JsonArray mangasArray = parser.parse(unparsedJson).getAsJsonArray(); | ||||
|  | ||||
|         for (JsonElement mangaElement : mangasArray) { | ||||
|             Manga currentManga = constructSearchMangaFromJsonObject(mangaElement.getAsJsonObject()); | ||||
|             mangaList.add(currentManga); | ||||
|         } | ||||
|         return mangaList; | ||||
|     } | ||||
|  | ||||
|     private Manga constructSearchMangaFromJsonObject(JsonObject jsonObject) { | ||||
|         Manga manga = new Manga(); | ||||
|         manga.source = getId(); | ||||
|  | ||||
|         manga.setUrl(gson.fromJson(jsonObject.get("url"), String.class)); | ||||
|         manga.title = gson.fromJson(jsonObject.get("title"), String.class); | ||||
|  | ||||
|         return manga; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected List<Manga> parseSearchFromHtml(Document parsedHtml) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     protected String parseNextSearchUrl(Document parsedHtml, MangasPage page, String query) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public Manga parseHtmlToManga(String mangaUrl, String unparsedHtml) { | ||||
|         int beginIndex = unparsedHtml.indexOf("<!-- content start -->"); | ||||
|         int endIndex = unparsedHtml.indexOf("<!-- /content-end -->", beginIndex); | ||||
|         String trimmedHtml = unparsedHtml.substring(beginIndex, endIndex); | ||||
|  | ||||
|         Document parsedDocument = Jsoup.parse(trimmedHtml); | ||||
|         Element detailElement = parsedDocument.select("div.movie-meta").first(); | ||||
|  | ||||
|         Manga manga = Manga.create(mangaUrl); | ||||
|         for (Element castHtmlBlock : parsedDocument.select("div.cast ul.cast-list > li")) { | ||||
|             String name = Parser.text(castHtmlBlock, "ul > li > a"); | ||||
|             String role = Parser.text(castHtmlBlock, "ul > li:eq(1)"); | ||||
|             if (role.equals("Author")) { | ||||
|                 manga.author = name; | ||||
|             } else if (role.equals("Artist")) { | ||||
|                 manga.artist = name; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         String description = Parser.text(detailElement, "li.movie-detail"); | ||||
|         if (description != null) { | ||||
|             manga.description = description; | ||||
|         } | ||||
|         String genres = Parser.text(detailElement, "dl.dl-horizontal > dd:eq(5)"); | ||||
|         if (genres != null) { | ||||
|             manga.genre = genres; | ||||
|         } | ||||
|         manga.status = parseStatus(Parser.text(detailElement, "dl.dl-horizontal > dd:eq(3)")); | ||||
|         manga.thumbnail_url = Parser.src(detailElement, "img.img-responsive"); | ||||
|  | ||||
|         manga.initialized = true; | ||||
|         return manga; | ||||
|     } | ||||
|  | ||||
|     private int parseStatus(String status) { | ||||
|         if (status.contains("Ongoing")) { | ||||
|             return Manga.ONGOING; | ||||
|         } else if (status.contains("Completed")) { | ||||
|             return Manga.COMPLETED; | ||||
|         } | ||||
|         return Manga.UNKNOWN; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<Chapter> parseHtmlToChapters(String unparsedHtml) { | ||||
|         int beginIndex = unparsedHtml.indexOf("<!-- content start -->"); | ||||
|         int endIndex = unparsedHtml.indexOf("<!-- /content-end -->", beginIndex); | ||||
|         String trimmedHtml = unparsedHtml.substring(beginIndex, endIndex); | ||||
|  | ||||
|         Document parsedDocument = Jsoup.parse(trimmedHtml); | ||||
|  | ||||
|         List<Chapter> chapterList = new ArrayList<>(); | ||||
|  | ||||
|         for (Element chapterElement : parsedDocument.select("ul.chp_lst > li")) { | ||||
|             Chapter currentChapter = constructChapterFromHtmlBlock(chapterElement); | ||||
|             chapterList.add(currentChapter); | ||||
|         } | ||||
|         return chapterList; | ||||
|     } | ||||
|  | ||||
|     private Chapter constructChapterFromHtmlBlock(Element chapterElement) { | ||||
|         Chapter chapter = Chapter.create(); | ||||
|  | ||||
|         Element urlElement = chapterElement.select("a").first(); | ||||
|         Element dateElement = chapterElement.select("span.dte").first(); | ||||
|  | ||||
|         if (urlElement != null) { | ||||
|             chapter.setUrl(urlElement.attr("href")); | ||||
|             chapter.name = urlElement.select("span.val").text(); | ||||
|         } | ||||
|         if (dateElement != null) { | ||||
|             chapter.date_upload = parseDateFromElement(dateElement); | ||||
|         } | ||||
|         return chapter; | ||||
|     } | ||||
|  | ||||
|     private long parseDateFromElement(Element dateElement) { | ||||
|         String dateAsString = dateElement.text(); | ||||
|         String[] dateWords = dateAsString.split(" "); | ||||
|  | ||||
|         if (dateWords.length == 3) { | ||||
|             int timeAgo = Integer.parseInt(dateWords[0]); | ||||
|             Calendar date = Calendar.getInstance(); | ||||
|  | ||||
|             if (dateWords[1].contains("Minute")) { | ||||
|                 date.add(Calendar.MINUTE, - timeAgo); | ||||
|             } else if (dateWords[1].contains("Hour")) { | ||||
|                 date.add(Calendar.HOUR_OF_DAY, - timeAgo); | ||||
|             } else if (dateWords[1].contains("Day")) { | ||||
|                 date.add(Calendar.DAY_OF_YEAR, -timeAgo); | ||||
|             } else if (dateWords[1].contains("Week")) { | ||||
|                 date.add(Calendar.WEEK_OF_YEAR, -timeAgo); | ||||
|             } else if (dateWords[1].contains("Month")) { | ||||
|                 date.add(Calendar.MONTH, -timeAgo); | ||||
|             } else if (dateWords[1].contains("Year")) { | ||||
|                 date.add(Calendar.YEAR, -timeAgo); | ||||
|             } | ||||
|  | ||||
|             return date.getTimeInMillis(); | ||||
|         } | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<String> parseHtmlToPageUrls(String unparsedHtml) { | ||||
|         int beginIndex = unparsedHtml.indexOf("<!-- content start -->"); | ||||
|         int endIndex = unparsedHtml.indexOf("<!-- /content-end -->", beginIndex); | ||||
|         String trimmedHtml = unparsedHtml.substring(beginIndex, endIndex); | ||||
|  | ||||
|         Document parsedDocument = Jsoup.parse(trimmedHtml); | ||||
|  | ||||
|         List<String> pageUrlList = new ArrayList<>(); | ||||
|  | ||||
|         Elements pageUrlElements = parsedDocument.select("ul.list-switcher-2 > li > select.jump-menu").first().getElementsByTag("option"); | ||||
|         for (Element pageUrlElement : pageUrlElements) { | ||||
|             pageUrlList.add(pageUrlElement.attr("value")); | ||||
|         } | ||||
|  | ||||
|         return pageUrlList; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String parseHtmlToImageUrl(String unparsedHtml) { | ||||
|         int beginIndex = unparsedHtml.indexOf("<!-- content start -->"); | ||||
|         int endIndex = unparsedHtml.indexOf("<!-- /content-end -->", beginIndex); | ||||
|         String trimmedHtml = unparsedHtml.substring(beginIndex, endIndex); | ||||
|  | ||||
|         Document parsedDocument = Jsoup.parse(trimmedHtml); | ||||
|  | ||||
|         Element imageElement = Parser.element(parsedDocument, "img.img-responsive-2"); | ||||
|  | ||||
|         return imageElement.attr("src"); | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user