Replace Timber with Square Logcat and make logging configurable (#6062)

* Replace Timber with Square Logcat

* Configurable logger

(cherry picked from commit 2e127dff1f0b00f6a92359a07132c6016db6ea36)

# Conflicts:
#	app/src/main/java/eu/kanade/tachiyomi/App.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/extension/details/SourcePreferencesController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourceController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/browse/source/browse/BrowseSourcePresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/more/AboutController.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/HttpPageLoader.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewer.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/pager/PagerViewerAdapter.kt
This commit is contained in:
Ivan Iskandar 2021-10-08 09:12:55 +07:00 committed by Jobobby04
parent b10de38e9a
commit 14d6e8dd94
59 changed files with 270 additions and 196 deletions

View File

@ -240,7 +240,7 @@ dependencies {
implementation("io.github.reactivecircus.flowbinding:flowbinding-viewpager:$flowbindingVersion") implementation("io.github.reactivecircus.flowbinding:flowbinding-viewpager:$flowbindingVersion")
// Logging // Logging
implementation("com.jakewharton.timber:timber:5.0.1") implementation("com.squareup.logcat:logcat:0.1")
// Crash reports/analytics // Crash reports/analytics
//implementation("ch.acra:acra-http:5.8.1") //implementation("ch.acra:acra-http:5.8.1")

View File

@ -22,6 +22,7 @@ import coil.ImageLoader
import coil.ImageLoaderFactory import coil.ImageLoaderFactory
import coil.decode.GifDecoder import coil.decode.GifDecoder
import coil.decode.ImageDecoderDecoder import coil.decode.ImageDecoderDecoder
import coil.util.DebugLogger
import com.elvishew.xlog.LogConfiguration import com.elvishew.xlog.LogConfiguration
import com.elvishew.xlog.LogLevel import com.elvishew.xlog.LogLevel
import com.elvishew.xlog.XLog import com.elvishew.xlog.XLog
@ -51,7 +52,7 @@ import exh.log.CrashlyticsPrinter
import exh.log.EHDebugModeOverlay import exh.log.EHDebugModeOverlay
import exh.log.EHLogLevel import exh.log.EHLogLevel
import exh.log.EnhancedFilePrinter import exh.log.EnhancedFilePrinter
import exh.log.XLogTree import exh.log.XLogLogcatLogger
import exh.log.xLogD import exh.log.xLogD
import exh.log.xLogE import exh.log.xLogE
import exh.syDebugVersion import exh.syDebugVersion
@ -59,8 +60,8 @@ import exh.util.days
import io.realm.Realm import io.realm.Realm
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import logcat.LogcatLogger
import org.conscrypt.Conscrypt import org.conscrypt.Conscrypt
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -79,7 +80,7 @@ open class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
super<Application>.onCreate() super<Application>.onCreate()
// if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree()) // if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
setupExhLogging() // EXH logging setupExhLogging() // EXH logging
Timber.plant(XLogTree()) // SY Redirect Timber to XLog LogcatLogger.install(XLogLogcatLogger()) // SY Redirect Logcat to XLog
if (!BuildConfig.DEBUG) addAnalytics() if (!BuildConfig.DEBUG) addAnalytics()
// TLS 1.3 support for Android < 10 // TLS 1.3 support for Android < 10
@ -141,6 +142,10 @@ open class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
} }
) )
}.launchIn(ProcessLifecycleOwner.get().lifecycleScope) }.launchIn(ProcessLifecycleOwner.get().lifecycleScope)
/*if (!LogcatLogger.isInstalled && preferences.verboseLogging()) {
LogcatLogger.install(AndroidLogcatLogger(LogPriority.VERBOSE))
}*/
} }
override fun newImageLoader(): ImageLoader { override fun newImageLoader(): ImageLoader {
@ -158,6 +163,7 @@ open class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
okHttpClient(Injekt.get<NetworkHelper>().coilClient) okHttpClient(Injekt.get<NetworkHelper>().coilClient)
crossfade((300 * this@App.animatorDurationScale).toInt()) crossfade((300 * this@App.animatorDurationScale).toInt())
allowRgb565(getSystemService<ActivityManager>()!!.isLowRamDevice) allowRgb565(getSystemService<ActivityManager>()!!.isLowRamDevice)
if (preferences.verboseLogging()) logger(DebugLogger())
}.build() }.build()
} }

View File

@ -13,13 +13,14 @@ import eu.kanade.tachiyomi.data.backup.legacy.LegacyBackupRestore
import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.system.acquireWakeLock import eu.kanade.tachiyomi.util.system.acquireWakeLock
import eu.kanade.tachiyomi.util.system.isServiceRunning import eu.kanade.tachiyomi.util.system.isServiceRunning
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber import logcat.LogPriority
/** /**
* Restores backup. * Restores backup.
@ -128,7 +129,7 @@ class BackupRestoreService : Service() {
} }
val handler = CoroutineExceptionHandler { _, exception -> val handler = CoroutineExceptionHandler { _, exception ->
Timber.e(exception) logcat(LogPriority.ERROR, exception)
backupRestore?.writeErrorLog() backupRestore?.writeErrorLog()
notifier.showRestoreError(exception.message) notifier.showRestoreError(exception.message)

View File

@ -35,6 +35,7 @@ import eu.kanade.tachiyomi.data.database.models.MangaCategory
import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.source.online.MetadataSource import eu.kanade.tachiyomi.source.online.MetadataSource
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.system.logcat
import exh.metadata.metadata.base.getFlatMetadataForManga import exh.metadata.metadata.base.getFlatMetadataForManga
import exh.metadata.metadata.base.insertFlatMetadataAsync import exh.metadata.metadata.base.insertFlatMetadataAsync
import exh.savedsearches.JsonSavedSearch import exh.savedsearches.JsonSavedSearch
@ -45,10 +46,10 @@ import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
import logcat.LogPriority
import okio.buffer import okio.buffer
import okio.gzip import okio.gzip
import okio.sink import okio.sink
import timber.log.Timber
import kotlin.math.max import kotlin.math.max
class FullBackupManager(context: Context) : AbstractBackupManager(context) { class FullBackupManager(context: Context) : AbstractBackupManager(context) {
@ -109,7 +110,7 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
file.openOutputStream().sink().gzip().buffer().use { it.write(byteArray) } file.openOutputStream().sink().gzip().buffer().use { it.write(byteArray) }
return file.uri.toString() return file.uri.toString()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) logcat(LogPriority.ERROR, e)
throw e throw e
} }
} }

View File

@ -15,8 +15,10 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.system.logcat
import exh.log.xLogE
import logcat.LogPriority
import rx.Observable import rx.Observable
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -327,7 +329,7 @@ class DownloadManager(
mangaFolder.delete() mangaFolder.delete()
cache.removeManga(manga) cache.removeManga(manga)
} else { } else {
Timber.e("Cache and download folder doesn't match for %s", manga.title) xLogE("Cache and download folder doesn't match for " + manga.title)
} }
} }
return cleaned return cleaned
@ -391,7 +393,7 @@ class DownloadManager(
cache.removeChapter(oldChapter, manga) cache.removeChapter(oldChapter, manga)
cache.addChapter(newName + if (oldFolder.name?.endsWith(".cbz") == true) ".cbz" else "", mangaDir, manga) cache.addChapter(newName + if (oldFolder.name?.endsWith(".cbz") == true) ".cbz" else "", mangaDir, manga)
} else { } else {
Timber.e("Could not rename downloaded chapter: %s.", oldNames.joinToString()) logcat(LogPriority.ERROR) { "Could not rename downloaded chapter: ${oldNames.joinToString()}." }
} }
} }

View File

@ -9,10 +9,11 @@ import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import timber.log.Timber import logcat.LogPriority
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
/** /**
@ -54,7 +55,7 @@ class DownloadProvider(private val context: Context) {
.createDirectory(getSourceDirName(source)) .createDirectory(getSourceDirName(source))
.createDirectory(getMangaDirName(manga)) .createDirectory(getMangaDirName(manga))
} catch (e: Throwable) { } catch (e: Throwable) {
Timber.e(e, "Invalid download directory") logcat(LogPriority.ERROR, e) { "Invalid download directory" }
throw Exception(context.getString(R.string.invalid_download_dir)) throw Exception(context.getString(R.string.invalid_download_dir))
} }
} }

View File

@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.util.system.acquireWakeLock
import eu.kanade.tachiyomi.util.system.isConnectedToWifi import eu.kanade.tachiyomi.util.system.isConnectedToWifi
import eu.kanade.tachiyomi.util.system.isOnline import eu.kanade.tachiyomi.util.system.isOnline
import eu.kanade.tachiyomi.util.system.isServiceRunning import eu.kanade.tachiyomi.util.system.isServiceRunning
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.notification import eu.kanade.tachiyomi.util.system.notification
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -27,9 +28,9 @@ import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import logcat.LogPriority
import ru.beryukhov.reactivenetwork.ReactiveNetwork import ru.beryukhov.reactivenetwork.ReactiveNetwork
import rx.subscriptions.CompositeSubscription import rx.subscriptions.CompositeSubscription
import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
/** /**
@ -143,7 +144,7 @@ class DownloadService : Service() {
} }
.catch { error -> .catch { error ->
withUIContext { withUIContext {
Timber.e(error) logcat(LogPriority.ERROR, error)
toast(R.string.download_queue_error) toast(R.string.download_queue_error)
stopSelf() stopSelf()
} }

View File

@ -23,13 +23,14 @@ import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.storage.saveTo import eu.kanade.tachiyomi.util.storage.saveTo
import eu.kanade.tachiyomi.util.system.ImageUtil import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.async import kotlinx.coroutines.async
import logcat.LogPriority
import okhttp3.Response import okhttp3.Response
import rx.Observable import rx.Observable
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import rx.subscriptions.CompositeSubscription import rx.subscriptions.CompositeSubscription
import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.BufferedOutputStream import java.io.BufferedOutputStream
import java.io.File import java.io.File
@ -216,7 +217,7 @@ class Downloader(
}, },
{ error -> { error ->
DownloadService.stop(context) DownloadService.stop(context)
Timber.e(error) logcat(LogPriority.ERROR, error)
notifier.onError(error.message) notifier.onError(error.message)
} }
) )

View File

@ -41,6 +41,8 @@ import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.acquireWakeLock import eu.kanade.tachiyomi.util.system.acquireWakeLock
import eu.kanade.tachiyomi.util.system.createFileInCacheDir import eu.kanade.tachiyomi.util.system.createFileInCacheDir
import eu.kanade.tachiyomi.util.system.isServiceRunning import eu.kanade.tachiyomi.util.system.isServiceRunning
import eu.kanade.tachiyomi.util.system.logcat
import exh.log.xLogE
import exh.md.utils.FollowStatus import exh.md.utils.FollowStatus
import exh.md.utils.MdUtil import exh.md.utils.MdUtil
import exh.metadata.metadata.base.insertFlatMetadataAsync import exh.metadata.metadata.base.insertFlatMetadataAsync
@ -64,7 +66,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.supervisorScope import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit import kotlinx.coroutines.sync.withPermit
import timber.log.Timber import logcat.LogPriority
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
@ -246,7 +248,7 @@ class LibraryUpdateService(
// Destroy service when completed or in case of an error. // Destroy service when completed or in case of an error.
val handler = CoroutineExceptionHandler { _, exception -> val handler = CoroutineExceptionHandler { _, exception ->
Timber.e(exception) logcat(LogPriority.ERROR, exception)
stopSelf(startId) stopSelf(startId)
} }
updateJob = ioScope.launch(handler) { updateJob = ioScope.launch(handler) {
@ -461,7 +463,7 @@ class LibraryUpdateService(
// Update manga details metadata in the background // Update manga details metadata in the background
if (preferences.autoUpdateMetadata()) { if (preferences.autoUpdateMetadata()) {
val handler = CoroutineExceptionHandler { _, exception -> val handler = CoroutineExceptionHandler { _, exception ->
Timber.e(exception) logcat(LogPriority.ERROR, exception)
} }
GlobalScope.launch(Dispatchers.IO + handler) { GlobalScope.launch(Dispatchers.IO + handler) {
val updatedManga = source.getMangaDetails(manga.toMangaInfo()) val updatedManga = source.getMangaDetails(manga.toMangaInfo())
@ -481,7 +483,7 @@ class LibraryUpdateService(
// SY --> // SY -->
if (source.isMdBasedSource() && trackManager.mdList in loggedServices) { if (source.isMdBasedSource() && trackManager.mdList in loggedServices) {
val handler = CoroutineExceptionHandler { _, exception -> val handler = CoroutineExceptionHandler { _, exception ->
Timber.e(exception) xLogE("Error adding initial track for ${manga.title}", exception)
} }
ioScope.launch(handler) { ioScope.launch(handler) {
val tracks = db.getTracks(manga).executeAsBlocking() val tracks = db.getTracks(manga).executeAsBlocking()
@ -536,7 +538,7 @@ class LibraryUpdateService(
} }
} catch (e: Throwable) { } catch (e: Throwable) {
// Ignore errors and continue // Ignore errors and continue
Timber.e(e) logcat(LogPriority.ERROR, e)
} }
} }
@ -597,7 +599,7 @@ class LibraryUpdateService(
} }
} catch (e: Throwable) { } catch (e: Throwable) {
// Ignore errors and continue // Ignore errors and continue
Timber.e(e) logcat(LogPriority.ERROR, e)
} }
} }
} }

View File

@ -233,6 +233,8 @@ object PreferenceKeys {
const val extensionInstaller = "extension_installer" const val extensionInstaller = "extension_installer"
const val verboseLogging = "verbose_logging"
fun trackUsername(syncId: Int) = "pref_mangasync_username_$syncId" fun trackUsername(syncId: Int) = "pref_mangasync_username_$syncId"
fun trackPassword(syncId: Int) = "pref_mangasync_password_$syncId" fun trackPassword(syncId: Int) = "pref_mangasync_password_$syncId"

View File

@ -339,6 +339,8 @@ class PreferencesHelper(val context: Context) {
if (MiuiUtil.isMiui()) Values.ExtensionInstaller.LEGACY else Values.ExtensionInstaller.PACKAGEINSTALLER if (MiuiUtil.isMiui()) Values.ExtensionInstaller.LEGACY else Values.ExtensionInstaller.PACKAGEINSTALLER
) )
fun verboseLogging() = prefs.getBoolean(Keys.verboseLogging, false)
fun setChapterSettingsDefault(manga: Manga) { fun setChapterSettingsDefault(manga: Manga) {
prefs.edit { prefs.edit {
putInt(Keys.defaultChapterFilterByRead, manga.readFilter) putInt(Keys.defaultChapterFilterByRead, manga.readFilter)

View File

@ -3,7 +3,8 @@ package eu.kanade.tachiyomi.data.track.job
import android.content.Context import android.content.Context
import androidx.core.content.edit import androidx.core.content.edit
import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.database.models.Track
import timber.log.Timber import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class DelayedTrackingStore(context: Context) { class DelayedTrackingStore(context: Context) {
@ -17,7 +18,7 @@ class DelayedTrackingStore(context: Context) {
val (_, lastChapterRead) = preferences.getString(trackId, "0:0.0")!!.split(":") val (_, lastChapterRead) = preferences.getString(trackId, "0:0.0")!!.split(":")
if (track.last_chapter_read > lastChapterRead.toFloat()) { if (track.last_chapter_read > lastChapterRead.toFloat()) {
val value = "${track.manga_id}:${track.last_chapter_read}" val value = "${track.manga_id}:${track.last_chapter_read}"
Timber.i("Queuing track item: $trackId, $value") logcat(LogPriority.INFO) { "Queuing track item: $trackId, $value" }
preferences.edit { preferences.edit {
putString(trackId, value) putString(trackId, value)
} }

View File

@ -11,9 +11,10 @@ import androidx.work.WorkManager
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import timber.log.Timber import logcat.LogPriority
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -44,7 +45,7 @@ class DelayedTrackingUpdateJob(context: Context, workerParams: WorkerParameters)
db.insertTrack(track).executeAsBlocking() db.insertTrack(track).executeAsBlocking()
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) logcat(LogPriority.ERROR, e)
} }
} }

View File

@ -7,13 +7,14 @@ import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import logcat.LogPriority
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
const val READLIST_API = "/api/v1/readlists" const val READLIST_API = "/api/v1/readlists"
@ -56,7 +57,7 @@ class KomgaApi(private val client: OkHttpClient) {
last_chapter_read = progress.lastReadContinuousNumberSort last_chapter_read = progress.lastReadContinuousNumberSort
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.w(e, "Could not get item: $url") logcat(LogPriority.WARN, e) { "Could not get item: $url" }
throw e throw e
} }
} }

View File

@ -20,7 +20,8 @@ import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.storage.saveTo import eu.kanade.tachiyomi.util.storage.saveTo
import eu.kanade.tachiyomi.util.system.acquireWakeLock import eu.kanade.tachiyomi.util.system.acquireWakeLock
import eu.kanade.tachiyomi.util.system.isServiceRunning import eu.kanade.tachiyomi.util.system.isServiceRunning
import timber.log.Timber import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
@ -121,7 +122,7 @@ class UpdaterService : Service() {
} }
notifier.onDownloadFinished(apkFile.getUriCompat(this)) notifier.onDownloadFinished(apkFile.getUriCompat(this))
} catch (error: Exception) { } catch (error: Exception) {
Timber.e(error) logcat(LogPriority.ERROR, error)
notifier.onDownloadError(url) notifier.onDownloadError(url)
} }
} }

View File

@ -11,7 +11,8 @@ import android.os.Build
import eu.kanade.tachiyomi.extension.model.InstallStep import eu.kanade.tachiyomi.extension.model.InstallStep
import eu.kanade.tachiyomi.util.lang.use import eu.kanade.tachiyomi.util.lang.use
import eu.kanade.tachiyomi.util.system.getUriSize import eu.kanade.tachiyomi.util.system.getUriSize
import timber.log.Timber import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class PackageInstallerInstaller(private val service: Service) : Installer(service) { class PackageInstallerInstaller(private val service: Service) : Installer(service) {
@ -23,7 +24,7 @@ class PackageInstallerInstaller(private val service: Service) : Installer(servic
PackageInstaller.STATUS_PENDING_USER_ACTION -> { PackageInstaller.STATUS_PENDING_USER_ACTION -> {
val userAction = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT) val userAction = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)
if (userAction == null) { if (userAction == null) {
Timber.e("Fatal error for $intent") logcat(LogPriority.ERROR) { "Fatal error for $intent" }
continueQueue(InstallStep.Error) continueQueue(InstallStep.Error)
return return
} }
@ -74,7 +75,7 @@ class PackageInstallerInstaller(private val service: Service) : Installer(servic
session.commit(intentSender) session.commit(intentSender)
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "Failed to install extension ${entry.downloadId} ${entry.uri}") logcat(LogPriority.ERROR) { "Failed to install extension ${entry.downloadId} ${entry.uri}" }
activeSession?.let { (_, sessionId) -> activeSession?.let { (_, sessionId) ->
packageInstaller.abandonSession(sessionId) packageInstaller.abandonSession(sessionId)
} }

View File

@ -6,14 +6,15 @@ import android.os.Build
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.extension.model.InstallStep import eu.kanade.tachiyomi.extension.model.InstallStep
import eu.kanade.tachiyomi.util.system.getUriSize import eu.kanade.tachiyomi.util.system.getUriSize
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import logcat.LogPriority
import rikka.shizuku.Shizuku import rikka.shizuku.Shizuku
import timber.log.Timber
import java.io.BufferedReader import java.io.BufferedReader
import java.io.InputStream import java.io.InputStream
@ -22,7 +23,7 @@ class ShizukuInstaller(private val service: Service) : Installer(service) {
private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private val shizukuDeadListener = Shizuku.OnBinderDeadListener { private val shizukuDeadListener = Shizuku.OnBinderDeadListener {
Timber.e("Shizuku was killed prematurely") logcat { "Shizuku was killed prematurely" }
service.stopSelf() service.stopSelf()
} }
@ -72,7 +73,7 @@ class ShizukuInstaller(private val service: Service) : Installer(service) {
continueQueue(InstallStep.Installed) continueQueue(InstallStep.Installed)
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e, "Failed to install extension ${entry.downloadId} ${entry.uri}") logcat(LogPriority.ERROR, e) { "Failed to install extension ${entry.downloadId} ${entry.uri}" }
if (sessionId != null) { if (sessionId != null) {
exec("pm install-abandon $sessionId") exec("pm install-abandon $sessionId")
} }
@ -115,7 +116,7 @@ class ShizukuInstaller(private val service: Service) : Installer(service) {
false false
} }
} else { } else {
Timber.e("Shizuku is not ready to use.") logcat(LogPriority.ERROR) { "Shizuku is not ready to use." }
service.toast(R.string.ext_installer_shizuku_stopped) service.toast(R.string.ext_installer_shizuku_stopped)
service.stopSelf() service.stopSelf()
false false

View File

@ -12,8 +12,9 @@ import eu.kanade.tachiyomi.extension.installer.Installer
import eu.kanade.tachiyomi.extension.installer.PackageInstallerInstaller import eu.kanade.tachiyomi.extension.installer.PackageInstallerInstaller
import eu.kanade.tachiyomi.extension.installer.ShizukuInstaller import eu.kanade.tachiyomi.extension.installer.ShizukuInstaller
import eu.kanade.tachiyomi.extension.util.ExtensionInstaller.Companion.EXTRA_DOWNLOAD_ID import eu.kanade.tachiyomi.extension.util.ExtensionInstaller.Companion.EXTRA_DOWNLOAD_ID
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.notificationBuilder import eu.kanade.tachiyomi.util.system.notificationBuilder
import timber.log.Timber import logcat.LogPriority
class ExtensionInstallService : Service() { class ExtensionInstallService : Service() {
@ -46,7 +47,7 @@ class ExtensionInstallService : Service() {
PreferenceValues.ExtensionInstaller.PACKAGEINSTALLER -> PackageInstallerInstaller(this) PreferenceValues.ExtensionInstaller.PACKAGEINSTALLER -> PackageInstallerInstaller(this)
PreferenceValues.ExtensionInstaller.SHIZUKU -> ShizukuInstaller(this) PreferenceValues.ExtensionInstaller.SHIZUKU -> ShizukuInstaller(this)
else -> { else -> {
Timber.e("Not implemented for installer $installerUsed") logcat(LogPriority.ERROR) { "Not implemented for installer $installerUsed" }
stopSelf() stopSelf()
return START_NOT_STICKY return START_NOT_STICKY
} }

View File

@ -17,9 +17,10 @@ import eu.kanade.tachiyomi.extension.installer.Installer
import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.extension.model.Extension
import eu.kanade.tachiyomi.extension.model.InstallStep import eu.kanade.tachiyomi.extension.model.InstallStep
import eu.kanade.tachiyomi.util.storage.getUriCompat import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
import rx.Observable import rx.Observable
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
@ -239,7 +240,7 @@ internal class ExtensionInstaller(private val context: Context) {
// Set next installation step // Set next installation step
if (uri == null) { if (uri == null) {
Timber.e("Couldn't locate downloaded APK") logcat(LogPriority.ERROR) { "Couldn't locate downloaded APK" }
downloadsRelay.call(id to InstallStep.Error) downloadsRelay.call(id to InstallStep.Error)
return return
} }

View File

@ -13,9 +13,10 @@ import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceFactory import eu.kanade.tachiyomi.source.SourceFactory
import eu.kanade.tachiyomi.util.lang.Hash import eu.kanade.tachiyomi.util.lang.Hash
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import timber.log.Timber import logcat.LogPriority
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
/** /**
@ -107,7 +108,7 @@ internal object ExtensionLoader {
if (versionName.isNullOrEmpty()) { if (versionName.isNullOrEmpty()) {
val exception = Exception("Missing versionName for extension $extName") val exception = Exception("Missing versionName for extension $extName")
Timber.w(exception) logcat(LogPriority.WARN, exception)
return LoadResult.Error(exception) return LoadResult.Error(exception)
} }
@ -118,7 +119,7 @@ internal object ExtensionLoader {
"Lib version is $libVersion, while only versions " + "Lib version is $libVersion, while only versions " +
"$LIB_VERSION_MIN to $LIB_VERSION_MAX are allowed" "$LIB_VERSION_MIN to $LIB_VERSION_MAX are allowed"
) )
Timber.w(exception) logcat(LogPriority.WARN, exception)
return LoadResult.Error(exception) return LoadResult.Error(exception)
} }
@ -128,7 +129,7 @@ internal object ExtensionLoader {
return LoadResult.Error("Package $pkgName isn't signed") return LoadResult.Error("Package $pkgName isn't signed")
} else if (signatureHash !in trustedSignatures) { } else if (signatureHash !in trustedSignatures) {
val extension = Extension.Untrusted(extName, pkgName, versionName, versionCode, signatureHash) val extension = Extension.Untrusted(extName, pkgName, versionName, versionCode, signatureHash)
Timber.w("Extension $pkgName isn't trusted") logcat(LogPriority.WARN) { "Extension $pkgName isn't trusted" }
return LoadResult.Untrusted(extension) return LoadResult.Untrusted(extension)
} }
@ -157,7 +158,7 @@ internal object ExtensionLoader {
else -> throw Exception("Unknown source class type! ${obj.javaClass}") else -> throw Exception("Unknown source class type! ${obj.javaClass}")
} }
} catch (e: Throwable) { } catch (e: Throwable) {
Timber.e(e, "Extension load error: $extName ($it)") logcat(LogPriority.ERROR, e) { "Extension load error: $extName ($it)" }
return LoadResult.Error(e) return LoadResult.Error(e)
} }
} }

View File

@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.network
import android.content.Context import android.content.Context
import coil.util.CoilUtils import coil.util.CoilUtils
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.network.interceptor.CloudflareInterceptor import eu.kanade.tachiyomi.network.interceptor.CloudflareInterceptor
import eu.kanade.tachiyomi.network.interceptor.UserAgentInterceptor import eu.kanade.tachiyomi.network.interceptor.UserAgentInterceptor

View File

@ -15,12 +15,13 @@ import eu.kanade.tachiyomi.util.lang.compareToCaseInsensitiveNaturalOrder
import eu.kanade.tachiyomi.util.storage.DiskUtil import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.storage.EpubFile import eu.kanade.tachiyomi.util.storage.EpubFile
import eu.kanade.tachiyomi.util.system.ImageUtil import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.encodeToStream import kotlinx.serialization.json.encodeToStream
import logcat.LogPriority
import rx.Observable import rx.Observable
import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
@ -152,7 +153,7 @@ class LocalSource(private val context: Context) : CatalogueSource {
val dest = updateCover(chapter, this) val dest = updateCover(chapter, this)
thumbnail_url = dest?.absolutePath thumbnail_url = dest?.absolutePath
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) logcat(LogPriority.ERROR, e)
} }
} }
} }

View File

@ -10,10 +10,10 @@ import androidx.viewbinding.ViewBinding
import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.ControllerChangeHandler import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType import com.bluelinelabs.conductor.ControllerChangeType
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import timber.log.Timber
abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) : Controller(bundle) { abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) : Controller(bundle) {
@ -31,20 +31,20 @@ abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) : Contro
override fun preCreateView(controller: Controller) { override fun preCreateView(controller: Controller) {
viewScope = MainScope() viewScope = MainScope()
Timber.d("Create view for ${controller.instance()}") logcat { "Create view for ${controller.instance()}" }
} }
override fun preAttach(controller: Controller, view: View) { override fun preAttach(controller: Controller, view: View) {
Timber.d("Attach view for ${controller.instance()}") logcat { "Attach view for ${controller.instance()}" }
} }
override fun preDetach(controller: Controller, view: View) { override fun preDetach(controller: Controller, view: View) {
Timber.d("Detach view for ${controller.instance()}") logcat { "Detach view for ${controller.instance()}" }
} }
override fun preDestroyView(controller: Controller, view: View) { override fun preDestroyView(controller: Controller, view: View) {
viewScope.cancel() viewScope.cancel()
Timber.d("Destroy view for ${controller.instance()}") logcat { "Destroy view for ${controller.instance()}" }
} }
} }
) )

View File

@ -27,9 +27,10 @@ import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.getPreferenceKey import eu.kanade.tachiyomi.source.getPreferenceKey
import eu.kanade.tachiyomi.ui.base.controller.NucleusController import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito import eu.kanade.tachiyomi.widget.TachiyomiTextInputEditText.Companion.setIncognito
import exh.source.EnhancedHttpSource import exh.source.EnhancedHttpSource
import timber.log.Timber import logcat.LogPriority
@SuppressLint("RestrictedApi") @SuppressLint("RestrictedApi")
class SourcePreferencesController(bundle: Bundle? = null) : class SourcePreferencesController(bundle: Bundle? = null) :
@ -88,7 +89,7 @@ class SourcePreferencesController(bundle: Bundle? = null) :
} }
// SY <-- // SY <--
} catch (e: AbstractMethodError) { } catch (e: AbstractMethodError) {
Timber.e("Source did not implement [addPreferencesForSource]: ${source.name}") logcat(LogPriority.ERROR) { "Source did not implement [addPreferencesForSource]: ${source.name}" }
} }
manager.setPreferences(screen) manager.setPreferences(screen)

View File

@ -12,12 +12,13 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toSManga import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.lang.runAsObservable import eu.kanade.tachiyomi.util.lang.runAsObservable
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -125,7 +126,7 @@ open class LatestPresenter(
view.setItems(manga) view.setItems(manga)
}, },
{ _, error -> { _, error ->
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
) )
} }
@ -160,7 +161,7 @@ open class LatestPresenter(
view?.onMangaInitialized(source, manga) view?.onMangaInitialized(source, manga)
}, },
{ error -> { error ->
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
) )
} }

View File

@ -38,6 +38,7 @@ import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
import eu.kanade.tachiyomi.util.lang.launchUI import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import exh.eh.EHentaiThrottleManager import exh.eh.EHentaiThrottleManager
import exh.smartsearch.SmartSearchEngine import exh.smartsearch.SmartSearchEngine
@ -52,7 +53,7 @@ import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit import kotlinx.coroutines.sync.withPermit
import timber.log.Timber import logcat.LogPriority
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
@ -224,7 +225,7 @@ class MigrationListController(bundle: Bundle? = null) :
source.getChapterList(localManga.toMangaInfo()) source.getChapterList(localManga.toMangaInfo())
}.map { it.toSChapter() } }.map { it.toSChapter() }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) this@MigrationListController.logcat(LogPriority.ERROR, e)
emptyList() emptyList()
} }
withIOContext { withIOContext {

View File

@ -39,6 +39,7 @@ import eu.kanade.tachiyomi.util.chapter.syncChaptersWithTrackServiceTwoWay
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.removeCovers import eu.kanade.tachiyomi.util.removeCovers
import eu.kanade.tachiyomi.util.system.logcat
import exh.log.xLogE import exh.log.xLogE
import exh.savedsearches.EXHSavedSearch import exh.savedsearches.EXHSavedSearch
import exh.savedsearches.JsonSavedSearch import exh.savedsearches.JsonSavedSearch
@ -53,10 +54,10 @@ import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonArray
import logcat.LogPriority
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import xyz.nulldev.ts.api.http.serializer.FilterSerializer import xyz.nulldev.ts.api.http.serializer.FilterSerializer
@ -194,7 +195,7 @@ open class BrowseSourcePresenter(
view.onAddPage(page, mangas) view.onAddPage(page, mangas)
}, },
{ _, error -> { _, error ->
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
) )
@ -260,7 +261,7 @@ open class BrowseSourcePresenter(
view?.onMangaInitialized(it) view?.onMangaInitialized(it)
} }
} }
.catch { e -> Timber.e(e) } .catch { e -> logcat(LogPriority.ERROR, e) }
.collect() .collect()
} }
} }
@ -278,7 +279,7 @@ open class BrowseSourcePresenter(
manga.initialized = true manga.initialized = true
db.insertManga(manga).executeAsBlocking() db.insertManga(manga).executeAsBlocking()
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) logcat(LogPriority.ERROR, e)
} }
return manga return manga
} }
@ -321,7 +322,7 @@ open class BrowseSourcePresenter(
syncChaptersWithTrackServiceTwoWay(db, db.getChapters(manga).executeAsBlocking(), track, service as TrackService) syncChaptersWithTrackServiceTwoWay(db, db.getChapters(manga).executeAsBlocking(), track, service as TrackService)
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.w(e, "Could not match manga: ${manga.title} with service $service") logcat(LogPriority.WARN, e) { "Could not match manga: ${manga.title} with service $service" }
} }
} }
} }

View File

@ -16,12 +16,13 @@ import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter
import eu.kanade.tachiyomi.util.lang.runAsObservable import eu.kanade.tachiyomi.util.lang.runAsObservable
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -200,7 +201,7 @@ open class GlobalSearchPresenter(
view.setItems(manga) view.setItems(manga)
}, },
{ _, error -> { _, error ->
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
) )
} }
@ -235,7 +236,7 @@ open class GlobalSearchPresenter(
view?.onMangaInitialized(source, manga) view?.onMangaInitialized(source, manga)
}, },
{ error -> { error ->
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
) )
} }

View File

@ -16,6 +16,7 @@ import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourcePresenter.Compani
import eu.kanade.tachiyomi.util.lang.awaitSingle import eu.kanade.tachiyomi.util.lang.awaitSingle
import eu.kanade.tachiyomi.util.lang.runAsObservable import eu.kanade.tachiyomi.util.lang.runAsObservable
import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.system.logcat
import exh.log.xLogE import exh.log.xLogE
import exh.savedsearches.EXHSavedSearch import exh.savedsearches.EXHSavedSearch
import exh.savedsearches.JsonSavedSearch import exh.savedsearches.JsonSavedSearch
@ -24,12 +25,12 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import logcat.LogPriority
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import xyz.nulldev.ts.api.http.serializer.FilterSerializer import xyz.nulldev.ts.api.http.serializer.FilterSerializer
@ -170,7 +171,7 @@ open class IndexPresenter(
view?.onMangaInitialized(pair.first, pair.second) view?.onMangaInitialized(pair.first, pair.second)
}, },
{ error -> { error ->
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
) )
} }

View File

@ -5,9 +5,10 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.download.model.DownloadQueue import eu.kanade.tachiyomi.data.download.model.DownloadQueue
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
import rx.Observable import rx.Observable
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
/** /**
@ -30,7 +31,7 @@ class DownloadPresenter : BasePresenter<DownloadController>() {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.map { it.map(::DownloadItem) } .map { it.map(::DownloadItem) }
.subscribeLatestCache(DownloadController::onNextDownloads) { _, error -> .subscribeLatestCache(DownloadController::onNextDownloads) { _, error ->
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
} }

View File

@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.ui.category.CategoryAdapter import eu.kanade.tachiyomi.ui.category.CategoryAdapter
import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.lang.withUIContext
import exh.log.xLogW
import exh.metadata.sql.models.SearchTag import exh.metadata.sql.models.SearchTag
import exh.metadata.sql.models.SearchTitle import exh.metadata.sql.models.SearchTitle
import exh.search.Namespace import exh.search.Namespace
@ -30,7 +31,6 @@ import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
/** /**
@ -151,7 +151,7 @@ class LibraryCategoryAdapter(view: LibraryCategoryView, val controller: LibraryC
// Do not catch cancellations // Do not catch cancellations
if (e is CancellationException) throw e if (e is CancellationException) throw e
Timber.w(e, "Could not filter mangas!") this@LibraryCategoryAdapter.xLogW("Could not filter mangas!", e)
mangas mangas
} }

View File

@ -62,6 +62,7 @@ import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.launchUI import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.isTablet import eu.kanade.tachiyomi.util.system.isTablet
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat
import exh.EXHMigrations import exh.EXHMigrations
@ -74,7 +75,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import timber.log.Timber import logcat.LogPriority
import java.util.Date import java.util.Date
import java.util.LinkedList import java.util.LinkedList
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -394,7 +395,7 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
NewUpdateDialogController(result).showDialog(router) NewUpdateDialogController(result).showDialog(router)
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) logcat(LogPriority.ERROR, e)
} }
} }
} }
@ -410,7 +411,7 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
val pendingUpdates = ExtensionGithubApi().checkForUpdates(this@MainActivity) val pendingUpdates = ExtensionGithubApi().checkForUpdates(this@MainActivity)
preferences.extensionUpdatesCount().set(pendingUpdates.size) preferences.extensionUpdatesCount().set(pendingUpdates.size)
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) logcat(LogPriority.ERROR, e)
} }
} }
} }

View File

@ -96,6 +96,7 @@ import eu.kanade.tachiyomi.util.hasCustomCover
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.launchUI import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.storage.getUriCompat import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toShareIntent import eu.kanade.tachiyomi.util.system.toShareIntent
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.getCoordinates import eu.kanade.tachiyomi.util.view.getCoordinates
@ -117,9 +118,9 @@ import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import logcat.LogPriority
import reactivecircus.flowbinding.recyclerview.scrollStateChanges import reactivecircus.flowbinding.recyclerview.scrollStateChanges
import reactivecircus.flowbinding.swiperefreshlayout.refreshes import reactivecircus.flowbinding.swiperefreshlayout.refreshes
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -738,7 +739,9 @@ class MangaController :
presenter.registerTracking(track, service as TrackService) presenter.registerTracking(track, service as TrackService)
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.w(e, "Could not match manga: ${manga.title} with service $service") logcat(LogPriority.WARN, e) {
"Could not match manga: ${manga.title} with service $service"
}
} }
} }
} }
@ -987,7 +990,7 @@ class MangaController :
startActivity(uri.toShareIntent(activity)) startActivity(uri.toShareIntent(activity))
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) logcat(LogPriority.ERROR, e)
activity?.toast(R.string.error_sharing_cover) activity?.toast(R.string.error_sharing_cover)
} }
} }
@ -1000,7 +1003,7 @@ class MangaController :
activity.toast(R.string.cover_saved) activity.toast(R.string.cover_saved)
} }
} catch (e: Exception) { } catch (e: Exception) {
Timber.e(e) logcat(LogPriority.ERROR, e)
activity?.toast(R.string.error_saving_cover) activity?.toast(R.string.error_saving_cover)
} }
} }
@ -1061,7 +1064,7 @@ class MangaController :
fun onSetCoverError(error: Throwable) { fun onSetCoverError(error: Throwable) {
activity?.toast(R.string.notification_cover_update_failed) activity?.toast(R.string.notification_cover_update_failed)
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
/** /**
@ -1406,7 +1409,7 @@ class MangaController :
} }
fun onChaptersDeletedError(error: Throwable) { fun onChaptersDeletedError(error: Throwable) {
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
override fun startDownloadNow(position: Int) { override fun startDownloadNow(position: Int) {
@ -1460,7 +1463,7 @@ class MangaController :
} }
fun onTrackingRefreshError(error: Throwable) { fun onTrackingRefreshError(error: Throwable) {
Timber.e(error) logcat(LogPriority.ERROR, error)
activity?.toast(error.message) activity?.toast(error.message)
} }
@ -1469,7 +1472,7 @@ class MangaController :
} }
fun onTrackingSearchResultsError(error: Throwable) { fun onTrackingSearchResultsError(error: Throwable) {
Timber.e(error) logcat(LogPriority.ERROR, error)
getTrackingSearchDialog()?.onSearchResultsError(error.message) getTrackingSearchDialog()?.onSearchResultsError(error.message)
} }

View File

@ -47,6 +47,7 @@ import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.storage.getPicturesDir import eu.kanade.tachiyomi.util.storage.getPicturesDir
import eu.kanade.tachiyomi.util.storage.getTempShareDir import eu.kanade.tachiyomi.util.storage.getTempShareDir
import eu.kanade.tachiyomi.util.system.ImageUtil import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.updateCoverLastModified import eu.kanade.tachiyomi.util.updateCoverLastModified
import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.State
@ -74,12 +75,12 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.supervisorScope import kotlinx.coroutines.supervisorScope
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import logcat.LogPriority
import rx.Observable import rx.Observable
import rx.Single import rx.Single
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -201,7 +202,9 @@ class MangaPresenter(
getTrackingObservable() getTrackingObservable()
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribeLatestCache(MangaController::onTrackingCount) { _, error -> Timber.e(error) } .subscribeLatestCache(MangaController::onTrackingCount) { _, error ->
logcat(LogPriority.ERROR, error)
}
// Prepare the relay. // Prepare the relay.
chaptersRelay.flatMap { applyChapterFilters(it) } chaptersRelay.flatMap { applyChapterFilters(it) }
@ -211,7 +214,7 @@ class MangaPresenter(
filteredAndSortedChapters = chapters filteredAndSortedChapters = chapters
view?.onNextChapters(chapters) view?.onNextChapters(chapters)
}, },
{ _, error -> Timber.e(error) } { _, error -> logcat(LogPriority.ERROR, error) }
) )
// Manga info - end // Manga info - end
@ -763,7 +766,7 @@ class MangaPresenter(
view.onChapterDownloadUpdate(it) view.onChapterDownloadUpdate(it)
}, },
{ _, error -> { _, error ->
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
) )
@ -774,7 +777,7 @@ class MangaPresenter(
.filter { download -> /* SY --> */ if (isMergedSource) download.manga.id in mergedIds else /* SY <-- */ download.manga.id == manga.id } .filter { download -> /* SY --> */ if (isMergedSource) download.manga.id in mergedIds else /* SY <-- */ download.manga.id == manga.id }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribeLatestCache(MangaController::onChapterDownloadUpdate) { _, error -> .subscribeLatestCache(MangaController::onChapterDownloadUpdate) { _, error ->
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
} }

View File

@ -19,9 +19,10 @@ import eu.kanade.tachiyomi.util.preference.onClick
import eu.kanade.tachiyomi.util.preference.preference import eu.kanade.tachiyomi.util.preference.preference
import eu.kanade.tachiyomi.util.preference.titleRes import eu.kanade.tachiyomi.util.preference.titleRes
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import exh.syDebugVersion import exh.syDebugVersion
import timber.log.Timber import logcat.LogPriority
import java.text.DateFormat import java.text.DateFormat
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
@ -111,7 +112,7 @@ class AboutController : SettingsController(), NoAppBarElevationController {
} }
} catch (error: Exception) { } catch (error: Exception) {
activity?.toast(error.message) activity?.toast(error.message)
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
} }
} }

View File

@ -18,7 +18,6 @@ import android.graphics.PorterDuff
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.view.Gravity import android.view.Gravity
import android.view.HapticFeedbackConstants
import android.view.KeyEvent import android.view.KeyEvent
import android.view.Menu import android.view.Menu
import android.view.MotionEvent import android.view.MotionEvent
@ -85,6 +84,7 @@ import eu.kanade.tachiyomi.util.system.getThemeColor
import eu.kanade.tachiyomi.util.system.hasDisplayCutout import eu.kanade.tachiyomi.util.system.hasDisplayCutout
import eu.kanade.tachiyomi.util.system.isLTR import eu.kanade.tachiyomi.util.system.isLTR
import eu.kanade.tachiyomi.util.system.isNightMode import eu.kanade.tachiyomi.util.system.isNightMode
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.popupMenu import eu.kanade.tachiyomi.util.view.popupMenu
import eu.kanade.tachiyomi.util.view.setTooltip import eu.kanade.tachiyomi.util.view.setTooltip
@ -105,11 +105,11 @@ import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.sample import kotlinx.coroutines.flow.sample
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import logcat.LogPriority
import nucleus.factory.RequiresPresenter import nucleus.factory.RequiresPresenter
import reactivecircus.flowbinding.android.view.clicks import reactivecircus.flowbinding.android.view.clicks
import reactivecircus.flowbinding.android.widget.checkedChanges import reactivecircus.flowbinding.android.widget.checkedChanges
import reactivecircus.flowbinding.android.widget.textChanges import reactivecircus.flowbinding.android.widget.textChanges
import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.File import java.io.File
import kotlin.math.abs import kotlin.math.abs
@ -1121,7 +1121,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
readingModeToast?.cancel() readingModeToast?.cancel()
readingModeToast = toast(strings[mode]) readingModeToast = toast(strings[mode])
} catch (e: ArrayIndexOutOfBoundsException) { } catch (e: ArrayIndexOutOfBoundsException) {
Timber.e("Unknown reading mode: $mode") logcat(LogPriority.ERROR) { "Unknown reading mode: $mode" }
} }
} }
@ -1189,7 +1189,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
* this case the activity is closed and a toast is shown to the user. * this case the activity is closed and a toast is shown to the user.
*/ */
fun setInitialChapterError(error: Throwable) { fun setInitialChapterError(error: Throwable) {
Timber.e(error) logcat(LogPriority.ERROR, error)
finish() finish()
toast(error.message) toast(error.message)
} }
@ -1401,7 +1401,7 @@ class ReaderActivity : BaseRxActivity<ReaderActivityBinding, ReaderPresenter>()
toast(R.string.picture_saved) toast(R.string.picture_saved)
} }
is ReaderPresenter.SaveImageResult.Error -> { is ReaderPresenter.SaveImageResult.Error -> {
Timber.e(result.error) logcat(LogPriority.ERROR, result.error)
} }
} }
} }

View File

@ -41,6 +41,7 @@ import eu.kanade.tachiyomi.util.storage.getPicturesDir
import eu.kanade.tachiyomi.util.storage.getTempShareDir import eu.kanade.tachiyomi.util.storage.getTempShareDir
import eu.kanade.tachiyomi.util.system.ImageUtil import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.isOnline import eu.kanade.tachiyomi.util.system.isOnline
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.updateCoverLastModified import eu.kanade.tachiyomi.util.updateCoverLastModified
import exh.md.utils.FollowStatus import exh.md.utils.FollowStatus
import exh.md.utils.MdUtil import exh.md.utils.MdUtil
@ -53,11 +54,11 @@ import exh.util.defaultReaderType
import exh.util.mangaType import exh.util.mangaType
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import logcat.LogPriority
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
@ -373,7 +374,7 @@ class ReaderPresenter(
private fun loadNewChapter(chapter: ReaderChapter) { private fun loadNewChapter(chapter: ReaderChapter) {
val loader = loader ?: return val loader = loader ?: return
Timber.d("Loading ${chapter.chapter.url}") logcat { "Loading ${chapter.chapter.url}" }
activeChapterSubscription?.unsubscribe() activeChapterSubscription?.unsubscribe()
activeChapterSubscription = getLoadObservable(loader, chapter) activeChapterSubscription = getLoadObservable(loader, chapter)
@ -396,7 +397,7 @@ class ReaderPresenter(
private fun loadAdjacent(chapter: ReaderChapter) { private fun loadAdjacent(chapter: ReaderChapter) {
val loader = loader ?: return val loader = loader ?: return
Timber.d("Loading adjacent ${chapter.chapter.url}") logcat { "Loading adjacent ${chapter.chapter.url}" }
activeChapterSubscription?.unsubscribe() activeChapterSubscription?.unsubscribe()
activeChapterSubscription = getLoadObservable(loader, chapter) activeChapterSubscription = getLoadObservable(loader, chapter)
@ -421,7 +422,7 @@ class ReaderPresenter(
return return
} }
Timber.d("Preloading ${chapter.chapter.url}") logcat { "Preloading ${chapter.chapter.url}" }
val loader = loader ?: return val loader = loader ?: return
@ -473,7 +474,7 @@ class ReaderPresenter(
} }
if (selectedChapter != currentChapters.currChapter) { if (selectedChapter != currentChapters.currChapter) {
Timber.d("Setting ${selectedChapter.chapter.url} as active") logcat { "Setting ${selectedChapter.chapter.url} as active" }
onChapterChanged(currentChapters.currChapter) onChapterChanged(currentChapters.currChapter)
loadNewChapter(selectedChapter) loadNewChapter(selectedChapter)
} }
@ -654,7 +655,7 @@ class ReaderPresenter(
manga.orientationType = rotationType manga.orientationType = rotationType
db.updateViewerFlags(manga).executeAsBlocking() db.updateViewerFlags(manga).executeAsBlocking()
Timber.i("Manga orientation is ${manga.orientationType}") logcat(LogPriority.INFO) { "Manga orientation is ${manga.orientationType}" }
Observable.timer(250, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread()) Observable.timer(250, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
.subscribeFirst({ view, _ -> .subscribeFirst({ view, _ ->
@ -919,7 +920,7 @@ class ReaderPresenter(
} }
.awaitAll() .awaitAll()
.mapNotNull { it.exceptionOrNull() } .mapNotNull { it.exceptionOrNull() }
.forEach { Timber.w(it) } .forEach { logcat(LogPriority.INFO, it) }
} }
} }

View File

@ -10,13 +10,13 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.source.online.all.MergedSource import eu.kanade.tachiyomi.source.online.all.MergedSource
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.util.system.logcat
import exh.debug.DebugFunctions.prefs import exh.debug.DebugFunctions.prefs
import exh.merged.sql.models.MergedMangaReference import exh.merged.sql.models.MergedMangaReference
import rx.Completable import rx.Completable
import rx.Observable import rx.Observable
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import timber.log.Timber
/** /**
* Loader used to retrieve the [PageLoader] for a given chapter. * Loader used to retrieve the [PageLoader] for a given chapter.
@ -46,7 +46,7 @@ class ChapterLoader(
.doOnNext { chapter.state = ReaderChapter.State.Loading } .doOnNext { chapter.state = ReaderChapter.State.Loading }
.observeOn(Schedulers.io()) .observeOn(Schedulers.io())
.flatMap { readerChapter -> .flatMap { readerChapter ->
Timber.d("Loading pages for ${chapter.chapter.name}") logcat { "Loading pages for ${chapter.chapter.name}" }
val loader = getPageLoader(readerChapter) val loader = getPageLoader(readerChapter)

View File

@ -7,14 +7,15 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.util.lang.plusAssign import eu.kanade.tachiyomi.util.lang.plusAssign
import eu.kanade.tachiyomi.util.system.logcat
import exh.source.isEhBasedSource import exh.source.isEhBasedSource
import logcat.LogPriority
import rx.Completable import rx.Completable
import rx.Observable import rx.Observable
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import rx.subjects.PublishSubject import rx.subjects.PublishSubject
import rx.subjects.SerializedSubject import rx.subjects.SerializedSubject
import rx.subscriptions.CompositeSubscription import rx.subscriptions.CompositeSubscription
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.concurrent.PriorityBlockingQueue import java.util.concurrent.PriorityBlockingQueue
@ -59,7 +60,7 @@ class HttpPageLoader(
}, },
{ error -> { error ->
if (error !is InterruptedException) { if (error !is InterruptedException) {
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
} }
) )
@ -285,7 +286,7 @@ class HttpPageLoader(
}, },
{ error -> { error ->
if (error !is InterruptedException) { if (error !is InterruptedException) {
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
} }
) )

View File

@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.reader.model
import com.jakewharton.rxrelay.BehaviorRelay import com.jakewharton.rxrelay.BehaviorRelay
import eu.kanade.tachiyomi.data.database.models.Chapter import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.ui.reader.loader.PageLoader import eu.kanade.tachiyomi.ui.reader.loader.PageLoader
import timber.log.Timber import eu.kanade.tachiyomi.util.system.logcat
data class ReaderChapter(val chapter: Chapter) { data class ReaderChapter(val chapter: Chapter) {
@ -36,7 +36,7 @@ data class ReaderChapter(val chapter: Chapter) {
references-- references--
if (references == 0) { if (references == 0) {
if (pageLoader != null) { if (pageLoader != null) {
Timber.d("Recycling chapter ${chapter.name}") logcat { "Recycling chapter ${chapter.name}" }
} }
pageLoader?.recycle() pageLoader?.recycle()
pageLoader = null pageLoader = null

View File

@ -21,15 +21,16 @@ import eu.kanade.tachiyomi.ui.webview.WebViewActivity
import eu.kanade.tachiyomi.util.lang.launchUI import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.system.ImageUtil import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.widget.ViewPagerAdapter import eu.kanade.tachiyomi.widget.ViewPagerAdapter
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import logcat.LogPriority
import rx.Observable import rx.Observable
import rx.Subscription import rx.Subscription
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import timber.log.Timber
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.InputStream import java.io.InputStream
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -389,7 +390,7 @@ class PagerPageHolder(
imageStream.close() imageStream.close()
page.fullPage = true page.fullPage = true
skipExtra = true skipExtra = true
Timber.e("Cannot combine pages ${e.message}") logcat(LogPriority.ERROR, e) { "Cannot combine pages" }
return imageBytes.inputStream() return imageBytes.inputStream()
} }
scope?.launchUI { progressIndicator.setProgress(96) } scope?.launchUI { progressIndicator.setProgress(96) }
@ -413,7 +414,7 @@ class PagerPageHolder(
extraPage?.fullPage = true extraPage?.fullPage = true
skipExtra = true skipExtra = true
page.isolatedPage = true page.isolatedPage = true
Timber.e("Cannot combine pages ${e.message}") logcat(LogPriority.ERROR, e) { "Cannot combine pages" }
return imageBytes.inputStream() return imageBytes.inputStream()
} }
scope?.launchUI { progressIndicator.setProgress(97) } scope?.launchUI { progressIndicator.setProgress(97) }

View File

@ -17,9 +17,9 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation.NavigationRegion import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation.NavigationRegion
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import timber.log.Timber
import kotlin.math.min import kotlin.math.min
/** /**
@ -204,7 +204,7 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
*/ */
private fun onReaderPageSelected(page: ReaderPage, allowPreload: Boolean, hasExtraPage: Boolean) { private fun onReaderPageSelected(page: ReaderPage, allowPreload: Boolean, hasExtraPage: Boolean) {
val pages = page.chapter.pages ?: return val pages = page.chapter.pages ?: return
Timber.d("onReaderPageSelected: ${page.number}/${pages.size}") logcat { "onReaderPageSelected: ${page.number}/${pages.size}" }
activity.onPageSelected(page, hasExtraPage) activity.onPageSelected(page, hasExtraPage)
// Skip preload on inserts it causes unwanted page jumping // Skip preload on inserts it causes unwanted page jumping
@ -215,7 +215,7 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
// Preload next chapter once we're within the last 5 pages of the current chapter // Preload next chapter once we're within the last 5 pages of the current chapter
val inPreloadRange = pages.size - page.number < 5 val inPreloadRange = pages.size - page.number < 5
if (inPreloadRange && allowPreload && page.chapter == adapter.currentChapter) { if (inPreloadRange && allowPreload && page.chapter == adapter.currentChapter) {
Timber.d("Request preload next chapter because we're at page ${page.number} of ${pages.size}") logcat { "Request preload next chapter because we're at page ${page.number} of ${pages.size}" }
adapter.nextTransition?.to?.let { adapter.nextTransition?.to?.let {
activity.requestPreloadChapter(it) activity.requestPreloadChapter(it)
} }
@ -227,10 +227,10 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
* preload of the destination chapter of the transition. * preload of the destination chapter of the transition.
*/ */
private fun onTransitionSelected(transition: ChapterTransition) { private fun onTransitionSelected(transition: ChapterTransition) {
Timber.d("onTransitionSelected: $transition") logcat { "onTransitionSelected: $transition" }
val toChapter = transition.to val toChapter = transition.to
if (toChapter != null) { if (toChapter != null) {
Timber.d("Request preload destination chapter because we're on the transition") logcat { "Request preload destination chapter because we're on the transition" }
activity.requestPreloadChapter(toChapter) activity.requestPreloadChapter(toChapter)
} else if (transition is ChapterTransition.Next) { } else if (transition is ChapterTransition.Next) {
// No more chapters, show menu because the user is probably going to close the reader // No more chapters, show menu because the user is probably going to close the reader
@ -254,13 +254,13 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
* Sets the active [chapters] on this pager. * Sets the active [chapters] on this pager.
*/ */
private fun setChaptersInternal(chapters: ViewerChapters) { private fun setChaptersInternal(chapters: ViewerChapters) {
Timber.d("setChaptersInternal") logcat { "setChaptersInternal" }
val forceTransition = config.alwaysShowChapterTransition || adapter.joinedItems.getOrNull(pager.currentItem)?.first is ChapterTransition val forceTransition = config.alwaysShowChapterTransition || adapter.joinedItems.getOrNull(pager.currentItem)?.first is ChapterTransition
adapter.setChapters(chapters, forceTransition) adapter.setChapters(chapters, forceTransition)
// Layout the pager once a chapter is being set // Layout the pager once a chapter is being set
if (pager.isGone) { if (pager.isGone) {
Timber.d("Pager first layout") logcat { "Pager first layout" }
val pages = chapters.currChapter.pages ?: return val pages = chapters.currChapter.pages ?: return
moveToPage(pages[min(chapters.currChapter.requestedPage, pages.lastIndex)]) moveToPage(pages[min(chapters.currChapter.requestedPage, pages.lastIndex)])
pager.isVisible = true pager.isVisible = true
@ -271,7 +271,7 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
* Tells this viewer to move to the given [page]. * Tells this viewer to move to the given [page].
*/ */
override fun moveToPage(page: ReaderPage) { override fun moveToPage(page: ReaderPage) {
Timber.d("moveToPage ${page.number}") logcat { "moveToPage ${page.number}" }
val position = adapter.joinedItems.indexOfFirst { it.first == page || it.second == page } val position = adapter.joinedItems.indexOfFirst { it.first == page || it.second == page }
if (position != -1) { if (position != -1) {
val currentPosition = pager.currentItem val currentPosition = pager.currentItem
@ -289,7 +289,7 @@ abstract class PagerViewer(val activity: ReaderActivity) : BaseViewer {
) )
} }
} else { } else {
Timber.d("Page $page not found in adapter") logcat { "Page $page not found in adapter" }
} }
} }

View File

@ -9,8 +9,8 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
import eu.kanade.tachiyomi.ui.reader.viewer.hasMissingChapters import eu.kanade.tachiyomi.ui.reader.viewer.hasMissingChapters
import eu.kanade.tachiyomi.util.system.createReaderThemeContext import eu.kanade.tachiyomi.util.system.createReaderThemeContext
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.widget.ViewPagerAdapter import eu.kanade.tachiyomi.widget.ViewPagerAdapter
import timber.log.Timber
import kotlin.math.max import kotlin.math.max
/** /**
@ -174,7 +174,7 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
if (position != -1) { if (position != -1) {
return position return position
} else { } else {
Timber.d("Position for ${view.item} not found") logcat { "Position for ${view.item} not found" }
} }
} }
return POSITION_NONE return POSITION_NONE

View File

@ -18,10 +18,10 @@ import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation.NavigationRegion import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation.NavigationRegion
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel import kotlinx.coroutines.cancel
import rx.subscriptions.CompositeSubscription import rx.subscriptions.CompositeSubscription
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import kotlin.math.max import kotlin.math.max
@ -201,17 +201,17 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
*/ */
private fun onPageSelected(page: ReaderPage, allowPreload: Boolean) { private fun onPageSelected(page: ReaderPage, allowPreload: Boolean) {
val pages = page.chapter.pages ?: return val pages = page.chapter.pages ?: return
Timber.d("onPageSelected: ${page.number}/${pages.size}") logcat { "onPageSelected: ${page.number}/${pages.size}" }
activity.onPageSelected(page) activity.onPageSelected(page)
// Preload next chapter once we're within the last 5 pages of the current chapter // Preload next chapter once we're within the last 5 pages of the current chapter
val inPreloadRange = pages.size - page.number < 5 val inPreloadRange = pages.size - page.number < 5
if (inPreloadRange && allowPreload && page.chapter == adapter.currentChapter) { if (inPreloadRange && allowPreload && page.chapter == adapter.currentChapter) {
Timber.d("Request preload next chapter because we're at page ${page.number} of ${pages.size}") logcat { "Request preload next chapter because we're at page ${page.number} of ${pages.size}" }
val nextItem = adapter.items.getOrNull(adapter.items.size - 1) val nextItem = adapter.items.getOrNull(adapter.items.size - 1)
val transitionChapter = (nextItem as? ChapterTransition.Next)?.to ?: (nextItem as?ReaderPage)?.chapter val transitionChapter = (nextItem as? ChapterTransition.Next)?.to ?: (nextItem as?ReaderPage)?.chapter
if (transitionChapter != null) { if (transitionChapter != null) {
Timber.d("Requesting to preload chapter ${transitionChapter.chapter.chapter_number}") logcat { "Requesting to preload chapter ${transitionChapter.chapter.chapter_number}" }
activity.requestPreloadChapter(transitionChapter) activity.requestPreloadChapter(transitionChapter)
} }
} }
@ -222,10 +222,10 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
* preload of the destination chapter of the transition. * preload of the destination chapter of the transition.
*/ */
private fun onTransitionSelected(transition: ChapterTransition) { private fun onTransitionSelected(transition: ChapterTransition) {
Timber.d("onTransitionSelected: $transition") logcat { "onTransitionSelected: $transition" }
val toChapter = transition.to val toChapter = transition.to
if (toChapter != null) { if (toChapter != null) {
Timber.d("Request preload destination chapter because we're on the transition") logcat { "Request preload destination chapter because we're on the transition" }
activity.requestPreloadChapter(toChapter) activity.requestPreloadChapter(toChapter)
} else if (transition is ChapterTransition.Next) { } else if (transition is ChapterTransition.Next) {
// No more chapters, show menu because the user is probably going to close the reader // No more chapters, show menu because the user is probably going to close the reader
@ -237,12 +237,12 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
* Tells this viewer to set the given [chapters] as active. * Tells this viewer to set the given [chapters] as active.
*/ */
override fun setChapters(chapters: ViewerChapters) { override fun setChapters(chapters: ViewerChapters) {
Timber.d("setChapters") logcat { "setChapters" }
val forceTransition = config.alwaysShowChapterTransition || currentPage is ChapterTransition val forceTransition = config.alwaysShowChapterTransition || currentPage is ChapterTransition
adapter.setChapters(chapters, forceTransition) adapter.setChapters(chapters, forceTransition)
if (recycler.isGone) { if (recycler.isGone) {
Timber.d("Recycler first layout") logcat { "Recycler first layout" }
val pages = chapters.currChapter.pages ?: return val pages = chapters.currChapter.pages ?: return
moveToPage(pages[min(chapters.currChapter.requestedPage, pages.lastIndex)]) moveToPage(pages[min(chapters.currChapter.requestedPage, pages.lastIndex)])
recycler.isVisible = true recycler.isVisible = true
@ -253,7 +253,7 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
* Tells this viewer to move to the given [page]. * Tells this viewer to move to the given [page].
*/ */
override fun moveToPage(page: ReaderPage) { override fun moveToPage(page: ReaderPage) {
Timber.d("moveToPage") logcat { "moveToPage" }
val position = adapter.items.indexOf(page) val position = adapter.items.indexOf(page)
if (position != -1) { if (position != -1) {
recycler.scrollToPosition(position) recycler.scrollToPosition(position)
@ -261,7 +261,7 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
onScrolled(pos = position) onScrolled(pos = position)
} }
} else { } else {
Timber.d("Page $page not found in adapter") logcat { "Page $page not found in adapter" }
} }
} }

View File

@ -26,13 +26,14 @@ import eu.kanade.tachiyomi.ui.browse.source.browse.ProgressItem
import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.onAnimationsFinished import eu.kanade.tachiyomi.util.view.onAnimationsFinished
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import logcat.LogPriority
import reactivecircus.flowbinding.appcompat.queryTextChanges import reactivecircus.flowbinding.appcompat.queryTextChanges
import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
/** /**
@ -123,7 +124,7 @@ class HistoryController :
fun onAddPageError(error: Throwable) { fun onAddPageError(error: Throwable) {
adapter?.onLoadMoreComplete(null) adapter?.onLoadMoreComplete(null)
adapter?.endlessTargetCount = 1 adapter?.endlessTargetCount = 1
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
override fun onUpdateEmptyView(size: Int) { override fun onUpdateEmptyView(size: Int) {

View File

@ -25,14 +25,15 @@ import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.manga.MangaController
import eu.kanade.tachiyomi.ui.manga.chapter.base.BaseChaptersAdapter import eu.kanade.tachiyomi.ui.manga.chapter.base.BaseChaptersAdapter
import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.notificationManager import eu.kanade.tachiyomi.util.system.notificationManager
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.onAnimationsFinished import eu.kanade.tachiyomi.util.view.onAnimationsFinished
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import logcat.LogPriority
import reactivecircus.flowbinding.recyclerview.scrollStateChanges import reactivecircus.flowbinding.recyclerview.scrollStateChanges
import reactivecircus.flowbinding.swiperefreshlayout.refreshes import reactivecircus.flowbinding.swiperefreshlayout.refreshes
import timber.log.Timber
/** /**
* Fragment that shows recent chapters. * Fragment that shows recent chapters.
@ -300,7 +301,7 @@ class UpdatesController :
* @param error error message * @param error error message
*/ */
fun onChaptersDeletedError(error: Throwable) { fun onChaptersDeletedError(error: Throwable) {
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
override fun downloadChapter(position: Int) { override fun downloadChapter(position: Int) {

View File

@ -11,10 +11,11 @@ import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import eu.kanade.tachiyomi.ui.recent.DateSectionItem import eu.kanade.tachiyomi.ui.recent.DateSectionItem
import eu.kanade.tachiyomi.util.lang.toDateKey import eu.kanade.tachiyomi.util.lang.toDateKey
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
import rx.Observable import rx.Observable
import rx.android.schedulers.AndroidSchedulers import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers import rx.schedulers.Schedulers
import timber.log.Timber
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.text.DateFormat import java.text.DateFormat
import java.util.Calendar import java.util.Calendar
@ -53,7 +54,7 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() {
view.onChapterDownloadUpdate(it) view.onChapterDownloadUpdate(it)
}, },
{ _, error -> { _, error ->
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
) )
@ -62,7 +63,7 @@ class UpdatesPresenter : BasePresenter<UpdatesController>() {
.onBackpressureBuffer() .onBackpressureBuffer()
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribeLatestCache(UpdatesController::onChapterDownloadUpdate) { _, error -> .subscribeLatestCache(UpdatesController::onChapterDownloadUpdate) { _, error ->
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
} }

View File

@ -7,7 +7,8 @@ import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil import eu.kanade.tachiyomi.util.system.AuthenticatorUtil
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.startAuthentication import eu.kanade.tachiyomi.util.system.AuthenticatorUtil.startAuthentication
import timber.log.Timber import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
import java.util.Date import java.util.Date
/** /**
@ -27,7 +28,7 @@ class UnlockActivity : BaseThemedActivity() {
errString: CharSequence errString: CharSequence
) { ) {
super.onAuthenticationError(activity, errorCode, errString) super.onAuthenticationError(activity, errorCode, errString)
Timber.e(errString.toString()) logcat(LogPriority.ERROR) { errString.toString() }
finishAffinity() finishAffinity()
} }

View File

@ -83,6 +83,18 @@ class SettingsAdvancedController : SettingsController() {
} }
} }
/*switchPreference {
key = Keys.verboseLogging
titleRes = R.string.pref_verbose_logging
summaryRes = R.string.pref_verbose_logging_summary
defaultValue = false
onChange {
activity?.toast(R.string.requires_app_restart)
true
}
}*/
preferenceCategory { preferenceCategory {
titleRes = R.string.label_background_activity titleRes = R.string.label_background_activity

View File

@ -5,7 +5,8 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchIO
import timber.log.Timber import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
/** /**
* Helper method for syncing a remote track with the local chapters, and back * Helper method for syncing a remote track with the local chapters, and back
@ -33,7 +34,7 @@ fun syncChaptersWithTrackServiceTwoWay(db: DatabaseHelper, chapters: List<Chapte
service.update(remoteTrack) service.update(remoteTrack)
db.insertTrack(remoteTrack).executeAsBlocking() db.insertTrack(remoteTrack).executeAsBlocking()
} catch (e: Throwable) { } catch (e: Throwable) {
Timber.w(e) logcat(LogPriority.WARN, e)
} }
} }
} }

View File

@ -47,7 +47,7 @@ import eu.kanade.tachiyomi.data.preference.PreferenceValues
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity import eu.kanade.tachiyomi.ui.base.activity.BaseThemedActivity
import eu.kanade.tachiyomi.util.lang.truncateCenter import eu.kanade.tachiyomi.util.lang.truncateCenter
import timber.log.Timber import logcat.LogPriority
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
@ -93,7 +93,7 @@ fun Context.copyToClipboard(label: String, content: String) {
toast(getString(R.string.copied_to_clipboard, content.truncateCenter(50))) toast(getString(R.string.copied_to_clipboard, content.truncateCenter(50)))
} catch (e: Throwable) { } catch (e: Throwable) {
Timber.e(e) logcat(LogPriority.ERROR, e)
toast(R.string.clipboard_copy_error) toast(R.string.clipboard_copy_error)
} }
} }

View File

@ -0,0 +1,18 @@
package eu.kanade.tachiyomi.util.system
import logcat.LogPriority
import logcat.asLog
import logcat.logcat
inline fun Any.logcat(
priority: LogPriority = LogPriority.DEBUG,
throwable: Throwable? = null,
message: () -> String = { "" }
) = logcat(priority = priority) {
var msg = message()
if (throwable != null) {
if (msg.isNotBlank()) msg += "\n"
msg += throwable.asLog()
}
msg
}

View File

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.util.system package eu.kanade.tachiyomi.util.system
import android.annotation.SuppressLint import android.annotation.SuppressLint
import timber.log.Timber import logcat.LogPriority
object MiuiUtil { object MiuiUtil {
@ -32,7 +32,7 @@ object MiuiUtil {
.getDeclaredMethod("get", String::class.java) .getDeclaredMethod("get", String::class.java)
.invoke(null, key) as String .invoke(null, key) as String
} catch (e: Exception) { } catch (e: Exception) {
Timber.w(e, "Unable to use SystemProperties.get") logcat(LogPriority.WARN, e) { "Unable to use SystemProperties.get()" }
null null
} }
} }

View File

@ -6,7 +6,7 @@ import android.content.pm.PackageManager
import android.webkit.CookieManager import android.webkit.CookieManager
import android.webkit.WebSettings import android.webkit.WebSettings
import android.webkit.WebView import android.webkit.WebView
import timber.log.Timber import logcat.LogPriority
object WebViewUtil { object WebViewUtil {
const val REQUESTED_WITH = "com.android.browser" const val REQUESTED_WITH = "com.android.browser"
@ -19,7 +19,7 @@ object WebViewUtil {
// is not installed // is not installed
CookieManager.getInstance() CookieManager.getInstance()
} catch (e: Throwable) { } catch (e: Throwable) {
Timber.e(e) logcat(LogPriority.ERROR, e)
return false return false
} }

View File

@ -8,7 +8,8 @@ import android.view.View
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import eu.kanade.tachiyomi.databinding.DownloadCustomAmountBinding import eu.kanade.tachiyomi.databinding.DownloadCustomAmountBinding
import timber.log.Timber import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
/** /**
* Custom dialog to select how many chapters to download. * Custom dialog to select how many chapters to download.
@ -71,7 +72,7 @@ class DialogCustomDownloadView @JvmOverloads constructor(context: Context, attrs
amount = getAmount(text.toString().toInt()) amount = getAmount(text.toString().toInt())
} catch (error: NumberFormatException) { } catch (error: NumberFormatException) {
// Catch NumberFormatException to prevent parse exception when input is empty. // Catch NumberFormatException to prevent parse exception when input is empty.
Timber.e(error) logcat(LogPriority.ERROR, error)
} }
} }
} }

View File

@ -0,0 +1,24 @@
package exh.log
import com.elvishew.xlog.XLog
import logcat.LogPriority
import logcat.LogcatLogger
class XLogLogcatLogger : LogcatLogger {
override fun log(priority: LogPriority, tag: String, message: String) {
XLog.tag(tag).log(priority.toXLogLevel(), message)
}
private fun LogPriority.toXLogLevel(): Int {
return when (this) {
LogPriority.ASSERT -> LogLevel.None.int
LogPriority.ERROR -> LogLevel.Error.int
LogPriority.WARN -> LogLevel.Warn.int
LogPriority.INFO -> LogLevel.Info.int
LogPriority.DEBUG -> LogLevel.Debug.int
LogPriority.VERBOSE -> LogLevel.Verbose.int
else -> LogLevel.All.int
}
}
}

View File

@ -1,35 +0,0 @@
package exh.log
import android.util.Log
import com.elvishew.xlog.XLog
import timber.log.Timber
class XLogTree : Timber.DebugTree() {
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
if (tag != null) {
if (t != null) {
XLog.tag(tag).log(priority.toXLogLevel(), message, t)
} else {
XLog.tag(tag).log(priority.toXLogLevel(), message)
}
} else {
if (t != null) {
XLog.log(priority.toXLogLevel(), message, t)
} else {
XLog.log(priority.toXLogLevel(), message)
}
}
}
private fun Int.toXLogLevel(): Int {
return when (this) {
Log.ASSERT -> LogLevel.None.int
Log.ERROR -> LogLevel.Error.int
Log.WARN -> LogLevel.Warn.int
Log.INFO -> LogLevel.Info.int
Log.DEBUG -> LogLevel.Debug.int
Log.VERBOSE -> LogLevel.Verbose.int
else -> LogLevel.All.int
}
}
}

View File

@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.ui.browse.source.browse.NoResultsException import eu.kanade.tachiyomi.ui.browse.source.browse.NoResultsException
import eu.kanade.tachiyomi.ui.browse.source.browse.Pager import eu.kanade.tachiyomi.ui.browse.source.browse.Pager
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat
import exh.util.MangaType import exh.util.MangaType
import exh.util.mangaType import exh.util.mangaType
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
@ -23,10 +24,10 @@ import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.put import kotlinx.serialization.json.put
import logcat.LogPriority
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -53,7 +54,7 @@ class MyAnimeList : API("https://api.jikan.moe/v3/") {
val data = Json.decodeFromString<JsonObject>(body) val data = Json.decodeFromString<JsonObject>(body)
val recommendations = data["recommendations"] as? JsonArray val recommendations = data["recommendations"] as? JsonArray
return recommendations?.filterIsInstance<JsonObject>()?.map { rec -> return recommendations?.filterIsInstance<JsonObject>()?.map { rec ->
Timber.tag("RECOMMENDATIONS").d("MYANIMELIST > RECOMMENDATION: %s", rec["title"]?.jsonPrimitive?.content.orEmpty()) logcat { "MYANIMELIST > RECOMMENDATION: " + rec["title"]?.jsonPrimitive?.content.orEmpty() }
SManga.create().apply { SManga.create().apply {
title = rec["title"]!!.jsonPrimitive.content title = rec["title"]!!.jsonPrimitive.content
thumbnail_url = rec["image_url"]!!.jsonPrimitive.content thumbnail_url = rec["image_url"]!!.jsonPrimitive.content
@ -178,7 +179,7 @@ class Anilist : API("https://graphql.anilist.co/") {
return result["recommendations"]?.jsonObject?.get("edges")?.jsonArray?.map { return result["recommendations"]?.jsonObject?.get("edges")?.jsonArray?.map {
val rec = it.jsonObject["node"]!!.jsonObject["mediaRecommendation"]!!.jsonObject val rec = it.jsonObject["node"]!!.jsonObject["mediaRecommendation"]!!.jsonObject
val recTitle = getTitle(rec) val recTitle = getTitle(rec)
Timber.tag("RECOMMENDATIONS").d("ANILIST > RECOMMENDATION: %s", recTitle) logcat { "ANILIST > RECOMMENDATION: $recTitle" }
SManga.create().apply { SManga.create().apply {
title = recTitle title = recTitle
thumbnail_url = rec["coverImage"]!!.jsonObject["large"]!!.jsonPrimitive.content thumbnail_url = rec["coverImage"]!!.jsonObject["large"]!!.jsonPrimitive.content
@ -202,10 +203,10 @@ open class RecommendsPager(
val recs = apiList.firstNotNullOfOrNull { (key, api) -> val recs = apiList.firstNotNullOfOrNull { (key, api) ->
try { try {
val recs = api.getRecsBySearch(manga.originalTitle) val recs = api.getRecsBySearch(manga.originalTitle)
Timber.tag("RECOMMENDATIONS").d("%s > Results: %s", key, recs.count()) logcat { key.toString() + " > Results: " + recs.count() }
recs recs
} catch (e: Exception) { } catch (e: Exception) {
Timber.tag("RECOMMENDATIONS").e("%s > Error: %s", key, e.message) logcat(LogPriority.ERROR, e) { key.toString() }
null null
} }
}.orEmpty() }.orEmpty()

View File

@ -476,6 +476,8 @@
<string name="battery_optimization_setting_activity_not_found">Couldn\'t open device settings</string> <string name="battery_optimization_setting_activity_not_found">Couldn\'t open device settings</string>
<string name="about_dont_kill_my_app">Some manufacturers have additional app restrictions that kill background services. This website has more info on how to fix it.</string> <string name="about_dont_kill_my_app">Some manufacturers have additional app restrictions that kill background services. This website has more info on how to fix it.</string>
<string name="pref_tablet_ui_mode">Force tablet UI</string> <string name="pref_tablet_ui_mode">Force tablet UI</string>
<string name="pref_verbose_logging">Verbose logging</string>
<string name="pref_verbose_logging_summary">Print verbose logs to system log (reduces app performance)</string>
<!-- About section --> <!-- About section -->
<string name="website">Website</string> <string name="website">Website</string>