diff --git a/.github/summary.yaml b/.github/summary.yaml index e507b38c..e9b61d42 100644 --- a/.github/summary.yaml +++ b/.github/summary.yaml @@ -1 +1 @@ -total: 1206 +total: 1212 diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/iken/en/HiveComic.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/iken/en/HiveComic.kt new file mode 100644 index 00000000..90ac1f91 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/iken/en/HiveComic.kt @@ -0,0 +1,14 @@ +package org.koitharu.kotatsu.parsers.site.iken.en + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.site.iken.IkenParser +import org.koitharu.kotatsu.parsers.Broken + +@Broken("Need to fix getPages") +@MangaSourceParser("HIVECOMIC", "HiveComic", "en") +internal class HiveComic(context: MangaLoaderContext) : + IkenParser(context, MangaParserSource.HIVECOMIC, "hivecomic.com") { + override val selectPages = "main section img" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/AsuraScansTR.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/AsuraScansTR.kt new file mode 100644 index 00000000..77be488d --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/AsuraScansTR.kt @@ -0,0 +1,12 @@ +package org.koitharu.kotatsu.parsers.site.madara.tr + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("ASURASCANSTR", "AsuraScansTR", "tr") +internal class AsuraScansTR(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.ASURASCANSTR, "asurascans.com.tr") { + override val tagPrefix = "tur/" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/TrMangaOku.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/TrMangaOku.kt new file mode 100644 index 00000000..80111682 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/TrMangaOku.kt @@ -0,0 +1,12 @@ +package org.koitharu.kotatsu.parsers.site.madara.tr + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("TRMANGAOKU", "TrMangaOku", "tr") +internal class TrMangaOku(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.TRMANGAOKU, "trmangaoku.com") { + override val tagPrefix = "tur/" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/MangaKoleji.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/MangaKoleji.kt new file mode 100644 index 00000000..781b4c68 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/MangaKoleji.kt @@ -0,0 +1,16 @@ +package org.koitharu.kotatsu.parsers.site.mangareader.tr + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser + +@MangaSourceParser("MANGAKOLEJI", "MangaKoleji", "tr") +internal class MangaKoleji(context: MangaLoaderContext) : + MangaReaderParser(context, MangaParserSource.MANGAKOLEJI, "mangakoleji.com", pageSize = 20, searchPageSize = 10) { + override val filterCapabilities: MangaListFilterCapabilities + get() = super.filterCapabilities.copy( + isTagsExclusionSupported = true, + ) +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/Mangacix.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/Mangacix.kt new file mode 100644 index 00000000..92e2ba46 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/Mangacix.kt @@ -0,0 +1,16 @@ +package org.koitharu.kotatsu.parsers.site.mangareader.tr + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser + +@MangaSourceParser("MANGACIX", "Mangacix", "tr") +internal class Mangacix(context: MangaLoaderContext) : + MangaReaderParser(context, MangaParserSource.MANGACIX, "mangacix.com", 20, 10) { + override val filterCapabilities: MangaListFilterCapabilities + get() = super.filterCapabilities.copy( + isTagsExclusionSupported = true, + ) +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/UzayManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/UzayManga.kt new file mode 100644 index 00000000..d4e5ec2b --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/UzayManga.kt @@ -0,0 +1,135 @@ +package org.koitharu.kotatsu.parsers.site.tr + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.config.ConfigKey +import org.koitharu.kotatsu.parsers.core.LegacyPagedMangaParser +import org.koitharu.kotatsu.parsers.model.* +import org.koitharu.kotatsu.parsers.util.* +import java.text.SimpleDateFormat +import java.util.* + +@MangaSourceParser("UZAYMANGA", "Uzay Manga", "tr") +internal class UzayManga(context: MangaLoaderContext) : LegacyPagedMangaParser(context, MangaParserSource.UZAYMANGA, 2) { + + override val configKeyDomain = ConfigKey.Domain("uzaymanga.com") + + override val availableSortOrders: Set = EnumSet.of( + SortOrder.NEWEST, + SortOrder.UPDATED, + SortOrder.POPULARITY, + ) + + override val filterCapabilities: MangaListFilterCapabilities + get() = MangaListFilterCapabilities( + isSearchSupported = true, + isMultipleTagsSupported = true, + ) + + override suspend fun getFilterOptions() = MangaListFilterOptions( + availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED), + availableContentTypes = EnumSet.of( + ContentType.MANGA, + ContentType.MANHWA, + ContentType.MANHUA, + ContentType.COMICS, + ContentType.OTHER, + ), + ) + + override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List { + val url = buildString { + append("https://") + append(domain) + append("/search") + append("&page=") + append(page.toString()) + + if (!filter.query.isNullOrEmpty()) { + append("&search") + append(filter.query.urlEncoded()) + } + + append("&order=") + append( + when (order) { + SortOrder.NEWEST -> "3" + SortOrder.UPDATED -> "4" + SortOrder.POPULARITY -> "2" + else -> "3" + } + ) + } + + val doc = webClient.httpGet(url).parseHtml() + return doc.select("section[aria-label='series area'] .card").map { card -> + val href = card.selectFirstOrThrow("a").attrAsRelativeUrl("href") + Manga( + id = generateUid(href), + title = card.selectFirst("h2")?.text().orEmpty(), + altTitles = emptySet(), + url = href, + publicUrl = href.toAbsoluteUrl("uzaymanga.com"), + rating = RATING_UNKNOWN, + contentRating = null, + coverUrl = card.selectFirst("img")?.attrAsAbsoluteUrlOrNull("src"), + tags = emptySet(), + state = null, + authors = emptySet(), + source = source, + ) + } + } + + override suspend fun getDetails(manga: Manga): Manga { + val doc = webClient.httpGet(manga.url.toAbsoluteUrl("uzaymanga.com")).parseHtml() + val statusText = doc.selectFirst("span:contains(Durum) + span")?.text().orEmpty() + return manga.copy( + tags = doc.select("a[href^='search?categories']").mapToSet { + MangaTag( + key = it.text().lowercase(Locale.ROOT), + title = it.text(), + source = source, + ) + }, + description = doc.selectFirst("div.grid h2 + p")?.text(), + state = when (statusText) { + "Devam Ediyor" -> MangaState.ONGOING + "Birakildi" -> MangaState.ONGOING + "Tamamlandi" -> MangaState.FINISHED + else -> null + }, + chapters = doc.select("div.list-episode a").mapChapters(reversed = true) { i, el -> + val href = el.attrAsRelativeUrl("href") + val dateFormat = SimpleDateFormat("MMM d ,yyyy", Locale("tr")) + MangaChapter( + id = generateUid(href), + title = el.selectFirstOrThrow("h3").text(), + number = (i + 1).toFloat(), + volume = 0, + url = href, + scanlator = null, + uploadDate = el.selectFirst("span")?.text()?.let { dateFormat.tryParse(it) } ?: 0L, + branch = null, + source = source, + ) + }, + ) + } + + override suspend fun getPages(chapter: MangaChapter): List { + val doc = webClient.httpGet(chapter.url.toAbsoluteUrl("uzaymanga.com")).parseHtml() + val pageRegex = Regex("\\\\\"path\\\\\":\\\\\"([^\"]+)\\\\\"") + val script = doc.select("script").find { it.html().contains(pageRegex) }?.html() ?: return emptyList() + return pageRegex.findAll(script).mapNotNull { result -> + result.groups[1]?.value?.let { url -> + MangaPage( + id = generateUid(url), + url = "https://cdn1.uzaymanga.com/upload/series/$url", + preview = null, + source = source, + ) + } + }.toList() + } +}