From 26b512d42e7e461d2dade97d3153d0a8b960b18a Mon Sep 17 00:00:00 2001 From: Mac135135 Date: Sat, 28 Sep 2024 19:10:56 +0300 Subject: [PATCH] Added an periodical backup to the telegram bot --- .../kotatsu/core/prefs/AppSettings.kt | 8 ++ .../PeriodicalBackupSettingsFragment.kt | 100 ++++++++++++++++++ .../settings/backup/PeriodicalBackupWorker.kt | 43 +++++++- app/src/main/res/xml/pref_backup_periodic.xml | 12 +++ 4 files changed, 162 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt index 3d3b82081..468a1a84a 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt @@ -41,6 +41,14 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { private val prefs = PreferenceManager.getDefaultSharedPreferences(context) private val connectivityManager = context.connectivityManager + private val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) + + + var telegramChatId: String? + get() = preferences.getString("telegram_chat_id", null) + set(value) { + preferences.edit().putString("telegram_chat_id", value).apply() + } var listMode: ListMode get() = prefs.getEnumValue(KEY_LIST_MODE, ListMode.GRID) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/backup/PeriodicalBackupSettingsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/backup/PeriodicalBackupSettingsFragment.kt index 3e5dfd316..cb8ec0267 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/backup/PeriodicalBackupSettingsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/backup/PeriodicalBackupSettingsFragment.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.net.Uri import android.os.Bundle import android.view.View +import android.widget.Toast import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.documentfile.provider.DocumentFile @@ -20,7 +21,13 @@ import org.koitharu.kotatsu.core.ui.BasePreferenceFragment import org.koitharu.kotatsu.core.util.ext.resolveFile import org.koitharu.kotatsu.core.util.ext.tryLaunch import org.koitharu.kotatsu.core.util.ext.viewLifecycleScope +import okhttp3.Call +import okhttp3.Callback +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response import java.io.File +import java.io.IOException import java.text.SimpleDateFormat import javax.inject.Inject @@ -38,8 +45,101 @@ class PeriodicalBackupSettingsFragment : BasePreferenceFragment(R.string.periodi override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.pref_backup_periodic) + + val openTelegramBotPreference = findPreference("open_telegram_chat") + + openTelegramBotPreference?.setOnPreferenceClickListener { + openTelegramBot("kotatsu_backup_bot") + true + } + // Кнопка для проверки работы API + val checkApiButton = Preference(requireContext()).apply { + key = "check_api_working" + title = "Проверить работу API" + summary = "Нажмите для проверки работы Telegram Bot API" + } + + checkApiButton.setOnPreferenceClickListener { + val apiKey = "7455491254:AAGYJKgpP1DZN3d9KZfb8tvtIdaIMxUayXM" // Получите API Key из настроек + if (apiKey.isNotEmpty()) { + checkTelegramBotApiKey(apiKey) + } else { + Toast.makeText(requireContext(), "Введите API Key в настройках!", Toast.LENGTH_SHORT).show() + } + true + } + + preferenceScreen.addPreference(checkApiButton) + } + private fun checkTelegramBotApiKey(apiKey: String) { + val url = "https://api.telegram.org/bot$apiKey/getMe" + + val client = OkHttpClient() + val request = Request.Builder() + .url(url) + .build() + + client.newCall(request).enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + requireActivity().runOnUiThread { + if (response.isSuccessful) { + sendMessageToTelegram(apiKey, "Kotatsu's backup in Telegram is working!!") + } + } + } + + override fun onFailure(call: Call, e: IOException) { + requireActivity().runOnUiThread { + Toast.makeText(requireContext(), "Network error! Check your Net", Toast.LENGTH_SHORT).show() + } + } + }) + } + private fun openTelegramBot(botUsername: String) { + try { + val telegramIntent = Intent(Intent.ACTION_VIEW) + telegramIntent.data = Uri.parse("https://t.me/$botUsername") + telegramIntent.setPackage("org.telegram.messenger") + startActivity(telegramIntent) + } catch (e: Exception) { + // Если Telegram не установлен, открываем через браузер + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://t.me/$botUsername")) + startActivity(browserIntent) + } + } + private fun sendMessageToTelegram(apiKey: String, message: String) { + val chatId = settings.telegramChatId + if (chatId.isNullOrEmpty()) { + Toast.makeText(requireContext(), "Chat ID is not set!", Toast.LENGTH_SHORT).show() + return + } + + val url = "https://api.telegram.org/bot$apiKey/sendMessage?chat_id=$chatId&text=$message" + val client = OkHttpClient() + val request = Request.Builder() + .url(url) + .build() + + client.newCall(request).enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + requireActivity().runOnUiThread { + if (response.isSuccessful) { + Toast.makeText(requireContext(), "Success! Check Telegram Bot", Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(requireContext(), "OOPS! Something went wrong", Toast.LENGTH_SHORT).show() + } + } + } + + override fun onFailure(call: Call, e: IOException) { + requireActivity().runOnUiThread { + Toast.makeText(requireContext(), "Network error!", Toast.LENGTH_SHORT).show() + } + } + }) } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) bindOutputSummary() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/backup/PeriodicalBackupWorker.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/backup/PeriodicalBackupWorker.kt index 224df7b7b..e585b2f03 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/backup/PeriodicalBackupWorker.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/backup/PeriodicalBackupWorker.kt @@ -25,6 +25,15 @@ import org.koitharu.kotatsu.settings.work.PeriodicWorkScheduler import java.util.Date import java.util.concurrent.TimeUnit import javax.inject.Inject +import okhttp3.Call +import okhttp3.Callback +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.RequestBody.Companion.asRequestBody +import okhttp3.Response +import java.io.File @HiltWorker class PeriodicalBackupWorker @AssistedInject constructor( @@ -54,8 +63,40 @@ class PeriodicalBackupWorker @AssistedInject constructor( applicationContext.contentResolver.openOutputStream(target, "wt")?.use { output -> file.inputStream().copyTo(output) } ?: return Result.failure() + + val botToken = "7455491254:AAGYJKgpP1DZN3d9KZfb8tvtIdaIMxUayXM" + val chatId = settings.telegramChatId ?: return Result.failure() + + val success = sendBackupToTelegram(file, botToken, chatId) + file.deleteAwait() - return Result.success(resultData) + + return if (success) { + Result.success(resultData) + } else { + Result.failure() + } + } + + fun sendBackupToTelegram(file: File, botToken: String, chatId: String): Boolean { + val client = OkHttpClient() + 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 -> + return response.isSuccessful + } } @Reusable diff --git a/app/src/main/res/xml/pref_backup_periodic.xml b/app/src/main/res/xml/pref_backup_periodic.xml index a205e8657..db089196b 100644 --- a/app/src/main/res/xml/pref_backup_periodic.xml +++ b/app/src/main/res/xml/pref_backup_periodic.xml @@ -32,4 +32,16 @@ app:allowDividerAbove="true" app:isPreferenceVisible="false" /> + + + +