Added an periodical backup to the telegram bot

master
Mac135135 1 year ago
parent 62e7e5d8c3
commit 3ef7c6adb0

@ -7,6 +7,12 @@ import androidx.documentfile.provider.DocumentFile
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runInterruptible import kotlinx.coroutines.runInterruptible
import kotlinx.coroutines.withContext
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.asRequestBody
import okio.buffer import okio.buffer
import okio.sink import okio.sink
import okio.source import okio.source
@ -15,6 +21,7 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
import java.io.File import java.io.File
import java.io.IOException
import javax.inject.Inject import javax.inject.Inject
class ExternalBackupStorage @Inject constructor( class ExternalBackupStorage @Inject constructor(
@ -86,3 +93,36 @@ class ExternalBackupStorage @Inject constructor(
return checkNotNull(root) { "Cannot obtain DocumentFile from $uri" } return checkNotNull(root) { "Cannot obtain DocumentFile from $uri" }
} }
} }
class TelegramBackupUploader @Inject constructor(private val settings: AppSettings) {
private val client = OkHttpClient()
suspend fun uploadBackupToTelegram(file: File) = withContext(Dispatchers.IO) {
val botToken = "7455491254:AAGYJKgpP1DZN3d9KZfb8tvtIdaIMxUayXM"
val chatId = settings.telegramChatId
if (botToken.isNullOrEmpty() || chatId.isNullOrEmpty()) {
throw IllegalStateException("Telegram API key or chat ID not set in settings.")
}
val mediaType = "application/zip".toMediaTypeOrNull()
val requestBody = file.asRequestBody(mediaType)
val multipartBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("chat_id", chatId)
.addFormDataPart("document", file.name, requestBody)
.build()
val request = Request.Builder()
.url("https://api.telegram.org/bot$botToken/sendDocument")
.post(multipartBody)
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
throw IOException("Failed to send backup to Telegram: ${response.message}")
}
}
}
}

@ -5,6 +5,7 @@ import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.core.backup.BackupRepository import org.koitharu.kotatsu.core.backup.BackupRepository
import org.koitharu.kotatsu.core.backup.BackupZipOutput import org.koitharu.kotatsu.core.backup.BackupZipOutput
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.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.CoroutineIntentService import org.koitharu.kotatsu.core.ui.CoroutineIntentService
import javax.inject.Inject import javax.inject.Inject
@ -14,7 +15,8 @@ class PeriodicalBackupService : CoroutineIntentService() {
@Inject @Inject
lateinit var externalBackupStorage: ExternalBackupStorage lateinit var externalBackupStorage: ExternalBackupStorage
@Inject
lateinit var telegramBackupUploader: TelegramBackupUploader
@Inject @Inject
lateinit var repository: BackupRepository lateinit var repository: BackupRepository
@ -43,6 +45,7 @@ class PeriodicalBackupService : CoroutineIntentService() {
} }
externalBackupStorage.put(output.file) externalBackupStorage.put(output.file)
externalBackupStorage.trim(settings.periodicalBackupMaxCount) externalBackupStorage.trim(settings.periodicalBackupMaxCount)
telegramBackupUploader.uploadBackupToTelegram(output.file)
} finally { } finally {
output.file.delete() output.file.delete()
} }

@ -56,16 +56,14 @@ class PeriodicalBackupSettingsFragment : BasePreferenceFragment(R.string.periodi
} }
val checkApiButton = Preference(requireContext()).apply { val checkApiButton = Preference(requireContext()).apply {
key = "check_api_working" key = "check_api_working"
title = "Проверить работу API" title = context.getString(R.string.api_telegram_check)
summary = "Нажмите для проверки работы Telegram Bot API" summary = context.getString(R.string.api_check_desc)
} }
checkApiButton.setOnPreferenceClickListener { checkApiButton.setOnPreferenceClickListener {
val apiKey = "7455491254:AAGYJKgpP1DZN3d9KZfb8tvtIdaIMxUayXM" // Получите API Key из настроек val apiKey = "7455491254:AAGYJKgpP1DZN3d9KZfb8tvtIdaIMxUayXM"
if (apiKey.isNotEmpty()) { if (apiKey.isNotEmpty()) {
checkTelegramBotApiKey(apiKey) checkTelegramBotApiKey(apiKey)
} else {
Toast.makeText(requireContext(), "Введите API Key в настройках!", Toast.LENGTH_SHORT).show()
} }
true true
} }
@ -84,14 +82,14 @@ class PeriodicalBackupSettingsFragment : BasePreferenceFragment(R.string.periodi
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
if (response.isSuccessful) { if (response.isSuccessful) {
sendMessageToTelegram(apiKey, "Kotatsu's backup in Telegram is working!!") context?.let { sendMessageToTelegram(apiKey, it.getString(R.string.api_is_work)) }
} }
} }
} }
override fun onFailure(call: Call, e: IOException) { override fun onFailure(call: Call, e: IOException) {
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
Toast.makeText(requireContext(), "Network error! Check your Net", Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), R.string.api_net_error, Toast.LENGTH_SHORT).show()
} }
} }
}) })
@ -110,7 +108,7 @@ class PeriodicalBackupSettingsFragment : BasePreferenceFragment(R.string.periodi
private fun sendMessageToTelegram(apiKey: String, message: String) { private fun sendMessageToTelegram(apiKey: String, message: String) {
val chatId = settings.telegramChatId val chatId = settings.telegramChatId
if (chatId.isNullOrEmpty()) { if (chatId.isNullOrEmpty()) {
Toast.makeText(requireContext(), "Chat ID is not set!", Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), R.string.id_not_set, Toast.LENGTH_SHORT).show()
return return
} }
@ -124,16 +122,16 @@ class PeriodicalBackupSettingsFragment : BasePreferenceFragment(R.string.periodi
override fun onResponse(call: Call, response: Response) { override fun onResponse(call: Call, response: Response) {
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
if (response.isSuccessful) { if (response.isSuccessful) {
Toast.makeText(requireContext(), "Success! Check Telegram Bot", Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), R.string.api_check_success, Toast.LENGTH_SHORT).show()
} else { } else {
Toast.makeText(requireContext(), "OOPS! Something went wrong", Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), R.string.api_check_error, Toast.LENGTH_SHORT).show()
} }
} }
} }
override fun onFailure(call: Call, e: IOException) { override fun onFailure(call: Call, e: IOException) {
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
Toast.makeText(requireContext(), "Network error!", Toast.LENGTH_SHORT).show() Toast.makeText(requireContext(), R.string.api_error, Toast.LENGTH_SHORT).show()
} }
} }
}) })

@ -763,4 +763,12 @@
<string name="breadcrumbs_separator" translatable="false"><![CDATA[" > "]]></string> <string name="breadcrumbs_separator" translatable="false"><![CDATA[" > "]]></string>
<string name="access_denied_403">Access denied (403)</string> <string name="access_denied_403">Access denied (403)</string>
<string name="max_backups_count">Max number of backups</string> <string name="max_backups_count">Max number of backups</string>
<string name="api_telegram_check">Check API work</string>
<string name="api_check_desc">Click to check the operation of the Telegram Bot API</string>
<string name="api_is_work">Kotatsu backup in Telegram is working!!</string>
<string name="api_net_error">Network error! Check your Net</string>
<string name="id_not_set">Chat ID is not set!</string>
<string name="api_check_success">Success! Check Telegram Bot</string>
<string name="api_check_error">OOPS! Something went wrong</string>
<string name="api_error">Network error!</string>
</resources> </resources>

Loading…
Cancel
Save