Added an periodical backup to the telegram bot

This commit is contained in:
Mac135135
2024-09-28 19:10:56 +03:00
parent 4fb3173185
commit 26b512d42e
4 changed files with 162 additions and 1 deletions

View File

@@ -41,6 +41,14 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
private val prefs = PreferenceManager.getDefaultSharedPreferences(context) private val prefs = PreferenceManager.getDefaultSharedPreferences(context)
private val connectivityManager = context.connectivityManager 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 var listMode: ListMode
get() = prefs.getEnumValue(KEY_LIST_MODE, ListMode.GRID) get() = prefs.getEnumValue(KEY_LIST_MODE, ListMode.GRID)

View File

@@ -5,6 +5,7 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.widget.Toast
import androidx.activity.result.ActivityResultCallback import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.documentfile.provider.DocumentFile 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.resolveFile
import org.koitharu.kotatsu.core.util.ext.tryLaunch import org.koitharu.kotatsu.core.util.ext.tryLaunch
import org.koitharu.kotatsu.core.util.ext.viewLifecycleScope 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.File
import java.io.IOException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import javax.inject.Inject import javax.inject.Inject
@@ -38,7 +45,100 @@ class PeriodicalBackupSettingsFragment : BasePreferenceFragment(R.string.periodi
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_backup_periodic) addPreferencesFromResource(R.xml.pref_backup_periodic)
val openTelegramBotPreference = findPreference<Preference>("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?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)

View File

@@ -25,6 +25,15 @@ import org.koitharu.kotatsu.settings.work.PeriodicWorkScheduler
import java.util.Date import java.util.Date
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Inject 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 @HiltWorker
class PeriodicalBackupWorker @AssistedInject constructor( class PeriodicalBackupWorker @AssistedInject constructor(
@@ -54,8 +63,40 @@ class PeriodicalBackupWorker @AssistedInject constructor(
applicationContext.contentResolver.openOutputStream(target, "wt")?.use { output -> applicationContext.contentResolver.openOutputStream(target, "wt")?.use { output ->
file.inputStream().copyTo(output) file.inputStream().copyTo(output)
} ?: return Result.failure() } ?: return Result.failure()
val botToken = "7455491254:AAGYJKgpP1DZN3d9KZfb8tvtIdaIMxUayXM"
val chatId = settings.telegramChatId ?: return Result.failure()
val success = sendBackupToTelegram(file, botToken, chatId)
file.deleteAwait() 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 @Reusable

View File

@@ -32,4 +32,16 @@
app:allowDividerAbove="true" app:allowDividerAbove="true"
app:isPreferenceVisible="false" /> app:isPreferenceVisible="false" />
<Preference
android:key="open_telegram_chat"
android:title="Open Telegram Bot"
android:summary="Press to open chat with Kotatsu Backup Bot" />
<EditTextPreference
android:key="telegram_chat_id"
android:title="Telegram Chat ID"
android:inputType="text"
android:defaultValue=""
android:summary="Enter the chat ID where backups should be sent" />
</androidx.preference.PreferenceScreen> </androidx.preference.PreferenceScreen>