diff --git a/src/en/irovedout/AndroidManifest.xml b/src/en/irovedout/AndroidManifest.xml new file mode 100644 index 000000000..b4571bfa8 --- /dev/null +++ b/src/en/irovedout/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/en/irovedout/build.gradle b/src/en/irovedout/build.gradle new file mode 100644 index 000000000..88484283b --- /dev/null +++ b/src/en/irovedout/build.gradle @@ -0,0 +1,12 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +ext { + extName = 'I Roved Out' + pkgNameSuffix = 'en.irovedout' + extClass = '.IRovedOut' + extVersionCode = 1 + isNsfw = true +} + +apply from: "$rootDir/common.gradle" diff --git a/src/en/irovedout/res/mipmap-hdpi/ic_launcher.png b/src/en/irovedout/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..23a83e125 Binary files /dev/null and b/src/en/irovedout/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/en/irovedout/res/mipmap-mdpi/ic_launcher.png b/src/en/irovedout/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..e4c61108b Binary files /dev/null and b/src/en/irovedout/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/en/irovedout/res/mipmap-xhdpi/ic_launcher.png b/src/en/irovedout/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..1e2ab3ccf Binary files /dev/null and b/src/en/irovedout/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/en/irovedout/res/mipmap-xxhdpi/ic_launcher.png b/src/en/irovedout/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..423aacc9d Binary files /dev/null and b/src/en/irovedout/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/en/irovedout/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/irovedout/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..483558a60 Binary files /dev/null and b/src/en/irovedout/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/en/irovedout/res/web_hi_res_512.png b/src/en/irovedout/res/web_hi_res_512.png new file mode 100644 index 000000000..944436dcf Binary files /dev/null and b/src/en/irovedout/res/web_hi_res_512.png differ diff --git a/src/en/irovedout/src/eu/kanade/tachiyomi/extension/en/irovedout/IRovedOut.kt b/src/en/irovedout/src/eu/kanade/tachiyomi/extension/en/irovedout/IRovedOut.kt new file mode 100644 index 000000000..aee0b3911 --- /dev/null +++ b/src/en/irovedout/src/eu/kanade/tachiyomi/extension/en/irovedout/IRovedOut.kt @@ -0,0 +1,122 @@ +package eu.kanade.tachiyomi.extension.en.irovedout + +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.MangasPage +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.source.online.HttpSource +import eu.kanade.tachiyomi.util.asJsoup +import okhttp3.Request +import okhttp3.Response +import rx.Observable +import java.lang.Exception +import java.text.SimpleDateFormat +import java.util.Locale + +class IRovedOut : HttpSource() { + + override val name = "I Roved Out" + override val baseUrl = "https://irovedout.com" + override val lang = "en" + override val supportsLatest = false + private val archiveUrl = "$baseUrl/archive" + private val thumbnailUrl = "https://i.ibb.co/2g7Htwq/irovedout.png" + private val seriesTitle = "I Roved Out in Search of Truth and Love" + private val authorName = "Alexis Flower" + private val seriesGenre = "Fantasy" + private val seriesDescription = """ + I ROVED OUT IN SEARCH OF TRUTH AND LOVE is written & illustrated by Alexis Flower. + It updates in chunks anywhere between 3 and 30 pages long at least once a month. + """.trimIndent() + private val dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.US) + private val titleRegex = Regex("Book (?\\d+): (?.+)") + + override fun chapterListRequest(manga: SManga): Request = throw Exception("Not used") + + override fun chapterListParse(response: Response): List = throw Exception("Not used") + + override fun fetchChapterList(manga: SManga): Observable> { + val mainPage = client.newCall(GET(baseUrl, headers)).execute().asJsoup() + val books = mainPage.select("#menu-menu > li > a[href^=$archiveUrl]") + + var chapterCounter = 1F + val chaptersByBook = books.mapIndexed { bookIndex, book -> + val bookNumber = bookIndex + 1 + val bookUrl = book.attr("href") + val bookPage = client.newCall(GET(bookUrl, headers)).execute().asJsoup() + val chapters = bookPage.select(".comic-archive-chapter-wrap") + chapters.map { + val chapterWrap = it.selectFirst(".comic-archive-chapter-wrap") + SChapter.create().apply { + name = "Book $bookNumber: ${chapterWrap.selectFirst(".comic-archive-chapter").text()}" + url = chapterWrap.selectFirst(".comic-archive-title > a").attr("href") + date_upload = dateFormat.parse(chapterWrap.select(".comic-archive-date").last().text())?.time ?: 0L + chapter_number = chapterCounter++ + } + } + } + return Observable.just(chaptersByBook.flatten().reversed()) + } + + override fun fetchImageUrl(page: Page): Observable { + val comicPage = client.newCall(GET(page.url, headers)).execute().asJsoup() + val imageUrl = comicPage.selectFirst("#comic > a > img").attr("src") + return Observable.just(imageUrl) + } + + override fun imageUrlParse(response: Response): String = throw Exception("Not used") + + override fun latestUpdatesParse(response: Response): MangasPage = throw Exception("Not used") + + override fun latestUpdatesRequest(page: Int): Request = throw Exception("Not used") + + override fun fetchMangaDetails(manga: SManga): Observable { + return Observable.just(manga) + } + + override fun mangaDetailsParse(response: Response): SManga = throw Exception("Not used") + + override fun fetchPageList(chapter: SChapter): Observable> { + val match = titleRegex.matchEntire(chapter.name) ?: return Observable.just(listOf()) + val bookNumber = match.groups["bookNumber"]!!.value.toInt() + val title = match.groups["chapterTitle"]!!.value + val bookPage = client.newCall(GET(archiveUrl + if (bookNumber != 1) "-book-$bookNumber" else "", headers)).execute().asJsoup() + val chapterWrap = bookPage.select(".comic-archive-chapter-wrap").find { it.selectFirst(".comic-archive-chapter").text() == title } + val pageUrls = chapterWrap?.select(".comic-archive-list-wrap .comic-archive-title > a")?.map { it.attr("href") } ?: return Observable.just(listOf()) + val pages = pageUrls.mapIndexed { pageIndex, pageUrl -> + Page(pageIndex, pageUrl) + } + return Observable.just(pages) + } + + override fun pageListRequest(chapter: SChapter): Request = throw Exception("Not used") + + override fun pageListParse(response: Response): List = throw Exception("Not used") + + override fun fetchPopularManga(page: Int): Observable { + val manga = SManga.create().apply { + url = "" + thumbnail_url = thumbnailUrl + title = seriesTitle + author = authorName + artist = authorName + description = seriesDescription + genre = seriesGenre + status = SManga.ONGOING + initialized = true + } + return Observable.just(MangasPage(listOf(manga), false)) + } + + override fun popularMangaParse(response: Response): MangasPage = throw Exception("Not used") + + override fun popularMangaRequest(page: Int): Request = throw Exception("Not used") + + override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = throw Exception("Not used") + + override fun searchMangaParse(response: Response): MangasPage = throw Exception("Not used") + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw Exception("Not used") +} diff --git a/src/en/zeroscans/src/eu/kanade/tachiyomi/extension/en/zeroscans/ZeroScansDto.kt b/src/en/zeroscans/src/eu/kanade/tachiyomi/extension/en/zeroscans/ZeroScansDto.kt index e2914f1e5..f11a6e807 100644 --- a/src/en/zeroscans/src/eu/kanade/tachiyomi/extension/en/zeroscans/ZeroScansDto.kt +++ b/src/en/zeroscans/src/eu/kanade/tachiyomi/extension/en/zeroscans/ZeroScansDto.kt @@ -1,6 +1,5 @@ package eu.kanade.tachiyomi.extension.en.zeroscans -import eu.kanade.tachiyomi.source.model.Page import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonElement