chore: code style fixes for detekt
This commit is contained in:
@ -9,12 +9,14 @@ class NaiveTrustManager : X509TrustManager {
|
||||
chain: Array<out X509Certificate>?,
|
||||
authType: String?,
|
||||
) {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
override fun checkServerTrusted(
|
||||
chain: Array<out X509Certificate>?,
|
||||
authType: String?,
|
||||
) {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
override fun getAcceptedIssuers(): Array<out X509Certificate> = arrayOf()
|
||||
|
@ -3,6 +3,7 @@ package bou.amine.apps.readerforselfossv2.utils
|
||||
import android.text.format.DateUtils
|
||||
import kotlinx.datetime.Clock
|
||||
|
||||
@Suppress("detekt:UtilityClassWithPublicConstructor")
|
||||
actual class DateUtils {
|
||||
actual companion object {
|
||||
actual fun parseRelativeDate(dateString: String): String {
|
||||
|
@ -12,16 +12,14 @@ actual fun SelfossModel.Item.getIcon(baseUrl: String): String = constructUrl(bas
|
||||
|
||||
actual fun SelfossModel.Item.getThumbnail(baseUrl: String): String = constructUrl(baseUrl, "thumbnails", thumbnail)
|
||||
|
||||
val IMAGE_EXTENSION_REGEXP = """\.(jpg|jpeg|png|webp)""".toRegex()
|
||||
|
||||
actual fun SelfossModel.Item.getImages(): ArrayList<String> {
|
||||
val allImages = ArrayList<String>()
|
||||
|
||||
for (image in Jsoup.parse(content).getElementsByTag("img")) {
|
||||
val url = image.attr("src")
|
||||
if (url.lowercase(Locale.US).contains(".jpg") ||
|
||||
url.lowercase(Locale.US).contains(".jpeg") ||
|
||||
url.lowercase(Locale.US).contains(".png") ||
|
||||
url.lowercase(Locale.US).contains(".webp")
|
||||
) {
|
||||
if (IMAGE_EXTENSION_REGEXP.containsMatchIn(url.lowercase(Locale.US))) {
|
||||
allImages.add(url)
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
@file:Suppress("detekt:LongParameterList")
|
||||
|
||||
package bou.amine.apps.readerforselfossv2.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
class MercuryModel {
|
||||
@Suppress("detekt:ConstructorParameterNaming")
|
||||
@Serializable
|
||||
class ParsedContent(
|
||||
val title: String? = null,
|
||||
val content: String? = null,
|
||||
val lead_image_url: String? = null, // NOSONAR
|
||||
val lead_image_url: String? = null,
|
||||
val url: String? = null,
|
||||
val error: Boolean? = null,
|
||||
val message: String? = null,
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("detekt:LongParameterList")
|
||||
|
||||
package bou.amine.apps.readerforselfossv2.model
|
||||
|
||||
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
||||
@ -18,6 +20,10 @@ import kotlinx.serialization.json.booleanOrNull
|
||||
import kotlinx.serialization.json.int
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
|
||||
class ModelException(
|
||||
message: String,
|
||||
) : Throwable(message)
|
||||
|
||||
class SelfossModel {
|
||||
@Serializable
|
||||
data class Tag(
|
||||
@ -141,7 +147,7 @@ class SelfossModel {
|
||||
}
|
||||
|
||||
if (stringUrl.isEmptyOrNullOrNullString()) {
|
||||
throw Exception("Link $link was translated to $stringUrl, but was empty. Handle this.")
|
||||
throw ModelException("Link $link was translated to $stringUrl, but was empty. Handle this.")
|
||||
}
|
||||
|
||||
return stringUrl
|
||||
@ -170,7 +176,7 @@ class SelfossModel {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this seems to be super slow.
|
||||
// this seems to be super slow.
|
||||
object TagsListSerializer : KSerializer<List<String>> {
|
||||
override fun deserialize(decoder: Decoder): List<String> =
|
||||
when (val json = ((decoder as JsonDecoder).decodeJsonElement())) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("detekt:TooManyFunctions")
|
||||
|
||||
package bou.amine.apps.readerforselfossv2.repository
|
||||
|
||||
import bou.amine.apps.readerforselfossv2.dao.ACTION
|
||||
@ -23,6 +25,8 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
private const val MAX_ITEMS_NUMBER = 200
|
||||
|
||||
class Repository(
|
||||
private val api: SelfossApi,
|
||||
private val appSettingsService: AppSettingsService,
|
||||
@ -127,7 +131,7 @@ class Repository(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
200,
|
||||
MAX_ITEMS_NUMBER,
|
||||
)
|
||||
return if (items.success && items.data != null) {
|
||||
items.data
|
||||
@ -139,6 +143,7 @@ class Repository(
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("detekt:ForbiddenComment")
|
||||
suspend fun reloadBadges(): Boolean {
|
||||
var success = false
|
||||
if (isNetworkAvailable()) {
|
||||
@ -559,6 +564,7 @@ class Repository(
|
||||
item.id.toString(),
|
||||
)
|
||||
|
||||
@Suppress("detekt:SwallowedException")
|
||||
suspend fun tryToCacheItemsAndGetNewOnes(): List<SelfossModel.Item> {
|
||||
try {
|
||||
val newItems = getMaxItemsForBackground(ItemType.UNREAD)
|
||||
|
@ -33,6 +33,7 @@ suspend fun maybeResponse(r: HttpResponse?): SuccessResponse =
|
||||
SuccessResponse(false)
|
||||
}
|
||||
|
||||
@Suppress("detekt:SwallowedException")
|
||||
suspend inline fun <reified T> bodyOrFailure(r: HttpResponse?): StatusAndData<T> {
|
||||
try {
|
||||
return if (r != null && r.status.isSuccess()) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("detekt:TooManyFunctions", "detekt:LongParameterList", "detekt:LargeClass")
|
||||
|
||||
package bou.amine.apps.readerforselfossv2.rest
|
||||
|
||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||
@ -35,6 +37,8 @@ import kotlinx.serialization.json.Json
|
||||
|
||||
expect fun setupInsecureHttpEngine(config: CIOEngineConfig)
|
||||
|
||||
private const val VERSION_WHERE_POST_LOGIN_SHOULD_WORK = 5
|
||||
|
||||
class SelfossApi(
|
||||
private val appSettingsService: AppSettingsService,
|
||||
) {
|
||||
@ -176,7 +180,7 @@ class SelfossApi(
|
||||
},
|
||||
)
|
||||
|
||||
private fun shouldHaveNewLogout() = appSettingsService.getApiVersion() >= 5 // We are missing 4.1.0
|
||||
private fun shouldHaveNewLogout() = appSettingsService.getApiVersion() >= VERSION_WHERE_POST_LOGIN_SHOULD_WORK // We are missing 4.1.0
|
||||
|
||||
suspend fun logout(): SuccessResponse =
|
||||
if (shouldHaveNewLogout()) {
|
||||
|
@ -1,3 +1,5 @@
|
||||
@file:Suppress("detekt:TooManyFunctions")
|
||||
|
||||
package bou.amine.apps.readerforselfossv2.service
|
||||
|
||||
import com.russhwolf.settings.Settings
|
||||
|
@ -1,7 +1,19 @@
|
||||
@file:Suppress("detekt:TooManyFunctions")
|
||||
|
||||
package bou.amine.apps.readerforselfossv2.service
|
||||
|
||||
import com.russhwolf.settings.Settings
|
||||
|
||||
private const val DEFAULT_FONT_SIZE = 16
|
||||
|
||||
private const val DEFAULT_REFRESH_MINUTES = 360L
|
||||
|
||||
private const val MIN_REFRESH_MINUTES = 15L
|
||||
|
||||
private const val DEFAULT_API_TIMEOUT = 60L
|
||||
|
||||
private const val DEFAULT_ITEMS_NUMBER = 20
|
||||
|
||||
class AppSettingsService(
|
||||
acraSenderServiceProcess: Boolean = false,
|
||||
) {
|
||||
@ -36,7 +48,7 @@ class AppSettingsService(
|
||||
private var notifyNewItems: Boolean? = null
|
||||
private var itemsNumber: Int? = null
|
||||
private var apiTimeout: Long? = null
|
||||
private var refreshMinutes: Long = 360
|
||||
private var refreshMinutes: Long = DEFAULT_REFRESH_MINUTES
|
||||
private var markOnScroll: Boolean? = null
|
||||
private var activeAlignment: Int? = null
|
||||
|
||||
@ -141,13 +153,14 @@ class AppSettingsService(
|
||||
return itemsNumber!!
|
||||
}
|
||||
|
||||
@Suppress("detekt:SwallowedException")
|
||||
private fun refreshItemsNumber() {
|
||||
itemsNumber =
|
||||
try {
|
||||
settings.getString(API_ITEMS_NUMBER, "20").toInt()
|
||||
settings.getString(API_ITEMS_NUMBER, DEFAULT_ITEMS_NUMBER.toString()).toInt()
|
||||
} catch (e: Exception) {
|
||||
settings.remove(API_ITEMS_NUMBER)
|
||||
20
|
||||
DEFAULT_ITEMS_NUMBER
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,22 +171,24 @@ class AppSettingsService(
|
||||
return apiTimeout!!
|
||||
}
|
||||
|
||||
@Suppress("detekt:MagicNumber")
|
||||
private fun secToMs(n: Long) = n * 1000
|
||||
|
||||
@Suppress("detekt:SwallowedException")
|
||||
private fun refreshApiTimeout() {
|
||||
apiTimeout =
|
||||
secToMs(
|
||||
try {
|
||||
val settingsTimeout = settings.getString(API_TIMEOUT, "60")
|
||||
val settingsTimeout = settings.getString(API_TIMEOUT, DEFAULT_API_TIMEOUT.toString())
|
||||
if (settingsTimeout.toLong() > 0) {
|
||||
settingsTimeout.toLong()
|
||||
} else {
|
||||
settings.remove(API_TIMEOUT)
|
||||
60
|
||||
DEFAULT_API_TIMEOUT
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
settings.remove(API_TIMEOUT)
|
||||
60
|
||||
DEFAULT_API_TIMEOUT
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -287,14 +302,14 @@ class AppSettingsService(
|
||||
}
|
||||
|
||||
private fun refreshRefreshMinutes() {
|
||||
refreshMinutes = settings.getString(PERIODIC_REFRESH_MINUTES, "360").toLong()
|
||||
if (refreshMinutes <= 15) {
|
||||
refreshMinutes = 15
|
||||
refreshMinutes = settings.getString(PERIODIC_REFRESH_MINUTES, DEFAULT_REFRESH_MINUTES.toString()).toLong()
|
||||
if (refreshMinutes <= MIN_REFRESH_MINUTES) {
|
||||
refreshMinutes = MIN_REFRESH_MINUTES
|
||||
}
|
||||
}
|
||||
|
||||
fun getRefreshMinutes(): Long {
|
||||
if (refreshMinutes != 360L) {
|
||||
if (refreshMinutes != DEFAULT_REFRESH_MINUTES) {
|
||||
refreshRefreshMinutes()
|
||||
}
|
||||
return refreshMinutes
|
||||
@ -368,7 +383,7 @@ class AppSettingsService(
|
||||
if (fontSize != null) {
|
||||
refreshFontSize()
|
||||
}
|
||||
return fontSize ?: 16
|
||||
return fontSize ?: DEFAULT_FONT_SIZE
|
||||
}
|
||||
|
||||
private fun refreshStaticBarEnabled() {
|
||||
|
@ -4,6 +4,12 @@ import kotlinx.datetime.LocalDateTime
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.toInstant
|
||||
|
||||
class DateParseException(
|
||||
message: String,
|
||||
e: Throwable? = null,
|
||||
) : Throwable(message, e)
|
||||
|
||||
@Suppress("detekt:ThrowsCount")
|
||||
fun String.toParsedDate(): Long {
|
||||
// Possible formats are
|
||||
// yyyy-mm-dd hh:mm:ss format
|
||||
@ -21,17 +27,18 @@ fun String.toParsedDate(): Long {
|
||||
.find(this)
|
||||
?.groups
|
||||
?.get(1)
|
||||
?.value ?: throw Exception("Couldn't parse $this")
|
||||
?.value ?: throw DateParseException("Couldn't parse $this")
|
||||
} else {
|
||||
throw Exception("Unrecognized format for $this")
|
||||
throw DateParseException("Unrecognized format for $this")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw Exception("parseDate failed for $this", e)
|
||||
throw DateParseException("parseDate failed for $this", e)
|
||||
}
|
||||
|
||||
return LocalDateTime.parse(isoDateString).toInstant(TimeZone.currentSystemDefault()).toEpochMilliseconds()
|
||||
}
|
||||
|
||||
@Suppress("detekt:UtilityClassWithPublicConstructor")
|
||||
expect class DateUtils() {
|
||||
companion object {
|
||||
fun parseRelativeDate(dateString: String): String
|
||||
|
@ -17,7 +17,7 @@ fun SOURCE.toView(): SelfossModel.SourceDetail =
|
||||
this.id.toInt(),
|
||||
this.title,
|
||||
null,
|
||||
this.tags?.split(","),
|
||||
this.tags.split(","),
|
||||
this.spout,
|
||||
this.error,
|
||||
this.icon,
|
||||
@ -74,6 +74,7 @@ fun SelfossModel.Item.toEntity(): ITEM =
|
||||
this.author,
|
||||
)
|
||||
|
||||
@Suppress("detekt:MagicNumber")
|
||||
fun SelfossModel.Tag.getColorHexCode(): String =
|
||||
if (this.color.length == 4) { // #000
|
||||
val char1 = this.color.get(1)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package bou.amine.apps.readerforselfossv2.utils
|
||||
|
||||
@Suppress("detekt:MagicNumber")
|
||||
enum class ItemType(
|
||||
val position: Int,
|
||||
val type: String,
|
||||
|
@ -2,6 +2,7 @@ package bou.amine.apps.readerforselfossv2.utils
|
||||
|
||||
fun String?.isEmptyOrNullOrNullString(): Boolean = this == null || this == "null" || this.isEmpty()
|
||||
|
||||
@Suppress("detekt:MagicNumber")
|
||||
fun String.longHash(): Long {
|
||||
var h = 98764321261L
|
||||
val l = this.length
|
||||
|
@ -2,5 +2,6 @@ package bou.amine.apps.readerforselfossv2.rest
|
||||
|
||||
import io.ktor.client.engine.cio.CIOEngineConfig
|
||||
|
||||
@Suppress("detekt:EmptyFunctionBlock")
|
||||
actual fun setupInsecureHttpEngine(config: CIOEngineConfig) {
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package bou.amine.apps.readerforselfossv2.utils
|
||||
|
||||
@Suppress("detekt:UtilityClassWithPublicConstructor")
|
||||
actual class DateUtils {
|
||||
actual companion object {
|
||||
actual fun parseRelativeDate(dateString: String): String {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package bou.amine.apps.readerforselfossv2.utils
|
||||
|
||||
@Suppress("detekt:UtilityClassWithPublicConstructor")
|
||||
actual class DateUtils actual constructor() {
|
||||
actual companion object {
|
||||
actual fun parseRelativeDate(dateString: String): String {
|
@ -2,5 +2,6 @@ package bou.amine.apps.readerforselfossv2.rest
|
||||
|
||||
import io.ktor.client.engine.cio.CIOEngineConfig
|
||||
|
||||
@Suppress("detekt:EmptyFunctionBlock")
|
||||
actual fun setupInsecureHttpEngine(config: CIOEngineConfig) {
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package bou.amine.apps.readerforselfossv2.utils
|
||||
|
||||
@Suppress("detekt:UtilityClassWithPublicConstructor")
|
||||
actual class DateUtils {
|
||||
actual companion object {
|
||||
actual fun parseRelativeDate(dateString: String): String {
|
||||
|
Reference in New Issue
Block a user