Merge branch 'feature/sync' into feature/nextgen

This commit is contained in:
Koitharu
2022-07-19 12:57:38 +03:00
64 changed files with 1721 additions and 160 deletions

View File

@@ -1,5 +1,6 @@
package org.koitharu.kotatsu.utils
import android.util.ArrayMap
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.isActive
@@ -11,7 +12,7 @@ import kotlin.coroutines.resume
class CompositeMutex<T : Any> : Set<T> {
private val data = HashMap<T, MutableList<CancellableContinuation<Unit>>>()
private val data = ArrayMap<T, MutableList<CancellableContinuation<Unit>>>()
private val mutex = Mutex()
override val size: Int

View File

@@ -0,0 +1,14 @@
package org.koitharu.kotatsu.utils
import okhttp3.Interceptor
import okhttp3.Response
import org.koitharu.kotatsu.core.network.CommonHeaders.CONTENT_ENCODING
class GZipInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val newRequest = chain.request().newBuilder()
newRequest.addHeader(CONTENT_ENCODING, "gzip")
return chain.proceed(newRequest.build())
}
}

View File

@@ -4,9 +4,13 @@ import android.app.ActivityManager
import android.app.ActivityOptions
import android.content.Context
import android.content.Context.ACTIVITY_SERVICE
import android.content.OperationApplicationException
import android.content.SharedPreferences
import android.content.SyncResult
import android.content.pm.ResolveInfo
import android.database.SQLException
import android.graphics.Color
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkRequest
@@ -35,6 +39,9 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import okio.IOException
import org.json.JSONException
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.utils.InternalResourceHelper
import kotlin.coroutines.resume
@@ -111,6 +118,17 @@ fun Lifecycle.postDelayed(runnable: Runnable, delay: Long) {
}
}
fun SyncResult.onError(error: Throwable) {
when (error) {
is IOException -> stats.numIoExceptions++
is OperationApplicationException,
is SQLException -> databaseError = true
is JSONException -> stats.numParseExceptions++
else -> if (BuildConfig.DEBUG) throw error
}
error.printStackTraceDebug()
}
fun Window.setNavigationBarTransparentCompat(context: Context, elevation: Float = 0F) {
navigationBarColor = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
!InternalResourceHelper.getBoolean(context, "config_navBarNeedsScrim", true)
@@ -150,4 +168,4 @@ fun scaleUpActivityOptionsOf(view: View): ActivityOptions = ActivityOptions.make
0,
view.width,
view.height,
)
)

View File

@@ -0,0 +1,39 @@
package org.koitharu.kotatsu.utils.ext
import android.content.ContentValues
import android.database.Cursor
import org.json.JSONObject
fun Cursor.toJson(): JSONObject {
val jo = JSONObject()
for (i in 0 until columnCount) {
val name = getColumnName(i)
when (getType(i)) {
Cursor.FIELD_TYPE_STRING -> jo.put(name, getString(i))
Cursor.FIELD_TYPE_FLOAT -> jo.put(name, getDouble(i))
Cursor.FIELD_TYPE_INTEGER -> jo.put(name, getLong(i))
Cursor.FIELD_TYPE_NULL -> jo.put(name, null)
Cursor.FIELD_TYPE_BLOB -> jo.put(name, getBlob(i))
}
}
return jo
}
fun JSONObject.toContentValues(): ContentValues {
val cv = ContentValues(length())
for (key in keys()) {
val name = key.escapeName()
when (val value = get(key)) {
JSONObject.NULL, "null", null -> cv.putNull(name)
is String -> cv.put(name, value)
is Float -> cv.put(name, value)
is Double -> cv.put(name, value)
is Int -> cv.put(name, value)
is Long -> cv.put(name, value)
else -> throw IllegalArgumentException("Value $value cannot be putted in ContentValues")
}
}
return cv
}
private fun String.escapeName() = "`$this`"

View File

@@ -1,10 +1,20 @@
package org.koitharu.kotatsu.utils.ext
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import org.json.JSONObject
import org.koitharu.kotatsu.parsers.util.parseJson
import java.net.HttpURLConnection
private val TYPE_JSON = "application/json".toMediaType()
fun JSONObject.toRequestBody() = toString().toRequestBody(TYPE_JSON)
fun JSONObject.toRequestBody() = toString().toRequestBody(TYPE_JSON)
fun Response.parseJsonOrNull(): JSONObject? {
return if (code == HttpURLConnection.HTTP_NO_CONTENT) {
null
} else {
parseJson()
}
}