diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/logs/FileLogger.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/logs/FileLogger.kt deleted file mode 100644 index 60a1e1d83..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/logs/FileLogger.kt +++ /dev/null @@ -1,148 +0,0 @@ -package org.koitharu.kotatsu.core.logs - -import android.content.Context -import androidx.annotation.WorkerThread -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.NonCancellable -import kotlinx.coroutines.cancelAndJoin -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.runInterruptible -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.withContext -import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.core.util.ext.processLifecycleScope -import org.koitharu.kotatsu.core.util.ext.subdir -import org.koitharu.kotatsu.parsers.util.runCatchingCancellable -import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug -import java.io.File -import java.io.FileOutputStream -import java.time.LocalDateTime -import java.time.format.DateTimeFormatter -import java.time.format.FormatStyle -import java.util.Locale -import java.util.concurrent.ConcurrentLinkedQueue - -private const val DIR = "logs" -private const val FLUSH_DELAY = 2_000L -private const val MAX_SIZE_BYTES = 1024 * 1024 // 1 MB - -class FileLogger( - context: Context, - private val settings: AppSettings, - name: String, -) { - - val file by lazy { - val dir = context.getExternalFilesDir(DIR) ?: context.filesDir.subdir(DIR) - File(dir, "$name.log") - } - val isEnabled: Boolean - get() = settings.isLoggingEnabled - private val dateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withLocale(Locale.ROOT) - private val buffer = ConcurrentLinkedQueue() - private val mutex = Mutex() - private var flushJob: Job? = null - - fun log(message: String, e: Throwable? = null) { - if (!isEnabled) { - return - } - val text = buildString { - append(dateTimeFormatter.format(LocalDateTime.now())) - append(": ") - if (e != null) { - append("E!") - } - append(message) - if (e != null) { - append(' ') - append(e.stackTraceToString()) - appendLine() - } - } - buffer.add(text) - postFlush() - } - - inline fun log(messageProducer: () -> String) { - if (isEnabled) { - log(messageProducer()) - } - } - - suspend fun flush() { - if (!isEnabled) { - return - } - flushJob?.cancelAndJoin() - flushImpl() - } - - @WorkerThread - fun flushBlocking() { - if (!isEnabled) { - return - } - runBlockingSafe { flushJob?.cancelAndJoin() } - runBlockingSafe { flushImpl() } - } - - private fun postFlush() { - if (flushJob?.isActive == true) { - return - } - flushJob = processLifecycleScope.launch(Dispatchers.Default) { - delay(FLUSH_DELAY) - runCatchingCancellable { - flushImpl() - }.onFailure { - it.printStackTraceDebug() - } - } - } - - private suspend fun flushImpl() = withContext(NonCancellable) { - mutex.withLock { - if (buffer.isEmpty()) { - return@withContext - } - runInterruptible(Dispatchers.IO) { - if (file.length() > MAX_SIZE_BYTES) { - rotate() - } - FileOutputStream(file, true).use { - while (true) { - val message = buffer.poll() ?: break - it.write(message.toByteArray()) - it.write('\n'.code) - } - it.flush() - } - } - } - } - - @WorkerThread - private fun rotate() { - val length = file.length() - val bakFile = File(file.parentFile, file.name + ".bak") - file.renameTo(bakFile) - bakFile.inputStream().use { input -> - input.skip(length - MAX_SIZE_BYTES / 2) - file.outputStream().use { output -> - input.copyTo(output) - output.flush() - } - } - bakFile.delete() - } - - private inline fun runBlockingSafe(crossinline block: suspend () -> Unit) = try { - runBlocking(NonCancellable) { block() } - } catch (_: InterruptedException) { - } -} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/logs/Loggers.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/logs/Loggers.kt deleted file mode 100644 index 008ca7d92..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/logs/Loggers.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.koitharu.kotatsu.core.logs - -import javax.inject.Qualifier - -@Qualifier -@Retention(AnnotationRetention.BINARY) -annotation class TrackerLogger - -@Qualifier -@Retention(AnnotationRetention.BINARY) -annotation class SyncLogger diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/logs/LoggersModule.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/logs/LoggersModule.kt deleted file mode 100644 index 8253044d8..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/logs/LoggersModule.kt +++ /dev/null @@ -1,40 +0,0 @@ -package org.koitharu.kotatsu.core.logs - -import android.content.Context -import androidx.collection.arraySetOf -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.components.SingletonComponent -import dagger.multibindings.ElementsIntoSet -import org.koitharu.kotatsu.core.prefs.AppSettings - -@Module -@InstallIn(SingletonComponent::class) -object LoggersModule { - - @Provides - @TrackerLogger - fun provideTrackerLogger( - @ApplicationContext context: Context, - settings: AppSettings, - ) = FileLogger(context, settings, "tracker") - - @Provides - @SyncLogger - fun provideSyncLogger( - @ApplicationContext context: Context, - settings: AppSettings, - ) = FileLogger(context, settings, "sync") - - @Provides - @ElementsIntoSet - fun provideAllLoggers( - @TrackerLogger trackerLogger: FileLogger, - @SyncLogger syncLogger: FileLogger, - ): Set<@JvmSuppressWildcards FileLogger> = arraySetOf( - trackerLogger, - syncLogger, - ) -} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/NetworkModule.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/NetworkModule.kt index 8d617cb68..0200b99c4 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/NetworkModule.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/NetworkModule.kt @@ -74,7 +74,7 @@ interface NetworkModule { if (settings.isSSLBypassEnabled) { disableCertificateVerification() } else { - installExtraCertsificates(contextProvider.get()) + installExtraCertificates(contextProvider.get()) } cache(cache) addInterceptor(GZipInterceptor()) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/SSLUtils.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/SSLUtils.kt index 505ebc6d3..fa1c44911 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/SSLUtils.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/SSLUtils.kt @@ -35,7 +35,7 @@ fun OkHttpClient.Builder.disableCertificateVerification() = also { builder -> } } -fun OkHttpClient.Builder.installExtraCertsificates(context: Context) = also { builder -> +fun OkHttpClient.Builder.installExtraCertificates(context: Context) = also { builder -> val certificatesBuilder = HandshakeCertificates.Builder() .addPlatformTrustedCertificates() val assets = context.assets.list("").orEmpty() 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..11b7fac46 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 @@ -239,9 +239,6 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { } } ?: EnumSet.allOf(SearchSuggestionType::class.java) - val isLoggingEnabled: Boolean - get() = prefs.getBoolean(KEY_LOGGING_ENABLED, false) - var isBiometricProtectionEnabled: Boolean get() = prefs.getBoolean(KEY_PROTECT_APP_BIOMETRIC, true) set(value) = prefs.edit { putBoolean(KEY_PROTECT_APP_BIOMETRIC, value) } @@ -665,7 +662,6 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { const val KEY_WEBTOON_ZOOM_OUT = "webtoon_zoom_out" const val KEY_PREFETCH_CONTENT = "prefetch_content" const val KEY_APP_LOCALE = "app_locale" - const val KEY_LOGGING_ENABLED = "logging" const val KEY_SOURCES_GRID = "sources_grid" const val KEY_UPDATES_UNSTABLE = "updates_unstable" const val KEY_TIPS_CLOSED = "tips_closed" @@ -709,9 +705,11 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { const val KEY_APP_VERSION = "app_version" const val KEY_IGNORE_DOZE = "ignore_dose" const val KEY_TRACKER_DEBUG = "tracker_debug" - const val KEY_LOGS_SHARE = "logs_share" const val KEY_APP_UPDATE = "app_update" - const val KEY_APP_TRANSLATION = "about_app_translation" + const val KEY_LINK_WEBLATE = "about_app_translation" + const val KEY_LINK_TELEGRAM = "about_telegram" + const val KEY_LINK_GITHUB = "about_github" + const val KEY_LINK_MANUAL = "about_help" const val PROXY_TEST = "proxy_test" // old keys are for migration only diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt index 43b29b380..357e792e4 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BasePreferenceFragment.kt @@ -80,11 +80,11 @@ abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : (activity as? SettingsActivity)?.setSectionTitle(title) } - protected fun startActivitySafe(intent: Intent) { - try { - startActivity(intent) - } catch (_: ActivityNotFoundException) { - Snackbar.make(listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show() - } + protected fun startActivitySafe(intent: Intent): Boolean = try { + startActivity(intent) + true + } catch (_: ActivityNotFoundException) { + Snackbar.make(listView, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show() + false } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ShareHelper.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ShareHelper.kt index c16502090..fc486cb4f 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ShareHelper.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/util/ShareHelper.kt @@ -2,12 +2,10 @@ package org.koitharu.kotatsu.core.util import android.content.Context import android.net.Uri -import android.widget.Toast import androidx.core.app.ShareCompat import androidx.core.content.FileProvider import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.core.logs.FileLogger import org.koitharu.kotatsu.core.model.appUrl import org.koitharu.kotatsu.parsers.model.Manga import java.io.File @@ -84,25 +82,4 @@ class ShareHelper(private val context: Context) { .setChooserTitle(R.string.share) .startChooser() } - - fun shareLogs(loggers: Collection) { - val intentBuilder = ShareCompat.IntentBuilder(context) - .setType(TYPE_TEXT) - var hasLogs = false - for (logger in loggers) { - val logFile = logger.file - if (!logFile.exists()) { - continue - } - val uri = FileProvider.getUriForFile(context, "${BuildConfig.APPLICATION_ID}.files", logFile) - intentBuilder.addStream(uri) - hasLogs = true - } - if (hasLogs) { - intentBuilder.setChooserTitle(R.string.share_logs) - intentBuilder.startChooser() - } else { - Toast.makeText(context, R.string.nothing_here, Toast.LENGTH_SHORT).show() - } - } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AboutSettingsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AboutSettingsFragment.kt index 944355452..cc6655248 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AboutSettingsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/about/AboutSettingsFragment.kt @@ -3,6 +3,7 @@ package org.koitharu.kotatsu.settings.about import android.content.Intent import android.os.Bundle import android.view.View +import androidx.annotation.StringRes import androidx.core.net.toUri import androidx.fragment.app.viewModels import androidx.preference.Preference @@ -14,23 +15,16 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.github.AppVersion import org.koitharu.kotatsu.core.github.VersionId import org.koitharu.kotatsu.core.github.isStable -import org.koitharu.kotatsu.core.logs.FileLogger import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.ui.BasePreferenceFragment -import org.koitharu.kotatsu.core.util.ShareHelper import org.koitharu.kotatsu.core.util.ext.observe import org.koitharu.kotatsu.core.util.ext.observeEvent -import org.koitharu.kotatsu.tracker.ui.debug.TrackerDebugActivity -import javax.inject.Inject @AndroidEntryPoint class AboutSettingsFragment : BasePreferenceFragment(R.string.about) { private val viewModel by viewModels() - @Inject - lateinit var loggers: Set<@JvmSuppressWildcards FileLogger> - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.pref_about) findPreference(AppSettings.KEY_APP_VERSION)?.run { @@ -41,12 +35,6 @@ class AboutSettingsFragment : BasePreferenceFragment(R.string.about) { isEnabled = VersionId(BuildConfig.VERSION_NAME).isStable if (!isEnabled) isChecked = true } - if (!settings.isTrackerEnabled) { - findPreference(AppSettings.KEY_TRACKER_DEBUG)?.run { - isEnabled = false - setSummary(R.string.check_for_new_chapters_disabled) - } - } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -64,21 +52,27 @@ class AboutSettingsFragment : BasePreferenceFragment(R.string.about) { true } - AppSettings.KEY_APP_TRANSLATION -> { - openLink(getString(R.string.url_weblate), preference.title) + AppSettings.KEY_LINK_WEBLATE -> { + openLink(R.string.url_weblate, preference.title) true } - AppSettings.KEY_LOGS_SHARE -> { - ShareHelper(preference.context).shareLogs(loggers) + AppSettings.KEY_LINK_GITHUB -> { + openLink(R.string.url_github, preference.title) true } - AppSettings.KEY_TRACKER_DEBUG -> { - startActivity(Intent(preference.context, TrackerDebugActivity::class.java)) + AppSettings.KEY_LINK_MANUAL -> { + openLink(R.string.url_user_manual, preference.title) true } + AppSettings.KEY_LINK_TELEGRAM -> { + if (!openLink(R.string.url_telegram, null)) { + openLink(R.string.url_telegram_web, preference.title) + } + true + } else -> super.onPreferenceTreeClick(preference) } @@ -87,15 +81,15 @@ class AboutSettingsFragment : BasePreferenceFragment(R.string.about) { private fun onUpdateAvailable(version: AppVersion?) { if (version == null) { Snackbar.make(listView, R.string.no_update_available, Snackbar.LENGTH_SHORT).show() - return + } else { + startActivity(Intent(requireContext(), AppUpdateActivity::class.java)) } - startActivity(Intent(requireContext(), AppUpdateActivity::class.java)) } - private fun openLink(url: String, title: CharSequence?) { + private fun openLink(@StringRes url: Int, title: CharSequence?): Boolean { val intent = Intent(Intent.ACTION_VIEW) - intent.data = url.toUri() - startActivitySafe( + intent.data = getString(url).toUri() + return startActivitySafe( if (title != null) { Intent.createChooser(intent, title) } else { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/TrackerSettingsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/TrackerSettingsFragment.kt index 2d6d771e4..cb0ccd202 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/TrackerSettingsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/tracker/TrackerSettingsFragment.kt @@ -25,6 +25,7 @@ import org.koitharu.kotatsu.parsers.util.names import org.koitharu.kotatsu.settings.tracker.categories.TrackerCategoriesConfigSheet import org.koitharu.kotatsu.settings.utils.DozeHelper import org.koitharu.kotatsu.settings.utils.MultiSummaryProvider +import org.koitharu.kotatsu.tracker.ui.debug.TrackerDebugActivity import org.koitharu.kotatsu.tracker.work.TrackerNotificationHelper import javax.inject.Inject @@ -116,6 +117,11 @@ class TrackerSettingsFragment : true } + AppSettings.KEY_TRACKER_DEBUG -> { + startActivity(Intent(preference.context, TrackerDebugActivity::class.java)) + true + } + else -> super.onPreferenceTreeClick(preference) } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/utils/AboutLinksPreference.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/utils/AboutLinksPreference.kt deleted file mode 100644 index ed9aabd94..000000000 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/utils/AboutLinksPreference.kt +++ /dev/null @@ -1,62 +0,0 @@ -package org.koitharu.kotatsu.settings.utils - -import android.content.ActivityNotFoundException -import android.content.Context -import android.content.Intent -import android.util.AttributeSet -import android.view.View -import androidx.appcompat.widget.TooltipCompat -import androidx.core.net.toUri -import androidx.core.view.forEach -import androidx.preference.Preference -import androidx.preference.PreferenceViewHolder -import com.google.android.material.snackbar.Snackbar -import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.databinding.PreferenceAboutLinksBinding - -class AboutLinksPreference @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, -) : Preference(context, attrs), View.OnClickListener { - - init { - layoutResource = R.layout.preference_about_links - isSelectable = false - isPersistent = false - } - - override fun onBindViewHolder(holder: PreferenceViewHolder) { - super.onBindViewHolder(holder) - - val binding = PreferenceAboutLinksBinding.bind(holder.itemView) - binding.root.forEach { button -> - TooltipCompat.setTooltipText(button, button.contentDescription) - button.setOnClickListener(this) - } - } - - override fun onClick(v: View) { - val urlResId = when (v.id) { - R.id.btn_discord -> R.string.url_discord - R.id.btn_telegram -> R.string.url_telegram - R.id.btn_github -> R.string.url_github - else -> return - } - openLink(v, v.context.getString(urlResId), v.contentDescription) - } - - private fun openLink(v: View, url: String, title: CharSequence?) { - val intent = Intent(Intent.ACTION_VIEW, url.toUri()) - try { - context.startActivity( - if (title != null) { - Intent.createChooser(intent, title) - } else { - intent - }, - ) - } catch (_: ActivityNotFoundException) { - Snackbar.make(v, R.string.operation_not_supported, Snackbar.LENGTH_SHORT).show() - } - } -} diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/sync/domain/SyncHelper.kt b/app/src/main/kotlin/org/koitharu/kotatsu/sync/domain/SyncHelper.kt index ae68969e0..3aa5959c4 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/sync/domain/SyncHelper.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/sync/domain/SyncHelper.kt @@ -10,6 +10,7 @@ import android.content.SyncResult import android.content.SyncStats import android.database.Cursor import android.net.Uri +import android.util.Log import androidx.annotation.WorkerThread import androidx.core.content.contentValuesOf import dagger.assisted.Assisted @@ -18,9 +19,9 @@ import dagger.assisted.AssistedInject import dagger.hilt.android.qualifiers.ApplicationContext import okhttp3.OkHttpClient import okhttp3.Request -import okhttp3.Response import org.json.JSONArray import org.json.JSONObject +import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.db.TABLE_FAVOURITES import org.koitharu.kotatsu.core.db.TABLE_FAVOURITE_CATEGORIES @@ -28,10 +29,9 @@ import org.koitharu.kotatsu.core.db.TABLE_HISTORY import org.koitharu.kotatsu.core.db.TABLE_MANGA import org.koitharu.kotatsu.core.db.TABLE_MANGA_TAGS import org.koitharu.kotatsu.core.db.TABLE_TAGS -import org.koitharu.kotatsu.core.logs.FileLogger -import org.koitharu.kotatsu.core.logs.SyncLogger import org.koitharu.kotatsu.core.network.BaseHttpClient import org.koitharu.kotatsu.core.util.ext.parseJsonOrNull +import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug import org.koitharu.kotatsu.core.util.ext.toContentValues import org.koitharu.kotatsu.core.util.ext.toJson import org.koitharu.kotatsu.core.util.ext.toRequestBody @@ -50,7 +50,6 @@ class SyncHelper @AssistedInject constructor( @Assisted private val account: Account, @Assisted private val provider: ContentProviderClient, private val settings: SyncSettings, - @SyncLogger private val logger: FileLogger, ) { private val authorityHistory = context.getString(R.string.sync_authority_history) @@ -75,7 +74,7 @@ class SyncHelper @AssistedInject constructor( .url("$baseUrl/resource/$TABLE_FAVOURITES") .post(data.toRequestBody()) .build() - val response = httpClient.newCall(request).execute().log().parseJsonOrNull() + val response = httpClient.newCall(request).execute().parseJsonOrNull() if (response != null) { val categoriesResult = upsertFavouriteCategories(response.getJSONArray(TABLE_FAVOURITE_CATEGORIES)) stats.numDeletes += categoriesResult.first().count?.toLong() ?: 0L @@ -97,7 +96,7 @@ class SyncHelper @AssistedInject constructor( .url("$baseUrl/resource/$TABLE_HISTORY") .post(data.toRequestBody()) .build() - val response = httpClient.newCall(request).execute().log().parseJsonOrNull() + val response = httpClient.newCall(request).execute().parseJsonOrNull() if (response != null) { val result = upsertHistory( json = response.getJSONArray(TABLE_HISTORY), @@ -110,15 +109,12 @@ class SyncHelper @AssistedInject constructor( } fun onError(e: Throwable) { - if (logger.isEnabled) { - logger.log("Sync error", e) - } + e.printStackTraceDebug() } fun onSyncComplete(result: SyncResult) { - if (logger.isEnabled) { - logger.log("Sync finished: ${result.toDebugString()}") - logger.flushBlocking() + if (BuildConfig.DEBUG) { + Log.i("Sync", "Sync finished: ${result.toDebugString()}") } } @@ -298,12 +294,6 @@ class SyncHelper @AssistedInject constructor( private fun JSONObject.removeJSONArray(name: String) = remove(name) as JSONArray - private fun Response.log() = apply { - if (logger.isEnabled) { - logger.log("$code ${request.url}") - } - } - @AssistedFactory interface Factory { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt index ddb9a9b8d..0c2cc96c8 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt @@ -45,13 +45,12 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.browser.cloudflare.CaptchaNotifier import org.koitharu.kotatsu.core.db.MangaDatabase import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException -import org.koitharu.kotatsu.core.logs.FileLogger -import org.koitharu.kotatsu.core.logs.TrackerLogger import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.TrackerDownloadStrategy import org.koitharu.kotatsu.core.util.ext.awaitUniqueWorkInfoByName import org.koitharu.kotatsu.core.util.ext.checkNotificationPermission import org.koitharu.kotatsu.core.util.ext.onEachIndexed +import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug import org.koitharu.kotatsu.core.util.ext.trySetForeground import org.koitharu.kotatsu.download.ui.worker.DownloadWorker import org.koitharu.kotatsu.local.data.LocalMangaRepository @@ -80,7 +79,6 @@ class TrackWorker @AssistedInject constructor( private val getTracksUseCase: GetTracksUseCase, private val checkNewChaptersUseCase: CheckNewChaptersUseCase, private val workManager: WorkManager, - @TrackerLogger private val logger: FileLogger, private val localRepositoryLazy: Lazy, private val downloadSchedulerLazy: Lazy, ) : CoroutineWorker(context, workerParams) { @@ -90,17 +88,15 @@ class TrackWorker @AssistedInject constructor( override suspend fun doWork(): Result { notificationHelper.updateChannels() val isForeground = trySetForeground() - logger.log("doWork(): attempt $runAttemptCount") return try { doWorkImpl(isFullRun = isForeground && TAG_ONESHOT in tags) } catch (e: CancellationException) { throw e } catch (e: Throwable) { - logger.log("fatal", e) + e.printStackTraceDebug() Result.failure() } finally { withContext(NonCancellable) { - logger.flush() notificationManager.cancel(WORKER_NOTIFICATION_ID) } } @@ -111,7 +107,6 @@ class TrackWorker @AssistedInject constructor( return Result.success() } val tracks = getTracksUseCase(if (isFullRun) Int.MAX_VALUE else BATCH_SIZE) - logger.log("Total ${tracks.size} tracks") if (tracks.isEmpty()) { return Result.success() } @@ -154,7 +149,6 @@ class TrackWorker @AssistedInject constructor( when (it) { is MangaUpdates.Failure -> { val e = it.error - logger.log("checkUpdatesAsync", e) if (e is CloudFlareProtectedException) { CaptchaNotifier(applicationContext).notify(e) } diff --git a/app/src/main/res/values/constants.xml b/app/src/main/res/values/constants.xml index c69fc6be3..c1db553ce 100644 --- a/app/src/main/res/values/constants.xml +++ b/app/src/main/res/values/constants.xml @@ -1,9 +1,10 @@ https://github.com/KotatsuApp/Kotatsu - https://discord.gg/NNJ5RgVBC5 - https://t.me/kotatsuapp + https://t.me/kotatsuapp + tg://resolve?domain=kotatsuapp https://hosted.weblate.org/engage/kotatsu + https://kotatsu.app/manuals/guides/getting-started/ https://bugs.kotatsu.app/report org.kotatsu.sync https://sync.kotatsu.app diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2648670ac..e0cca68e8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -733,4 +733,8 @@ Image set Artist CG Game CG + Debug + Source code + User manual + Telegram group diff --git a/app/src/main/res/xml/pref_about.xml b/app/src/main/res/xml/pref_about.xml index 2ce94cb0c..aa3e7c27f 100644 --- a/app/src/main/res/xml/pref_about.xml +++ b/app/src/main/res/xml/pref_about.xml @@ -3,45 +3,40 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> - + - + - + - + - + - - - - - - - + diff --git a/app/src/main/res/xml/pref_tracker.xml b/app/src/main/res/xml/pref_tracker.xml index 71b113a1e..b6b4bdae1 100644 --- a/app/src/main/res/xml/pref_tracker.xml +++ b/app/src/main/res/xml/pref_tracker.xml @@ -1,8 +1,7 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> - + - + + + + + +