[Komga] don't display password in plain text, custom source name (#15037)

* don't display password in preference summary

* add preference for source display name
decouple title from key for preferences
This commit is contained in:
Gauthier 2023-01-20 23:12:20 +08:00 committed by GitHub
parent d6a6a0d74f
commit df601fdade
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 28 deletions

View File

@ -1,3 +1,11 @@
## 1.3.45
Minimum Komga version required: `0.151.0`
### Feat
* Edit source display name
## 1.3.44 ## 1.3.44
Minimum Komga version required: `0.151.0` Minimum Komga version required: `0.151.0`

View File

@ -6,7 +6,7 @@ ext {
extName = 'Komga' extName = 'Komga'
pkgNameSuffix = 'all.komga' pkgNameSuffix = 'all.komga'
extClass = '.KomgaFactory' extClass = '.KomgaFactory'
extVersionCode = 44 extVersionCode = 45
} }
dependencies { dependencies {

View File

@ -48,7 +48,7 @@ import uy.kohesive.injekt.injectLazy
import java.security.MessageDigest import java.security.MessageDigest
import java.util.Locale import java.util.Locale
open class Komga(suffix: String = "") : ConfigurableSource, UnmeteredSource, HttpSource() { open class Komga(private val suffix: String = "") : ConfigurableSource, UnmeteredSource, HttpSource() {
override fun popularMangaRequest(page: Int): Request = override fun popularMangaRequest(page: Int): Request =
GET("$baseUrl/api/v1/series?page=${page - 1}&deleted=false&sort=metadata.titleSort,asc", headers) GET("$baseUrl/api/v1/series?page=${page - 1}&deleted=false&sort=metadata.titleSort,asc", headers)
@ -384,19 +384,15 @@ open class Komga(suffix: String = "") : ConfigurableSource, UnmeteredSource, Htt
private var publishers = emptySet<String>() private var publishers = emptySet<String>()
private var authors = emptyMap<String, List<AuthorDto>>() // roles to list of authors private var authors = emptyMap<String, List<AuthorDto>>() // roles to list of authors
override val name = "Komga${if (suffix.isNotBlank()) " ($suffix)" else ""}"
override val lang = "all"
override val supportsLatest = true
private val LOG_TAG = "extension.all.komga${if (suffix.isNotBlank()) ".$suffix" else ""}"
// keep the previous ID when lang was "en", so that preferences and manga bindings are not lost // keep the previous ID when lang was "en", so that preferences and manga bindings are not lost
override val id by lazy { override val id by lazy {
val key = "${name.lowercase()}/en/$versionId" val key = "komga${if (suffix.isNotBlank()) " ($suffix)" else ""}/en/$versionId"
val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray()) val bytes = MessageDigest.getInstance("MD5").digest(key.toByteArray())
(0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }.reduce(Long::or) and Long.MAX_VALUE (0..7).map { bytes[it].toLong() and 0xff shl 8 * (7 - it) }.reduce(Long::or) and Long.MAX_VALUE
} }
override val baseUrl by lazy { preferences.baseUrl } private val displayName by lazy { preferences.displayName }
final override val baseUrl by lazy { preferences.baseUrl }
private val username by lazy { preferences.username } private val username by lazy { preferences.username }
private val password by lazy { preferences.password } private val password by lazy { preferences.password }
private val json: Json by injectLazy() private val json: Json by injectLazy()
@ -409,6 +405,11 @@ open class Komga(suffix: String = "") : ConfigurableSource, UnmeteredSource, Htt
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000) Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
} }
override val name = "Komga${displayName.ifBlank { suffix }.let { if (it.isNotBlank()) " ($it)" else "" }}"
override val lang = "all"
override val supportsLatest = true
private val LOG_TAG = "extension.all.komga${if (suffix.isNotBlank()) ".$suffix" else ""}"
override val client: OkHttpClient = override val client: OkHttpClient =
network.client.newBuilder() network.client.newBuilder()
.authenticator { _, response -> .authenticator { _, response ->
@ -425,38 +426,48 @@ open class Komga(suffix: String = "") : ConfigurableSource, UnmeteredSource, Htt
override fun setupPreferenceScreen(screen: PreferenceScreen) { override fun setupPreferenceScreen(screen: PreferenceScreen) {
screen.addEditTextPreference( screen.addEditTextPreference(
title = ADDRESS_TITLE, title = "Source display name",
default = suffix,
summary = displayName.ifBlank { "Here you can change the source displayed suffix" },
key = PREF_DISPLAYNAME
)
screen.addEditTextPreference(
title = "Address",
default = ADDRESS_DEFAULT, default = ADDRESS_DEFAULT,
value = baseUrl, summary = baseUrl.ifBlank { "The server address" },
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI, inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI,
validate = { it.toHttpUrlOrNull() != null }, validate = { it.toHttpUrlOrNull() != null },
validationMessage = "The URL is invalid or malformed" validationMessage = "The URL is invalid or malformed",
key = PREF_ADDRESS
) )
screen.addEditTextPreference( screen.addEditTextPreference(
title = USERNAME_TITLE, title = "Username",
default = USERNAME_DEFAULT, default = USERNAME_DEFAULT,
value = username summary = username.ifBlank { "The user account email" },
key = PREF_USERNAME
) )
screen.addEditTextPreference( screen.addEditTextPreference(
title = PASSWORD_TITLE, title = "Password",
default = PASSWORD_DEFAULT, default = PASSWORD_DEFAULT,
value = password, summary = if (password.isBlank()) "The user account password" else "*".repeat(password.length),
inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD,
key = PREF_PASSWORD
) )
} }
private fun PreferenceScreen.addEditTextPreference( private fun PreferenceScreen.addEditTextPreference(
title: String, title: String,
default: String, default: String,
value: String, summary: String,
inputType: Int? = null, inputType: Int? = null,
validate: ((String) -> Boolean)? = null, validate: ((String) -> Boolean)? = null,
validationMessage: String? = null validationMessage: String? = null,
key: String = title,
) { ) {
val preference = EditTextPreference(context).apply { val preference = EditTextPreference(context).apply {
key = title this.key = key
this.title = title this.title = title
summary = value this.summary = summary
this.setDefaultValue(default) this.setDefaultValue(default)
dialogTitle = title dialogTitle = title
@ -488,7 +499,7 @@ open class Komga(suffix: String = "") : ConfigurableSource, UnmeteredSource, Htt
setOnPreferenceChangeListener { _, newValue -> setOnPreferenceChangeListener { _, newValue ->
try { try {
val res = preferences.edit().putString(title, newValue as String).commit() val res = preferences.edit().putString(this.key, newValue as String).commit()
Toast.makeText(context, "Restart Tachiyomi to apply new setting.", Toast.LENGTH_LONG).show() Toast.makeText(context, "Restart Tachiyomi to apply new setting.", Toast.LENGTH_LONG).show()
res res
} catch (e: Exception) { } catch (e: Exception) {
@ -501,14 +512,17 @@ open class Komga(suffix: String = "") : ConfigurableSource, UnmeteredSource, Htt
addPreference(preference) addPreference(preference)
} }
private val SharedPreferences.displayName
get() = getString(PREF_DISPLAYNAME, "")!!
private val SharedPreferences.baseUrl private val SharedPreferences.baseUrl
get() = getString(ADDRESS_TITLE, ADDRESS_DEFAULT)!!.removeSuffix("/") get() = getString(PREF_ADDRESS, ADDRESS_DEFAULT)!!.removeSuffix("/")
private val SharedPreferences.username private val SharedPreferences.username
get() = getString(USERNAME_TITLE, USERNAME_DEFAULT)!! get() = getString(PREF_USERNAME, USERNAME_DEFAULT)!!
private val SharedPreferences.password private val SharedPreferences.password
get() = getString(PASSWORD_TITLE, PASSWORD_DEFAULT)!! get() = getString(PREF_PASSWORD, PASSWORD_DEFAULT)!!
init { init {
if (baseUrl.isNotBlank()) { if (baseUrl.isNotBlank()) {
@ -640,11 +654,12 @@ open class Komga(suffix: String = "") : ConfigurableSource, UnmeteredSource, Htt
} }
companion object { companion object {
private const val ADDRESS_TITLE = "Address" private const val PREF_DISPLAYNAME = "Source display name"
private const val PREF_ADDRESS = "Address"
private const val ADDRESS_DEFAULT = "" private const val ADDRESS_DEFAULT = ""
private const val USERNAME_TITLE = "Username" private const val PREF_USERNAME = "Username"
private const val USERNAME_DEFAULT = "" private const val USERNAME_DEFAULT = ""
private const val PASSWORD_TITLE = "Password" private const val PREF_PASSWORD = "Password"
private const val PASSWORD_DEFAULT = "" private const val PASSWORD_DEFAULT = ""
private val supportedImageTypes = listOf("image/jpeg", "image/png", "image/gif", "image/webp", "image/jxl") private val supportedImageTypes = listOf("image/jpeg", "image/png", "image/gif", "image/webp", "image/jxl")