Fix Telegram backups uploading

This commit is contained in:
Koitharu
2024-12-22 09:01:18 +02:00
parent a54744abc6
commit 22d203fc60
4 changed files with 27 additions and 8 deletions

View File

@@ -3,8 +3,7 @@ package org.koitharu.kotatsu.core.backup
import android.content.Context import android.content.Context
import androidx.annotation.CheckResult import androidx.annotation.CheckResult
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers import okhttp3.HttpUrl
import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@@ -31,7 +30,7 @@ class TelegramBackupUploader @Inject constructor(
private val botToken = context.getString(R.string.tg_backup_bot_token) private val botToken = context.getString(R.string.tg_backup_bot_token)
suspend fun uploadBackup(file: File) = withContext(Dispatchers.IO) { suspend fun uploadBackup(file: File) {
val requestBody = file.asRequestBody("application/zip".toMediaTypeOrNull()) val requestBody = file.asRequestBody("application/zip".toMediaTypeOrNull())
val multipartBody = MultipartBody.Builder() val multipartBody = MultipartBody.Builder()
.setType(MultipartBody.FORM) .setType(MultipartBody.FORM)
@@ -39,7 +38,7 @@ class TelegramBackupUploader @Inject constructor(
.addFormDataPart("document", file.name, requestBody) .addFormDataPart("document", file.name, requestBody)
.build() .build()
val request = Request.Builder() val request = Request.Builder()
.url("https://api.telegram.org/bot$botToken/sendDocument") .url(urlOf("sendDocument").build())
.post(multipartBody) .post(multipartBody)
.build() .build()
client.newCall(request).await().consume() client.newCall(request).await().consume()
@@ -47,7 +46,7 @@ class TelegramBackupUploader @Inject constructor(
suspend fun sendTestMessage() { suspend fun sendTestMessage() {
val request = Request.Builder() val request = Request.Builder()
.url("https://api.telegram.org/bot$botToken/getMe") .url(urlOf("getMe").build())
.build() .build()
client.newCall(request).await().consume() client.newCall(request).await().consume()
sendMessage(context.getString(R.string.backup_tg_echo)) sendMessage(context.getString(R.string.backup_tg_echo))
@@ -61,7 +60,10 @@ class TelegramBackupUploader @Inject constructor(
} }
private suspend fun sendMessage(message: String) { private suspend fun sendMessage(message: String) {
val url = "https://api.telegram.org/bot$botToken/sendMessage?chat_id=${requireChatId()}&text=$message" val url = urlOf("sendMessage")
.addQueryParameter("chat_id", requireChatId())
.addQueryParameter("text", message)
.build()
val request = Request.Builder() val request = Request.Builder()
.url(url) .url(url)
.build() .build()
@@ -82,4 +84,10 @@ class TelegramBackupUploader @Inject constructor(
throw RuntimeException(jo.getStringOrNull("description")) throw RuntimeException(jo.getStringOrNull("description"))
} }
} }
private fun urlOf(method: String) = HttpUrl.Builder()
.scheme("https")
.host("api.telegram.org")
.addPathSegment("bot$botToken")
.addPathSegment(method)
} }

View File

@@ -1,6 +1,7 @@
package org.koitharu.kotatsu.core.network package org.koitharu.kotatsu.core.network
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.MultipartBody
import okhttp3.Response import okhttp3.Response
import okio.IOException import okio.IOException
import org.koitharu.kotatsu.core.network.CommonHeaders.CONTENT_ENCODING import org.koitharu.kotatsu.core.network.CommonHeaders.CONTENT_ENCODING
@@ -8,7 +9,11 @@ import org.koitharu.kotatsu.core.network.CommonHeaders.CONTENT_ENCODING
class GZipInterceptor : Interceptor { class GZipInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
val newRequest = chain.request().newBuilder() val request = chain.request()
if (request.body is MultipartBody) {
return chain.proceed(request)
}
val newRequest = request.newBuilder()
newRequest.addHeader(CONTENT_ENCODING, "gzip") newRequest.addHeader(CONTENT_ENCODING, "gzip")
return try { return try {
chain.proceed(newRequest.build()) chain.proceed(newRequest.build())

View File

@@ -7,11 +7,15 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.backup.BackupZipOutput.Companion.DIR_BACKUPS import org.koitharu.kotatsu.core.backup.BackupZipOutput.Companion.DIR_BACKUPS
import org.koitharu.kotatsu.core.backup.ExternalBackupStorage import org.koitharu.kotatsu.core.backup.ExternalBackupStorage
import org.koitharu.kotatsu.core.backup.TelegramBackupUploader import org.koitharu.kotatsu.core.backup.TelegramBackupUploader
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.BaseViewModel import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.ui.util.ReversibleAction
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
import org.koitharu.kotatsu.core.util.ext.call
import org.koitharu.kotatsu.core.util.ext.resolveFile import org.koitharu.kotatsu.core.util.ext.resolveFile
import java.io.File import java.io.File
import java.util.Date import java.util.Date
@@ -28,6 +32,7 @@ class PeriodicalBackupSettingsViewModel @Inject constructor(
val lastBackupDate = MutableStateFlow<Date?>(null) val lastBackupDate = MutableStateFlow<Date?>(null)
val backupsDirectory = MutableStateFlow<String?>("") val backupsDirectory = MutableStateFlow<String?>("")
val isTelegramCheckLoading = MutableStateFlow(false) val isTelegramCheckLoading = MutableStateFlow(false)
val onActionDone = MutableEventFlow<ReversibleAction>()
init { init {
updateSummaryData() updateSummaryData()
@@ -38,6 +43,7 @@ class PeriodicalBackupSettingsViewModel @Inject constructor(
try { try {
isTelegramCheckLoading.value = true isTelegramCheckLoading.value = true
telegramUploader.sendTestMessage() telegramUploader.sendTestMessage()
onActionDone.call(ReversibleAction(R.string.connection_ok, null))
} finally { } finally {
isTelegramCheckLoading.value = false isTelegramCheckLoading.value = false
} }

View File

@@ -779,7 +779,7 @@
<string name="incognito">Incognito</string> <string name="incognito">Incognito</string>
<string name="error_connection_reset">Connection reset by remote host</string> <string name="error_connection_reset">Connection reset by remote host</string>
<string name="backup_tg_check">Check if API works</string> <string name="backup_tg_check">Check if API works</string>
<string name="backup_tg_echo">Kotatsu backup in Telegram is working!!</string> <string name="backup_tg_echo">Test message</string>
<string name="backup_tg_id_not_set">Chat ID is not set</string> <string name="backup_tg_id_not_set">Chat ID is not set</string>
<string name="telegram_chat_id">Telegram chat ID</string> <string name="telegram_chat_id">Telegram chat ID</string>
<string name="open_telegram_bot">Open the Telegram bot</string> <string name="open_telegram_bot">Open the Telegram bot</string>