[Komga] add filters by library (#1638)
* add filters by library * add custom User-Agent, Komga server can log it to identify clients * use BuildConfig for version name in User-Agent * add file size to chapter name
This commit is contained in:
parent
374915a989
commit
3152424782
@ -5,7 +5,7 @@ ext {
|
|||||||
appName = 'Tachiyomi: Komga'
|
appName = 'Tachiyomi: Komga'
|
||||||
pkgNameSuffix = 'all.komga'
|
pkgNameSuffix = 'all.komga'
|
||||||
extClass = '.Komga'
|
extClass = '.Komga'
|
||||||
extVersionCode = 2
|
extVersionCode = 3
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,6 +14,8 @@ dependencies {
|
|||||||
compileOnly 'com.google.code.gson:gson:2.8.5'
|
compileOnly 'com.google.code.gson:gson:2.8.5'
|
||||||
compileOnly 'com.github.salomonbrys.kotson:kotson:2.5.0'
|
compileOnly 'com.github.salomonbrys.kotson:kotson:2.5.0'
|
||||||
compileOnly 'com.github.inorichi.injekt:injekt-core:65b0440'
|
compileOnly 'com.github.inorichi.injekt:injekt-core:65b0440'
|
||||||
|
implementation 'io.reactivex:rxandroid:1.2.1'
|
||||||
|
implementation 'io.reactivex:rxjava:1.3.6'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
@ -7,15 +7,16 @@ import android.support.v7.preference.PreferenceScreen
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
import com.github.salomonbrys.kotson.fromJson
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import eu.kanade.tachiyomi.extension.all.komga.dto.BookDto
|
import eu.kanade.tachiyomi.extension.BuildConfig
|
||||||
import eu.kanade.tachiyomi.extension.all.komga.dto.PageDto
|
import eu.kanade.tachiyomi.extension.all.komga.dto.*
|
||||||
import eu.kanade.tachiyomi.extension.all.komga.dto.PageWrapperDto
|
|
||||||
import eu.kanade.tachiyomi.extension.all.komga.dto.SerieDto
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
import eu.kanade.tachiyomi.source.model.*
|
import eu.kanade.tachiyomi.source.model.*
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
|
import rx.Single
|
||||||
|
import rx.android.schedulers.AndroidSchedulers
|
||||||
|
import rx.schedulers.Schedulers
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
@ -35,8 +36,27 @@ open class Komga : ConfigurableSource, HttpSource() {
|
|||||||
override fun latestUpdatesParse(response: Response): MangasPage =
|
override fun latestUpdatesParse(response: Response): MangasPage =
|
||||||
processSeriePage(response)
|
processSeriePage(response)
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request =
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
GET("$baseUrl/api/v1/series?search=$query&page=${page - 1}", headers)
|
val url = HttpUrl.parse("$baseUrl/api/v1/series?search=$query&page=${page - 1}")!!.newBuilder()
|
||||||
|
|
||||||
|
filters.forEach { filter ->
|
||||||
|
when (filter) {
|
||||||
|
is LibraryGroup -> {
|
||||||
|
val libraryToInclude = mutableListOf<Long>()
|
||||||
|
filter.state.forEach { content ->
|
||||||
|
if (content.state) {
|
||||||
|
libraryToInclude.add(content.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (libraryToInclude.isNotEmpty()) {
|
||||||
|
url.addQueryParameter("library_id", libraryToInclude.joinToString(","))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GET(url.toString(), headers)
|
||||||
|
}
|
||||||
|
|
||||||
override fun searchMangaParse(response: Response): MangasPage =
|
override fun searchMangaParse(response: Response): MangasPage =
|
||||||
processSeriePage(response)
|
processSeriePage(response)
|
||||||
@ -45,8 +65,8 @@ open class Komga : ConfigurableSource, HttpSource() {
|
|||||||
GET(baseUrl + manga.url, headers)
|
GET(baseUrl + manga.url, headers)
|
||||||
|
|
||||||
override fun mangaDetailsParse(response: Response): SManga {
|
override fun mangaDetailsParse(response: Response): SManga {
|
||||||
val serie = gson.fromJson<SerieDto>(response.body()?.charStream()!!)
|
val series = gson.fromJson<SeriesDto>(response.body()?.charStream()!!)
|
||||||
return serie.toSManga()
|
return series.toSManga()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListRequest(manga: SManga): Request =
|
override fun chapterListRequest(manga: SManga): Request =
|
||||||
@ -60,7 +80,7 @@ open class Komga : ConfigurableSource, HttpSource() {
|
|||||||
return page.content.mapIndexed { i, book ->
|
return page.content.mapIndexed { i, book ->
|
||||||
SChapter.create().apply {
|
SChapter.create().apply {
|
||||||
chapter_number = (i + 1).toFloat()
|
chapter_number = (i + 1).toFloat()
|
||||||
name = book.name
|
name = "${book.name} (${book.size})"
|
||||||
url = "$chapterListUrl/${book.id}"
|
url = "$chapterListUrl/${book.id}"
|
||||||
date_upload = parseDate(book.lastModified)
|
date_upload = parseDate(book.lastModified)
|
||||||
}
|
}
|
||||||
@ -87,14 +107,14 @@ open class Komga : ConfigurableSource, HttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processSeriePage(response: Response): MangasPage {
|
private fun processSeriePage(response: Response): MangasPage {
|
||||||
val page = gson.fromJson<PageWrapperDto<SerieDto>>(response.body()?.charStream()!!)
|
val page = gson.fromJson<PageWrapperDto<SeriesDto>>(response.body()?.charStream()!!)
|
||||||
val mangas = page.content.map {
|
val mangas = page.content.map {
|
||||||
it.toSManga()
|
it.toSManga()
|
||||||
}
|
}
|
||||||
return MangasPage(mangas, !page.last)
|
return MangasPage(mangas, !page.last)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SerieDto.toSManga(): SManga =
|
private fun SeriesDto.toSManga(): SManga =
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
title = this@toSManga.name
|
title = this@toSManga.name
|
||||||
url = "/api/v1/series/${this@toSManga.id}"
|
url = "/api/v1/series/${this@toSManga.id}"
|
||||||
@ -119,19 +139,47 @@ open class Komga : ConfigurableSource, HttpSource() {
|
|||||||
|
|
||||||
override fun imageUrlParse(response: Response): String = ""
|
override fun imageUrlParse(response: Response): String = ""
|
||||||
|
|
||||||
override val name = "Komga"
|
private class LibraryFilter(val id: Long, name: String) : Filter.CheckBox(name, false)
|
||||||
override val lang = "en"
|
private class LibraryGroup(libraries: List<LibraryFilter>) : Filter.Group<LibraryFilter>("Libraries", libraries)
|
||||||
|
|
||||||
|
override fun getFilterList(): FilterList =
|
||||||
|
FilterList(
|
||||||
|
LibraryGroup(libraries.map { LibraryFilter(it.id, it.name) }.sortedBy { it.name })
|
||||||
|
)
|
||||||
|
|
||||||
|
private var libraries = emptyList<LibraryDto>()
|
||||||
|
|
||||||
|
|
||||||
|
override val name = "Komga"
|
||||||
|
|
||||||
|
override val lang = "en"
|
||||||
override val supportsLatest = true
|
override val supportsLatest = true
|
||||||
|
|
||||||
override val baseUrl by lazy { getPrefBaseUrl() }
|
override val baseUrl by lazy { getPrefBaseUrl() }
|
||||||
private val username by lazy { getPrefUsername() }
|
private val username by lazy { getPrefUsername() }
|
||||||
private val password by lazy { getPrefPassword() }
|
private val password by lazy { getPrefPassword() }
|
||||||
|
|
||||||
private val gson by lazy { Gson() }
|
private val gson by lazy { Gson() }
|
||||||
|
|
||||||
|
init {
|
||||||
|
Single.fromCallable {
|
||||||
|
client.newCall(GET("$baseUrl/api/v1/libraries", headers)).execute()
|
||||||
|
}
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe({
|
||||||
|
libraries = try {
|
||||||
|
gson.fromJson(it.body()?.charStream()!!)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
}, {})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun headersBuilder(): Headers.Builder =
|
override fun headersBuilder(): Headers.Builder =
|
||||||
Headers.Builder()
|
Headers.Builder()
|
||||||
.add("Authorization", Credentials.basic(username, password))
|
.add("Authorization", Credentials.basic(username, password))
|
||||||
|
.add("User-Agent", "Tachiyomi Komga v${BuildConfig.VERSION_NAME}")
|
||||||
|
|
||||||
private val preferences: SharedPreferences by lazy {
|
private val preferences: SharedPreferences by lazy {
|
||||||
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package eu.kanade.tachiyomi.extension.all.komga.dto
|
package eu.kanade.tachiyomi.extension.all.komga.dto
|
||||||
|
|
||||||
data class SerieDto(
|
data class LibraryDto(
|
||||||
|
val id: Long,
|
||||||
|
val name: String
|
||||||
|
)
|
||||||
|
|
||||||
|
data class SeriesDto(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
val name: String,
|
val name: String,
|
||||||
val lastModified: String?
|
val lastModified: String?
|
||||||
@ -10,6 +15,8 @@ data class BookDto(
|
|||||||
val id: Long,
|
val id: Long,
|
||||||
val name: String,
|
val name: String,
|
||||||
val lastModified: String?,
|
val lastModified: String?,
|
||||||
|
val sizeBytes: Long,
|
||||||
|
val size: String,
|
||||||
val metadata: BookMetadataDto
|
val metadata: BookMetadataDto
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user