diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/source/SourceManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/source/SourceManager.kt index 681faf9dd3..1d243d7dde 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/source/SourceManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/source/SourceManager.kt @@ -10,6 +10,9 @@ import eu.kanade.tachiyomi.data.source.online.english.Batoto import eu.kanade.tachiyomi.data.source.online.english.Kissmanga import eu.kanade.tachiyomi.data.source.online.english.Mangafox 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 org.yaml.snakeyaml.Yaml import timber.log.Timber import java.io.File @@ -40,6 +43,9 @@ open class SourceManager(private val context: Context) { KISSMANGA -> Kissmanga(context, id) MANGAHERE -> Mangahere(context, id) MANGAFOX -> Mangafox(context, id) + READMANGA -> Readmanga(context, id) + MINTMANGA -> Mintmanga(context, id) + MANGACHAN -> Mangachan(context, id) else -> null } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/source/online/russian/Mangachan.kt b/app/src/main/java/eu/kanade/tachiyomi/data/source/online/russian/Mangachan.kt new file mode 100644 index 0000000000..277b6b8428 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/data/source/online/russian/Mangachan.kt @@ -0,0 +1,95 @@ +package eu.kanade.tachiyomi.data.source.online.russian + +import android.content.Context +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.RU +import eu.kanade.tachiyomi.data.source.base.ParsedOnlineSource +import eu.kanade.tachiyomi.data.source.model.Page +import okhttp3.Response +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import java.text.SimpleDateFormat +import java.util.* + +class Mangachan(context: Context, override val id: Int) : ParsedOnlineSource(context) { + + override val name = "Mangachan" + + override val baseUrl = "http://mangachan.ru" + + override val lang: Language get() = RU + + override fun popularMangaInitialUrl() = "$baseUrl/mostfavorites" + + override fun searchMangaInitialUrl(query: String) = "$baseUrl/?do=search&subaction=search&story=$query" + + override fun popularMangaSelector() = "div.content_row" + + override fun popularMangaFromElement(element: Element, manga: Manga) { + element.select("h2 > a").first().let { + manga.setUrl(it.attr("href")) + manga.title = it.text() + } + element.select("img").first().let { + manga.thumbnail_url = baseUrl + it.attr("src") + } + } + + override fun popularMangaNextPageSelector() = "a:contains(Вперед)" + + override fun searchMangaSelector() = popularMangaSelector() + + override fun searchMangaFromElement(element: Element, manga: Manga) { + popularMangaFromElement(element, manga) + } + + override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() + + override fun mangaDetailsParse(document: Document, manga: Manga) { + val infoElement = document.select("table.mangatitle").first() + val descElement = document.select("div#description").first() + + manga.author = infoElement.select("tr:eq(2) > td:eq(1)").text() + manga.genre = infoElement.select("tr:eq(5) > td:eq(1)").text() + manga.status = parseStatus(infoElement.select("tr:eq(4) > td:eq(1)").text()) + manga.description = descElement.textNodes().first().text() + } + + private fun parseStatus(element: String): Int { + when { + element.contains("перевод завершен") -> return Manga.COMPLETED + element.contains("перевод продолжается") -> return Manga.ONGOING + else -> return Manga.UNKNOWN + } + } + + override fun chapterListSelector() = "table.table_cha tr:gt(1)" + + override fun chapterFromElement(element: Element, chapter: Chapter) { + val urlElement = element.select("a").first() + + chapter.setUrl(urlElement.attr("href")) + chapter.name = urlElement.text() + chapter.date_upload = element.select("div.date").first()?.text()?.let { + SimpleDateFormat("yyyy-MM-dd", Locale.US).parse(it).time + } ?: 0 + } + + override fun pageListParse(response: Response, pages: MutableList) { + val html = response.body().string() + val beginIndex = html.indexOf("fullimg\":[") + 10 + val endIndex = html.indexOf(",]", beginIndex) + val trimmedHtml = html.substring(beginIndex, endIndex).replace("\"", "") + val pageUrls = trimmedHtml.split(',') + + for ((i, url) in pageUrls.withIndex()) { + pages.add(Page(i, "", url)) + } + } + + override fun pageListParse(document: Document, pages: MutableList) { } + + override fun imageUrlParse(document: Document) = "" +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/source/online/russian/Mintmanga.kt b/app/src/main/java/eu/kanade/tachiyomi/data/source/online/russian/Mintmanga.kt new file mode 100644 index 0000000000..4ba85729a4 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/data/source/online/russian/Mintmanga.kt @@ -0,0 +1,102 @@ +package eu.kanade.tachiyomi.data.source.online.russian + +import android.content.Context +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.RU +import eu.kanade.tachiyomi.data.source.base.ParsedOnlineSource +import eu.kanade.tachiyomi.data.source.model.Page +import okhttp3.Response +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import java.text.SimpleDateFormat +import java.util.* +import java.util.regex.Pattern + +class Mintmanga(context: Context, override val id: Int) : ParsedOnlineSource(context) { + + override val name = "Mintmanga" + + override val baseUrl = "http://mintmanga.com" + + override val lang: Language get() = RU + + override fun popularMangaInitialUrl() = "$baseUrl/list?sortType=rate" + + override fun searchMangaInitialUrl(query: String) = "$baseUrl/search?q=$query" + + override fun popularMangaSelector() = "div.desc" + + override fun popularMangaFromElement(element: Element, manga: Manga) { + element.select("h3 > a").first().let { + manga.setUrl(it.attr("href")) + manga.title = it.attr("title") + } + } + + override fun popularMangaNextPageSelector() = "a.nextLink" + + override fun searchMangaSelector() = popularMangaSelector() + + override fun searchMangaFromElement(element: Element, manga: Manga) { + popularMangaFromElement(element, manga) + } + + override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() + + override fun mangaDetailsParse(document: Document, manga: Manga) { + val infoElement = document.select("div.leftContent").first() + + manga.author = infoElement.select("span.elem_author").first()?.text() + manga.genre = infoElement.select("span.elem_genre").text().replace(" ,", ",") + manga.description = infoElement.select("div.manga-description").text() + manga.status = parseStatus(infoElement.html()) + manga.thumbnail_url = infoElement.select("img").attr("data-full") + } + + private fun parseStatus(element: String): Int { + when { + element.contains("

Запрещена публикация произведения по копирайту

") -> return Manga.LICENSED + element.contains("

Сингл") || element.contains("Перевод: завершен") -> return Manga.COMPLETED + element.contains("Перевод: продолжается") -> return Manga.ONGOING + else -> return Manga.UNKNOWN + } + } + + override fun chapterListSelector() = "div.chapters-link tbody tr" + + override fun chapterFromElement(element: Element, chapter: Chapter) { + val urlElement = element.select("a").first() + + chapter.setUrl(urlElement.attr("href") + "?mature=1") + chapter.name = urlElement.text().replace(" новое", "") + chapter.date_upload = element.select("td:eq(1)").first()?.text()?.let { + SimpleDateFormat("dd/MM/yy", Locale.US).parse(it).time + } ?: 0 + } + + override fun parseChapterNumber(chapter: Chapter) { + chapter.chapter_number = -2f + } + + override fun pageListParse(response: Response, pages: MutableList) { + val html = response.body().string() + val beginIndex = html.indexOf("rm_h.init( [") + val endIndex = html.indexOf("], 0, false);", beginIndex) + val trimmedHtml = html.substring(beginIndex, endIndex).replace("[\"\']+".toRegex(), "") + + val p = Pattern.compile("auto/[\\w/]+,http://[\\w.]+/,/[\\w./]+.(png|jpg)+") + val m = p.matcher(trimmedHtml) + + var i = 0 + while (m.find()) { + val urlParts = m.group().split(',') + pages.add(Page(i++, "", urlParts[1] + urlParts[0] + urlParts[2])) + } + } + + override fun pageListParse(document: Document, pages: MutableList) { } + + override fun imageUrlParse(document: Document) = "" +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/source/online/russian/Readmanga.kt b/app/src/main/java/eu/kanade/tachiyomi/data/source/online/russian/Readmanga.kt new file mode 100644 index 0000000000..d2f6d9e1ab --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/data/source/online/russian/Readmanga.kt @@ -0,0 +1,102 @@ +package eu.kanade.tachiyomi.data.source.online.russian + +import android.content.Context +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.RU +import eu.kanade.tachiyomi.data.source.base.ParsedOnlineSource +import eu.kanade.tachiyomi.data.source.model.Page +import okhttp3.Response +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import java.text.SimpleDateFormat +import java.util.* +import java.util.regex.Pattern + +class Readmanga(context: Context, override val id: Int) : ParsedOnlineSource(context) { + + override val name = "Readmanga" + + override val baseUrl = "http://readmanga.me" + + override val lang: Language get() = RU + + override fun popularMangaInitialUrl() = "$baseUrl/list?sortType=rate" + + override fun searchMangaInitialUrl(query: String) = "$baseUrl/search?q=$query" + + override fun popularMangaSelector() = "div.desc" + + override fun popularMangaFromElement(element: Element, manga: Manga) { + element.select("h3 > a").first().let { + manga.setUrl(it.attr("href")) + manga.title = it.attr("title") + } + } + + override fun popularMangaNextPageSelector() = "a.nextLink" + + override fun searchMangaSelector() = popularMangaSelector() + + override fun searchMangaFromElement(element: Element, manga: Manga) { + popularMangaFromElement(element, manga) + } + + override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() + + override fun mangaDetailsParse(document: Document, manga: Manga) { + val infoElement = document.select("div.leftContent").first() + + manga.author = infoElement.select("span.elem_author").first()?.text() + manga.genre = infoElement.select("span.elem_genre").text().replace(" ,", ",") + manga.description = infoElement.select("div.manga-description").text() + manga.status = parseStatus(infoElement.html()) + manga.thumbnail_url = infoElement.select("img").attr("data-full") + } + + private fun parseStatus(element: String): Int { + when { + element.contains("

Запрещена публикация произведения по копирайту

") -> return Manga.LICENSED + element.contains("

Сингл") || element.contains("Перевод: завершен") -> return Manga.COMPLETED + element.contains("Перевод: продолжается") -> return Manga.ONGOING + else -> return Manga.UNKNOWN + } + } + + override fun chapterListSelector() = "div.chapters-link tbody tr" + + override fun chapterFromElement(element: Element, chapter: Chapter) { + val urlElement = element.select("a").first() + + chapter.setUrl(urlElement.attr("href") + "?mature=1") + chapter.name = urlElement.text().replace(" новое", "") + chapter.date_upload = element.select("td:eq(1)").first()?.text()?.let { + SimpleDateFormat("dd/MM/yy", Locale.US).parse(it).time + } ?: 0 + } + + override fun parseChapterNumber(chapter: Chapter) { + chapter.chapter_number = -2f + } + + override fun pageListParse(response: Response, pages: MutableList) { + val html = response.body().string() + val beginIndex = html.indexOf("rm_h.init( [") + val endIndex = html.indexOf("], 0, false);", beginIndex) + val trimmedHtml = html.substring(beginIndex, endIndex).replace("[\"\']+".toRegex(), "") + + val p = Pattern.compile("auto/[\\w/]+,http://[\\w.]+/,/[\\w./]+.(png|jpg)+") + val m = p.matcher(trimmedHtml) + + var i = 0 + while (m.find()) { + val urlParts = m.group().split(',') + pages.add(Page(i++, "", urlParts[1] + urlParts[0] + urlParts[2])) + } + } + + override fun pageListParse(document: Document, pages: MutableList) { } + + override fun imageUrlParse(document: Document) = "" +} \ No newline at end of file