Remove Kouhai Work (#525)

This commit is contained in:
Mike 2024-01-23 08:36:48 -05:00 committed by Draff
parent a4c0420bf7
commit fa3fc7188f
11 changed files with 0 additions and 391 deletions

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity android:name=".en.kouhaiwork.KouhaiActivity"
android:theme="@android:style/Theme.NoDisplay"
android:exported="true"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="kouhai.work"
android:pathPattern="/series/..*"
android:scheme="https" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -1,7 +0,0 @@
ext {
extName = 'Kouhai Work'
extClass = '.KouhaiWork'
extVersionCode = 8
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,116 +0,0 @@
package eu.kanade.tachiyomi.extension.en.kouhaiwork
import kotlinx.serialization.Serializable
import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.Locale
const val ID_QUERY = "id:"
const val API_URL = "https://api.kouhai.work/v3"
const val STORAGE_URL = "https://api.kouhai.work/storage/"
private const val ISO_DATE = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'"
private val dateFormat = SimpleDateFormat(ISO_DATE, Locale.ROOT)
private val decimalFormat = DecimalFormat("#.##")
@Serializable
data class KouhaiSeries(
val id: Int,
val title: String,
val cover: String,
) {
inline val url get() = id.toString()
inline val thumbnail get() = STORAGE_URL + cover
override fun toString() = title.trim()
}
@Serializable
data class KouhaiSeriesDetails(
val synopsis: String,
val status: String,
val alternative_titles: List<String>? = null,
val artists: List<KouhaiTag>? = null,
val authors: List<KouhaiTag>? = null,
val genres: List<KouhaiTag>? = null,
val themes: List<KouhaiTag>? = null,
val demographics: List<KouhaiTag>? = null,
val chapters: List<KouhaiChapter>,
) {
val tags by lazy {
genres.orEmpty() + themes.orEmpty() + demographics.orEmpty()
}
override fun toString() = buildString {
append(synopsis)
alternative_titles?.joinTo(
this,
"\n",
"\n\nAlternative Names:\n",
)
}
}
@Serializable
data class KouhaiChapter(
val id: Int,
val volume: Int? = null,
val number: Float,
val name: String? = null,
val groups: List<KouhaiTag>,
val updated_at: String,
) {
inline val url get() = id.toString()
val timestamp by lazy {
dateFormat.parse(updated_at)?.time ?: 0L
}
override fun toString() = buildString {
volume?.let {
append("[Vol. ").append(it).append("] ")
}
append("Chapter ")
append(decimalFormat.format(number))
name?.let { append(" - ").append(it) }
}
}
@Serializable
data class KouhaiTag(
private val id: Int,
private val name: String,
) {
override fun toString() = name
}
@Serializable
data class KouhaiTagList(
val genres: List<KouhaiTag>,
val themes: List<KouhaiTag>,
val demographics: List<KouhaiTag>,
val status: KouhaiTag?,
)
@Serializable
data class KouhaiPages(
private val pages: List<KouhaiMedia>,
) : Iterable<KouhaiMedia> by pages
@Serializable
data class KouhaiMedia(private val media: String) {
override fun toString() = STORAGE_URL + media
}
typealias KouhaiSearch = List<String>
inline val KouhaiSearch.url get() = this[0]
inline val KouhaiSearch.title get() = this[1].trim()
inline val KouhaiSearch.thumbnail get() = STORAGE_URL + last()

View File

@ -1,35 +0,0 @@
package eu.kanade.tachiyomi.extension.en.kouhaiwork
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import android.util.Log
import kotlin.system.exitProcess
/**
* Springboard that accepts `{baseUrl}/series/{id}`
* intents and redirects them to the main Tachiyomi process.
*/
class KouhaiActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val segments = intent?.data?.pathSegments
if (segments != null && segments.size > 1) {
val activity = Intent().apply {
action = "eu.kanade.tachiyomi.SEARCH"
putExtra("query", ID_QUERY + segments[1])
putExtra("filter", packageName)
}
try {
startActivity(activity)
} catch (ex: ActivityNotFoundException) {
Log.e("KouhaiActivity", ex.message, ex)
}
} else {
Log.e("KouhaiActivity", "Failed to parse URI from intent: $intent")
}
finish()
exitProcess(0)
}
}

View File

@ -1,58 +0,0 @@
package eu.kanade.tachiyomi.extension.en.kouhaiwork
import eu.kanade.tachiyomi.source.model.Filter
class Genre(val id: Int, name: String) : Filter.CheckBox(name)
private val genres: List<Genre>
get() = listOf(
Genre(1, "Romance"),
Genre(2, "Comedy"),
Genre(3, "Slice of Life"),
Genre(4, "Fantasy"),
Genre(5, "Sci-Fi"),
Genre(6, "Psychological"),
Genre(7, "Horror"),
Genre(8, "Mystery"),
Genre(9, "Girls' Love"),
Genre(10, "Drama"),
Genre(11, "Action"),
Genre(12, "Ecchi"),
Genre(13, "Adventure"),
)
class GenresFilter(values: List<Genre> = genres) :
Filter.Group<Genre>("Genres", values)
class Theme(val id: Int, name: String) : Filter.CheckBox(name)
private val themes: List<Theme>
get() = listOf(
Theme(1, "Office Workers"),
Theme(2, "Family"),
Theme(3, "Supernatural"),
Theme(4, "Demons"),
Theme(5, "Magic"),
Theme(6, "Aliens"),
Theme(7, "Suggestive"),
Theme(8, "Doujinshi"),
Theme(9, "School Life"),
Theme(10, "Police"),
)
class ThemesFilter(values: List<Theme> = themes) :
Filter.Group<Theme>("Themes", values)
private val demographics: Array<String>
get() = arrayOf("Any", "Shounen", "Shoujo", "Seinen")
class DemographicsFilter(values: Array<String> = demographics) :
Filter.Select<String>("Demographic", values)
private val statuses: Array<String>
get() = arrayOf("Any", "Ongoing", "Finished", "Axed/Dropped")
class StatusFilter(values: Array<String> = statuses) :
Filter.Select<String>("Status", values)
inline fun <reified T> List<Filter<*>>.find() = find { it is T } as? T

View File

@ -1,157 +0,0 @@
package eu.kanade.tachiyomi.extension.en.kouhaiwork
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.asObservableSuccess
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.json.Json
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.json.encodeToJsonElement
import kotlinx.serialization.json.jsonObject
import okhttp3.FormBody
import okhttp3.Response
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class KouhaiWork : HttpSource() {
override val name = "Kouhai Work"
override val baseUrl = "https://kouhai.work"
override val lang = "en"
override val supportsLatest = true
override val id = 1273675602267580928L
private val json by lazy {
Json(Injekt.get()) { isLenient = true }
}
override fun latestUpdatesRequest(page: Int) =
GET("$API_URL/manga/recent", headers)
override fun latestUpdatesParse(response: Response) =
response.decode<List<KouhaiSeries>>().map {
SManga.create().apply {
url = it.url
title = it.toString()
thumbnail_url = it.thumbnail
}
}.let { MangasPage(it, false) }
override fun popularMangaRequest(page: Int) =
GET("$API_URL/manga/all", headers)
override fun popularMangaParse(response: Response) =
latestUpdatesParse(response)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) =
FormBody.Builder().add("search", query).add("tags", filters.json())
.let { POST("$API_URL/search/manga", headers, it.build()) }
override fun searchMangaParse(response: Response) =
response.decode<List<KouhaiSearch>>().map {
SManga.create().apply {
url = it.url
title = it.title
thumbnail_url = it.thumbnail
}
}.let { MangasPage(it, false) }
override fun fetchSearchManga(page: Int, query: String, filters: FilterList) =
if (!query.startsWith(ID_QUERY)) {
super.fetchSearchManga(page, query, filters)
} else {
val id = query.substringAfter(ID_QUERY)
val req = GET("$API_URL/manga/get/$id", headers)
client.newCall(req).asObservableSuccess().map {
val series = it.decode<KouhaiSeries>()
val manga = SManga.create().apply {
url = series.url
title = series.title
thumbnail_url = series.thumbnail
}
MangasPage(listOf(manga), false)
}!!
}
override fun mangaDetailsRequest(manga: SManga) =
GET("$API_URL/manga/get/${manga.url}", headers)
override fun mangaDetailsParse(response: Response) =
SManga.create().apply {
val series = response.decode<KouhaiSeriesDetails>()
description = series.toString()
author = series.authors?.joinToString()
artist = series.artists?.joinToString()
genre = series.tags.joinToString()
status = when (series.status) {
"ongoing" -> SManga.ONGOING
"finished" -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
initialized = true
}
override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga)
override fun chapterListParse(response: Response) =
response.decode<KouhaiSeriesDetails>().chapters.map {
SChapter.create().apply {
url = it.url
name = it.toString()
chapter_number = it.number
date_upload = it.timestamp
scanlator = it.groups.joinToString()
}
}.reversed()
override fun pageListRequest(chapter: SChapter) =
GET("$API_URL/chapters/get/${chapter.url}", headers)
override fun pageListParse(response: Response) =
response.decode<KouhaiPages>("chapter")
.mapIndexed { idx, img -> Page(idx, "", img.toString()) }
override fun getMangaUrl(manga: SManga) = "$baseUrl/series/${manga.url}"
override fun getChapterUrl(chapter: SChapter) = "$baseUrl/read/${chapter.url}"
override fun getFilterList() = FilterList(
GenresFilter(),
ThemesFilter(),
DemographicsFilter(),
StatusFilter(),
)
override fun imageUrlParse(response: Response) =
throw UnsupportedOperationException()
private fun FilterList.json() = json.encodeToJsonElement(
KouhaiTagList(
find<GenresFilter>()?.state?.filter { it.state }?.map {
KouhaiTag(it.id, it.name)
} ?: emptyList(),
find<ThemesFilter>()?.state?.filter { it.state }?.map {
KouhaiTag(it.id, it.name)
} ?: emptyList(),
find<DemographicsFilter>()?.takeIf { it.state != 0 }?.let {
listOf(KouhaiTag(it.state, it.values[it.state]))
} ?: emptyList(),
find<StatusFilter>()?.takeIf { it.state != 0 }?.let {
KouhaiTag(it.state - 1, it.values[it.state])
},
),
).toString()
private inline fun <reified T> Response.decode(key: String = "data") =
json.decodeFromJsonElement<T>(
json.parseToJsonElement(body.string()).jsonObject[key]!!,
)
}