diff --git a/src/ja/rawQQ/build.gradle b/src/ja/rawQQ/build.gradle new file mode 100644 index 000000000..00cc830e6 --- /dev/null +++ b/src/ja/rawQQ/build.gradle @@ -0,0 +1,13 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +ext { + appName = 'Tachiyomi: RawQQ' + pkgNameSuffix = "ja.rawqq" + extClass = '.Rawqq' + extVersionCode = 1 + extVersionSuffix = 0 + libVersion = '1.2' +} + +apply from: "$rootDir/common.gradle" diff --git a/src/ja/rawQQ/res/mipmap-hdpi/ic_launcher.png b/src/ja/rawQQ/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..45d53a379 Binary files /dev/null and b/src/ja/rawQQ/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/ja/rawQQ/res/mipmap-mdpi/ic_launcher.png b/src/ja/rawQQ/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..7b4ebddb1 Binary files /dev/null and b/src/ja/rawQQ/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/ja/rawQQ/res/mipmap-xhdpi/ic_launcher.png b/src/ja/rawQQ/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..176b82084 Binary files /dev/null and b/src/ja/rawQQ/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/ja/rawQQ/res/mipmap-xxhdpi/ic_launcher.png b/src/ja/rawQQ/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..949434dd9 Binary files /dev/null and b/src/ja/rawQQ/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/ja/rawQQ/res/mipmap-xxxhdpi/ic_launcher.png b/src/ja/rawQQ/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..73a2ddea3 Binary files /dev/null and b/src/ja/rawQQ/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/ja/rawQQ/res/web_hi_res_512.png b/src/ja/rawQQ/res/web_hi_res_512.png new file mode 100644 index 000000000..ec8069037 Binary files /dev/null and b/src/ja/rawQQ/res/web_hi_res_512.png differ diff --git a/src/ja/rawQQ/src/eu/kanade/tachiyomi/extension/ja/rawqq/Rawqq.kt b/src/ja/rawQQ/src/eu/kanade/tachiyomi/extension/ja/rawqq/Rawqq.kt new file mode 100644 index 000000000..02a623bd0 --- /dev/null +++ b/src/ja/rawQQ/src/eu/kanade/tachiyomi/extension/ja/rawqq/Rawqq.kt @@ -0,0 +1,226 @@ +package eu.kanade.tachiyomi.extension.ja.rawqq + +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.source.model.* +import eu.kanade.tachiyomi.source.online.ParsedHttpSource +import okhttp3.HttpUrl +import okhttp3.Request +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import java.util.* + +class Rawqq : ParsedHttpSource() { + + override val name = "RawQQ" + + override val baseUrl = "http://rawqq.com" + + override val lang = "ja" + + override val supportsLatest = true + + override fun popularMangaRequest(page: Int): Request = + GET("$baseUrl/manga-list.html?listType=pagination&page=$page&artist=&author=&group=&m_status=&name=&genre=&ungenre=&sort=views&sort_type=DESC", headers) + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { + val url = HttpUrl.parse("$baseUrl/manga-list.html?")!!.newBuilder().addQueryParameter("name", query) + (if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> + when (filter) { + is Status -> { + val status = arrayOf("", "1", "2")[filter.state] + url.addQueryParameter("m_status", status) + } + is TextField -> url.addQueryParameter(filter.key, filter.state) + is GenreList -> { + + var genre = mutableListOf() + var ungenre = mutableListOf() + + filter.state.forEach {it -> + if (it.isIncluded()) genre.add(it.name) + if (it.isExcluded()) ungenre.add(it.name) + } + url.addQueryParameter("genre", genre.joinToString()) + url.addQueryParameter("ungenre", ungenre.joinToString()) + } + } + } + return GET(url.toString(), headers) + } + + override fun latestUpdatesRequest(page: Int): Request = + GET("$baseUrl/manga-list.html?listType=pagination&page=$page&artist=&author=&group=&m_status=&name=&genre=&sort=last_update&sort_type=DESC") + + override fun popularMangaSelector() = "div.media" + + override fun latestUpdatesSelector() = popularMangaSelector() + + override fun searchMangaSelector() = popularMangaSelector() + + override fun popularMangaFromElement(element: Element): SManga { + val manga = SManga.create() + element.select("h3 > a").first().let { + manga.setUrlWithoutDomain("/" + it.attr("href")) + manga.title = it.text() + } + return manga + } + + override fun latestUpdatesFromElement(element: Element): SManga = + popularMangaFromElement(element) + + override fun searchMangaFromElement(element: Element): SManga = popularMangaFromElement(element) + + override fun popularMangaNextPageSelector() = "a:contains(ยป)" + + override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() + + override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() + + + override fun mangaDetailsParse(document: Document): SManga { + val manga = SManga.create() + val infoElement = document.select("div.row").first() + manga.author = infoElement.select("small a.btn.btn-xs.btn-info").first()?.text() + manga.status = parseStatus(infoElement.select("a.btn.btn-xs.btn-success").first().text()) + + manga.description = document.select("div.content").first()?.text() + val imgUrl = document.select("img.thumbnail").first()?.attr("src") + if (imgUrl!!.startsWith("app/")) { + manga.thumbnail_url = "$baseUrl/$imgUrl" + } else { + manga.thumbnail_url = imgUrl + } + var genres = mutableListOf() + infoElement.select("div.row small a.btn.btn-xs.btn-danger")?.forEach { it -> genres.add(it.text())} + manga.genre = genres.joinToString(", ") + + return manga + } + + private fun parseStatus(element: String): Int = when { + element.contains("Completed") -> SManga.COMPLETED + element.contains("Ongoing") -> SManga.ONGOING + else -> SManga.UNKNOWN + } + + //override fun chapterListSelector() = " table.table.table-hover tbody tr" + override fun chapterListSelector() = " div#list-chapters.list-wrap p" + + + override fun chapterFromElement(element: Element): SChapter { + val urlElement = element.select("span.title a").first() + val timeElement = element.select("span.publishedDate time").first() + + val chapter = SChapter.create() + chapter.setUrlWithoutDomain("/" + urlElement.attr("href")) + chapter.name = urlElement.text() + chapter.date_upload = parseChapterDate(timeElement.text()) + return chapter + } + + private fun parseChapterDate(date: String): Long { + val value = date.split(' ')[0].toInt() + return when { + "hour(s) ago" in date -> Calendar.getInstance().apply { + add(Calendar.HOUR_OF_DAY, value * -1) + set(Calendar.SECOND, 0) + set(Calendar.MILLISECOND, 0) + }.timeInMillis + "day(s) ago" in date -> Calendar.getInstance().apply { + add(Calendar.DATE, value * -1) + set(Calendar.SECOND, 0) + set(Calendar.MILLISECOND, 0) + }.timeInMillis + "week(s) ago" in date -> Calendar.getInstance().apply { + add(Calendar.DATE, value * 7 * -1) + set(Calendar.SECOND, 0) + set(Calendar.MILLISECOND, 0) + }.timeInMillis + "month(s) ago" in date -> Calendar.getInstance().apply { + add(Calendar.MONTH, value * -1) + set(Calendar.SECOND, 0) + set(Calendar.MILLISECOND, 0) + }.timeInMillis + else -> { + return 0 + } + } + } + + + override fun pageListParse(document: Document): List { + val pages = mutableListOf() + document.select("img.chapter-img").forEach { + val url = it.attr("src") + if (url != "") { + pages.add(Page(pages.size, "", url)) + } + } + return pages + } + + override fun imageUrlParse(document: Document) = "" + + private class TextField(name: String, val key: String) : Filter.Text(name) + private class Status : Filter.Select("Status", arrayOf("Any", "Completed", "Ongoing")) + private class GenreList(genres: List) : Filter.Group("Genre", genres) + private class Genre(name: String, val id: String = name.replace(' ', '+')) : Filter.TriState(name) + + + override fun getFilterList() = FilterList( + TextField("Author", "author"), + TextField("Group", "group"), + Status(), + GenreList(getGenreList()) + ) + + + private fun getGenreList() = listOf( + Genre("4-Koma"), + Genre("Action"), + Genre("Adult"), + Genre("Adventure"), + Genre("Isekai"), + Genre("Comedy"), + Genre("Comic"), + Genre("Cooking"), + Genre("Doujinshi"), + Genre("Drama"), + Genre("Ecchi"), + Genre("Fantasy"), + Genre("Gender Bender"), + Genre("Harem"), + Genre("Historical"), + Genre("Horror"), + Genre("Josei"), + Genre("Lolicon"), + Genre("Manga"), + Genre("Manhua"), + Genre("Manhwa"), + Genre("Martial Art"), + Genre("Mature"), + Genre("Mecha"), + Genre("Medical"), + Genre("Music"), + Genre("Mystery"), + Genre("One shot"), + Genre("Psychological"), + Genre("Romance"), + Genre("School Life"), + Genre("Sci-fi"), + Genre("Seinen"), + Genre("Shoujo"), + Genre("Shojou Ai"), + Genre("Shounen"), + Genre("Shounen Ai"), + Genre("Slice of Life"), + Genre("Smut"), + Genre("Sports"), + Genre("Supernatural"), + Genre("Tragedy"), + Genre("Webtoon"), + Genre("Yaoi"), + Genre("Yuri") + ) +} \ No newline at end of file diff --git a/src/ja/rawlh/build.gradle b/src/ja/rawlh/build.gradle index 777d73e60..5a6a4b16f 100644 --- a/src/ja/rawlh/build.gradle +++ b/src/ja/rawlh/build.gradle @@ -5,8 +5,8 @@ ext { appName = 'Tachiyomi: RawLH' pkgNameSuffix = "ja.rawlh" extClass = '.Rawlh' - extVersionCode = 2 - extVersionSuffix = 0 + extVersionCode = 3 + extVersionSuffix = 1 libVersion = '1.2' } diff --git a/src/ja/rawlh/src/eu/kanade/tachiyomi/extension/ja/rawlh/Rawlh.kt b/src/ja/rawlh/src/eu/kanade/tachiyomi/extension/ja/rawlh/Rawlh.kt index ac79d5fe1..64c145209 100644 --- a/src/ja/rawlh/src/eu/kanade/tachiyomi/extension/ja/rawlh/Rawlh.kt +++ b/src/ja/rawlh/src/eu/kanade/tachiyomi/extension/ja/rawlh/Rawlh.kt @@ -7,13 +7,13 @@ import okhttp3.HttpUrl import okhttp3.Request import org.jsoup.nodes.Document import org.jsoup.nodes.Element -import java.util.Calendar +import java.util.* class Rawlh : ParsedHttpSource() { override val name = "RawLH" - override val baseUrl = "http://rawlh.com" + override val baseUrl = "http://lhscan.net" override val lang = "ja"