feat: logging to file
This commit is contained in:
parent
1028ac66cb
commit
dbce7c5b29
67 changed files with 475 additions and 324 deletions
|
@ -42,7 +42,7 @@ android {
|
|||
buildTypes {
|
||||
alpha {
|
||||
applicationIdSuffix ".beta" // keep as beta by popular request
|
||||
versionNameSuffix "-alpha02"
|
||||
versionNameSuffix "-alpha03"
|
||||
manifestPlaceholders = [icon_placeholder: "@mipmap/ic_launcher_alpha", icon_placeholder_round: "@mipmap/ic_launcher_alpha_round"]
|
||||
debuggable System.getenv("CI") == null
|
||||
isDefault true
|
||||
|
|
|
@ -14,8 +14,18 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.core.content.FileProvider
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import ani.dantotsu.*
|
||||
import ani.dantotsu.BuildConfig
|
||||
import ani.dantotsu.Mapper
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.client
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.logError
|
||||
import ani.dantotsu.openLinkInBrowser
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.toast
|
||||
import ani.dantotsu.tryWithSuspend
|
||||
import ani.dantotsu.util.Logger
|
||||
import io.noties.markwon.Markwon
|
||||
import io.noties.markwon.SoftBreakAddsNewLinePlugin
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -50,7 +60,7 @@ object AppUpdater {
|
|||
res to res.substringAfter("# ").substringBefore("\n")
|
||||
}
|
||||
|
||||
logger("Git Version : $version")
|
||||
Logger.log("Git Version : $version")
|
||||
val dontShow = PrefManager.getCustomVal("dont_ask_for_update_$version", false)
|
||||
if (compareVersion(version) && !dontShow && !activity.isDestroyed) activity.runOnUiThread {
|
||||
CustomBottomDialog.newInstance().apply {
|
||||
|
|
|
@ -21,6 +21,8 @@ import ani.dantotsu.parsers.novel.NovelExtensionManager
|
|||
import ani.dantotsu.settings.SettingsActivity
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.util.FinalExceptionHandler
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.google.android.material.color.DynamicColors
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
|
||||
|
@ -83,7 +85,8 @@ class App : MultiDexApplication() {
|
|||
}
|
||||
crashlytics.setCustomKey("device Info", SettingsActivity.getDeviceInfo())
|
||||
|
||||
|
||||
Logger.init(this)
|
||||
Thread.setDefaultUncaughtExceptionHandler(FinalExceptionHandler())
|
||||
|
||||
initializeNetwork(baseContext)
|
||||
|
||||
|
@ -99,19 +102,19 @@ class App : MultiDexApplication() {
|
|||
val animeScope = CoroutineScope(Dispatchers.Default)
|
||||
animeScope.launch {
|
||||
animeExtensionManager.findAvailableExtensions()
|
||||
logger("Anime Extensions: ${animeExtensionManager.installedExtensionsFlow.first()}")
|
||||
Logger.log("Anime Extensions: ${animeExtensionManager.installedExtensionsFlow.first()}")
|
||||
AnimeSources.init(animeExtensionManager.installedExtensionsFlow)
|
||||
}
|
||||
val mangaScope = CoroutineScope(Dispatchers.Default)
|
||||
mangaScope.launch {
|
||||
mangaExtensionManager.findAvailableExtensions()
|
||||
logger("Manga Extensions: ${mangaExtensionManager.installedExtensionsFlow.first()}")
|
||||
Logger.log("Manga Extensions: ${mangaExtensionManager.installedExtensionsFlow.first()}")
|
||||
MangaSources.init(mangaExtensionManager.installedExtensionsFlow)
|
||||
}
|
||||
val novelScope = CoroutineScope(Dispatchers.Default)
|
||||
novelScope.launch {
|
||||
novelExtensionManager.findAvailableExtensions()
|
||||
logger("Novel Extensions: ${novelExtensionManager.installedExtensionsFlow.first()}")
|
||||
Logger.log("Novel Extensions: ${novelExtensionManager.installedExtensionsFlow.first()}")
|
||||
NovelSources.init(novelExtensionManager.installedExtensionsFlow)
|
||||
}
|
||||
val commentsScope = CoroutineScope(Dispatchers.Default)
|
||||
|
@ -138,7 +141,8 @@ class App : MultiDexApplication() {
|
|||
try {
|
||||
Notifications.createChannels(this)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e) { "Failed to modify notification channels" }
|
||||
Logger.log("Failed to modify notification channels")
|
||||
Logger.log(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ import android.telephony.TelephonyManager
|
|||
import android.text.InputFilter
|
||||
import android.text.Spanned
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.util.TypedValue
|
||||
import android.view.*
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
|
@ -60,6 +59,7 @@ import ani.dantotsu.settings.saving.PrefName
|
|||
import ani.dantotsu.settings.saving.internal.PreferenceKeystore
|
||||
import ani.dantotsu.settings.saving.internal.PreferenceKeystore.Companion.generateSalt
|
||||
import ani.dantotsu.subcriptions.NotificationClickReceiver
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.RequestBuilder
|
||||
import com.bumptech.glide.RequestManager
|
||||
|
@ -128,13 +128,6 @@ fun currActivity(): Activity? {
|
|||
var loadMedia: Int? = null
|
||||
var loadIsMAL = false
|
||||
|
||||
fun logger(e: Any?, print: Boolean = true) {
|
||||
if (print)
|
||||
//println(e)
|
||||
Log.d("Logger", e.toString())
|
||||
}
|
||||
|
||||
|
||||
fun initActivity(a: Activity) {
|
||||
val window = a.window
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
|
@ -306,7 +299,7 @@ class InputFilterMinMax(
|
|||
val input = (dest.toString() + source.toString()).toDouble()
|
||||
if (isInRange(min, max, input)) return null
|
||||
} catch (nfe: NumberFormatException) {
|
||||
logger(nfe.stackTraceToString())
|
||||
Logger.log(nfe)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
@ -761,7 +754,7 @@ fun saveImage(image: Bitmap, path: String, imageFileName: String): File? {
|
|||
|
||||
private fun scanFile(path: String, context: Context) {
|
||||
MediaScannerConnection.scanFile(context, arrayOf(path), null) { p, _ ->
|
||||
logger("Finished scanning $p")
|
||||
Logger.log("Finished scanning $p")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -903,7 +896,7 @@ class EmptyAdapter(private val count: Int) : RecyclerView.Adapter<RecyclerView.V
|
|||
|
||||
fun toast(string: String?) {
|
||||
if (string != null) {
|
||||
logger(string)
|
||||
Logger.log(string)
|
||||
MainScope().launch {
|
||||
Toast.makeText(currActivity()?.application ?: return@launch, string, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
|
@ -942,10 +935,10 @@ fun snackString(s: String?, activity: Activity? = null, clipboard: String? = nul
|
|||
}
|
||||
return snackBar
|
||||
}
|
||||
logger(s)
|
||||
Logger.log(s)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger(e.stackTraceToString())
|
||||
Logger.log(e)
|
||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||
}
|
||||
return null
|
||||
|
|
|
@ -49,6 +49,7 @@ import ani.dantotsu.settings.saving.PrefName
|
|||
import ani.dantotsu.settings.saving.SharedPreferenceBooleanLiveData
|
||||
import ani.dantotsu.subcriptions.Subscription.Companion.startSubscription
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.google.android.material.snackbar.BaseTransientBottomBar
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.os.Build
|
|||
import androidx.fragment.app.FragmentActivity
|
||||
import ani.dantotsu.others.webview.CloudFlare
|
||||
import ani.dantotsu.others.webview.WebViewBottomDialog
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.lagradost.nicehttp.Requests
|
||||
import com.lagradost.nicehttp.ResponseParser
|
||||
import com.lagradost.nicehttp.addGenericDns
|
||||
|
@ -104,6 +105,7 @@ fun logError(e: Throwable, post: Boolean = true, snackbar: Boolean = true) {
|
|||
toast(e.localizedMessage)
|
||||
}
|
||||
e.printStackTrace()
|
||||
Logger.log(e)
|
||||
}
|
||||
|
||||
fun <T> tryWith(post: Boolean = false, snackbar: Boolean = true, call: () -> T): T? {
|
||||
|
|
|
@ -14,6 +14,7 @@ import ani.dantotsu.settings.saving.PrefName
|
|||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.toast
|
||||
import ani.dantotsu.tryWithSuspend
|
||||
import ani.dantotsu.util.Logger
|
||||
import java.util.Calendar
|
||||
|
||||
object Anilist {
|
||||
|
@ -150,7 +151,7 @@ object Anilist {
|
|||
cacheTime = cache ?: 10
|
||||
)
|
||||
val remaining = json.headers["X-RateLimit-Remaining"]?.toIntOrNull() ?: -1
|
||||
Log.d("AnilistQuery", "Remaining requests: $remaining")
|
||||
Logger.log("Remaining requests: $remaining")
|
||||
if (json.code == 429) {
|
||||
val retry = json.headers["Retry-After"]?.toIntOrNull() ?: -1
|
||||
val passedLimitReset = json.headers["X-RateLimit-Reset"]?.toLongOrNull() ?: 0
|
||||
|
@ -161,13 +162,13 @@ object Anilist {
|
|||
toast("Rate limited. Try after $retry seconds")
|
||||
throw Exception("Rate limited after $retry seconds")
|
||||
}
|
||||
if (!json.text.startsWith("{")) throw Exception(currContext()?.getString(R.string.anilist_down))
|
||||
if (!json.text.startsWith("{")) {throw Exception(currContext()?.getString(R.string.anilist_down))}
|
||||
if (show) println("Response : ${json.text}")
|
||||
json.parsed()
|
||||
} else null
|
||||
} catch (e: Exception) {
|
||||
if (show) snackString("Error fetching Anilist data: ${e.message}")
|
||||
Log.e("AnilistQuery", "Error: ${e.message}")
|
||||
Logger.log("Anilist Query Error: ${e.message}")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import ani.dantotsu.settings.saving.PrefManager
|
|||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.tryWithSuspend
|
||||
import ani.dantotsu.util.Logger
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -99,6 +100,7 @@ class AnilistHomeViewModel : ViewModel() {
|
|||
|
||||
suspend fun initHomePage() {
|
||||
val res = Anilist.query.initHomePage()
|
||||
Logger.log("AnilistHomeViewModel : res=$res")
|
||||
res["currentAnime"]?.let { animeContinue.postValue(it) }
|
||||
res["favoriteAnime"]?.let { animeFav.postValue(it) }
|
||||
res["plannedAnime"]?.let { animePlanned.postValue(it) }
|
||||
|
|
|
@ -4,7 +4,7 @@ import android.net.Uri
|
|||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import ani.dantotsu.logError
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.startMainActivity
|
||||
|
@ -16,7 +16,7 @@ class Login : AppCompatActivity() {
|
|||
|
||||
ThemeManager(this).applyTheme()
|
||||
val data: Uri? = intent?.data
|
||||
logger(data.toString())
|
||||
Logger.log(data.toString())
|
||||
try {
|
||||
Anilist.token =
|
||||
Regex("""(?<=access_token=).+(?=&token_type)""").find(data.toString())!!.value
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
package ani.dantotsu.connections.crashlytics
|
||||
|
||||
import android.content.Context
|
||||
import ani.dantotsu.util.Logger
|
||||
|
||||
class CrashlyticsStub : CrashlyticsInterface {
|
||||
override fun initialize(context: Context) {
|
||||
//no-op
|
||||
}
|
||||
override fun logException(e: Throwable) {
|
||||
//no-op
|
||||
Logger.log(e)
|
||||
}
|
||||
|
||||
override fun log(message: String) {
|
||||
//no-op
|
||||
Logger.log(message)
|
||||
}
|
||||
|
||||
override fun setUserId(id: String) {
|
||||
|
|
|
@ -15,7 +15,6 @@ import android.os.Environment
|
|||
import android.os.IBinder
|
||||
import android.os.PowerManager
|
||||
import android.provider.MediaStore
|
||||
import android.util.Log
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
|
@ -26,6 +25,7 @@ import ani.dantotsu.connections.discord.serializers.User
|
|||
import ani.dantotsu.isOnline
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
|
@ -274,7 +274,7 @@ class DiscordService : Service() {
|
|||
return
|
||||
}
|
||||
}
|
||||
t.message?.let { Log.d("WebSocket", "onFailure() $it") }
|
||||
t.message?.let { Logger.log("onFailure() $it") }
|
||||
log("WebSocket: Error, onFailure() reason: ${t.message}")
|
||||
client = OkHttpClient()
|
||||
client.newWebSocket(
|
||||
|
@ -289,7 +289,7 @@ class DiscordService : Service() {
|
|||
|
||||
override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
|
||||
super.onClosing(webSocket, code, reason)
|
||||
Log.d("WebSocket", "onClosing() $code $reason")
|
||||
Logger.log("onClosing() $code $reason")
|
||||
if (::heartbeatThread.isInitialized && !heartbeatThread.isInterrupted) {
|
||||
heartbeatThread.interrupt()
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ class DiscordService : Service() {
|
|||
|
||||
override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
|
||||
super.onClosed(webSocket, code, reason)
|
||||
Log.d("WebSocket", "onClosed() $code $reason")
|
||||
Logger.log("onClosed() $code $reason")
|
||||
if (code >= 4000) {
|
||||
log("WebSocket: Error, code: $code reason: $reason")
|
||||
client = OkHttpClient()
|
||||
|
@ -382,52 +382,7 @@ class DiscordService : Service() {
|
|||
}
|
||||
|
||||
fun log(string: String) {
|
||||
Log.d("WebSocket_Discord", string)
|
||||
//log += "${SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().time)} $string\n"
|
||||
}
|
||||
|
||||
fun saveLogToFile() {
|
||||
val fileName = "log_${System.currentTimeMillis()}.txt"
|
||||
|
||||
// ContentValues to store file metadata
|
||||
val values = ContentValues().apply {
|
||||
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
|
||||
put(MediaStore.MediaColumns.MIME_TYPE, "text/plain")
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
put(MediaStore.MediaColumns.RELATIVE_PATH, "Download/")
|
||||
}
|
||||
}
|
||||
|
||||
// Inserting the file in the MediaStore
|
||||
val resolver = baseContext.contentResolver
|
||||
val uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values)
|
||||
} else {
|
||||
val directory =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||
val file = File(directory, fileName)
|
||||
|
||||
// Make sure the Downloads directory exists
|
||||
if (!directory.exists()) {
|
||||
directory.mkdirs()
|
||||
}
|
||||
|
||||
// Use FileProvider to get the URI for the file
|
||||
val authority =
|
||||
"${baseContext.packageName}.provider" // Adjust with your app's package name
|
||||
Uri.fromFile(file)
|
||||
}
|
||||
|
||||
// Writing to the file
|
||||
uri?.let {
|
||||
resolver.openOutputStream(it).use { outputStream ->
|
||||
OutputStreamWriter(outputStream).use { writer ->
|
||||
writer.write(log)
|
||||
}
|
||||
}
|
||||
} ?: run {
|
||||
log("Error saving log file")
|
||||
}
|
||||
//Logger.log(string)
|
||||
}
|
||||
|
||||
fun resume() {
|
||||
|
|
|
@ -27,7 +27,7 @@ import ani.dantotsu.download.DownloadedType
|
|||
import ani.dantotsu.download.DownloadsManager
|
||||
import ani.dantotsu.download.video.ExoplayerDownloadService
|
||||
import ani.dantotsu.download.video.Helper
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.SubtitleDownloader
|
||||
import ani.dantotsu.media.anime.AnimeWatchFragment
|
||||
|
@ -249,7 +249,7 @@ class AnimeDownloaderService : Service() {
|
|||
hasDownloadStarted(downloadManager, task, 30000) // 30 seconds timeout
|
||||
|
||||
if (!downloadStarted) {
|
||||
logger("Download failed to start")
|
||||
Logger.log("Download failed to start")
|
||||
builder.setContentText("${task.title} - ${task.episode} Download failed to start")
|
||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||
snackString("${task.title} - ${task.episode} Download failed to start")
|
||||
|
@ -263,11 +263,11 @@ class AnimeDownloaderService : Service() {
|
|||
val download = downloadManager.downloadIndex.getDownload(task.video.file.url)
|
||||
if (download != null) {
|
||||
if (download.state == androidx.media3.exoplayer.offline.Download.STATE_FAILED) {
|
||||
logger("Download failed")
|
||||
Logger.log("Download failed")
|
||||
builder.setContentText("${task.title} - ${task.episode} Download failed")
|
||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||
snackString("${task.title} - ${task.episode} Download failed")
|
||||
logger("Download failed: ${download.failureReason}")
|
||||
Logger.log("Download failed: ${download.failureReason}")
|
||||
downloadsManager.removeDownload(
|
||||
DownloadedType(
|
||||
task.title,
|
||||
|
@ -289,7 +289,7 @@ class AnimeDownloaderService : Service() {
|
|||
break
|
||||
}
|
||||
if (download.state == androidx.media3.exoplayer.offline.Download.STATE_COMPLETED) {
|
||||
logger("Download completed")
|
||||
Logger.log("Download completed")
|
||||
builder.setContentText("${task.title} - ${task.episode} Download completed")
|
||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||
snackString("${task.title} - ${task.episode} Download completed")
|
||||
|
@ -309,7 +309,7 @@ class AnimeDownloaderService : Service() {
|
|||
break
|
||||
}
|
||||
if (download.state == androidx.media3.exoplayer.offline.Download.STATE_STOPPED) {
|
||||
logger("Download stopped")
|
||||
Logger.log("Download stopped")
|
||||
builder.setContentText("${task.title} - ${task.episode} Download stopped")
|
||||
notificationManager.notify(NOTIFICATION_ID, builder.build())
|
||||
snackString("${task.title} - ${task.episode} Download stopped")
|
||||
|
@ -328,7 +328,7 @@ class AnimeDownloaderService : Service() {
|
|||
}
|
||||
} catch (e: Exception) {
|
||||
if (e.message?.contains("Coroutine was cancelled") == false) { //wut
|
||||
logger("Exception while downloading file: ${e.message}")
|
||||
Logger.log("Exception while downloading file: ${e.message}")
|
||||
snackString("Exception while downloading file: ${e.message}")
|
||||
e.printStackTrace()
|
||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||
|
|
|
@ -33,7 +33,7 @@ import ani.dantotsu.currContext
|
|||
import ani.dantotsu.download.DownloadedType
|
||||
import ani.dantotsu.download.DownloadsManager
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.MediaDetailsActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
|
@ -318,8 +318,8 @@ class OfflineAnimeFragment : Fragment(), OfflineAnimeSearchListener {
|
|||
val mediaJson = media.readText()
|
||||
gson.fromJson(mediaJson, Media::class.java)
|
||||
} catch (e: Exception) {
|
||||
logger("Error loading media.json: ${e.message}")
|
||||
logger(e.printStackTrace())
|
||||
Logger.log("Error loading media.json: ${e.message}")
|
||||
Logger.log(e)
|
||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||
null
|
||||
}
|
||||
|
@ -374,8 +374,8 @@ class OfflineAnimeFragment : Fragment(), OfflineAnimeSearchListener {
|
|||
bannerUri
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
logger("Error loading media.json: ${e.message}")
|
||||
logger(e.printStackTrace())
|
||||
Logger.log("Error loading media.json: ${e.message}")
|
||||
Logger.log(e)
|
||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||
return OfflineAnimeModel(
|
||||
"unknown",
|
||||
|
|
|
@ -21,7 +21,7 @@ import ani.dantotsu.R
|
|||
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
|
||||
import ani.dantotsu.download.DownloadedType
|
||||
import ani.dantotsu.download.DownloadsManager
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.manga.ImageData
|
||||
import ani.dantotsu.media.manga.MangaReadFragment.Companion.ACTION_DOWNLOAD_FAILED
|
||||
|
@ -251,7 +251,7 @@ class MangaDownloaderService : Service() {
|
|||
snackString("${task.title} - ${task.chapter} Download finished")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger("Exception while downloading file: ${e.message}")
|
||||
Logger.log("Exception while downloading file: ${e.message}")
|
||||
snackString("Exception while downloading file: ${e.message}")
|
||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||
broadcastDownloadFailed(task.chapter)
|
||||
|
|
|
@ -30,7 +30,7 @@ import ani.dantotsu.currContext
|
|||
import ani.dantotsu.download.DownloadedType
|
||||
import ani.dantotsu.download.DownloadsManager
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.MediaDetailsActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
|
@ -308,8 +308,8 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
|||
val mediaJson = media.readText()
|
||||
gson.fromJson(mediaJson, Media::class.java)
|
||||
} catch (e: Exception) {
|
||||
logger("Error loading media.json: ${e.message}")
|
||||
logger(e.printStackTrace())
|
||||
Logger.log("Error loading media.json: ${e.message}")
|
||||
Logger.log(e)
|
||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||
null
|
||||
}
|
||||
|
@ -358,8 +358,8 @@ class OfflineMangaFragment : Fragment(), OfflineMangaSearchListener {
|
|||
bannerUri
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
logger("Error loading media.json: ${e.message}")
|
||||
logger(e.printStackTrace())
|
||||
Logger.log("Error loading media.json: ${e.message}")
|
||||
Logger.log(e)
|
||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||
return OfflineMangaModel(
|
||||
"unknown",
|
||||
|
|
|
@ -20,7 +20,7 @@ import ani.dantotsu.R
|
|||
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
|
||||
import ani.dantotsu.download.DownloadedType
|
||||
import ani.dantotsu.download.DownloadsManager
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.novel.NovelReadFragment
|
||||
import ani.dantotsu.snackString
|
||||
|
@ -186,15 +186,15 @@ class NovelDownloaderService : Service() {
|
|||
val contentType = response.header("Content-Type")
|
||||
val contentDisposition = response.header("Content-Disposition")
|
||||
|
||||
logger("Content-Type: $contentType")
|
||||
logger("Content-Disposition: $contentDisposition")
|
||||
Logger.log("Content-Type: $contentType")
|
||||
Logger.log("Content-Disposition: $contentDisposition")
|
||||
|
||||
// Return true if the Content-Type or Content-Disposition indicates an EPUB file
|
||||
contentType == "application/epub+zip" ||
|
||||
(contentDisposition?.contains(".epub") == true)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger("Error checking file type: ${e.message}")
|
||||
Logger.log("Error checking file type: ${e.message}")
|
||||
false
|
||||
}
|
||||
}
|
||||
|
@ -225,12 +225,12 @@ class NovelDownloaderService : Service() {
|
|||
|
||||
if (!isEpubFile(task.downloadLink)) {
|
||||
if (isAlreadyDownloaded(task.originalLink)) {
|
||||
logger("Already downloaded")
|
||||
Logger.log("Already downloaded")
|
||||
broadcastDownloadFinished(task.originalLink)
|
||||
snackString("Already downloaded")
|
||||
return@withContext
|
||||
}
|
||||
logger("Download link is not an .epub file")
|
||||
Logger.log("Download link is not an .epub file")
|
||||
broadcastDownloadFailed(task.originalLink)
|
||||
snackString("Download link is not an .epub file")
|
||||
return@withContext
|
||||
|
@ -301,7 +301,7 @@ class NovelDownloaderService : Service() {
|
|||
withContext(Dispatchers.Main) {
|
||||
val progress =
|
||||
(downloadedBytes * 100 / totalBytes).toInt()
|
||||
logger("Download progress: $progress")
|
||||
Logger.log("Download progress: $progress")
|
||||
broadcastDownloadProgress(task.originalLink, progress)
|
||||
}
|
||||
lastBroadcastUpdate = downloadedBytes
|
||||
|
@ -316,7 +316,7 @@ class NovelDownloaderService : Service() {
|
|||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger("Exception while downloading .epub inside request: ${e.message}")
|
||||
Logger.log("Exception while downloading .epub inside request: ${e.message}")
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ class NovelDownloaderService : Service() {
|
|||
snackString("${task.title} - ${task.chapter} Download finished")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger("Exception while downloading .epub: ${e.message}")
|
||||
Logger.log("Exception while downloading .epub: ${e.message}")
|
||||
snackString("Exception while downloading .epub: ${e.message}")
|
||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||
broadcastDownloadFailed(task.originalLink)
|
||||
|
|
|
@ -43,6 +43,7 @@ import ani.dantotsu.parsers.SubtitleType
|
|||
import ani.dantotsu.parsers.Video
|
||||
import ani.dantotsu.parsers.VideoType
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
@ -157,15 +158,15 @@ object Helper {
|
|||
finalException: Exception?
|
||||
) {
|
||||
if (download.state == Download.STATE_COMPLETED) {
|
||||
Log.e("Downloader", "Download Completed")
|
||||
Logger.log("Download Completed")
|
||||
} else if (download.state == Download.STATE_FAILED) {
|
||||
Log.e("Downloader", "Download Failed")
|
||||
Logger.log("Download Failed")
|
||||
} else if (download.state == Download.STATE_STOPPED) {
|
||||
Log.e("Downloader", "Download Stopped")
|
||||
Logger.log("Download Stopped")
|
||||
} else if (download.state == Download.STATE_QUEUED) {
|
||||
Log.e("Downloader", "Download Queued")
|
||||
Logger.log("Download Queued")
|
||||
} else if (download.state == Download.STATE_DOWNLOADING) {
|
||||
Log.e("Downloader", "Download Downloading")
|
||||
Logger.log("Download Downloading")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import androidx.lifecycle.ViewModel
|
|||
import ani.dantotsu.R
|
||||
import ani.dantotsu.connections.anilist.Anilist
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.media.anime.Episode
|
||||
import ani.dantotsu.media.anime.SelectorDialogFragment
|
||||
import ani.dantotsu.media.manga.MangaChapter
|
||||
|
@ -223,7 +223,7 @@ class MediaDetailsViewModel : ViewModel() {
|
|||
}
|
||||
|
||||
fun setEpisode(ep: Episode?, who: String) {
|
||||
logger("set episode ${ep?.number} - $who", false)
|
||||
Logger.log("set episode ${ep?.number} - $who")
|
||||
episode.postValue(ep)
|
||||
MainScope().launch(Dispatchers.Main) {
|
||||
episode.value = null
|
||||
|
@ -270,7 +270,7 @@ class MediaDetailsViewModel : ViewModel() {
|
|||
mangaChapters
|
||||
|
||||
suspend fun loadMangaChapters(media: Media, i: Int, invalidate: Boolean = false) {
|
||||
logger("Loading Manga Chapters : $mangaLoaded")
|
||||
Logger.log("Loading Manga Chapters : $mangaLoaded")
|
||||
if (!mangaLoaded.containsKey(i) || invalidate) tryWithSuspend {
|
||||
mangaLoaded[i] =
|
||||
mangaReadSources?.loadChaptersFromMedia(i, media) ?: return@tryWithSuspend
|
||||
|
|
|
@ -86,6 +86,7 @@ import ani.dantotsu.settings.PlayerSettingsActivity
|
|||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.gms.cast.framework.CastButtonFactory
|
||||
import com.google.android.gms.cast.framework.CastContext
|
||||
|
@ -1372,8 +1373,8 @@ class ExoplayerView : AppCompatActivity(), Player.Listener, SessionAvailabilityL
|
|||
|
||||
mediaItem = if (downloadedMediaItem == null) {
|
||||
val builder = MediaItem.Builder().setUri(video!!.file.url).setMimeType(mimeType)
|
||||
logger("url: ${video!!.file.url}")
|
||||
logger("mimeType: $mimeType")
|
||||
Logger.log("url: ${video!!.file.url}")
|
||||
Logger.log("mimeType: $mimeType")
|
||||
|
||||
if (sub != null) {
|
||||
val listofnotnullsubs = listOfNotNull(sub)
|
||||
|
|
|
@ -10,7 +10,7 @@ import android.os.Build
|
|||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import android.util.LruCache
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.snackString
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
|
@ -32,8 +32,8 @@ data class ImageData(
|
|||
try {
|
||||
// Fetch the image
|
||||
val response = httpSource.getImage(page)
|
||||
logger("Response: ${response.code}")
|
||||
logger("Response: ${response.message}")
|
||||
Logger.log("Response: ${response.code}")
|
||||
Logger.log("Response: ${response.message}")
|
||||
|
||||
// Convert the Response to an InputStream
|
||||
val inputStream = response.body.byteStream()
|
||||
|
@ -47,7 +47,7 @@ data class ImageData(
|
|||
return@withContext bitmap
|
||||
} catch (e: Exception) {
|
||||
// Handle any exceptions
|
||||
logger("An error occurred: ${e.message}")
|
||||
Logger.log("An error occurred: ${e.message}")
|
||||
snackString("An error occurred: ${e.message}")
|
||||
return@withContext null
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import ani.dantotsu.media.MediaDetailsViewModel
|
|||
import ani.dantotsu.media.novel.novelreader.NovelReaderActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.parsers.ShowResponse
|
||||
import ani.dantotsu.util.Logger
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -59,7 +60,7 @@ class NovelReadFragment : Fragment(),
|
|||
var loaded = false
|
||||
|
||||
override fun downloadTrigger(novelDownloadPackage: NovelDownloadPackage) {
|
||||
Log.e("downloadTrigger", novelDownloadPackage.link)
|
||||
Logger.log("novel link: ${novelDownloadPackage.link}")
|
||||
val downloadTask = NovelDownloaderService.DownloadTask(
|
||||
title = media.mainName(),
|
||||
chapter = novelDownloadPackage.novelName,
|
||||
|
|
|
@ -11,6 +11,7 @@ import ani.dantotsu.databinding.ItemNovelResponseBinding
|
|||
import ani.dantotsu.parsers.ShowResponse
|
||||
import ani.dantotsu.setAnimation
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
|
||||
|
@ -181,7 +182,7 @@ class NovelResponseAdapter(
|
|||
if (position != -1) {
|
||||
list[position].extra?.remove("0")
|
||||
list[position].extra?.set("0", "Downloading: $progress%")
|
||||
Log.d("NovelResponseAdapter", "updateDownloadProgress: $progress, position: $position")
|
||||
Logger.log( "updateDownloadProgress: $progress, position: $position")
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package ani.dantotsu.others
|
||||
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.math.pow
|
||||
|
||||
|
@ -64,7 +64,7 @@ class JsUnpacker(packedJS: String?) {
|
|||
return decoded.toString()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger(e)
|
||||
Logger.log(e)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package ani.dantotsu.others
|
|||
|
||||
import ani.dantotsu.FileUrl
|
||||
import ani.dantotsu.client
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.anime.Episode
|
||||
import ani.dantotsu.tryWithSuspend
|
||||
|
@ -41,8 +41,7 @@ object Kitsu {
|
|||
}
|
||||
|
||||
suspend fun getKitsuEpisodesDetails(media: Media): Map<String, Episode>? {
|
||||
val print = false
|
||||
logger("Kitsu : title=${media.mainName()}", print)
|
||||
Logger.log("Kitsu : title=${media.mainName()}")
|
||||
val query =
|
||||
"""
|
||||
query {
|
||||
|
@ -70,7 +69,7 @@ query {
|
|||
|
||||
|
||||
val result = getKitsuData(query) ?: return null
|
||||
logger("Kitsu : result=$result", print)
|
||||
//Logger.log("Kitsu : result=$result")
|
||||
media.idKitsu = result.data?.lookupMapping?.id
|
||||
val a = (result.data?.lookupMapping?.episodes?.nodes ?: return null).mapNotNull { ep ->
|
||||
val num = ep?.number?.toString() ?: return@mapNotNull null
|
||||
|
@ -81,7 +80,7 @@ query {
|
|||
thumb = FileUrl[ep.thumbnail?.original?.url],
|
||||
)
|
||||
}.toMap()
|
||||
logger("Kitsu : a=$a", print)
|
||||
//Logger.log("Kitsu : a=$a")
|
||||
return a
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import android.os.Environment
|
|||
import android.provider.MediaStore
|
||||
import ani.dantotsu.FileUrl
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.media.anime.AnimeNameAdapter
|
||||
import ani.dantotsu.media.manga.ImageData
|
||||
import ani.dantotsu.media.manga.MangaCache
|
||||
|
@ -129,7 +129,7 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
|
|||
val configurableSource = extension.sources[sourceLanguage] as? ConfigurableAnimeSource
|
||||
?: return false
|
||||
currContext()?.let { context ->
|
||||
logger("isDubAvailableSeparately: ${configurableSource.getPreferenceKey()}")
|
||||
Logger.log("isDubAvailableSeparately: ${configurableSource.getPreferenceKey()}")
|
||||
val sharedPreferences =
|
||||
context.getSharedPreferences(
|
||||
configurableSource.getPreferenceKey(),
|
||||
|
@ -205,7 +205,7 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
|
|||
}
|
||||
return sortedEpisodes.map { SEpisodeToEpisode(it) }
|
||||
} catch (e: Exception) {
|
||||
logger("Exception: $e")
|
||||
Logger.log("Exception: $e")
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
|
|||
val videos = source.getVideoList(sEpisode)
|
||||
videos.map { VideoToVideoServer(it) }
|
||||
} catch (e: Exception) {
|
||||
logger("Exception occurred: ${e.message}")
|
||||
Logger.log("Exception occurred: ${e.message}")
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
@ -260,16 +260,16 @@ class DynamicAnimeParser(extension: AnimeExtension.Installed) : AnimeParser() {
|
|||
?: return emptyList())
|
||||
return try {
|
||||
val res = source.fetchSearchAnime(1, query, source.getFilterList()).awaitSingle()
|
||||
logger("query: $query")
|
||||
Logger.log("query: $query")
|
||||
convertAnimesPageToShowResponse(res)
|
||||
} catch (e: CloudflareBypassException) {
|
||||
logger("Exception in search: $e")
|
||||
Logger.log("Exception in search: $e")
|
||||
withContext(Dispatchers.Main) {
|
||||
snackString("Failed to bypass Cloudflare")
|
||||
}
|
||||
emptyList()
|
||||
} catch (e: Exception) {
|
||||
logger("General exception in search: $e")
|
||||
Logger.log("General exception in search: $e")
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
@ -358,12 +358,12 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
val res = source.getChapterList(sManga)
|
||||
val reversedRes = res.reversed()
|
||||
val chapterList = reversedRes.map { SChapterToMangaChapter(it) }
|
||||
logger("chapterList size: ${chapterList.size}")
|
||||
logger("chapterList: ${chapterList[1].title}")
|
||||
logger("chapterList: ${chapterList[1].description}")
|
||||
Logger.log("chapterList size: ${chapterList.size}")
|
||||
Logger.log("chapterList: ${chapterList[1].title}")
|
||||
Logger.log("chapterList: ${chapterList[1].description}")
|
||||
chapterList
|
||||
} catch (e: Exception) {
|
||||
logger("loadChapters Exception: $e")
|
||||
Logger.log("loadChapters Exception: $e")
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
var imageDataList: List<ImageData> = listOf()
|
||||
val ret = coroutineScope {
|
||||
try {
|
||||
logger("source.name " + source.name)
|
||||
Logger.log("source.name " + source.name)
|
||||
val res = source.getPageList(sChapter)
|
||||
val reIndexedPages =
|
||||
res.mapIndexed { index, page -> Page(index, page.url, page.imageUrl, page.uri) }
|
||||
|
@ -388,7 +388,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
async(Dispatchers.IO) {
|
||||
mangaCache.put(page.imageUrl ?: "", ImageData(page, source))
|
||||
imageDataList += ImageData(page, source)
|
||||
logger("put page: ${page.imageUrl}")
|
||||
Logger.log("put page: ${page.imageUrl}")
|
||||
pageToMangaImage(page)
|
||||
}
|
||||
}
|
||||
|
@ -396,7 +396,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
deferreds.awaitAll()
|
||||
|
||||
} catch (e: Exception) {
|
||||
logger("loadImages Exception: $e")
|
||||
Logger.log("loadImages Exception: $e")
|
||||
snackString("Failed to load images: $e")
|
||||
emptyList()
|
||||
}
|
||||
|
@ -414,7 +414,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
|
||||
return coroutineScope {
|
||||
try {
|
||||
logger("source.name " + source.name)
|
||||
Logger.log("source.name " + source.name)
|
||||
val res = source.getPageList(sChapter)
|
||||
val reIndexedPages =
|
||||
res.mapIndexed { index, page -> Page(index, page.url, page.imageUrl, page.uri) }
|
||||
|
@ -430,7 +430,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
|
||||
deferreds.awaitAll()
|
||||
} catch (e: Exception) {
|
||||
logger("loadImages Exception: $e")
|
||||
Logger.log("loadImages Exception: $e")
|
||||
snackString("Failed to load images: $e")
|
||||
emptyList()
|
||||
}
|
||||
|
@ -446,8 +446,8 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
try {
|
||||
// Fetch the image
|
||||
val response = httpSource.getImage(page)
|
||||
logger("Response: ${response.code}")
|
||||
logger("Response: ${response.message}")
|
||||
Logger.log("Response: ${response.code}")
|
||||
Logger.log("Response: ${response.message}")
|
||||
|
||||
// Convert the Response to an InputStream
|
||||
val inputStream = response.body.byteStream()
|
||||
|
@ -467,7 +467,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
return@withContext bitmap
|
||||
} catch (e: Exception) {
|
||||
// Handle any exceptions
|
||||
logger("An error occurred: ${e.message}")
|
||||
Logger.log("An error occurred: ${e.message}")
|
||||
return@withContext null
|
||||
}
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
inputStream.close()
|
||||
} catch (e: Exception) {
|
||||
// Handle any exceptions
|
||||
logger("An error occurred: ${e.message}")
|
||||
Logger.log("An error occurred: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -547,7 +547,7 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
}
|
||||
} catch (e: Exception) {
|
||||
// Handle exception here
|
||||
logger("Exception while saving image: ${e.message}")
|
||||
Logger.log("Exception while saving image: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -562,16 +562,16 @@ class DynamicMangaParser(extension: MangaExtension.Installed) : MangaParser() {
|
|||
|
||||
return try {
|
||||
val res = source.fetchSearchManga(1, query, source.getFilterList()).awaitSingle()
|
||||
logger("res observable: $res")
|
||||
Logger.log("res observable: $res")
|
||||
convertMangasPageToShowResponse(res)
|
||||
} catch (e: CloudflareBypassException) {
|
||||
logger("Exception in search: $e")
|
||||
Logger.log("Exception in search: $e")
|
||||
withContext(Dispatchers.Main) {
|
||||
snackString("Failed to bypass Cloudflare")
|
||||
}
|
||||
emptyList()
|
||||
} catch (e: Exception) {
|
||||
logger("General exception in search: $e")
|
||||
Logger.log("General exception in search: $e")
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
@ -714,7 +714,7 @@ class VideoServerPassthrough(val videoServer: VideoServer) : VideoExtractor() {
|
|||
|
||||
// If the format is still undetermined, log an error
|
||||
if (format == null) {
|
||||
logger("Unknown video format: $videoUrl")
|
||||
Logger.log("Unknown video format: $videoUrl")
|
||||
format = VideoType.CONTAINER
|
||||
}
|
||||
val headersMap: Map<String, String> =
|
||||
|
@ -746,7 +746,7 @@ class VideoServerPassthrough(val videoServer: VideoServer) : VideoExtractor() {
|
|||
|
||||
private fun headRequest(fileName: String, networkHelper: NetworkHelper): VideoType? {
|
||||
return try {
|
||||
logger("attempting head request for $fileName")
|
||||
Logger.log("attempting head request for $fileName")
|
||||
val request = Request.Builder()
|
||||
.url(fileName)
|
||||
.head()
|
||||
|
@ -771,13 +771,13 @@ class VideoServerPassthrough(val videoServer: VideoServer) : VideoExtractor() {
|
|||
else -> null
|
||||
}
|
||||
} else {
|
||||
logger("failed head request for $fileName")
|
||||
Logger.log("failed head request for $fileName")
|
||||
null
|
||||
}
|
||||
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logger("Exception in headRequest: $e")
|
||||
Logger.log("Exception in headRequest: $e")
|
||||
null
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package ani.dantotsu.parsers
|
|||
import ani.dantotsu.FileUrl
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||
|
@ -59,11 +59,11 @@ abstract class BaseParser {
|
|||
saveShowResponse(mediaObj.id, response, true)
|
||||
} else {
|
||||
setUserText("Searching : ${mediaObj.mainName()}")
|
||||
logger("Searching : ${mediaObj.mainName()}")
|
||||
Logger.log("Searching : ${mediaObj.mainName()}")
|
||||
val results = search(mediaObj.mainName())
|
||||
//log all results
|
||||
results.forEach {
|
||||
logger("Result: ${it.name}")
|
||||
Logger.log("Result: ${it.name}")
|
||||
}
|
||||
val sortedResults = if (results.isNotEmpty()) {
|
||||
results.sortedByDescending {
|
||||
|
@ -83,7 +83,7 @@ abstract class BaseParser {
|
|||
) < 100
|
||||
) {
|
||||
setUserText("Searching : ${mediaObj.nameRomaji}")
|
||||
logger("Searching : ${mediaObj.nameRomaji}")
|
||||
Logger.log("Searching : ${mediaObj.nameRomaji}")
|
||||
val romajiResults = search(mediaObj.nameRomaji)
|
||||
val sortedRomajiResults = if (romajiResults.isNotEmpty()) {
|
||||
romajiResults.sortedByDescending {
|
||||
|
@ -96,10 +96,10 @@ abstract class BaseParser {
|
|||
emptyList()
|
||||
}
|
||||
val closestRomaji = sortedRomajiResults.firstOrNull()
|
||||
logger("Closest match from RomajiResults: ${closestRomaji?.name ?: "None"}")
|
||||
Logger.log("Closest match from RomajiResults: ${closestRomaji?.name ?: "None"}")
|
||||
|
||||
response = if (response == null) {
|
||||
logger("No exact match found in results. Using closest match from RomajiResults.")
|
||||
Logger.log("No exact match found in results. Using closest match from RomajiResults.")
|
||||
closestRomaji
|
||||
} else {
|
||||
val romajiRatio = FuzzySearch.ratio(
|
||||
|
@ -110,14 +110,14 @@ abstract class BaseParser {
|
|||
response.name.lowercase(),
|
||||
mediaObj.mainName().lowercase()
|
||||
)
|
||||
logger("Fuzzy ratio for closest match in results: $mainNameRatio for ${response.name.lowercase()}")
|
||||
logger("Fuzzy ratio for closest match in RomajiResults: $romajiRatio for ${closestRomaji?.name?.lowercase() ?: "None"}")
|
||||
Logger.log("Fuzzy ratio for closest match in results: $mainNameRatio for ${response.name.lowercase()}")
|
||||
Logger.log("Fuzzy ratio for closest match in RomajiResults: $romajiRatio for ${closestRomaji?.name?.lowercase() ?: "None"}")
|
||||
|
||||
if (romajiRatio > mainNameRatio) {
|
||||
logger("RomajiResults has a closer match. Replacing response.")
|
||||
Logger.log("RomajiResults has a closer match. Replacing response.")
|
||||
closestRomaji
|
||||
} else {
|
||||
logger("Results has a closer or equal match. Keeping existing response.")
|
||||
Logger.log("Results has a closer or equal match. Keeping existing response.")
|
||||
response
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package ani.dantotsu.parsers
|
||||
|
||||
import ani.dantotsu.Lazier
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.anime.Episode
|
||||
import ani.dantotsu.media.manga.MangaChapter
|
||||
|
@ -96,7 +96,7 @@ abstract class MangaReadSources : BaseSources() {
|
|||
}
|
||||
//must be downloaded
|
||||
if (show.sManga == null) {
|
||||
logger("sManga is null")
|
||||
Logger.log("sManga is null")
|
||||
}
|
||||
if (parser is OfflineMangaParser && show.sManga == null) {
|
||||
tryWithSuspend(true) {
|
||||
|
@ -106,11 +106,11 @@ abstract class MangaReadSources : BaseSources() {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
logger("Parser is not an instance of OfflineMangaParser")
|
||||
Logger.log("Parser is not an instance of OfflineMangaParser")
|
||||
}
|
||||
|
||||
|
||||
logger("map size ${map.size}")
|
||||
Logger.log("map size ${map.size}")
|
||||
return map
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import ani.dantotsu.parsers.novel.DynamicNovelParser
|
|||
import ani.dantotsu.parsers.novel.NovelExtension
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.util.Logger
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
|
||||
|
@ -47,8 +48,8 @@ object NovelSources : NovelReadSources() {
|
|||
}
|
||||
|
||||
private fun createParsersFromExtensions(extensions: List<NovelExtension.Installed>): List<Lazier<BaseParser>> {
|
||||
Log.d("NovelSources", "createParsersFromExtensions")
|
||||
Log.d("NovelSources", extensions.toString())
|
||||
Logger.log("createParsersFromExtensions")
|
||||
Logger.log(extensions.toString())
|
||||
return extensions.map { extension ->
|
||||
val name = extension.name
|
||||
Lazier({ DynamicNovelParser(extension) }, name)
|
||||
|
|
|
@ -3,7 +3,7 @@ package ani.dantotsu.parsers
|
|||
import android.os.Environment
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.download.DownloadsManager
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.media.manga.MangaNameAdapter
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
|
@ -68,7 +68,7 @@ class OfflineMangaParser : MangaParser() {
|
|||
matchResult?.groups?.get(1)?.value?.toIntOrNull() ?: Int.MAX_VALUE
|
||||
}
|
||||
for (image in images) {
|
||||
logger("imageNumber: ${image.url.url}")
|
||||
Logger.log("imageNumber: ${image.url.url}")
|
||||
}
|
||||
return images
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package ani.dantotsu.parsers
|
||||
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
|
||||
class StringMatcher {
|
||||
companion object {
|
||||
|
@ -54,10 +54,10 @@ class StringMatcher {
|
|||
val closestShowAndIndex = closestShow(target, shows)
|
||||
val closestIndex = closestShowAndIndex.second
|
||||
if (closestIndex == -1) {
|
||||
logger("No closest show found for $target")
|
||||
Logger.log("No closest show found for $target")
|
||||
return shows // Return original list if no closest show found
|
||||
}
|
||||
logger("Closest show found for $target is ${closestShowAndIndex.first.name}")
|
||||
Logger.log("Closest show found for $target is ${closestShowAndIndex.first.name}")
|
||||
return listOf(shows[closestIndex]) + shows.subList(0, closestIndex) + shows.subList(
|
||||
closestIndex + 1,
|
||||
shows.size
|
||||
|
|
|
@ -2,7 +2,7 @@ package ani.dantotsu.parsers.novel
|
|||
|
||||
|
||||
import android.content.Context
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import eu.kanade.tachiyomi.extension.ExtensionUpdateNotifier
|
||||
|
@ -14,9 +14,7 @@ import eu.kanade.tachiyomi.network.awaitSuccess
|
|||
import eu.kanade.tachiyomi.network.parseAs
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.lang.withIOContext
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.Date
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
@ -41,20 +39,20 @@ class NovelExtensionGithubApi {
|
|||
.newCall(GET("${REPO_URL_PREFIX}index.min.json"))
|
||||
.awaitSuccess()
|
||||
} catch (e: Throwable) {
|
||||
logcat(LogPriority.ERROR, e) { "Failed to get extensions from GitHub" }
|
||||
Logger.log("Failed to get extensions from GitHub")
|
||||
requiresFallbackSource = true
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
val response = githubResponse ?: run {
|
||||
logger("using fallback source")
|
||||
Logger.log("using fallback source")
|
||||
networkService.client
|
||||
.newCall(GET("${FALLBACK_REPO_URL_PREFIX}index.min.json"))
|
||||
.awaitSuccess()
|
||||
}
|
||||
|
||||
logger("response: $response")
|
||||
Logger.log("response: $response")
|
||||
|
||||
val extensions = with(json) {
|
||||
response
|
||||
|
@ -67,7 +65,7 @@ class NovelExtensionGithubApi {
|
|||
/*if (extensions.size < 10) { //TODO: uncomment when more extensions are added
|
||||
throw Exception()
|
||||
}*/
|
||||
logger("extensions: $extensions")
|
||||
Logger.log("extensions: $extensions")
|
||||
extensions
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package ani.dantotsu.parsers.novel
|
|||
import android.os.FileObserver
|
||||
import android.util.Log
|
||||
import ani.dantotsu.parsers.novel.FileObserver.fileObserver
|
||||
import ani.dantotsu.util.Logger
|
||||
import java.io.File
|
||||
|
||||
|
||||
|
@ -22,24 +23,24 @@ class NovelExtensionFileObserver(private val listener: Listener, private val pat
|
|||
|
||||
|
||||
override fun onEvent(event: Int, file: String?) {
|
||||
Log.e("NovelExtensionFileObserver", "Event: $event")
|
||||
Logger.log("Event: $event")
|
||||
if (file == null) return
|
||||
|
||||
val fullPath = File(path, file)
|
||||
|
||||
when (event) {
|
||||
CREATE -> {
|
||||
Log.e("NovelExtensionFileObserver", "File created: $fullPath")
|
||||
Logger.log("File created: $fullPath")
|
||||
listener.onExtensionFileCreated(fullPath)
|
||||
}
|
||||
|
||||
DELETE -> {
|
||||
Log.e("NovelExtensionFileObserver", "File deleted: $fullPath")
|
||||
Logger.log("File deleted: $fullPath")
|
||||
listener.onExtensionFileDeleted(fullPath)
|
||||
}
|
||||
|
||||
MODIFY -> {
|
||||
Log.e("NovelExtensionFileObserver", "File modified: $fullPath")
|
||||
Logger.log("File modified: $fullPath")
|
||||
listener.onExtensionFileModified(fullPath)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,12 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.core.content.getSystemService
|
||||
import androidx.core.net.toUri
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.jakewharton.rxrelay.PublishRelay
|
||||
import eu.kanade.tachiyomi.extension.InstallStep
|
||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import logcat.LogPriority
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
|
@ -77,12 +76,12 @@ internal class NovelExtensionInstaller(private val context: Context) {
|
|||
val fileToDelete = File("$sourcePath/${url.toUri().lastPathSegment}")
|
||||
if (fileToDelete.exists()) {
|
||||
if (fileToDelete.delete()) {
|
||||
Log.i("Install APK", "APK file deleted successfully.")
|
||||
Logger.log("APK file deleted successfully.")
|
||||
} else {
|
||||
Log.e("Install APK", "Failed to delete APK file.")
|
||||
Logger.log("Failed to delete APK file.")
|
||||
}
|
||||
} else {
|
||||
Log.e("Install APK", "APK file not found.")
|
||||
Logger.log("APK file not found.")
|
||||
}
|
||||
|
||||
// Register the receiver after removing (and unregistering) the previous download
|
||||
|
@ -161,7 +160,7 @@ internal class NovelExtensionInstaller(private val context: Context) {
|
|||
|
||||
// Check if source path is obtained correctly
|
||||
if (sourcePath == null) {
|
||||
Log.e("Install APK", "Source APK path not found.")
|
||||
Logger.log("Source APK path not found.")
|
||||
downloadsRelay.call(downloadId to InstallStep.Error)
|
||||
return InstallStep.Error
|
||||
}
|
||||
|
@ -172,14 +171,14 @@ internal class NovelExtensionInstaller(private val context: Context) {
|
|||
destinationDir.mkdirs()
|
||||
}
|
||||
if (destinationDir?.setWritable(true) == false) {
|
||||
Log.e("Install APK", "Failed to set destinationDir to writable.")
|
||||
Logger.log("Failed to set destinationDir to writable.")
|
||||
downloadsRelay.call(downloadId to InstallStep.Error)
|
||||
return InstallStep.Error
|
||||
}
|
||||
|
||||
// Copy the file to the new location
|
||||
copyFileToInternalStorage(sourcePath, destinationPath)
|
||||
Log.i("Install APK", "APK moved to $destinationPath")
|
||||
Logger.log("APK moved to $destinationPath")
|
||||
downloadsRelay.call(downloadId to InstallStep.Installed)
|
||||
return InstallStep.Installed
|
||||
}
|
||||
|
@ -198,9 +197,9 @@ internal class NovelExtensionInstaller(private val context: Context) {
|
|||
val fileToDelete = File(apkPath)
|
||||
//give write permission to the file
|
||||
if (fileToDelete.exists() && !fileToDelete.canWrite()) {
|
||||
Log.i("Uninstall APK", "File is not writable. Giving write permission.")
|
||||
Logger.log("File is not writable. Giving write permission.")
|
||||
val a = fileToDelete.setWritable(true)
|
||||
Log.i("Uninstall APK", "Success: $a")
|
||||
Logger.log("Success: $a")
|
||||
}
|
||||
//set the directory to writable
|
||||
val destinationDir = File(apkPath).parentFile
|
||||
|
@ -208,27 +207,27 @@ internal class NovelExtensionInstaller(private val context: Context) {
|
|||
destinationDir.mkdirs()
|
||||
}
|
||||
val s = destinationDir?.setWritable(true)
|
||||
Log.i("Uninstall APK", "Success destinationDir: $s")
|
||||
Logger.log("Success destinationDir: $s")
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
try {
|
||||
Files.delete(fileToDelete.toPath())
|
||||
} catch (e: Exception) {
|
||||
Log.e("Uninstall APK", "Failed to delete APK file.")
|
||||
Log.e("Uninstall APK", e.toString())
|
||||
Logger.log("Failed to delete APK file.")
|
||||
Logger.log(e)
|
||||
snackString("Failed to delete APK file.")
|
||||
}
|
||||
} else {
|
||||
if (fileToDelete.exists()) {
|
||||
if (fileToDelete.delete()) {
|
||||
Log.i("Uninstall APK", "APK file deleted successfully.")
|
||||
Logger.log("APK file deleted successfully.")
|
||||
snackString("APK file deleted successfully.")
|
||||
} else {
|
||||
Log.e("Uninstall APK", "Failed to delete APK file.")
|
||||
Logger.log("Failed to delete APK file.")
|
||||
snackString("Failed to delete APK file.")
|
||||
}
|
||||
} else {
|
||||
Log.e("Uninstall APK", "APK file not found.")
|
||||
Logger.log("APK file not found.")
|
||||
snackString("APK file not found.")
|
||||
}
|
||||
}
|
||||
|
@ -242,9 +241,9 @@ internal class NovelExtensionInstaller(private val context: Context) {
|
|||
//delete the file if it already exists
|
||||
if (destination.exists()) {
|
||||
if (destination.delete()) {
|
||||
Log.i("File Copy", "File deleted successfully.")
|
||||
Logger.log("File deleted successfully.")
|
||||
} else {
|
||||
Log.e("File Copy", "Failed to delete file.")
|
||||
Logger.log("Failed to delete file.")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +261,7 @@ internal class NovelExtensionInstaller(private val context: Context) {
|
|||
outputChannel?.close()
|
||||
}
|
||||
|
||||
Log.i("File Copy", "File copied to internal storage.")
|
||||
Logger.log("File copied to internal storage.")
|
||||
}
|
||||
|
||||
private fun getRealPathFromURI(context: Context, contentUri: Uri): String? {
|
||||
|
@ -350,7 +349,7 @@ internal class NovelExtensionInstaller(private val context: Context) {
|
|||
|
||||
// Set next installation step
|
||||
if (uri == null) {
|
||||
logcat(LogPriority.ERROR) { "Couldn't locate downloaded APK" }
|
||||
Logger.log("Couldn't locate downloaded APK")
|
||||
downloadsRelay.call(id to InstallStep.Error)
|
||||
return
|
||||
}
|
||||
|
@ -371,7 +370,7 @@ internal class NovelExtensionInstaller(private val context: Context) {
|
|||
val uri = Uri.parse(localUri)
|
||||
val path = uri.path
|
||||
val pkgName = path?.substring(path.lastIndexOf('/') + 1)?.removeSuffix(".apk")
|
||||
Log.i("Install APK", "Package name: $pkgName")
|
||||
Logger.log("Package name: $pkgName")
|
||||
return pkgName ?: ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import android.content.pm.PackageManager.GET_SIGNING_CERTIFICATES
|
|||
import android.os.Build
|
||||
import android.util.Log
|
||||
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.parsers.NovelInterface
|
||||
import ani.dantotsu.snackString
|
||||
import dalvik.system.PathClassLoader
|
||||
|
@ -26,21 +26,20 @@ internal object NovelExtensionLoader {
|
|||
val installDir = context.getExternalFilesDir(null)?.absolutePath + "/extensions/novel/"
|
||||
val results = mutableListOf<NovelLoadResult>()
|
||||
//the number of files
|
||||
Log.e("NovelExtensionLoader", "Loading extensions from $installDir")
|
||||
Log.e(
|
||||
"NovelExtensionLoader",
|
||||
Logger.log("Loading extensions from $installDir")
|
||||
Logger.log(
|
||||
"Loading extensions from ${File(installDir).listFiles()?.size}"
|
||||
)
|
||||
File(installDir).setWritable(false)
|
||||
File(installDir).listFiles()?.forEach {
|
||||
//set the file to read only
|
||||
it.setWritable(false)
|
||||
Log.e("NovelExtensionLoader", "Loading extension ${it.name}")
|
||||
Logger.log("Loading extension ${it.name}")
|
||||
val extension = loadExtension(context, it)
|
||||
if (extension is NovelLoadResult.Success) {
|
||||
results.add(extension)
|
||||
} else {
|
||||
logger("Failed to load extension ${it.name}")
|
||||
Logger.log("Failed to load extension ${it.name}")
|
||||
}
|
||||
}
|
||||
return results
|
||||
|
@ -62,7 +61,7 @@ internal object NovelExtensionLoader {
|
|||
context.packageManager.getPackageArchiveInfo(path, 0)
|
||||
} catch (error: Exception) {
|
||||
// Unlikely, but the package may have been uninstalled at this point
|
||||
logger("Failed to load extension $pkgName")
|
||||
Logger.log("Failed to load extension $pkgName")
|
||||
return NovelLoadResult.Error(Exception("Failed to load extension"))
|
||||
}
|
||||
return loadExtension(context, File(path))
|
||||
|
@ -88,8 +87,8 @@ internal object NovelExtensionLoader {
|
|||
val signatureHash = getSignatureHash(packageInfo)
|
||||
|
||||
if ((signatureHash == null) || !signatureHash.contains(officialSignature)) {
|
||||
logger("Package ${packageInfo.packageName} isn't signed")
|
||||
logger("signatureHash: $signatureHash")
|
||||
Logger.log("Package ${packageInfo.packageName} isn't signed")
|
||||
Logger.log("signatureHash: $signatureHash")
|
||||
snackString("Package ${packageInfo.packageName} isn't signed")
|
||||
//return NovelLoadResult.Error(Exception("Extension not signed"))
|
||||
}
|
||||
|
@ -128,12 +127,12 @@ internal object NovelExtensionLoader {
|
|||
|
||||
private fun loadSources(context: Context, file: File, className: String): List<NovelInterface> {
|
||||
return try {
|
||||
Log.e("NovelExtensionLoader", "isFileWritable: ${file.canWrite()}")
|
||||
Logger.log("isFileWritable: ${file.canWrite()}")
|
||||
if (file.canWrite()) {
|
||||
val a = file.setWritable(false)
|
||||
Log.e("NovelExtensionLoader", "success: $a")
|
||||
Logger.log("success: $a")
|
||||
}
|
||||
Log.e("NovelExtensionLoader", "isFileWritable: ${file.canWrite()}")
|
||||
Logger.log("isFileWritable: ${file.canWrite()}")
|
||||
val classLoader = PathClassLoader(file.absolutePath, null, context.classLoader)
|
||||
val className =
|
||||
"some.random.novelextensions.${className.lowercase(Locale.getDefault())}.$className"
|
||||
|
|
|
@ -2,7 +2,7 @@ package ani.dantotsu.parsers.novel
|
|||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.snackString
|
||||
import eu.kanade.tachiyomi.extension.InstallStep
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
@ -70,7 +70,7 @@ class NovelExtensionManager(private val context: Context) {
|
|||
val extensions: List<NovelExtension.Available> = try {
|
||||
api.findExtensions()
|
||||
} catch (e: Exception) {
|
||||
logger("Error finding extensions: ${e.message}")
|
||||
Logger.log("Error finding extensions: ${e.message}")
|
||||
withUIContext { snackString("Failed to get Novel extensions list") }
|
||||
emptyList()
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import ani.dantotsu.connections.anilist.Anilist
|
|||
import ani.dantotsu.connections.anilist.AnilistQueries
|
||||
import ani.dantotsu.connections.anilist.api.Activity
|
||||
import ani.dantotsu.databinding.FragmentFeedBinding
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.profile.ProfileActivity
|
||||
import ani.dantotsu.snackString
|
||||
import com.xwray.groupie.GroupieAdapter
|
||||
|
|
|
@ -25,7 +25,7 @@ import androidx.viewpager2.widget.ViewPager2
|
|||
import ani.dantotsu.R
|
||||
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
|
||||
import ani.dantotsu.databinding.FragmentAnimeExtensionsBinding
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.others.LanguageMapper
|
||||
import ani.dantotsu.parsers.AnimeSources
|
||||
import ani.dantotsu.settings.extensionprefs.AnimeSourcePreferencesFragment
|
||||
|
@ -146,7 +146,7 @@ class InstalledAnimeExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
},
|
||||
{ error ->
|
||||
Injekt.get<CrashlyticsInterface>().logException(error)
|
||||
Log.e("AnimeExtensionsAdapter", "Error: ", error) // Log the error
|
||||
Logger.log(error) // Log the error
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_ERROR
|
||||
|
|
|
@ -32,6 +32,7 @@ import ani.dantotsu.settings.extensionprefs.MangaSourcePreferencesFragment
|
|||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
|
@ -143,7 +144,7 @@ class InstalledMangaExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
},
|
||||
{ error ->
|
||||
Injekt.get<CrashlyticsInterface>().logException(error)
|
||||
Log.e("MangaExtensionsAdapter", "Error: ", error) // Log the error
|
||||
Logger.log(error) // Log the error
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_ERROR
|
||||
|
|
|
@ -30,6 +30,7 @@ import ani.dantotsu.parsers.novel.NovelExtensionManager
|
|||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import kotlinx.coroutines.launch
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
|
@ -72,7 +73,7 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
},
|
||||
{ error ->
|
||||
Injekt.get<CrashlyticsInterface>().logException(error)
|
||||
Log.e("NovelExtensionsAdapter", "Error: ", error) // Log the error
|
||||
Logger.log(error) // Log the error
|
||||
val builder = NotificationCompat.Builder(
|
||||
context,
|
||||
Notifications.CHANNEL_DOWNLOADER_ERROR
|
||||
|
@ -216,7 +217,7 @@ class InstalledNovelExtensionsFragment : Fragment(), SearchQueryHandler {
|
|||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_extension, parent, false)
|
||||
Log.d("NovelExtensionsAdapter", "onCreateViewHolder: $view")
|
||||
Logger.log("onCreateViewHolder: $view")
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ class NovelExtensionsFragment : Fragment(),
|
|||
|
||||
lifecycleScope.launch {
|
||||
viewModel.pagerFlow.collectLatest { pagingData ->
|
||||
Log.d("NovelExtensionsFragment", "collectLatest")
|
||||
adapter.submitData(pagingData)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ import ani.dantotsu.download.video.ExoplayerDownloadService
|
|||
import ani.dantotsu.downloadsPermission
|
||||
import ani.dantotsu.initActivity
|
||||
import ani.dantotsu.loadImage
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.openLinkInBrowser
|
||||
import ani.dantotsu.others.AppUpdater
|
||||
|
@ -730,6 +730,16 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
|
|||
binding.settingsShareUsername.isChecked = false
|
||||
}
|
||||
|
||||
binding.settingsLogToFile.isChecked = PrefManager.getVal(PrefName.LogToFile)
|
||||
binding.settingsLogToFile.setOnCheckedChangeListener { _, isChecked ->
|
||||
PrefManager.setVal(PrefName.LogToFile, isChecked)
|
||||
restartApp()
|
||||
}
|
||||
|
||||
binding.settingsShareLog.setOnClickListener {
|
||||
Logger.shareLog(this)
|
||||
}
|
||||
|
||||
binding.settingsAccountHelp.setOnClickListener {
|
||||
val title = getString(R.string.account_help)
|
||||
val full = getString(R.string.full_account_help)
|
||||
|
@ -884,7 +894,7 @@ class SettingsActivity : AppCompatActivity(), SimpleDialog.OnDialogResultListene
|
|||
if (dialogTag == "colorPicker") {
|
||||
val color = extras.getInt(SimpleColorDialog.COLOR)
|
||||
PrefManager.setVal(PrefName.CustomThemeInt, color)
|
||||
logger("Custom Theme: $color")
|
||||
Logger.log("Custom Theme: $color")
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
|
|
@ -61,11 +61,7 @@ class AnimeSourcePreferencesFragment : PreferenceFragmentCompat() {
|
|||
pref.isIconSpaceReserved = false
|
||||
if (pref is DialogPreference) {
|
||||
pref.dialogTitle = pref.title
|
||||
//println("pref.dialogTitle: ${pref.dialogTitle}") //TODO: could be useful for dub/sub selection
|
||||
}
|
||||
/*for (entry in sharedPreferences.all.entries) {
|
||||
Log.d("Preferences", "Key: ${entry.key}, Value: ${entry.value}")
|
||||
}*/
|
||||
|
||||
// Apply incognito IME for EditTextPreference
|
||||
if (pref is EditTextPreference) {
|
||||
|
|
|
@ -159,6 +159,7 @@ enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
|
|||
FirstComment(Pref(Location.Irrelevant, Boolean::class, true)),
|
||||
CommentAuthResponse(Pref(Location.Irrelevant, AuthResponse::class, "")),
|
||||
CommentTokenExpiry(Pref(Location.Irrelevant, Long::class, 0L)),
|
||||
LogToFile(Pref(Location.Irrelevant, Boolean::class, false)),
|
||||
|
||||
//Protected
|
||||
DiscordToken(Pref(Location.Protected, String::class, "")),
|
||||
|
|
|
@ -7,7 +7,7 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.isOnline
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.subcriptions.Subscription.Companion.defaultTime
|
||||
|
@ -22,7 +22,7 @@ class AlarmReceiver : BroadcastReceiver() {
|
|||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
when (intent?.action) {
|
||||
Intent.ACTION_BOOT_COMPLETED -> tryWith(true) {
|
||||
logger("Starting Dantotsu Subscription Service on Boot")
|
||||
Logger.log("Starting Dantotsu Subscription Service on Boot")
|
||||
context?.startSubscription()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import ani.dantotsu.parsers.Episode
|
|||
import ani.dantotsu.parsers.MangaChapter
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.util.Logger
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
|
@ -27,7 +28,7 @@ class Subscription {
|
|||
alreadyStarted = true
|
||||
SubscriptionWorker.enqueue(this)
|
||||
AlarmReceiver.alarm(this)
|
||||
} else logger("Already Subscribed")
|
||||
} else Logger.log("Already Subscribed")
|
||||
}
|
||||
|
||||
private var currentlyPerforming = false
|
||||
|
|
146
app/src/main/java/ani/dantotsu/util/Logger.kt
Normal file
146
app/src/main/java/ani/dantotsu/util/Logger.kt
Normal file
|
@ -0,0 +1,146 @@
|
|||
package ani.dantotsu.util
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.content.FileProvider
|
||||
import ani.dantotsu.BuildConfig
|
||||
import ani.dantotsu.connections.crashlytics.CrashlyticsInterface
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.snackString
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.File
|
||||
import java.util.Date
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
object Logger {
|
||||
var file: File? = null
|
||||
private val loggerExecutor = Executors.newSingleThreadExecutor()
|
||||
|
||||
fun init(context: Context) {
|
||||
try {
|
||||
if (!PrefManager.getVal<Boolean>(PrefName.LogToFile) || file != null) return
|
||||
file = File(context.getExternalFilesDir(null), "log.txt")
|
||||
if (file?.exists() == true) {
|
||||
val oldFile = File(context.getExternalFilesDir(null), "old_log.txt")
|
||||
file?.copyTo(oldFile, true)
|
||||
} else {
|
||||
file?.createNewFile()
|
||||
}
|
||||
file?.writeText("log started\n")
|
||||
file?.appendText("date/time: ${Date()}\n")
|
||||
file?.appendText("device: ${android.os.Build.MODEL}\n")
|
||||
file?.appendText("os version: ${android.os.Build.VERSION.RELEASE}\n")
|
||||
file?.appendText(
|
||||
"app version: ${
|
||||
context.packageManager.getPackageInfo(
|
||||
context.packageName,
|
||||
0
|
||||
).versionName
|
||||
}\n"
|
||||
)
|
||||
file?.appendText(
|
||||
"app version code: ${
|
||||
context.packageManager.getPackageInfo(
|
||||
context.packageName,
|
||||
0
|
||||
).versionCode
|
||||
}\n"
|
||||
)
|
||||
file?.appendText("sdk version: ${android.os.Build.VERSION.SDK_INT}\n")
|
||||
file?.appendText("manufacturer: ${android.os.Build.MANUFACTURER}\n")
|
||||
file?.appendText("brand: ${android.os.Build.BRAND}\n")
|
||||
file?.appendText("product: ${android.os.Build.PRODUCT}\n")
|
||||
file?.appendText("device: ${android.os.Build.DEVICE}\n")
|
||||
file?.appendText("hardware: ${android.os.Build.HARDWARE}\n")
|
||||
file?.appendText("host: ${android.os.Build.HOST}\n")
|
||||
file?.appendText("id: ${android.os.Build.ID}\n")
|
||||
file?.appendText("type: ${android.os.Build.TYPE}\n")
|
||||
file?.appendText("user: ${android.os.Build.USER}\n")
|
||||
file?.appendText("tags: ${android.os.Build.TAGS}\n")
|
||||
file?.appendText("time: ${android.os.Build.TIME}\n")
|
||||
file?.appendText("radio: ${android.os.Build.RADIO}\n")
|
||||
file?.appendText("bootloader: ${android.os.Build.BOOTLOADER}\n")
|
||||
file?.appendText("board: ${android.os.Build.BOARD}\n")
|
||||
file?.appendText("fingerprint: ${android.os.Build.FINGERPRINT}\n")
|
||||
file?.appendText("supported_abis: ${android.os.Build.SUPPORTED_ABIS.joinToString()}\n")
|
||||
file?.appendText("supported_32_bit_abis: ${android.os.Build.SUPPORTED_32_BIT_ABIS.joinToString()}\n")
|
||||
file?.appendText("supported_64_bit_abis: ${android.os.Build.SUPPORTED_64_BIT_ABIS.joinToString()}\n")
|
||||
file?.appendText("is emulator: ${android.os.Build.FINGERPRINT.contains("generic")}\n")
|
||||
file?.appendText("--------------------------------\n")
|
||||
} catch (e: Exception) {
|
||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||
file = null
|
||||
}
|
||||
}
|
||||
|
||||
fun log(message: String) {
|
||||
val trace = Thread.currentThread().stackTrace[3]
|
||||
loggerExecutor.execute {
|
||||
if (file == null) println(message)
|
||||
else {
|
||||
val className = trace.className
|
||||
val methodName = trace.methodName
|
||||
val lineNumber = trace.lineNumber
|
||||
file?.appendText("date/time: ${Date()} | $className.$methodName($lineNumber)\n")
|
||||
file?.appendText("message: $message\n-\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun log(e: Exception) {
|
||||
loggerExecutor.execute {
|
||||
if (file == null) e.printStackTrace() else {
|
||||
file?.appendText("---------------------------Exception---------------------------\n")
|
||||
file?.appendText("date/time: ${Date()} | ${e.message}\n")
|
||||
file?.appendText("trace: ${e.stackTrace}\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun log(e: Throwable) {
|
||||
loggerExecutor.execute {
|
||||
if (file == null) e.printStackTrace() else {
|
||||
file?.appendText("---------------------------Exception---------------------------\n")
|
||||
file?.appendText("date/time: ${Date()} | ${e.message}\n")
|
||||
file?.appendText("trace: ${e.stackTrace}\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun shareLog(context: Context) {
|
||||
if (file == null) {
|
||||
snackString("No log file found")
|
||||
return
|
||||
}
|
||||
val oldFile = File(context.getExternalFilesDir(null), "old_log.txt")
|
||||
val fileToUse = if (oldFile.exists()) {
|
||||
file?.readText()?.let { oldFile.appendText(it) }
|
||||
oldFile
|
||||
} else {
|
||||
file
|
||||
}
|
||||
val shareIntent = Intent(Intent.ACTION_SEND)
|
||||
shareIntent.type = "text/plain"
|
||||
shareIntent.putExtra(
|
||||
Intent.EXTRA_STREAM,
|
||||
FileProvider.getUriForFile(context, "${BuildConfig.APPLICATION_ID}.provider", fileToUse!!)
|
||||
)
|
||||
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Log file")
|
||||
shareIntent.putExtra(Intent.EXTRA_TEXT, "Log file")
|
||||
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
context.startActivity(Intent.createChooser(shareIntent, "Share log file"))
|
||||
}
|
||||
}
|
||||
|
||||
class FinalExceptionHandler : Thread.UncaughtExceptionHandler {
|
||||
private val defaultUEH: Thread.UncaughtExceptionHandler? =
|
||||
Thread.getDefaultUncaughtExceptionHandler()
|
||||
|
||||
override fun uncaughtException(t: Thread, e: Throwable) {
|
||||
Logger.log(e)
|
||||
Injekt.get<CrashlyticsInterface>().logException(e)
|
||||
defaultUEH?.uncaughtException(t, e)
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ import android.graphics.BitmapFactory
|
|||
import android.widget.RemoteViews
|
||||
import android.widget.RemoteViewsService
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
import java.io.InputStream
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
|
@ -19,7 +19,7 @@ class CurrentlyAiringRemoteViewsFactory(private val context: Context, intent: In
|
|||
override fun onCreate() {
|
||||
// 4 items for testing
|
||||
widgetItems.clear()
|
||||
logger("CurrentlyAiringRemoteViewsFactory onCreate")
|
||||
Logger.log("CurrentlyAiringRemoteViewsFactory onCreate")
|
||||
widgetItems = List(4) {
|
||||
WidgetItem(
|
||||
"Show $it",
|
||||
|
@ -31,7 +31,7 @@ class CurrentlyAiringRemoteViewsFactory(private val context: Context, intent: In
|
|||
|
||||
override fun onDataSetChanged() {
|
||||
// 4 items for testing
|
||||
logger("CurrentlyAiringRemoteViewsFactory onDataSetChanged")
|
||||
Logger.log("CurrentlyAiringRemoteViewsFactory onDataSetChanged")
|
||||
widgetItems.clear()
|
||||
widgetItems.add(
|
||||
WidgetItem(
|
||||
|
@ -79,7 +79,7 @@ class CurrentlyAiringRemoteViewsFactory(private val context: Context, intent: In
|
|||
}
|
||||
|
||||
override fun getViewAt(position: Int): RemoteViews {
|
||||
logger("CurrentlyAiringRemoteViewsFactory getViewAt")
|
||||
Logger.log("CurrentlyAiringRemoteViewsFactory getViewAt")
|
||||
val item = widgetItems[position]
|
||||
val rv = RemoteViews(context.packageName, R.layout.item_currently_airing_widget).apply {
|
||||
setTextViewText(R.id.text_show_title, item.title)
|
||||
|
|
|
@ -2,11 +2,11 @@ package ani.dantotsu.widgets
|
|||
|
||||
import android.content.Intent
|
||||
import android.widget.RemoteViewsService
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.util.Logger
|
||||
|
||||
class CurrentlyAiringRemoteViewsService : RemoteViewsService() {
|
||||
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
|
||||
logger("CurrentlyAiringRemoteViewsFactory onGetViewFactory")
|
||||
Logger.log("CurrentlyAiringRemoteViewsFactory onGetViewFactory")
|
||||
return CurrentlyAiringRemoteViewsFactory(applicationContext, intent)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.extension.anime
|
|||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.tachiyomi.extension.InstallStep
|
||||
import eu.kanade.tachiyomi.extension.anime.api.AnimeExtensionGithubApi
|
||||
|
@ -16,11 +17,9 @@ import eu.kanade.tachiyomi.util.preference.plusAssign
|
|||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import logcat.LogPriority
|
||||
import rx.Observable
|
||||
import tachiyomi.core.util.lang.launchNow
|
||||
import tachiyomi.core.util.lang.withUIContext
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import tachiyomi.domain.source.anime.model.AnimeSourceData
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
@ -120,7 +119,7 @@ class AnimeExtensionManager(
|
|||
val extensions: List<AnimeExtension.Available> = try {
|
||||
api.findExtensions()
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
Logger.log(e)
|
||||
withUIContext { snackString("Failed to get extensions list") }
|
||||
emptyList()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package eu.kanade.tachiyomi.extension.anime.api
|
||||
|
||||
import android.content.Context
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.tachiyomi.extension.ExtensionUpdateNotifier
|
||||
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||
|
@ -13,11 +14,9 @@ import eu.kanade.tachiyomi.network.awaitSuccess
|
|||
import eu.kanade.tachiyomi.network.parseAs
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.preference.Preference
|
||||
import tachiyomi.core.preference.PreferenceStore
|
||||
import tachiyomi.core.util.lang.withIOContext
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.Date
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
@ -45,7 +44,7 @@ internal class AnimeExtensionGithubApi {
|
|||
.newCall(GET("${REPO_URL_PREFIX}index.min.json"))
|
||||
.awaitSuccess()
|
||||
} catch (e: Throwable) {
|
||||
logcat(LogPriority.ERROR, e) { "Failed to get extensions from GitHub" }
|
||||
Logger.log("Failed to get extensions from GitHub")
|
||||
requiresFallbackSource = true
|
||||
null
|
||||
}
|
||||
|
|
|
@ -10,12 +10,11 @@ import android.content.pm.PackageInstaller
|
|||
import android.os.Build
|
||||
import androidx.core.content.ContextCompat
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.tachiyomi.extension.InstallStep
|
||||
import eu.kanade.tachiyomi.util.lang.use
|
||||
import eu.kanade.tachiyomi.util.system.getParcelableExtraCompat
|
||||
import eu.kanade.tachiyomi.util.system.getUriSize
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.system.logcat
|
||||
|
||||
class PackageInstallerInstallerAnime(private val service: Service) : InstallerAnime(service) {
|
||||
|
||||
|
@ -30,7 +29,7 @@ class PackageInstallerInstallerAnime(private val service: Service) : InstallerAn
|
|||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
val userAction = intent.getParcelableExtraCompat<Intent>(Intent.EXTRA_INTENT)
|
||||
if (userAction == null) {
|
||||
logcat(LogPriority.ERROR) { "Fatal error for $intent" }
|
||||
Logger.log("Fatal error for $intent")
|
||||
continueQueue(InstallStep.Error)
|
||||
return
|
||||
}
|
||||
|
@ -89,11 +88,8 @@ class PackageInstallerInstallerAnime(private val service: Service) : InstallerAn
|
|||
session.commit(intentSender)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logcat(
|
||||
LogPriority.ERROR,
|
||||
e
|
||||
) { "Failed to install extension ${entry.downloadId} ${entry.uri}" }
|
||||
logcat(LogPriority.ERROR) { "Exception: $e" }
|
||||
Logger.log(e)
|
||||
Logger.log("Failed to install extension ${entry.downloadId} ${entry.uri}")
|
||||
snackString("Failed to install extension ${entry.downloadId} ${entry.uri}")
|
||||
activeSession?.let { (_, sessionId) ->
|
||||
packageInstaller.abandonSession(sessionId)
|
||||
|
|
|
@ -5,15 +5,14 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import androidx.core.content.ContextCompat
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||
import eu.kanade.tachiyomi.extension.anime.model.AnimeLoadResult
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.async
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.lang.launchNow
|
||||
import tachiyomi.core.util.system.logcat
|
||||
|
||||
/**
|
||||
* Broadcast receiver that listens for the system's packages installed, updated or removed, and only
|
||||
|
@ -103,7 +102,7 @@ internal class AnimeExtensionInstallReceiver(private val listener: Listener) :
|
|||
private suspend fun getExtensionFromIntent(context: Context, intent: Intent?): AnimeLoadResult {
|
||||
val pkgName = getPackageNameFromIntent(intent)
|
||||
if (pkgName == null) {
|
||||
logcat(LogPriority.WARN) { "Package name not found" }
|
||||
Logger.log("Package name not found")
|
||||
return AnimeLoadResult.Error
|
||||
}
|
||||
return GlobalScope.async(Dispatchers.Default, CoroutineStart.DEFAULT) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.net.Uri
|
|||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.extension.anime.installer.InstallerAnime
|
||||
|
@ -15,8 +16,6 @@ import eu.kanade.tachiyomi.extension.anime.installer.PackageInstallerInstallerAn
|
|||
import eu.kanade.tachiyomi.extension.anime.util.AnimeExtensionInstaller.Companion.EXTRA_DOWNLOAD_ID
|
||||
import eu.kanade.tachiyomi.util.system.getSerializableExtraCompat
|
||||
import eu.kanade.tachiyomi.util.system.notificationBuilder
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.system.logcat
|
||||
|
||||
class AnimeExtensionInstallService : Service() {
|
||||
|
||||
|
@ -60,7 +59,7 @@ class AnimeExtensionInstallService : Service() {
|
|||
)
|
||||
|
||||
else -> {
|
||||
logcat(LogPriority.ERROR) { "Not implemented for installer $installerUsed" }
|
||||
Logger.log("Not implemented for installer $installerUsed")
|
||||
stopSelf()
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
|
|
@ -10,16 +10,15 @@ import android.os.Environment
|
|||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.net.toUri
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.jakewharton.rxrelay.PublishRelay
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.tachiyomi.extension.InstallStep
|
||||
import eu.kanade.tachiyomi.extension.anime.installer.InstallerAnime
|
||||
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import logcat.LogPriority
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.File
|
||||
|
@ -248,7 +247,7 @@ internal class AnimeExtensionInstaller(private val context: Context) {
|
|||
|
||||
// Set next installation step
|
||||
if (uri == null) {
|
||||
logcat(LogPriority.ERROR) { "Couldn't locate downloaded APK" }
|
||||
Logger.log("Couldn't locate downloaded APK")
|
||||
downloadsRelay.call(id to InstallStep.Error)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.content.pm.PackageInfo
|
|||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import androidx.core.content.pm.PackageInfoCompat
|
||||
import ani.dantotsu.util.Logger
|
||||
import dalvik.system.PathClassLoader
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||
|
@ -17,8 +18,6 @@ import eu.kanade.tachiyomi.util.lang.Hash
|
|||
import eu.kanade.tachiyomi.util.system.getApplicationIcon
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
/**
|
||||
|
@ -91,11 +90,11 @@ internal object AnimeExtensionLoader {
|
|||
context.packageManager.getPackageInfo(pkgName, PACKAGE_FLAGS)
|
||||
} catch (error: PackageManager.NameNotFoundException) {
|
||||
// Unlikely, but the package may have been uninstalled at this point
|
||||
logcat(LogPriority.ERROR, error)
|
||||
Logger.log(error)
|
||||
return AnimeLoadResult.Error
|
||||
}
|
||||
if (!isPackageAnExtension(pkgInfo)) {
|
||||
logcat(LogPriority.WARN) { "Tried to load a package that wasn't a extension ($pkgName)" }
|
||||
Logger.log("Tried to load a package that wasn't a extension ($pkgName)")
|
||||
return AnimeLoadResult.Error
|
||||
}
|
||||
return loadExtension(context, pkgName, pkgInfo)
|
||||
|
@ -119,7 +118,7 @@ internal object AnimeExtensionLoader {
|
|||
pkgManager.getApplicationInfo(pkgName, PackageManager.GET_META_DATA)
|
||||
} catch (error: PackageManager.NameNotFoundException) {
|
||||
// Unlikely, but the package may have been uninstalled at this point
|
||||
logcat(LogPriority.ERROR, error)
|
||||
Logger.log(error)
|
||||
return AnimeLoadResult.Error
|
||||
}
|
||||
|
||||
|
@ -128,24 +127,23 @@ internal object AnimeExtensionLoader {
|
|||
val versionCode = PackageInfoCompat.getLongVersionCode(pkgInfo)
|
||||
|
||||
if (versionName.isNullOrEmpty()) {
|
||||
logcat(LogPriority.WARN) { "Missing versionName for extension $extName" }
|
||||
Logger.log("Missing versionName for extension $extName")
|
||||
return AnimeLoadResult.Error
|
||||
}
|
||||
|
||||
// Validate lib version
|
||||
val libVersion = versionName.substringBeforeLast('.').toDoubleOrNull()
|
||||
if (libVersion == null || libVersion < LIB_VERSION_MIN || libVersion > LIB_VERSION_MAX) {
|
||||
logcat(LogPriority.WARN) {
|
||||
"Lib version is $libVersion, while only versions " +
|
||||
Logger.log("Lib version is $libVersion, while only versions " +
|
||||
"$LIB_VERSION_MIN to $LIB_VERSION_MAX are allowed"
|
||||
}
|
||||
)
|
||||
return AnimeLoadResult.Error
|
||||
}
|
||||
|
||||
val signatureHash = getSignatureHash(pkgInfo)
|
||||
|
||||
if (signatureHash == null) {
|
||||
logcat(LogPriority.WARN) { "Package $pkgName isn't signed" }
|
||||
Logger.log("Package $pkgName isn't signed")
|
||||
return AnimeLoadResult.Error
|
||||
} else if (signatureHash !in trustedSignatures) {
|
||||
val extension = AnimeExtension.Untrusted(
|
||||
|
@ -156,13 +154,13 @@ internal object AnimeExtensionLoader {
|
|||
libVersion,
|
||||
signatureHash
|
||||
)
|
||||
logcat(LogPriority.WARN, message = { "Extension $pkgName isn't trusted" })
|
||||
Logger.log("Extension $pkgName isn't trusted")
|
||||
return AnimeLoadResult.Untrusted(extension)
|
||||
}
|
||||
|
||||
val isNsfw = appInfo.metaData.getInt(METADATA_NSFW) == 1
|
||||
if (!loadNsfwSource && isNsfw) {
|
||||
logcat(LogPriority.WARN) { "NSFW extension $pkgName not allowed" }
|
||||
Logger.log("NSFW extension $pkgName not allowed")
|
||||
return AnimeLoadResult.Error
|
||||
}
|
||||
|
||||
|
@ -189,7 +187,7 @@ internal object AnimeExtensionLoader {
|
|||
else -> throw Exception("Unknown source class type! ${obj.javaClass}")
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
logcat(LogPriority.ERROR, e) { "Extension load error: $extName ($it)" }
|
||||
Logger.log("Extension load error: $extName ($it)")
|
||||
return AnimeLoadResult.Error
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.extension.manga
|
|||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.tachiyomi.extension.InstallStep
|
||||
import eu.kanade.tachiyomi.extension.manga.api.MangaExtensionGithubApi
|
||||
|
@ -16,11 +17,9 @@ import eu.kanade.tachiyomi.util.preference.plusAssign
|
|||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import logcat.LogPriority
|
||||
import rx.Observable
|
||||
import tachiyomi.core.util.lang.launchNow
|
||||
import tachiyomi.core.util.lang.withUIContext
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import tachiyomi.domain.source.manga.model.MangaSourceData
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
@ -117,7 +116,7 @@ class MangaExtensionManager(
|
|||
val extensions: List<MangaExtension.Available> = try {
|
||||
api.findExtensions()
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
Logger.log(e)
|
||||
withUIContext { snackString("Failed to get manga extensions") }
|
||||
emptyList()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package eu.kanade.tachiyomi.extension.manga.api
|
||||
|
||||
import android.content.Context
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.tachiyomi.extension.ExtensionUpdateNotifier
|
||||
import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.manga.model.AvailableMangaSources
|
||||
|
@ -13,11 +14,9 @@ import eu.kanade.tachiyomi.network.awaitSuccess
|
|||
import eu.kanade.tachiyomi.network.parseAs
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.preference.Preference
|
||||
import tachiyomi.core.preference.PreferenceStore
|
||||
import tachiyomi.core.util.lang.withIOContext
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.Date
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
@ -45,7 +44,7 @@ internal class MangaExtensionGithubApi {
|
|||
.newCall(GET("${REPO_URL_PREFIX}index.min.json"))
|
||||
.awaitSuccess()
|
||||
} catch (e: Throwable) {
|
||||
logcat(LogPriority.ERROR, e) { "Failed to get extensions from GitHub" }
|
||||
Logger.log("Failed to get extensions from GitHub")
|
||||
requiresFallbackSource = true
|
||||
null
|
||||
}
|
||||
|
|
|
@ -10,12 +10,11 @@ import android.content.pm.PackageInstaller
|
|||
import android.os.Build
|
||||
import androidx.core.content.ContextCompat
|
||||
import ani.dantotsu.snackString
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.tachiyomi.extension.InstallStep
|
||||
import eu.kanade.tachiyomi.util.lang.use
|
||||
import eu.kanade.tachiyomi.util.system.getParcelableExtraCompat
|
||||
import eu.kanade.tachiyomi.util.system.getUriSize
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.system.logcat
|
||||
|
||||
class PackageInstallerInstallerManga(private val service: Service) : InstallerManga(service) {
|
||||
|
||||
|
@ -30,7 +29,7 @@ class PackageInstallerInstallerManga(private val service: Service) : InstallerMa
|
|||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
val userAction = intent.getParcelableExtraCompat<Intent>(Intent.EXTRA_INTENT)
|
||||
if (userAction == null) {
|
||||
logcat(LogPriority.ERROR) { "Fatal error for $intent" }
|
||||
Logger.log("Fatal error for $intent")
|
||||
continueQueue(InstallStep.Error)
|
||||
return
|
||||
}
|
||||
|
@ -89,8 +88,8 @@ class PackageInstallerInstallerManga(private val service: Service) : InstallerMa
|
|||
session.commit(intentSender)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR) { "Failed to install extension ${entry.downloadId} ${entry.uri}" }
|
||||
logcat(LogPriority.ERROR) { "Exception: $e" }
|
||||
Logger.log("Failed to install extension ${entry.downloadId} ${entry.uri}")
|
||||
Logger.log(e)
|
||||
snackString("Failed to install extension ${entry.downloadId} ${entry.uri}")
|
||||
activeSession?.let { (_, sessionId) ->
|
||||
packageInstaller.abandonSession(sessionId)
|
||||
|
|
|
@ -5,15 +5,14 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import androidx.core.content.ContextCompat
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
||||
import eu.kanade.tachiyomi.extension.manga.model.MangaLoadResult
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.async
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.lang.launchNow
|
||||
import tachiyomi.core.util.system.logcat
|
||||
|
||||
/**
|
||||
* Broadcast receiver that listens for the system's packages installed, updated or removed, and only
|
||||
|
@ -103,7 +102,7 @@ internal class MangaExtensionInstallReceiver(private val listener: Listener) :
|
|||
private suspend fun getExtensionFromIntent(context: Context, intent: Intent?): MangaLoadResult {
|
||||
val pkgName = getPackageNameFromIntent(intent)
|
||||
if (pkgName == null) {
|
||||
logcat(LogPriority.WARN) { "Package name not found" }
|
||||
Logger.log("Package name not found")
|
||||
return MangaLoadResult.Error
|
||||
}
|
||||
return GlobalScope.async(Dispatchers.Default, CoroutineStart.DEFAULT) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.net.Uri
|
|||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.util.Logger
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.extension.manga.installer.InstallerManga
|
||||
|
@ -15,8 +16,6 @@ import eu.kanade.tachiyomi.extension.manga.installer.PackageInstallerInstallerMa
|
|||
import eu.kanade.tachiyomi.extension.manga.util.MangaExtensionInstaller.Companion.EXTRA_DOWNLOAD_ID
|
||||
import eu.kanade.tachiyomi.util.system.getSerializableExtraCompat
|
||||
import eu.kanade.tachiyomi.util.system.notificationBuilder
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.system.logcat
|
||||
|
||||
class MangaExtensionInstallService : Service() {
|
||||
|
||||
|
@ -60,7 +59,7 @@ class MangaExtensionInstallService : Service() {
|
|||
)
|
||||
|
||||
else -> {
|
||||
logcat(LogPriority.ERROR) { "Not implemented for installer $installerUsed" }
|
||||
Logger.log("Not implemented for installer $installerUsed")
|
||||
stopSelf()
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
|
|
@ -10,16 +10,15 @@ import android.os.Environment
|
|||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.net.toUri
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.jakewharton.rxrelay.PublishRelay
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.tachiyomi.extension.InstallStep
|
||||
import eu.kanade.tachiyomi.extension.manga.installer.InstallerManga
|
||||
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||
import logcat.LogPriority
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.File
|
||||
|
@ -245,7 +244,7 @@ internal class MangaExtensionInstaller(private val context: Context) {
|
|||
|
||||
// Set next installation step
|
||||
if (uri == null) {
|
||||
logcat(LogPriority.ERROR) { "Couldn't locate downloaded APK" }
|
||||
Logger.log("Couldn't locate downloaded APK")
|
||||
downloadsRelay.call(id to InstallStep.Error)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.content.pm.PackageInfo
|
|||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import androidx.core.content.pm.PackageInfoCompat
|
||||
import ani.dantotsu.util.Logger
|
||||
import dalvik.system.PathClassLoader
|
||||
import eu.kanade.domain.source.service.SourcePreferences
|
||||
import eu.kanade.tachiyomi.extension.manga.model.MangaExtension
|
||||
|
@ -17,8 +18,6 @@ import eu.kanade.tachiyomi.util.lang.Hash
|
|||
import eu.kanade.tachiyomi.util.system.getApplicationIcon
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
/**
|
||||
|
@ -91,11 +90,11 @@ internal object MangaExtensionLoader {
|
|||
context.packageManager.getPackageInfo(pkgName, PACKAGE_FLAGS)
|
||||
} catch (error: PackageManager.NameNotFoundException) {
|
||||
// Unlikely, but the package may have been uninstalled at this point
|
||||
logcat(LogPriority.ERROR, error)
|
||||
Logger.log(error)
|
||||
return MangaLoadResult.Error
|
||||
}
|
||||
if (!isPackageAnExtension(pkgInfo)) {
|
||||
logcat(LogPriority.WARN) { "Tried to load a package that wasn't a extension ($pkgName)" }
|
||||
Logger.log("Tried to load a package that wasn't a extension ($pkgName)")
|
||||
return MangaLoadResult.Error
|
||||
}
|
||||
return loadMangaExtension(context, pkgName, pkgInfo)
|
||||
|
@ -119,7 +118,7 @@ internal object MangaExtensionLoader {
|
|||
pkgManager.getApplicationInfo(pkgName, PackageManager.GET_META_DATA)
|
||||
} catch (error: PackageManager.NameNotFoundException) {
|
||||
// Unlikely, but the package may have been uninstalled at this point
|
||||
logcat(LogPriority.ERROR, error)
|
||||
Logger.log(error)
|
||||
return MangaLoadResult.Error
|
||||
}
|
||||
|
||||
|
@ -129,17 +128,16 @@ internal object MangaExtensionLoader {
|
|||
val versionCode = PackageInfoCompat.getLongVersionCode(pkgInfo)
|
||||
|
||||
if (versionName.isNullOrEmpty()) {
|
||||
logcat(LogPriority.WARN) { "Missing versionName for extension $extName" }
|
||||
Logger.log("Missing versionName for extension $extName")
|
||||
return MangaLoadResult.Error
|
||||
}
|
||||
|
||||
// Validate lib version
|
||||
val libVersion = versionName.substringBeforeLast('.').toDoubleOrNull()
|
||||
if (libVersion == null || libVersion < LIB_VERSION_MIN || libVersion > LIB_VERSION_MAX) {
|
||||
logcat(LogPriority.WARN) {
|
||||
"Lib version is $libVersion, while only versions " +
|
||||
Logger.log("Lib version is $libVersion, while only versions " +
|
||||
"$LIB_VERSION_MIN to $LIB_VERSION_MAX are allowed"
|
||||
}
|
||||
)
|
||||
return MangaLoadResult.Error
|
||||
}
|
||||
|
||||
|
@ -147,18 +145,18 @@ internal object MangaExtensionLoader {
|
|||
|
||||
/* temporarily disabling signature check TODO: remove?
|
||||
if (signatureHash == null) {
|
||||
logcat(LogPriority.WARN) { "Package $pkgName isn't signed" }
|
||||
Logger.log("Package $pkgName isn't signed")
|
||||
return MangaLoadResult.Error
|
||||
} else if (signatureHash !in trustedSignatures) {
|
||||
val extension = MangaExtension.Untrusted(extName, pkgName, versionName, versionCode, libVersion, signatureHash)
|
||||
logcat(LogPriority.WARN) { "Extension $pkgName isn't trusted" }
|
||||
Logger.log("Extension $pkgName isn't trusted")
|
||||
return MangaLoadResult.Untrusted(extension)
|
||||
}
|
||||
*/
|
||||
|
||||
val isNsfw = appInfo.metaData.getInt(METADATA_NSFW) == 1
|
||||
if (!loadNsfwSource && isNsfw) {
|
||||
logcat(LogPriority.WARN) { "NSFW extension $pkgName not allowed" }
|
||||
Logger.log("NSFW extension $pkgName not allowed")
|
||||
return MangaLoadResult.Error
|
||||
}
|
||||
|
||||
|
@ -185,7 +183,7 @@ internal object MangaExtensionLoader {
|
|||
else -> throw Exception("Unknown source class type! ${obj.javaClass}")
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
logcat(LogPriority.ERROR, e) { "Extension load error: $extName ($it)" }
|
||||
Logger.log("Extension load error: $extName ($it)")
|
||||
return MangaLoadResult.Error
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,10 +21,9 @@ import androidx.core.graphics.blue
|
|||
import androidx.core.graphics.green
|
||||
import androidx.core.graphics.red
|
||||
import androidx.core.net.toUri
|
||||
import ani.dantotsu.util.Logger
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.util.lang.truncateCenter
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import java.io.File
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
|
@ -47,7 +46,7 @@ fun Context.copyToClipboard(label: String, content: String) {
|
|||
toast("Copied to clipboard: " + content.truncateCenter(50))
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
Logger.log(e)
|
||||
toast("Failed to copy to clipboard")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@ package eu.kanade.tachiyomi.util.system
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Build
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import ani.dantotsu.util.Logger
|
||||
|
||||
object DeviceUtil {
|
||||
|
||||
|
@ -72,7 +71,7 @@ object DeviceUtil {
|
|||
.getDeclaredMethod("get", String::class.java)
|
||||
.invoke(null, key) as String
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.WARN, e) { "Unable to use SystemProperties.get()" }
|
||||
Logger.log("Unable to use SystemProperties.get()")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,7 @@ import android.content.pm.PackageManager
|
|||
import android.webkit.CookieManager
|
||||
import android.webkit.WebSettings
|
||||
import android.webkit.WebView
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.util.system.logcat
|
||||
import ani.dantotsu.util.Logger
|
||||
|
||||
object WebViewUtil {
|
||||
const val SPOOF_PACKAGE_NAME = "org.chromium.chrome"
|
||||
|
@ -20,7 +19,7 @@ object WebViewUtil {
|
|||
// is not installed
|
||||
CookieManager.getInstance()
|
||||
} catch (e: Throwable) {
|
||||
logcat(LogPriority.ERROR, e)
|
||||
Logger.log(e)
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
@ -989,6 +989,52 @@
|
|||
app:showText="false"
|
||||
app:thumbTint="@color/button_switch_track" />
|
||||
|
||||
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
android:id="@+id/settingsLogToFile"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
android:drawableStart="@drawable/ic_round_edit_note_24"
|
||||
android:drawablePadding="16dp"
|
||||
android:elegantTextHeight="true"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:minHeight="64dp"
|
||||
android:text="@string/log_to_file"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="?attr/colorOnBackground"
|
||||
app:cornerRadius="0dp"
|
||||
app:drawableTint="?attr/colorPrimary"
|
||||
app:showText="false"
|
||||
app:thumbTint="@color/button_switch_track" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:alpha="0.58"
|
||||
android:fontFamily="@font/poppins_bold"
|
||||
android:text="@string/logging_warning" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/settingsShareLog"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:src="@drawable/ic_round_share_24"
|
||||
android:padding="16dp" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ani.dantotsu.others.Xpandable>
|
||||
|
||||
<ani.dantotsu.others.Xpandable
|
||||
|
|
|
@ -692,5 +692,7 @@ Et magni quasi vel nemo omnis et voluptate quisquam vel corporis fuga ut consequ
|
|||
|
||||
Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exercitationem adipisci quo nemo aliquam ea numquam beatae. Eum Quis dolore aut quia accusantium sed vero autem vel quaerat eaque et beatae dicta non delectus galisum non ullam nulla.
|
||||
</string>
|
||||
<string name="log_to_file">Log to File</string>
|
||||
<string name="logging_warning">Logging to a file will slow down the app. Only enable if you are experiencing issues.</string>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue