diff --git a/src/pt/nixmangas/AndroidManifest.xml b/src/pt/nixmangas/AndroidManifest.xml deleted file mode 100644 index 8072ee00d..000000000 --- a/src/pt/nixmangas/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest /> diff --git a/src/pt/nixmangas/build.gradle b/src/pt/nixmangas/build.gradle deleted file mode 100644 index a161d0713..000000000 --- a/src/pt/nixmangas/build.gradle +++ /dev/null @@ -1,13 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply plugin: 'kotlinx-serialization' - -ext { - extName = 'Nix Mangás' - pkgNameSuffix = 'pt.nixmangas' - extClass = '.NixMangas' - extVersionCode = 3 - isNsfw = true -} - -apply from: "$rootDir/common.gradle" diff --git a/src/pt/nixmangas/res/mipmap-hdpi/ic_launcher.png b/src/pt/nixmangas/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 84ed29191..000000000 Binary files a/src/pt/nixmangas/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/pt/nixmangas/res/mipmap-mdpi/ic_launcher.png b/src/pt/nixmangas/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 008d349da..000000000 Binary files a/src/pt/nixmangas/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/pt/nixmangas/res/mipmap-xhdpi/ic_launcher.png b/src/pt/nixmangas/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index f7d413ee6..000000000 Binary files a/src/pt/nixmangas/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/pt/nixmangas/res/mipmap-xxhdpi/ic_launcher.png b/src/pt/nixmangas/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index cc0a1bd6f..000000000 Binary files a/src/pt/nixmangas/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/pt/nixmangas/res/mipmap-xxxhdpi/ic_launcher.png b/src/pt/nixmangas/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 1e4dc7152..000000000 Binary files a/src/pt/nixmangas/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/pt/nixmangas/res/web_hi_res_512.png b/src/pt/nixmangas/res/web_hi_res_512.png deleted file mode 100644 index 3f20f665a..000000000 Binary files a/src/pt/nixmangas/res/web_hi_res_512.png and /dev/null differ diff --git a/src/pt/nixmangas/src/eu/kanade/tachiyomi/extension/pt/nixmangas/NixMangas.kt b/src/pt/nixmangas/src/eu/kanade/tachiyomi/extension/pt/nixmangas/NixMangas.kt deleted file mode 100644 index 47711914f..000000000 --- a/src/pt/nixmangas/src/eu/kanade/tachiyomi/extension/pt/nixmangas/NixMangas.kt +++ /dev/null @@ -1,165 +0,0 @@ -package eu.kanade.tachiyomi.extension.pt.nixmangas - -import eu.kanade.tachiyomi.network.GET -import eu.kanade.tachiyomi.network.interceptor.rateLimitHost -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 kotlinx.serialization.decodeFromString -import kotlinx.serialization.json.Json -import okhttp3.Headers -import okhttp3.HttpUrl.Companion.toHttpUrl -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.Response -import rx.Observable -import uy.kohesive.injekt.injectLazy -import java.util.concurrent.TimeUnit - -class NixMangas : HttpSource() { - - override val name = "Nix Mangás" - - override val baseUrl = "https://nixmangas.com" - - override val lang = "pt-BR" - - override val supportsLatest = true - - override val client: OkHttpClient = network.cloudflareClient.newBuilder() - .rateLimitHost(baseUrl.toHttpUrl(), 1, 1, TimeUnit.SECONDS) - .rateLimitHost(API_URL.toHttpUrl(), 1, 1, TimeUnit.SECONDS) - .rateLimitHost(CDN_URL.toHttpUrl(), 1, 2, TimeUnit.SECONDS) - .build() - - private val json: Json by injectLazy() - - private val apiHeaders: Headers by lazy { apiHeadersBuilder().build() } - - override fun headersBuilder(): Headers.Builder = Headers.Builder() - .add("Origin", baseUrl) - .add("Referer", baseUrl) - - private fun apiHeadersBuilder(): Headers.Builder = headersBuilder() - .add("Accept", ACCEPT_JSON) - - /** - * The site doesn't have a popular section, so we use latest instead. - */ - override fun popularMangaRequest(page: Int) = latestUpdatesRequest(page) - - override fun popularMangaParse(response: Response) = latestUpdatesParse(response) - - override fun latestUpdatesRequest(page: Int): Request { - return GET("$API_URL/mangas?page=$page", apiHeaders) - } - - override fun latestUpdatesParse(response: Response): MangasPage { - val result = response.parseAs<NixMangasPaginatedContent<NixMangasWorkDto>>() - val workList = result.data.map(NixMangasWorkDto::toSManga) - - return MangasPage(workList, result.hasNextPage) - } - - override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - // The search with query isn't working in their direct API for some reason, - // so we use their site wrapped API instead for now. - val apiUrl = "$API_URL/mangas".toHttpUrl().newBuilder() - .addQueryParameter("page", page.toString()) - .addQueryParameter("search", query) - .build() - - return GET(apiUrl, apiHeaders) - } - - override fun searchMangaParse(response: Response): MangasPage = latestUpdatesParse(response) - - override fun getMangaUrl(manga: SManga): String = baseUrl + manga.url - - override fun mangaDetailsRequest(manga: SManga): Request { - val slug = manga.url.substringAfter("/obras/") - - return GET("$API_URL/mangas/$slug/details", apiHeaders) - } - - override fun mangaDetailsParse(response: Response): SManga { - val result = response.parseAs<NixMangasDetailsDto>() - - return result.manga.toSManga() - } - - override fun chapterListRequest(manga: SManga): Request { - val slug = manga.url.substringAfter("/obras/") - - return chapterListPaginatedRequest(slug) - } - - private fun chapterListPaginatedRequest(slug: String, page: Int = 1): Request { - return GET("$API_URL/mangas/$slug/chapters?page=$page", apiHeaders) - } - - override fun chapterListParse(response: Response): List<SChapter> { - var result = response.parseAs<NixMangasPaginatedContent<NixMangasChapterDto>>() - val currentTimeStamp = System.currentTimeMillis() - val chapters = result.data.toMutableList() - val slug = response.request.url.pathSegments[2] - - while (result.currentPage < result.lastPage) { - val nextRequest = chapterListPaginatedRequest(slug, result.currentPage + 1) - result = client.newCall(nextRequest).execute().parseAs() - - chapters += result.data - } - - return chapters - .filter { it.isPublished } - .map(NixMangasChapterDto::toSChapter) - .filter { it.date_upload <= currentTimeStamp } - .sortedByDescending(SChapter::chapter_number) - } - - override fun getChapterUrl(chapter: SChapter): String = baseUrl + chapter.url - - override fun pageListRequest(chapter: SChapter): Request { - val id = chapter.url.substringAfter("/ler/") - - return GET("$API_URL/chapters/$id") - } - - override fun pageListParse(response: Response): List<Page> { - val result = response.parseAs<NixMangasReaderDto>() - val chapterUrl = "$baseUrl/ler/${result.chapter.slug}" - - return result.chapter.pages.mapIndexed { i, pageDto -> - Page(i, chapterUrl, pageDto.pageUrl) - } - } - - override fun fetchImageUrl(page: Page): Observable<String> = Observable.just(page.imageUrl!!) - - override fun imageUrlParse(response: Response): String = "" - - override fun imageRequest(page: Page): Request { - val newHeaders = headersBuilder() - .add("Accept", ACCEPT_IMAGE) - .set("Referer", page.url) - .build() - - return GET(page.imageUrl!!, newHeaders) - } - - private inline fun <reified T> Response.parseAs(): T = use { - json.decodeFromString(it.body.string()) - } - - companion object { - private const val ACCEPT_IMAGE = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8" - private const val ACCEPT_JSON = "application/json" - - private const val API_URL = "https://api.nixmangas.com/v1" - private const val CDN_URL = "https://cdn.nixmangas.com" - } -} diff --git a/src/pt/nixmangas/src/eu/kanade/tachiyomi/extension/pt/nixmangas/NixMangasDto.kt b/src/pt/nixmangas/src/eu/kanade/tachiyomi/extension/pt/nixmangas/NixMangasDto.kt deleted file mode 100644 index a33af7489..000000000 --- a/src/pt/nixmangas/src/eu/kanade/tachiyomi/extension/pt/nixmangas/NixMangasDto.kt +++ /dev/null @@ -1,88 +0,0 @@ -package eu.kanade.tachiyomi.extension.pt.nixmangas - -import eu.kanade.tachiyomi.source.model.SChapter -import eu.kanade.tachiyomi.source.model.SManga -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import java.text.SimpleDateFormat -import java.util.Locale -import java.util.TimeZone - -@Serializable -data class NixMangasPaginatedContent<T>( - @SerialName("current_page") val currentPage: Int, - val data: List<T> = emptyList(), - @SerialName("last_page") val lastPage: Int, -) { - - val hasNextPage: Boolean - get() = currentPage < lastPage -} - -@Serializable -data class NixMangasSearchDto(val mangas: NixMangasPaginatedContent<NixMangasWorkDto>) - -@Serializable -data class NixMangasDetailsDto(val manga: NixMangasWorkDto) - -@Serializable -data class NixMangasReaderDto(val chapter: NixMangasChapterDto) - -@Serializable -data class NixMangasWorkDto( - val id: String, - val chapters: List<NixMangasChapterDto> = emptyList(), - val cover: String? = null, - val genres: List<NixMangasGenreDto> = emptyList(), - @SerialName("is_adult") val isAdult: Boolean = false, - val slug: String, - val status: String? = null, - @SerialName("synopses") val synopsis: String? = null, - val thumbnail: String, - val title: String, -) { - - fun toSManga(): SManga = SManga.create().apply { - title = this@NixMangasWorkDto.title - description = synopsis - genre = genres.joinToString { it.name } - status = when (this@NixMangasWorkDto.status) { - "ACTIVE" -> SManga.ONGOING - else -> SManga.UNKNOWN - } - thumbnail_url = cover - url = "/obras/$slug" - } -} - -@Serializable -data class NixMangasGenreDto(val name: String) - -@Serializable -data class NixMangasChapterDto( - val id: String, - @SerialName("is_published") val isPublished: Boolean, - val number: Float, - val pages: List<NixMangasPageDto> = emptyList(), - val slug: String, - @SerialName("published_at") val publishedAt: String? = null, -) { - - fun toSChapter(): SChapter = SChapter.create().apply { - name = "Capítulo ${number.toString().replace(".0", "")}" - chapter_number = number - date_upload = runCatching { DATE_FORMATTER.parse(publishedAt!!)?.time } - .getOrNull() ?: 0L - url = "/ler/$id" - } - - companion object { - private val DATE_FORMATTER by lazy { - SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S", Locale.US) - .apply { timeZone = TimeZone.getTimeZone("UTC") } - } - } -} - -@Serializable -data class NixMangasPageDto(@SerialName("page_url") val pageUrl: String)