mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-24 13:31:51 +01:00
Turned on kt lint
This commit is contained in:
parent
cc28ff7a77
commit
da786bbc40
@ -8,7 +8,7 @@ plugins {
|
|||||||
kotlin("android")
|
kotlin("android")
|
||||||
kotlin("android.extensions")
|
kotlin("android.extensions")
|
||||||
kotlin("kapt")
|
kotlin("kapt")
|
||||||
//id("org.jmailen.kotlinter") version "2.3.1"
|
id("org.jmailen.kotlinter") version "2.3.1"
|
||||||
id("com.github.zellius.shortcut-helper")
|
id("com.github.zellius.shortcut-helper")
|
||||||
id("com.google.gms.google-services") apply false
|
id("com.google.gms.google-services") apply false
|
||||||
}
|
}
|
||||||
@ -114,9 +114,9 @@ dependencies {
|
|||||||
|
|
||||||
implementation("com.google.firebase:firebase-core:17.2.3")
|
implementation("com.google.firebase:firebase-core:17.2.3")
|
||||||
|
|
||||||
val lifecycle_version = "2.1.0"
|
val lifecycleVersion = "2.1.0"
|
||||||
implementation("androidx.lifecycle:lifecycle-extensions:$lifecycle_version")
|
implementation("androidx.lifecycle:lifecycle-extensions:$lifecycleVersion")
|
||||||
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycle_version")
|
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion")
|
||||||
|
|
||||||
// ReactiveX
|
// ReactiveX
|
||||||
implementation("io.reactivex:rxandroid:1.2.1")
|
implementation("io.reactivex:rxandroid:1.2.1")
|
||||||
@ -126,15 +126,15 @@ dependencies {
|
|||||||
implementation("com.github.pwittchen:reactivenetwork:0.13.0")
|
implementation("com.github.pwittchen:reactivenetwork:0.13.0")
|
||||||
|
|
||||||
// Network client
|
// Network client
|
||||||
val okhttp_version = "4.3.1"
|
val okhttpVersion = "4.3.1"
|
||||||
implementation("com.squareup.okhttp3:okhttp:$okhttp_version")
|
implementation("com.squareup.okhttp3:okhttp:$okhttpVersion")
|
||||||
implementation("com.squareup.okhttp3:logging-interceptor:$okhttp_version")
|
implementation("com.squareup.okhttp3:logging-interceptor:$okhttpVersion")
|
||||||
implementation("com.squareup.okio:okio:2.4.3")
|
implementation("com.squareup.okio:okio:2.4.3")
|
||||||
|
|
||||||
// REST
|
// REST
|
||||||
val retrofit_version = "2.7.1"
|
val retrofitVersion = "2.7.1"
|
||||||
implementation("com.squareup.retrofit2:retrofit:$retrofit_version")
|
implementation("com.squareup.retrofit2:retrofit:$retrofitVersion")
|
||||||
implementation("com.squareup.retrofit2:converter-gson:$retrofit_version")
|
implementation("com.squareup.retrofit2:converter-gson:$retrofitVersion")
|
||||||
|
|
||||||
// JSON
|
// JSON
|
||||||
implementation("com.google.code.gson:gson:2.8.6")
|
implementation("com.google.code.gson:gson:2.8.6")
|
||||||
@ -164,18 +164,18 @@ dependencies {
|
|||||||
implementation("io.requery:sqlite-android:3.31.0")
|
implementation("io.requery:sqlite-android:3.31.0")
|
||||||
|
|
||||||
// Model View Presenter
|
// Model View Presenter
|
||||||
val nucleus_version = "3.0.0"
|
val nucleusVersion = "3.0.0"
|
||||||
implementation("info.android15.nucleus:nucleus:$nucleus_version")
|
implementation("info.android15.nucleus:nucleus:$nucleusVersion")
|
||||||
implementation("info.android15.nucleus:nucleus-support-v7:$nucleus_version")
|
implementation("info.android15.nucleus:nucleus-support-v7:$nucleusVersion")
|
||||||
|
|
||||||
// Dependency injection
|
// Dependency injection
|
||||||
implementation("com.github.inorichi.injekt:injekt-core:65b0440")
|
implementation("com.github.inorichi.injekt:injekt-core:65b0440")
|
||||||
|
|
||||||
// Image library
|
// Image library
|
||||||
val glide_version = "4.11.0"
|
val glideVersion = "4.11.0"
|
||||||
implementation("com.github.bumptech.glide:glide:$glide_version")
|
implementation("com.github.bumptech.glide:glide:$glideVersion")
|
||||||
implementation("com.github.bumptech.glide:okhttp3-integration:$glide_version")
|
implementation("com.github.bumptech.glide:okhttp3-integration:$glideVersion")
|
||||||
kapt("com.github.bumptech.glide:compiler:$glide_version")
|
kapt("com.github.bumptech.glide:compiler:$glideVersion")
|
||||||
|
|
||||||
// Transformations
|
// Transformations
|
||||||
implementation("jp.wasabeef:glide-transformations:4.1.0")
|
implementation("jp.wasabeef:glide-transformations:4.1.0")
|
||||||
@ -208,28 +208,28 @@ dependencies {
|
|||||||
implementation("com.github.inorichi:conductor-support-preference:a32c357")
|
implementation("com.github.inorichi:conductor-support-preference:a32c357")
|
||||||
|
|
||||||
// RxBindings
|
// RxBindings
|
||||||
val rxbindings_version = "1.0.1"
|
val rxbindingsVersion = "1.0.1"
|
||||||
implementation("com.jakewharton.rxbinding:rxbinding-kotlin:$rxbindings_version")
|
implementation("com.jakewharton.rxbinding:rxbinding-kotlin:$rxbindingsVersion")
|
||||||
implementation("com.jakewharton.rxbinding:rxbinding-appcompat-v7-kotlin:$rxbindings_version")
|
implementation("com.jakewharton.rxbinding:rxbinding-appcompat-v7-kotlin:$rxbindingsVersion")
|
||||||
implementation("com.jakewharton.rxbinding:rxbinding-support-v4-kotlin:$rxbindings_version")
|
implementation("com.jakewharton.rxbinding:rxbinding-support-v4-kotlin:$rxbindingsVersion")
|
||||||
implementation("com.jakewharton.rxbinding:rxbinding-recyclerview-v7-kotlin:$rxbindings_version")
|
implementation("com.jakewharton.rxbinding:rxbinding-recyclerview-v7-kotlin:$rxbindingsVersion")
|
||||||
|
|
||||||
// Tests
|
// Tests
|
||||||
testImplementation("junit:junit:4.13")
|
testImplementation("junit:junit:4.13")
|
||||||
testImplementation("org.assertj:assertj-core:1.7.1")
|
testImplementation("org.assertj:assertj-core:3.12.2")
|
||||||
testImplementation("org.mockito:mockito-core:1.10.19")
|
testImplementation("org.mockito:mockito-core:1.10.19")
|
||||||
|
|
||||||
val robolectric_version = "3.1.4"
|
val robolectricVersion = "3.1.4"
|
||||||
testImplementation("org.robolectric:robolectric:$robolectric_version")
|
testImplementation("org.robolectric:robolectric:$robolectricVersion")
|
||||||
testImplementation("org.robolectric:shadows-multidex:$robolectric_version")
|
testImplementation("org.robolectric:shadows-multidex:$robolectricVersion")
|
||||||
testImplementation("org.robolectric:shadows-play-services:$robolectric_version")
|
testImplementation("org.robolectric:shadows-play-services:$robolectricVersion")
|
||||||
|
|
||||||
|
|
||||||
implementation(kotlin("stdlib", org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION))
|
implementation(kotlin("stdlib", org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION))
|
||||||
|
|
||||||
val coroutines_version = "1.3.3"
|
val coroutinesVersion = "1.3.3"
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion")
|
||||||
|
|
||||||
//Crash reports
|
//Crash reports
|
||||||
val acraVersion = "4.9.2"
|
val acraVersion = "4.9.2"
|
||||||
@ -239,13 +239,13 @@ dependencies {
|
|||||||
implementation("info.debatty:java-string-similarity:1.2.1")
|
implementation("info.debatty:java-string-similarity:1.2.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
/*tasks.preBuild {
|
tasks.preBuild {
|
||||||
dependsOn(tasks.lintKotlin)
|
dependsOn(tasks.lintKotlin)
|
||||||
}
|
}
|
||||||
tasks.lintKotlin {
|
tasks.lintKotlin {
|
||||||
dependsOn(tasks.formatKotlin)
|
dependsOn(tasks.formatKotlin)
|
||||||
}*/
|
}
|
||||||
|
|
||||||
if (getGradle().getStartParameter().getTaskRequests().toString().contains("Standard")) {
|
if (gradle.startParameter.taskRequests.toString().contains("Standard")) {
|
||||||
apply(mapOf("plugin" to "com.google.gms.google-services"))
|
apply(mapOf("plugin" to "com.google.gms.google-services"))
|
||||||
}
|
}
|
@ -92,5 +92,4 @@ open class App : Application(), LifecycleObserver {
|
|||||||
protected open fun setupNotificationChannels() {
|
protected open fun setupNotificationChannels() {
|
||||||
Notifications.createChannels(this)
|
Notifications.createChannels(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,11 @@ import eu.kanade.tachiyomi.network.NetworkHelper
|
|||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import uy.kohesive.injekt.api.*
|
import uy.kohesive.injekt.api.InjektModule
|
||||||
|
import uy.kohesive.injekt.api.InjektRegistrar
|
||||||
|
import uy.kohesive.injekt.api.addSingleton
|
||||||
|
import uy.kohesive.injekt.api.addSingletonFactory
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
class AppModule(val app: Application) : InjektModule {
|
class AppModule(val app: Application) : InjektModule {
|
||||||
|
|
||||||
@ -52,7 +56,5 @@ class AppModule(val app: Application) : InjektModule {
|
|||||||
GlobalScope.launch { get<DatabaseHelper>() }
|
GlobalScope.launch { get<DatabaseHelper>() }
|
||||||
|
|
||||||
GlobalScope.launch { get<DownloadManager>() }
|
GlobalScope.launch { get<DownloadManager>() }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -67,5 +67,4 @@ object Migrations {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.data.backup
|
package eu.kanade.tachiyomi.data.backup
|
||||||
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID
|
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID
|
||||||
|
|
||||||
|
|
||||||
object BackupConst {
|
object BackupConst {
|
||||||
|
|
||||||
const val INTENT_FILTER = "SettingsBackupFragment"
|
const val INTENT_FILTER = "SettingsBackupFragment"
|
||||||
|
@ -5,8 +5,8 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
|
||||||
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID
|
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [IntentService] used to backup [Manga] information to [JsonArray]
|
* [IntentService] used to backup [Manga] information to [JsonArray]
|
||||||
@ -45,7 +45,6 @@ class BackupCreateService : IntentService(NAME) {
|
|||||||
}
|
}
|
||||||
context.startService(intent)
|
context.startService(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val backupManager by lazy { BackupManager(this) }
|
private val backupManager by lazy { BackupManager(this) }
|
||||||
@ -60,5 +59,4 @@ class BackupCreateService : IntentService(NAME) {
|
|||||||
if (uri != null)
|
if (uri != null)
|
||||||
backupManager.createBackup(uri, flags, false)
|
backupManager.createBackup(uri, flags, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@ import com.evernote.android.job.JobManager
|
|||||||
import com.evernote.android.job.JobRequest
|
import com.evernote.android.job.JobRequest
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class BackupCreatorJob : Job() {
|
class BackupCreatorJob : Job() {
|
||||||
|
|
||||||
|
@ -3,8 +3,15 @@ package eu.kanade.tachiyomi.data.backup
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.github.salomonbrys.kotson.*
|
import com.github.salomonbrys.kotson.fromJson
|
||||||
import com.google.gson.*
|
import com.github.salomonbrys.kotson.registerTypeAdapter
|
||||||
|
import com.github.salomonbrys.kotson.registerTypeHierarchyAdapter
|
||||||
|
import com.github.salomonbrys.kotson.set
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.GsonBuilder
|
||||||
|
import com.google.gson.JsonArray
|
||||||
|
import com.google.gson.JsonElement
|
||||||
|
import com.google.gson.JsonObject
|
||||||
import com.hippo.unifile.UniFile
|
import com.hippo.unifile.UniFile
|
||||||
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY
|
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY
|
||||||
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY_MASK
|
import eu.kanade.tachiyomi.data.backup.BackupCreateService.Companion.BACKUP_CATEGORY_MASK
|
||||||
@ -22,22 +29,34 @@ import eu.kanade.tachiyomi.data.backup.models.Backup.HISTORY
|
|||||||
import eu.kanade.tachiyomi.data.backup.models.Backup.MANGA
|
import eu.kanade.tachiyomi.data.backup.models.Backup.MANGA
|
||||||
import eu.kanade.tachiyomi.data.backup.models.Backup.TRACK
|
import eu.kanade.tachiyomi.data.backup.models.Backup.TRACK
|
||||||
import eu.kanade.tachiyomi.data.backup.models.DHistory
|
import eu.kanade.tachiyomi.data.backup.models.DHistory
|
||||||
import eu.kanade.tachiyomi.data.backup.serializer.*
|
import eu.kanade.tachiyomi.data.backup.serializer.CategoryTypeAdapter
|
||||||
|
import eu.kanade.tachiyomi.data.backup.serializer.ChapterTypeAdapter
|
||||||
|
import eu.kanade.tachiyomi.data.backup.serializer.HistoryTypeAdapter
|
||||||
|
import eu.kanade.tachiyomi.data.backup.serializer.MangaTypeAdapter
|
||||||
|
import eu.kanade.tachiyomi.data.backup.serializer.TrackTypeAdapter
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.*
|
import eu.kanade.tachiyomi.data.database.models.CategoryImpl
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.ChapterImpl
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.History
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.MangaImpl
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.TrackImpl
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
import eu.kanade.tachiyomi.util.system.sendLocalBroadcast
|
import eu.kanade.tachiyomi.util.system.sendLocalBroadcast
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import kotlin.math.max
|
|
||||||
|
|
||||||
class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
|
class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
|
||||||
|
|
||||||
|
@ -38,23 +38,22 @@ import eu.kanade.tachiyomi.util.lang.chop
|
|||||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||||
import eu.kanade.tachiyomi.util.system.isServiceRunning
|
import eu.kanade.tachiyomi.util.system.isServiceRunning
|
||||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||||
|
import java.io.File
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Locale
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restores backup from json file
|
* Restores backup from json file
|
||||||
*/
|
*/
|
||||||
class BackupRestoreService : Service() {
|
class BackupRestoreService : Service() {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wake lock that will be held until the service is destroyed.
|
* Wake lock that will be held until the service is destroyed.
|
||||||
*/
|
*/
|
||||||
@ -87,7 +86,6 @@ class BackupRestoreService : Service() {
|
|||||||
*/
|
*/
|
||||||
private val trackingErrors = mutableListOf<String>()
|
private val trackingErrors = mutableListOf<String>()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List containing missing sources
|
* List containing missing sources
|
||||||
*/
|
*/
|
||||||
@ -113,7 +111,6 @@ class BackupRestoreService : Service() {
|
|||||||
*/
|
*/
|
||||||
internal val trackManager: TrackManager by injectLazy()
|
internal val trackManager: TrackManager by injectLazy()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method called when the service is created. It injects dependencies and acquire the wake lock.
|
* Method called when the service is created. It injects dependencies and acquire the wake lock.
|
||||||
*/
|
*/
|
||||||
@ -216,7 +213,6 @@ class BackupRestoreService : Service() {
|
|||||||
showResultNotification(logFile.parent, logFile.name)
|
showResultNotification(logFile.parent, logFile.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**Restore categories if they were backed up
|
/**Restore categories if they were backed up
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -246,8 +242,7 @@ class BackupRestoreService : Service() {
|
|||||||
if (job?.isCancelled == false) {
|
if (job?.isCancelled == false) {
|
||||||
showProgressNotification(restoreProgress, totalAmount, manga.title)
|
showProgressNotification(restoreProgress, totalAmount, manga.title)
|
||||||
restoreProgress += 1
|
restoreProgress += 1
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
throw java.lang.Exception("Job was cancelled")
|
throw java.lang.Exception("Job was cancelled")
|
||||||
}
|
}
|
||||||
val dbManga = backupManager.getMangaFromDatabase(manga)
|
val dbManga = backupManager.getMangaFromDatabase(manga)
|
||||||
@ -280,8 +275,7 @@ class BackupRestoreService : Service() {
|
|||||||
val cause = e.cause
|
val cause = e.cause
|
||||||
if (cause is SourceNotFoundException) {
|
if (cause is SourceNotFoundException) {
|
||||||
sourcesMissing.add(cause.id)
|
sourcesMissing.add(cause.id)
|
||||||
}
|
} else if (e.message?.contains("licensed", true) == true) {
|
||||||
else if (e.message?.contains("licensed", true) == true) {
|
|
||||||
lincensedManga++
|
lincensedManga++
|
||||||
}
|
}
|
||||||
errors.add("${manga.title} - ${cause?.message ?: e.message}")
|
errors.add("${manga.title} - ${cause?.message ?: e.message}")
|
||||||
@ -357,7 +351,6 @@ class BackupRestoreService : Service() {
|
|||||||
NotificationReceiver.cancelRestorePendingBroadcast(this)
|
NotificationReceiver.cancelRestorePendingBroadcast(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the notification containing the currently updating manga and the progress.
|
* Shows the notification containing the currently updating manga and the progress.
|
||||||
*
|
*
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package eu.kanade.tachiyomi.data.backup.models
|
package eu.kanade.tachiyomi.data.backup.models
|
||||||
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Json values
|
* Json values
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package eu.kanade.tachiyomi.data.backup.serializer
|
package eu.kanade.tachiyomi.data.backup.serializer
|
||||||
|
|
||||||
import android.telecom.DisconnectCause.REMOTE
|
|
||||||
import com.github.salomonbrys.kotson.typeAdapter
|
import com.github.salomonbrys.kotson.typeAdapter
|
||||||
import com.google.gson.TypeAdapter
|
import com.google.gson.TypeAdapter
|
||||||
import com.google.gson.stream.JsonToken
|
import com.google.gson.stream.JsonToken
|
||||||
|
@ -9,14 +9,13 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
|
|||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
import eu.kanade.tachiyomi.util.storage.saveTo
|
import eu.kanade.tachiyomi.util.storage.saveTo
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import okio.Okio
|
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
import okio.sink
|
import okio.sink
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to create chapter cache
|
* Class used to create chapter cache
|
||||||
@ -136,7 +135,6 @@ class ChapterCache(private val context: Context) {
|
|||||||
diskCache.flush()
|
diskCache.flush()
|
||||||
editor.commit()
|
editor.commit()
|
||||||
editor.abortUnlessCommitted()
|
editor.abortUnlessCommitted()
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
// Ignore.
|
// Ignore.
|
||||||
} finally {
|
} finally {
|
||||||
@ -202,4 +200,3 @@ class ChapterCache(private val context: Context) {
|
|||||||
return "${chapter.manga_id}${chapter.url}"
|
return "${chapter.manga_id}${chapter.url}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ class CoverCache(private val context: Context) {
|
|||||||
/**
|
/**
|
||||||
* Cache directory used for cache management.
|
* Cache directory used for cache management.
|
||||||
*/
|
*/
|
||||||
private val cacheDir = context.getExternalFilesDir("covers") ?:
|
private val cacheDir = context.getExternalFilesDir("covers")
|
||||||
File(context.filesDir, "covers").also { it.mkdirs() }
|
?: File(context.filesDir, "covers").also { it.mkdirs() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cover from cache.
|
* Returns the cover from cache.
|
||||||
|
@ -29,8 +29,8 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory
|
|||||||
/**
|
/**
|
||||||
* This class provides operations to manage the database through its interfaces.
|
* This class provides operations to manage the database through its interfaces.
|
||||||
*/
|
*/
|
||||||
open class DatabaseHelper(context: Context)
|
open class DatabaseHelper(context: Context) :
|
||||||
: MangaQueries, ChapterQueries, TrackQueries, CategoryQueries, MangaCategoryQueries,
|
MangaQueries, ChapterQueries, TrackQueries, CategoryQueries, MangaCategoryQueries,
|
||||||
HistoryQueries, SearchMetadataQueries {
|
HistoryQueries, SearchMetadataQueries {
|
||||||
|
|
||||||
private val configuration = SupportSQLiteOpenHelper.Configuration.builder(context)
|
private val configuration = SupportSQLiteOpenHelper.Configuration.builder(context)
|
||||||
@ -52,5 +52,4 @@ open class DatabaseHelper(context: Context)
|
|||||||
inline fun inTransaction(block: () -> Unit) = db.inTransaction(block)
|
inline fun inTransaction(block: () -> Unit) = db.inTransaction(block)
|
||||||
|
|
||||||
fun lowLevel() = db.lowLevel()
|
fun lowLevel() = db.lowLevel()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,4 +22,3 @@ inline fun <T> StorIOSQLite.inTransactionReturn(block: () -> T): T {
|
|||||||
lowLevel().endTransaction()
|
lowLevel().endTransaction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,12 @@ package eu.kanade.tachiyomi.data.database
|
|||||||
|
|
||||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
import androidx.sqlite.db.SupportSQLiteOpenHelper
|
import androidx.sqlite.db.SupportSQLiteOpenHelper
|
||||||
import android.content.Context
|
import eu.kanade.tachiyomi.data.database.tables.CategoryTable
|
||||||
import android.database.sqlite.SQLiteDatabase
|
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
||||||
import android.database.sqlite.SQLiteOpenHelper
|
import eu.kanade.tachiyomi.data.database.tables.HistoryTable
|
||||||
import eu.kanade.tachiyomi.data.database.tables.*
|
import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable
|
||||||
|
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||||
|
import eu.kanade.tachiyomi.data.database.tables.TrackTable
|
||||||
|
|
||||||
class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
|
class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
|
||||||
|
|
||||||
@ -81,5 +83,4 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
|
|||||||
override fun onConfigure(db: SupportSQLiteDatabase) {
|
override fun onConfigure(db: SupportSQLiteDatabase) {
|
||||||
db.setForeignKeyConstraintsEnabled(true)
|
db.setForeignKeyConstraintsEnabled(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,4 @@ import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite
|
|||||||
interface DbProvider {
|
interface DbProvider {
|
||||||
|
|
||||||
val db: DefaultStorIOSQLite
|
val db: DefaultStorIOSQLite
|
||||||
|
|
||||||
}
|
}
|
@ -47,7 +47,6 @@ class CategoryPutResolver : DefaultPutResolver<Category>() {
|
|||||||
val orderString = obj.mangaOrder.joinToString("/")
|
val orderString = obj.mangaOrder.joinToString("/")
|
||||||
put(COL_MANGA_ORDER, orderString)
|
put(COL_MANGA_ORDER, orderString)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,4 +88,3 @@ class ChapterDeleteResolver : DefaultDeleteResolver<Chapter>() {
|
|||||||
.whereArgs(obj.id)
|
.whereArgs(obj.id)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package eu.kanade.tachiyomi.data.database.mappers
|
package eu.kanade.tachiyomi.data.database.mappers
|
||||||
|
|
||||||
|
|
||||||
import android.content.ContentValues
|
import android.content.ContentValues
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
|
import com.pushtorefresh.storio.sqlite.SQLiteTypeMapping
|
||||||
|
@ -54,7 +54,6 @@ class TrackPutResolver : DefaultPutResolver<Track>() {
|
|||||||
put(COL_STATUS, obj.status)
|
put(COL_STATUS, obj.status)
|
||||||
put(COL_TRACKING_URL, obj.tracking_url)
|
put(COL_TRACKING_URL, obj.tracking_url)
|
||||||
put(COL_SCORE, obj.score)
|
put(COL_SCORE, obj.score)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,5 +111,4 @@ interface Category : Serializable {
|
|||||||
isLast = true
|
isLast = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -30,5 +30,4 @@ class CategoryImpl : Category {
|
|||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
return name.hashCode()
|
return name.hashCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,5 +39,4 @@ class ChapterImpl : Chapter {
|
|||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
return url.hashCode()
|
return url.hashCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -5,5 +5,4 @@ class LibraryManga : MangaImpl() {
|
|||||||
var unread: Int = 0
|
var unread: Int = 0
|
||||||
|
|
||||||
var category: Int = 0
|
var category: Int = 0
|
||||||
|
|
||||||
}
|
}
|
@ -3,9 +3,9 @@ package eu.kanade.tachiyomi.data.database.models
|
|||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
|
import java.util.Locale
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
interface Manga : SManga {
|
interface Manga : SManga {
|
||||||
|
|
||||||
@ -168,5 +168,4 @@ interface Manga : SManga {
|
|||||||
this.source = source
|
this.source = source
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -17,5 +17,4 @@ class MangaCategory {
|
|||||||
return mc
|
return mc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ package eu.kanade.tachiyomi.data.database.models
|
|||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadProvider
|
import eu.kanade.tachiyomi.data.download.DownloadProvider
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
open class MangaImpl : Manga {
|
open class MangaImpl : Manga {
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ open class MangaImpl : Manga {
|
|||||||
title = if (currentTitle() != originalTitle()) {
|
title = if (currentTitle() != originalTitle()) {
|
||||||
val customTitle = currentTitle()
|
val customTitle = currentTitle()
|
||||||
val trueTitle = other.title
|
val trueTitle = other.title
|
||||||
"${customTitle}${SManga.splitter}${trueTitle}"
|
"${customTitle}${SManga.splitter}$trueTitle"
|
||||||
} else other.title
|
} else other.title
|
||||||
val db: DownloadManager by injectLazy()
|
val db: DownloadManager by injectLazy()
|
||||||
val provider = DownloadProvider(db.context)
|
val provider = DownloadProvider(db.context)
|
||||||
@ -63,7 +63,6 @@ open class MangaImpl : Manga {
|
|||||||
val manga = other as Manga
|
val manga = other as Manga
|
||||||
|
|
||||||
return url == manga.url
|
return url == manga.url
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
@ -79,5 +78,4 @@ open class MangaImpl : Manga {
|
|||||||
|
|
||||||
fun getLastCoverFetch(id: Long) = lastCoverFetch[id] ?: 0
|
fun getLastCoverFetch(id: Long) = lastCoverFetch[id] ?: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,5 +37,4 @@ interface Track : Serializable {
|
|||||||
sync_id = serviceId
|
sync_id = serviceId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,5 +41,4 @@ class TrackImpl : Track {
|
|||||||
result = 31 * result + media_id
|
result = 31 * result + media_id
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,5 +32,4 @@ interface CategoryQueries : DbProvider {
|
|||||||
fun deleteCategory(category: Category) = db.delete().`object`(category).prepare()
|
fun deleteCategory(category: Category) = db.delete().`object`(category).prepare()
|
||||||
|
|
||||||
fun deleteCategories(categories: List<Category>) = db.delete().objects(categories).prepare()
|
fun deleteCategories(categories: List<Category>) = db.delete().objects(categories).prepare()
|
||||||
|
|
||||||
}
|
}
|
@ -11,7 +11,7 @@ import eu.kanade.tachiyomi.data.database.resolvers.ChapterProgressPutResolver
|
|||||||
import eu.kanade.tachiyomi.data.database.resolvers.ChapterSourceOrderPutResolver
|
import eu.kanade.tachiyomi.data.database.resolvers.ChapterSourceOrderPutResolver
|
||||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterGetResolver
|
import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterGetResolver
|
||||||
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
import eu.kanade.tachiyomi.data.database.tables.ChapterTable
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
|
||||||
interface ChapterQueries : DbProvider {
|
interface ChapterQueries : DbProvider {
|
||||||
|
|
||||||
@ -88,5 +88,4 @@ interface ChapterQueries : DbProvider {
|
|||||||
.objects(chapters)
|
.objects(chapters)
|
||||||
.withPutResolver(ChapterSourceOrderPutResolver())
|
.withPutResolver(ChapterSourceOrderPutResolver())
|
||||||
.prepare()
|
.prepare()
|
||||||
|
|
||||||
}
|
}
|
@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.data.database.models.MangaChapterHistory
|
|||||||
import eu.kanade.tachiyomi.data.database.resolvers.HistoryLastReadPutResolver
|
import eu.kanade.tachiyomi.data.database.resolvers.HistoryLastReadPutResolver
|
||||||
import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterHistoryGetResolver
|
import eu.kanade.tachiyomi.data.database.resolvers.MangaChapterHistoryGetResolver
|
||||||
import eu.kanade.tachiyomi.data.database.tables.HistoryTable
|
import eu.kanade.tachiyomi.data.database.tables.HistoryTable
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
|
||||||
interface HistoryQueries : DbProvider {
|
interface HistoryQueries : DbProvider {
|
||||||
|
|
||||||
|
@ -28,5 +28,4 @@ interface MangaCategoryQueries : DbProvider {
|
|||||||
insertMangasCategories(mangasCategories).executeAsBlocking()
|
insertMangasCategories(mangasCategories).executeAsBlocking()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -145,5 +145,5 @@ interface MangaQueries : DbProvider {
|
|||||||
.prepare()
|
.prepare()
|
||||||
|
|
||||||
fun getTotalChapterManga() = db.get().listOfObjects(Manga::class.java)
|
fun getTotalChapterManga() = db.get().listOfObjects(Manga::class.java)
|
||||||
.withQuery(RawQuery.builder().query(getTotalChapterMangaQuery()).observesTables(MangaTable.TABLE).build()).prepare();
|
.withQuery(RawQuery.builder().query(getTotalChapterMangaQuery()).observesTables(MangaTable.TABLE).build()).prepare()
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ fun getRecentMangasQuery(offset: Int = 0, search: String = "") = """
|
|||||||
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
|
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
|
||||||
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ?
|
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ?
|
||||||
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||||
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%${search}%'
|
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%$search%'
|
||||||
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
||||||
LIMIT 25 OFFSET $offset
|
LIMIT 25 OFFSET $offset
|
||||||
"""
|
"""
|
||||||
@ -109,7 +109,7 @@ fun getRecentMangasLimitQuery(limit: Int = 25, search: String = "") = """
|
|||||||
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
|
ON ${Chapter.TABLE}.${Chapter.COL_MANGA_ID} = max_last_read.${Chapter.COL_MANGA_ID}
|
||||||
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ?
|
WHERE ${History.TABLE}.${History.COL_LAST_READ} > ?
|
||||||
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
AND max_last_read.${History.COL_CHAPTER_ID} = ${History.TABLE}.${History.COL_CHAPTER_ID}
|
||||||
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%${search}%'
|
AND lower(${Manga.TABLE}.${Manga.COL_TITLE}) LIKE '%$search%'
|
||||||
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
ORDER BY max_last_read.${History.COL_LAST_READ} DESC
|
||||||
LIMIT $limit
|
LIMIT $limit
|
||||||
"""
|
"""
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package eu.kanade.tachiyomi.data.database.queries
|
package eu.kanade.tachiyomi.data.database.queries
|
||||||
|
|
||||||
|
|
||||||
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
|
import com.pushtorefresh.storio.sqlite.queries.DeleteQuery
|
||||||
import com.pushtorefresh.storio.sqlite.queries.Query
|
import com.pushtorefresh.storio.sqlite.queries.Query
|
||||||
import eu.kanade.tachiyomi.data.database.DbProvider
|
import eu.kanade.tachiyomi.data.database.DbProvider
|
||||||
|
@ -30,5 +30,4 @@ interface TrackQueries : DbProvider {
|
|||||||
.whereArgs(manga.id, sync.id)
|
.whereArgs(manga.id, sync.id)
|
||||||
.build())
|
.build())
|
||||||
.prepare()
|
.prepare()
|
||||||
|
|
||||||
}
|
}
|
@ -30,6 +30,4 @@ class ChapterBackupPutResolver : PutResolver<Chapter>() {
|
|||||||
put(ChapterTable.COL_BOOKMARK, chapter.bookmark)
|
put(ChapterTable.COL_BOOKMARK, chapter.bookmark)
|
||||||
put(ChapterTable.COL_LAST_PAGE_READ, chapter.last_page_read)
|
put(ChapterTable.COL_LAST_PAGE_READ, chapter.last_page_read)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,4 @@ class ChapterProgressPutResolver : PutResolver<Chapter>() {
|
|||||||
put(ChapterTable.COL_LAST_PAGE_READ, chapter.last_page_read)
|
put(ChapterTable.COL_LAST_PAGE_READ, chapter.last_page_read)
|
||||||
put(ChapterTable.COL_PAGES_LEFT, chapter.pages_left)
|
put(ChapterTable.COL_PAGES_LEFT, chapter.pages_left)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,5 +28,4 @@ class ChapterSourceOrderPutResolver : PutResolver<Chapter>() {
|
|||||||
fun mapToContentValues(chapter: Chapter) = ContentValues(1).apply {
|
fun mapToContentValues(chapter: Chapter) = ContentValues(1).apply {
|
||||||
put(ChapterTable.COL_SOURCE_ORDER, chapter.source_order)
|
put(ChapterTable.COL_SOURCE_ORDER, chapter.source_order)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -60,5 +60,4 @@ class HistoryLastReadPutResolver : HistoryPutResolver() {
|
|||||||
fun mapToUpdateContentValues(history: History) = ContentValues(1).apply {
|
fun mapToUpdateContentValues(history: History) = ContentValues(1).apply {
|
||||||
put(HistoryTable.COL_LAST_READ, history.last_read)
|
put(HistoryTable.COL_LAST_READ, history.last_read)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,5 +21,4 @@ class LibraryMangaGetResolver : DefaultGetResolver<LibraryManga>(), BaseMangaGet
|
|||||||
|
|
||||||
return manga
|
return manga
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,5 +24,4 @@ class MangaChapterGetResolver : DefaultGetResolver<MangaChapter>() {
|
|||||||
|
|
||||||
return MangaChapter(manga, chapter)
|
return MangaChapter(manga, chapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,4 @@ class MangaFavoritePutResolver : PutResolver<Manga>() {
|
|||||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||||
put(MangaTable.COL_FAVORITE, manga.favorite)
|
put(MangaTable.COL_FAVORITE, manga.favorite)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,4 @@ class MangaFlagsPutResolver : PutResolver<Manga>() {
|
|||||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||||
put(MangaTable.COL_CHAPTER_FLAGS, manga.chapter_flags)
|
put(MangaTable.COL_CHAPTER_FLAGS, manga.chapter_flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import com.pushtorefresh.storio.sqlite.operations.put.PutResolver
|
|||||||
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
import com.pushtorefresh.storio.sqlite.operations.put.PutResult
|
||||||
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
import com.pushtorefresh.storio.sqlite.queries.UpdateQuery
|
||||||
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
import eu.kanade.tachiyomi.data.database.inTransactionReturn
|
||||||
import eu.kanade.tachiyomi.data.database.models.LibraryManga
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
import eu.kanade.tachiyomi.data.database.tables.MangaTable
|
||||||
|
|
||||||
@ -29,5 +28,4 @@ class MangaHideTitlePutResolver : PutResolver<Manga>() {
|
|||||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||||
put(MangaTable.COL_HIDE_TITLE, manga.hide_title)
|
put(MangaTable.COL_HIDE_TITLE, manga.hide_title)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,4 @@ class MangaInfoPutResolver(val reset:Boolean = false): PutResolver<Manga>() {
|
|||||||
put(MangaTable.COL_ARTIST, manga.originalArtist())
|
put(MangaTable.COL_ARTIST, manga.originalArtist())
|
||||||
put(MangaTable.COL_DESCRIPTION, manga.originalDesc())
|
put(MangaTable.COL_DESCRIPTION, manga.originalDesc())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -28,6 +28,4 @@ class MangaLastUpdatedPutResolver : PutResolver<Manga>() {
|
|||||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||||
put(MangaTable.COL_LAST_UPDATE, manga.last_update)
|
put(MangaTable.COL_LAST_UPDATE, manga.last_update)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,5 +28,4 @@ class MangaTitlePutResolver : PutResolver<Manga>() {
|
|||||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||||
put(MangaTable.COL_TITLE, manga.title)
|
put(MangaTable.COL_TITLE, manga.title)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,5 +28,4 @@ class MangaViewerPutResolver : PutResolver<Manga>() {
|
|||||||
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
|
||||||
put(MangaTable.COL_VIEWER, manga.viewer)
|
put(MangaTable.COL_VIEWER, manga.viewer)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ object CategoryTable {
|
|||||||
$COL_MANGA_ORDER TEXT NOT NULL
|
$COL_MANGA_ORDER TEXT NOT NULL
|
||||||
)"""
|
)"""
|
||||||
|
|
||||||
|
|
||||||
val addMangaOrder: String
|
val addMangaOrder: String
|
||||||
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_MANGA_ORDER TEXT"
|
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_MANGA_ORDER TEXT"
|
||||||
}
|
}
|
||||||
|
@ -67,5 +67,4 @@ object ChapterTable {
|
|||||||
|
|
||||||
val pagesLeftQuery: String
|
val pagesLeftQuery: String
|
||||||
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_PAGES_LEFT INTEGER DEFAULT 0"
|
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_PAGES_LEFT INTEGER DEFAULT 0"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,5 +20,4 @@ object MangaCategoryTable {
|
|||||||
FOREIGN KEY($COL_MANGA_ID) REFERENCES ${MangaTable.TABLE} (${MangaTable.COL_ID})
|
FOREIGN KEY($COL_MANGA_ID) REFERENCES ${MangaTable.TABLE} (${MangaTable.COL_ID})
|
||||||
ON DELETE CASCADE
|
ON DELETE CASCADE
|
||||||
)"""
|
)"""
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package eu.kanade.tachiyomi.data.database.tables
|
package eu.kanade.tachiyomi.data.database.tables
|
||||||
|
|
||||||
|
|
||||||
object SearchMetadataTable {
|
object SearchMetadataTable {
|
||||||
const val TABLE = "search_metadata"
|
const val TABLE = "search_metadata"
|
||||||
|
|
||||||
|
@ -10,10 +10,10 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache where we dump the downloads directory from the filesystem. This class is needed because
|
* Cache where we dump the downloads directory from the filesystem. This class is needed because
|
||||||
@ -143,8 +143,8 @@ class DownloadCache(
|
|||||||
val trueMangaDirs = mangaDirs.mapNotNull { mangaDir ->
|
val trueMangaDirs = mangaDirs.mapNotNull { mangaDir ->
|
||||||
val manga = sourceMangas.firstOrNull()?.find { DiskUtil.buildValidFilename(
|
val manga = sourceMangas.firstOrNull()?.find { DiskUtil.buildValidFilename(
|
||||||
it.originalTitle()).toLowerCase() == mangaDir.key
|
it.originalTitle()).toLowerCase() == mangaDir.key
|
||||||
.toLowerCase() && it.source == sourceValue.key } ?:
|
.toLowerCase() && it.source == sourceValue.key }
|
||||||
sourceMangas.lastOrNull()?.find { DiskUtil.buildValidFilename(
|
?: sourceMangas.lastOrNull()?.find { DiskUtil.buildValidFilename(
|
||||||
it.originalTitle()).toLowerCase() == mangaDir.key
|
it.originalTitle()).toLowerCase() == mangaDir.key
|
||||||
.toLowerCase() && it.source == sourceValue.key }
|
.toLowerCase() && it.source == sourceValue.key }
|
||||||
val id = manga?.id ?: return@mapNotNull null
|
val id = manga?.id ?: return@mapNotNull null
|
||||||
@ -169,8 +169,7 @@ class DownloadCache(
|
|||||||
val files = mangaFiles[id]
|
val files = mangaFiles[id]
|
||||||
if (files == null) {
|
if (files == null) {
|
||||||
mangaFiles[id] = mutableSetOf(chapterDirName)
|
mangaFiles[id] = mutableSetOf(chapterDirName)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
mangaFiles[id]?.add(chapterDirName)
|
mangaFiles[id]?.add(chapterDirName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,7 +215,6 @@ class DownloadCache(
|
|||||||
sourceDir.files = list
|
sourceDir.files = list
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a manga that has been deleted from this cache.
|
* Removes a manga that has been deleted from this cache.
|
||||||
*
|
*
|
||||||
@ -230,20 +228,26 @@ class DownloadCache(
|
|||||||
/**
|
/**
|
||||||
* Class to store the files under the root downloads directory.
|
* Class to store the files under the root downloads directory.
|
||||||
*/
|
*/
|
||||||
private class RootDirectory(val dir: UniFile,
|
private class RootDirectory(
|
||||||
var files: Map<Long, SourceDirectory> = hashMapOf())
|
val dir: UniFile,
|
||||||
|
var files: Map<Long, SourceDirectory> = hashMapOf()
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to store the files under a source directory.
|
* Class to store the files under a source directory.
|
||||||
*/
|
*/
|
||||||
private class SourceDirectory(val dir: UniFile,
|
private class SourceDirectory(
|
||||||
var files: Map<Long, MutableSet<String>> = hashMapOf())
|
val dir: UniFile,
|
||||||
|
var files: Map<Long, MutableSet<String>> = hashMapOf()
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to store the files under a manga directory.
|
* Class to store the files under a manga directory.
|
||||||
*/
|
*/
|
||||||
private class MangaDirectory(val dir: UniFile,
|
private class MangaDirectory(
|
||||||
var files: MutableSet<String> = hashSetOf())
|
val dir: UniFile,
|
||||||
|
var files: MutableSet<String> = hashSetOf()
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new map containing only the key entries of [transform] that are not null.
|
* Returns a new map containing only the key entries of [transform] that are not null.
|
||||||
@ -267,5 +271,4 @@ class DownloadCache(
|
|||||||
}
|
}
|
||||||
return destination
|
return destination
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -223,8 +223,7 @@ class DownloadManager(val context: Context) {
|
|||||||
downloader.queue.remove(chapters)
|
downloader.queue.remove(chapters)
|
||||||
if (!wasPaused && downloader.queue.isNotEmpty()) {
|
if (!wasPaused && downloader.queue.isNotEmpty()) {
|
||||||
downloader.start()
|
downloader.start()
|
||||||
}
|
} else if (downloader.queue.isEmpty() && DownloadService.isRunning(context)) {
|
||||||
else if (downloader.queue.isEmpty() && DownloadService.isRunning(context)) {
|
|
||||||
DownloadService.stop(context)
|
DownloadService.stop(context)
|
||||||
}
|
}
|
||||||
queue.remove(chapters)
|
queue.remove(chapters)
|
||||||
|
@ -6,7 +6,6 @@ import androidx.core.app.NotificationCompat
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
|
|
||||||
import eu.kanade.tachiyomi.data.notification.NotificationHandler
|
import eu.kanade.tachiyomi.data.notification.NotificationHandler
|
||||||
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||||
@ -93,8 +92,7 @@ internal class DownloadNotifier(private val context: Context) {
|
|||||||
setContentText(
|
setContentText(
|
||||||
context.getString(R.string.chapter_downloading)
|
context.getString(R.string.chapter_downloading)
|
||||||
)
|
)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
setContentTitle(
|
setContentTitle(
|
||||||
context.getString(
|
context.getString(
|
||||||
R.string.chapter_downloading
|
R.string.chapter_downloading
|
||||||
@ -107,7 +105,6 @@ internal class DownloadNotifier(private val context: Context) {
|
|||||||
}
|
}
|
||||||
// Displays the progress bar on notification
|
// Displays the progress bar on notification
|
||||||
notification.show()
|
notification.show()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,5 +194,4 @@ class DownloadPendingDeleter(context: Context) {
|
|||||||
it.name = name
|
it.name = name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,7 @@ class DownloadProvider(private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
preferences.downloadsDirectory().asObservable()
|
preferences.downloadsDirectory().asObservable().skip(1)
|
||||||
.skip(1)
|
|
||||||
.subscribe { downloadsDir = UniFile.fromUri(context, Uri.parse(it)) }
|
.subscribe { downloadsDir = UniFile.fromUri(context, Uri.parse(it)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,8 +49,7 @@ class DownloadProvider(private val context: Context) {
|
|||||||
*/
|
*/
|
||||||
internal fun getMangaDir(manga: Manga, source: Source): UniFile {
|
internal fun getMangaDir(manga: Manga, source: Source): UniFile {
|
||||||
try {
|
try {
|
||||||
return downloadsDir
|
return downloadsDir.createDirectory(getSourceDirName(source))
|
||||||
.createDirectory(getSourceDirName(source))
|
|
||||||
.createDirectory(getMangaDirName(manga))
|
.createDirectory(getMangaDirName(manga))
|
||||||
} catch (e: NullPointerException) {
|
} catch (e: NullPointerException) {
|
||||||
throw Exception(context.getString(R.string.invalid_download_dir))
|
throw Exception(context.getString(R.string.invalid_download_dir))
|
||||||
@ -136,8 +134,6 @@ class DownloadProvider(private val context: Context) {
|
|||||||
val sourceDir = findSourceDir(source)
|
val sourceDir = findSourceDir(source)
|
||||||
val mangaDir = sourceDir?.findFile(DiskUtil.buildValidFilename(from))
|
val mangaDir = sourceDir?.findFile(DiskUtil.buildValidFilename(from))
|
||||||
mangaDir?.renameTo(to)
|
mangaDir?.renameTo(to)
|
||||||
// val downloadManager:DownloadManager by injectLazy()
|
|
||||||
// downloadManager.renameCache(from, to, sourceId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,7 +143,11 @@ class DownloadProvider(private val context: Context) {
|
|||||||
* @param manga the manga of the chapter.
|
* @param manga the manga of the chapter.
|
||||||
* @param source the source of the chapter.
|
* @param source the source of the chapter.
|
||||||
*/
|
*/
|
||||||
fun findUnmatchedChapterDirs(chapters: List<Chapter>, manga: Manga, source: Source): List<UniFile> {
|
fun findUnmatchedChapterDirs(
|
||||||
|
chapters: List<Chapter>,
|
||||||
|
manga: Manga,
|
||||||
|
source: Source
|
||||||
|
): List<UniFile> {
|
||||||
val mangaDir = findMangaDir(manga, source) ?: return emptyList()
|
val mangaDir = findMangaDir(manga, source) ?: return emptyList()
|
||||||
return mangaDir.listFiles()!!.asList().filter {
|
return mangaDir.listFiles()!!.asList().filter {
|
||||||
(chapters.find { chp ->
|
(chapters.find { chp ->
|
||||||
@ -170,7 +170,6 @@ class DownloadProvider(private val context: Context) {
|
|||||||
return chapters.mapNotNull { mangaDir.findFile("${getChapterDirName(it)}_tmp") }
|
return chapters.mapNotNull { mangaDir.findFile("${getChapterDirName(it)}_tmp") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the download directory name for a source.
|
* Returns the download directory name for a source.
|
||||||
*
|
*
|
||||||
@ -213,5 +212,4 @@ class DownloadProvider(private val context: Context) {
|
|||||||
DiskUtil.buildValidFilename(chapter.name)
|
DiskUtil.buildValidFilename(chapter.name)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,6 @@ class DownloadService : Service() {
|
|||||||
.setContentTitle(getString(R.string.download_notifier_downloader_title))
|
.setContentTitle(getString(R.string.download_notifier_downloader_title))
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DownloadServiceListener {
|
interface DownloadServiceListener {
|
||||||
|
@ -133,5 +133,4 @@ class DownloadStore(
|
|||||||
* @param order the order of the download in the queue.
|
* @param order the order of the download in the queue.
|
||||||
*/
|
*/
|
||||||
data class DownloadObject(val mangaId: Long, val chapterId: Long, val order: Int)
|
data class DownloadObject(val mangaId: Long, val chapterId: Long, val order: Int)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import eu.kanade.tachiyomi.util.storage.saveTo
|
|||||||
import eu.kanade.tachiyomi.util.system.ImageUtil
|
import eu.kanade.tachiyomi.util.system.ImageUtil
|
||||||
import eu.kanade.tachiyomi.util.system.launchNow
|
import eu.kanade.tachiyomi.util.system.launchNow
|
||||||
import eu.kanade.tachiyomi.util.system.launchUI
|
import eu.kanade.tachiyomi.util.system.launchUI
|
||||||
|
import java.io.File
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
@ -28,7 +29,6 @@ import rx.android.schedulers.AndroidSchedulers
|
|||||||
import rx.schedulers.Schedulers
|
import rx.schedulers.Schedulers
|
||||||
import rx.subscriptions.CompositeSubscription
|
import rx.subscriptions.CompositeSubscription
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is the one in charge of downloading chapters.
|
* This class is the one in charge of downloading chapters.
|
||||||
@ -129,8 +129,7 @@ class Downloader(
|
|||||||
if (notifier.paused) {
|
if (notifier.paused) {
|
||||||
if (queue.isEmpty()) {
|
if (queue.isEmpty()) {
|
||||||
notifier.dismiss()
|
notifier.dismiss()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
notifier.paused = false
|
notifier.paused = false
|
||||||
notifier.onDownloadPaused()
|
notifier.onDownloadPaused()
|
||||||
}
|
}
|
||||||
@ -318,7 +317,6 @@ class Downloader(
|
|||||||
notifier.onError(error.message, download.chapter.name)
|
notifier.onError(error.message, download.chapter.name)
|
||||||
download
|
download
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -448,8 +446,12 @@ class Downloader(
|
|||||||
* @param tmpDir the directory where the download is currently stored.
|
* @param tmpDir the directory where the download is currently stored.
|
||||||
* @param dirname the real (non temporary) directory name of the download.
|
* @param dirname the real (non temporary) directory name of the download.
|
||||||
*/
|
*/
|
||||||
private fun ensureSuccessfulDownload(download: Download, mangaDir: UniFile,
|
private fun ensureSuccessfulDownload(
|
||||||
tmpDir: UniFile, dirname: String) {
|
download: Download,
|
||||||
|
mangaDir: UniFile,
|
||||||
|
tmpDir: UniFile,
|
||||||
|
dirname: String
|
||||||
|
) {
|
||||||
|
|
||||||
// Ensure that the chapter folder has all the images.
|
// Ensure that the chapter folder has all the images.
|
||||||
val downloadedImages = tmpDir.listFiles().orEmpty().filterNot { it.name!!.endsWith(".tmp") }
|
val downloadedImages = tmpDir.listFiles().orEmpty().filterNot { it.name!!.endsWith(".tmp") }
|
||||||
@ -497,5 +499,4 @@ class Downloader(
|
|||||||
companion object {
|
companion object {
|
||||||
const val TMP_DIR_SUFFIX = "_tmp"
|
const val TMP_DIR_SUFFIX = "_tmp"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,15 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadStore
|
import eu.kanade.tachiyomi.data.download.DownloadStore
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.subjects.PublishSubject
|
import rx.subjects.PublishSubject
|
||||||
import java.util.concurrent.CopyOnWriteArrayList
|
|
||||||
|
|
||||||
class DownloadQueue(
|
class DownloadQueue(
|
||||||
private val store: DownloadStore,
|
private val store: DownloadStore,
|
||||||
private val queue: MutableList<Download> = CopyOnWriteArrayList<Download>())
|
private val queue: MutableList<Download> = CopyOnWriteArrayList<Download>()
|
||||||
: List<Download> by queue {
|
) :
|
||||||
|
List<Download> by queue {
|
||||||
|
|
||||||
private val statusSubject = PublishSubject.create<Download>()
|
private val statusSubject = PublishSubject.create<Download>()
|
||||||
|
|
||||||
@ -89,8 +90,7 @@ class DownloadQueue(
|
|||||||
} else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) {
|
} else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) {
|
||||||
setPagesSubject(download.pages, null)
|
setPagesSubject(download.pages, null)
|
||||||
downloadListeners.forEach { it.updateDownload(download) }
|
downloadListeners.forEach { it.updateDownload(download) }
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
downloadListeners.forEach { it.updateDownload(download) }
|
downloadListeners.forEach { it.updateDownload(download) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +111,6 @@ class DownloadQueue(
|
|||||||
.onBackpressureBuffer()
|
.onBackpressureBuffer()
|
||||||
.filter { it == Page.READY }
|
.filter { it == Page.READY }
|
||||||
.map { download }
|
.map { download }
|
||||||
|
|
||||||
} else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) {
|
} else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) {
|
||||||
setPagesSubject(download.pages, null)
|
setPagesSubject(download.pages, null)
|
||||||
downloadListeners.forEach { it.updateDownload(download) }
|
downloadListeners.forEach { it.updateDownload(download) }
|
||||||
@ -140,5 +139,4 @@ class DownloadQueue(
|
|||||||
interface DownloadListener {
|
interface DownloadListener {
|
||||||
fun updateDownload(download: Download)
|
fun updateDownload(download: Download)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -5,7 +5,11 @@ import android.util.Log
|
|||||||
import com.bumptech.glide.Priority
|
import com.bumptech.glide.Priority
|
||||||
import com.bumptech.glide.load.DataSource
|
import com.bumptech.glide.load.DataSource
|
||||||
import com.bumptech.glide.load.data.DataFetcher
|
import com.bumptech.glide.load.data.DataFetcher
|
||||||
import java.io.*
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
open class FileFetcher(private val file: File) : DataFetcher<InputStream> {
|
open class FileFetcher(private val file: File) : DataFetcher<InputStream> {
|
||||||
|
|
||||||
|
@ -16,10 +16,12 @@ import java.io.InputStream
|
|||||||
* @param manga the manga of the cover to load.
|
* @param manga the manga of the cover to load.
|
||||||
* @param file the file where this cover should be. It may exists or not.
|
* @param file the file where this cover should be. It may exists or not.
|
||||||
*/
|
*/
|
||||||
class LibraryMangaUrlFetcher(private val networkFetcher: DataFetcher<InputStream>,
|
class LibraryMangaUrlFetcher(
|
||||||
|
private val networkFetcher: DataFetcher<InputStream>,
|
||||||
private val manga: Manga,
|
private val manga: Manga,
|
||||||
private val file: File)
|
private val file: File
|
||||||
: FileFetcher(file) {
|
) :
|
||||||
|
FileFetcher(file) {
|
||||||
|
|
||||||
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
@ -52,7 +54,6 @@ class LibraryMangaUrlFetcher(private val networkFetcher: DataFetcher<InputStream
|
|||||||
override fun onLoadFailed(e: Exception) {
|
override fun onLoadFailed(e: Exception) {
|
||||||
callback.onLoadFailed(e)
|
callback.onLoadFailed(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
loadFromFile(callback)
|
loadFromFile(callback)
|
||||||
@ -68,5 +69,4 @@ class LibraryMangaUrlFetcher(private val networkFetcher: DataFetcher<InputStream
|
|||||||
super.cancel()
|
super.cancel()
|
||||||
networkFetcher.cancel()
|
networkFetcher.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -3,18 +3,22 @@ package eu.kanade.tachiyomi.data.glide
|
|||||||
import android.util.LruCache
|
import android.util.LruCache
|
||||||
import com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher
|
import com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher
|
||||||
import com.bumptech.glide.load.Options
|
import com.bumptech.glide.load.Options
|
||||||
import com.bumptech.glide.load.model.*
|
import com.bumptech.glide.load.model.GlideUrl
|
||||||
|
import com.bumptech.glide.load.model.Headers
|
||||||
|
import com.bumptech.glide.load.model.LazyHeaders
|
||||||
|
import com.bumptech.glide.load.model.ModelLoader
|
||||||
|
import com.bumptech.glide.load.model.ModelLoaderFactory
|
||||||
|
import com.bumptech.glide.load.model.MultiModelLoaderFactory
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
|
import java.io.File
|
||||||
|
import java.io.InputStream
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class for loading a cover associated with a [Manga] that can be present in our own cache.
|
* A class for loading a cover associated with a [Manga] that can be present in our own cache.
|
||||||
@ -78,8 +82,12 @@ class MangaModelLoader : ModelLoader<Manga, InputStream> {
|
|||||||
* @param width the width of the view where the resource will be loaded.
|
* @param width the width of the view where the resource will be loaded.
|
||||||
* @param height the height of the view where the resource will be loaded.
|
* @param height the height of the view where the resource will be loaded.
|
||||||
*/
|
*/
|
||||||
override fun buildLoadData(manga: Manga, width: Int, height: Int,
|
override fun buildLoadData(
|
||||||
options: Options): ModelLoader.LoadData<InputStream>? {
|
manga: Manga,
|
||||||
|
width: Int,
|
||||||
|
height: Int,
|
||||||
|
options: Options
|
||||||
|
): ModelLoader.LoadData<InputStream>? {
|
||||||
// Check thumbnail is not null or empty
|
// Check thumbnail is not null or empty
|
||||||
val url = manga.thumbnail_url
|
val url = manga.thumbnail_url
|
||||||
if (url == null || url.isEmpty()) {
|
if (url == null || url.isEmpty()) {
|
||||||
@ -142,5 +150,4 @@ class MangaModelLoader : ModelLoader<Manga, InputStream> {
|
|||||||
value
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,6 @@ class PassthroughModelLoader : ModelLoader<InputStream, InputStream> {
|
|||||||
) {
|
) {
|
||||||
callback.onDataReady(stream)
|
callback.onDataReady(stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,5 +69,4 @@ class PassthroughModelLoader : ModelLoader<InputStream, InputStream> {
|
|||||||
|
|
||||||
override fun teardown() {}
|
override fun teardown() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@ import com.bumptech.glide.module.AppGlideModule
|
|||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
|
import java.io.InputStream
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.io.InputStream
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to update Glide module settings
|
* Class used to update Glide module settings
|
||||||
|
@ -5,9 +5,9 @@ import com.evernote.android.job.JobManager
|
|||||||
import com.evernote.android.job.JobRequest
|
import com.evernote.android.job.JobRequest
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class LibraryUpdateJob : Job() {
|
class LibraryUpdateJob : Job() {
|
||||||
|
|
||||||
|
@ -39,5 +39,4 @@ object LibraryUpdateRanker {
|
|||||||
compareValues(mangaFirst.currentTitle(), mangaSecond.currentTitle())
|
compareValues(mangaFirst.currentTitle(), mangaSecond.currentTitle())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -38,6 +38,10 @@ import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
|||||||
import eu.kanade.tachiyomi.util.lang.chop
|
import eu.kanade.tachiyomi.util.lang.chop
|
||||||
import eu.kanade.tachiyomi.util.system.notification
|
import eu.kanade.tachiyomi.util.system.notification
|
||||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||||
|
import java.util.ArrayList
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
@ -50,10 +54,6 @@ import rx.schedulers.Schedulers
|
|||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.ArrayList
|
|
||||||
import java.util.Date
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class will take care of updating the chapters of the manga from the library. It can be
|
* This class will take care of updating the chapters of the manga from the library. It can be
|
||||||
|
@ -10,6 +10,7 @@ import android.content.Intent
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
|
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.backup.BackupRestoreService
|
import eu.kanade.tachiyomi.data.backup.BackupRestoreService
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
@ -27,12 +28,10 @@ import eu.kanade.tachiyomi.util.storage.DiskUtil
|
|||||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
import java.io.File
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
|
||||||
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Global [BroadcastReceiver] that runs on UI thread
|
* Global [BroadcastReceiver] that runs on UI thread
|
||||||
@ -113,7 +112,6 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||||||
type = "image/*"
|
type = "image/*"
|
||||||
}
|
}
|
||||||
// Close Navigation Shade
|
// Close Navigation Shade
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -217,7 +215,6 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||||||
// Called to cancel restore
|
// Called to cancel restore
|
||||||
private const val ACTION_CANCEL_RESTORE = "$ID.$NAME.CANCEL_RESTORE"
|
private const val ACTION_CANCEL_RESTORE = "$ID.$NAME.CANCEL_RESTORE"
|
||||||
|
|
||||||
|
|
||||||
// Called to open chapter
|
// Called to open chapter
|
||||||
private const val ACTION_OPEN_CHAPTER = "$ID.$NAME.ACTION_OPEN_CHAPTER"
|
private const val ACTION_OPEN_CHAPTER = "$ID.$NAME.ACTION_OPEN_CHAPTER"
|
||||||
|
|
||||||
@ -322,8 +319,12 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||||||
* @param notificationId id of notification
|
* @param notificationId id of notification
|
||||||
* @return [PendingIntent]
|
* @return [PendingIntent]
|
||||||
*/
|
*/
|
||||||
internal fun dismissNotification(context: Context, notificationId: Int, groupId: Int? =
|
internal fun dismissNotification(
|
||||||
null) {
|
context: Context,
|
||||||
|
notificationId: Int,
|
||||||
|
groupId: Int? =
|
||||||
|
null
|
||||||
|
) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
val groupKey = context.notificationManager.activeNotifications.find {
|
val groupKey = context.notificationManager.activeNotifications.find {
|
||||||
it.id == notificationId
|
it.id == notificationId
|
||||||
@ -387,8 +388,12 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||||||
* @param manga manga of chapter
|
* @param manga manga of chapter
|
||||||
* @param chapter chapter that needs to be opened
|
* @param chapter chapter that needs to be opened
|
||||||
*/
|
*/
|
||||||
internal fun openChapterPendingActivity(context: Context, manga: Manga, chapter:
|
internal fun openChapterPendingActivity(
|
||||||
Chapter): PendingIntent {
|
context: Context,
|
||||||
|
manga: Manga,
|
||||||
|
chapter:
|
||||||
|
Chapter
|
||||||
|
): PendingIntent {
|
||||||
val newIntent = ReaderActivity.newIntent(context, manga, chapter)
|
val newIntent = ReaderActivity.newIntent(context, manga, chapter)
|
||||||
return PendingIntent.getActivity(context, manga.id.hashCode(), newIntent, PendingIntent
|
return PendingIntent.getActivity(context, manga.id.hashCode(), newIntent, PendingIntent
|
||||||
.FLAG_UPDATE_CURRENT)
|
.FLAG_UPDATE_CURRENT)
|
||||||
@ -440,15 +445,19 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||||||
return PendingIntent.getActivity(context, 0, toLaunch, 0)
|
return PendingIntent.getActivity(context, 0, toLaunch, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns [PendingIntent] that marks a chapter as read and deletes it if preferred
|
* Returns [PendingIntent] that marks a chapter as read and deletes it if preferred
|
||||||
*
|
*
|
||||||
* @param context context of application
|
* @param context context of application
|
||||||
* @param manga manga of chapter
|
* @param manga manga of chapter
|
||||||
*/
|
*/
|
||||||
internal fun markAsReadPendingBroadcast(context: Context, manga: Manga, chapters:
|
internal fun markAsReadPendingBroadcast(
|
||||||
Array<Chapter>, groupId: Int):
|
context: Context,
|
||||||
|
manga: Manga,
|
||||||
|
chapters:
|
||||||
|
Array<Chapter>,
|
||||||
|
groupId: Int
|
||||||
|
):
|
||||||
PendingIntent {
|
PendingIntent {
|
||||||
val newIntent = Intent(context, NotificationReceiver::class.java).apply {
|
val newIntent = Intent(context, NotificationReceiver::class.java).apply {
|
||||||
action = ACTION_MARK_AS_READ
|
action = ACTION_MARK_AS_READ
|
||||||
|
@ -38,6 +38,7 @@ object Notifications {
|
|||||||
const val CHANNEL_NEW_CHAPTERS = "new_chapters_channel"
|
const val CHANNEL_NEW_CHAPTERS = "new_chapters_channel"
|
||||||
const val ID_NEW_CHAPTERS = -301
|
const val ID_NEW_CHAPTERS = -301
|
||||||
const val GROUP_NEW_CHAPTERS = "eu.kanade.tachiyomi.NEW_CHAPTERS"
|
const val GROUP_NEW_CHAPTERS = "eu.kanade.tachiyomi.NEW_CHAPTERS"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification channel and ids used by the library updater.
|
* Notification channel and ids used by the library updater.
|
||||||
*/
|
*/
|
||||||
@ -49,7 +50,6 @@ object Notifications {
|
|||||||
const val ID_RESTORE_COMPLETE = -502
|
const val ID_RESTORE_COMPLETE = -502
|
||||||
const val ID_RESTORE_ERROR = -503
|
const val ID_RESTORE_ERROR = -503
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the notification channels introduced in Android Oreo.
|
* Creates the notification channels introduced in Android Oreo.
|
||||||
*
|
*
|
||||||
@ -58,8 +58,7 @@ object Notifications {
|
|||||||
fun createChannels(context: Context) {
|
fun createChannels(context: Context) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return
|
||||||
|
|
||||||
val channels = listOf(
|
val channels = listOf(NotificationChannel(
|
||||||
NotificationChannel(
|
|
||||||
CHANNEL_COMMON,
|
CHANNEL_COMMON,
|
||||||
context.getString(R.string.channel_common),
|
context.getString(R.string.channel_common),
|
||||||
NotificationManager.IMPORTANCE_LOW
|
NotificationManager.IMPORTANCE_LOW
|
||||||
@ -83,11 +82,13 @@ object Notifications {
|
|||||||
CHANNEL_NEW_CHAPTERS,
|
CHANNEL_NEW_CHAPTERS,
|
||||||
context.getString(R.string.channel_new_chapters),
|
context.getString(R.string.channel_new_chapters),
|
||||||
NotificationManager.IMPORTANCE_DEFAULT
|
NotificationManager.IMPORTANCE_DEFAULT
|
||||||
), NotificationChannel(CHANNEL_RESTORE, context.getString(R.string.channel_backup_restore),
|
), NotificationChannel(
|
||||||
NotificationManager.IMPORTANCE_LOW).apply {
|
CHANNEL_RESTORE,
|
||||||
|
context.getString(R.string.channel_backup_restore),
|
||||||
|
NotificationManager.IMPORTANCE_LOW
|
||||||
|
).apply {
|
||||||
setShowBadge(false)
|
setShowBadge(false)
|
||||||
}
|
})
|
||||||
)
|
|
||||||
context.notificationManager.createNotificationChannels(channels)
|
context.notificationManager.createNotificationChannels(channels)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,11 +155,9 @@ object PreferenceKeys {
|
|||||||
|
|
||||||
fun sourceSharedPref(sourceId: Long) = "source_$sourceId"
|
fun sourceSharedPref(sourceId: Long) = "source_$sourceId"
|
||||||
|
|
||||||
|
|
||||||
fun trackUsername(syncId: Int) = "pref_mangasync_username_$syncId"
|
fun trackUsername(syncId: Int) = "pref_mangasync_username_$syncId"
|
||||||
|
|
||||||
fun trackPassword(syncId: Int) = "pref_mangasync_password_$syncId"
|
fun trackPassword(syncId: Int) = "pref_mangasync_password_$syncId"
|
||||||
|
|
||||||
fun trackToken(syncId: Int) = "track_token_$syncId"
|
fun trackToken(syncId: Int) = "track_token_$syncId"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,13 @@ import androidx.preference.PreferenceManager
|
|||||||
import com.f2prateek.rx.preferences.Preference
|
import com.f2prateek.rx.preferences.Preference
|
||||||
import com.f2prateek.rx.preferences.RxSharedPreferences
|
import com.f2prateek.rx.preferences.RxSharedPreferences
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
|
|
||||||
|
|
||||||
fun <T> Preference<T>.getOrDefault(): T = get() ?: defaultValue()!!
|
fun <T> Preference<T>.getOrDefault(): T = get() ?: defaultValue()!!
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@ package eu.kanade.tachiyomi.data.track
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import eu.kanade.tachiyomi.data.track.anilist.Anilist
|
import eu.kanade.tachiyomi.data.track.anilist.Anilist
|
||||||
|
import eu.kanade.tachiyomi.data.track.bangumi.Bangumi
|
||||||
import eu.kanade.tachiyomi.data.track.kitsu.Kitsu
|
import eu.kanade.tachiyomi.data.track.kitsu.Kitsu
|
||||||
import eu.kanade.tachiyomi.data.track.myanimelist.MyAnimeList
|
import eu.kanade.tachiyomi.data.track.myanimelist.MyAnimeList
|
||||||
import eu.kanade.tachiyomi.data.track.shikimori.Shikimori
|
import eu.kanade.tachiyomi.data.track.shikimori.Shikimori
|
||||||
import eu.kanade.tachiyomi.data.track.bangumi.Bangumi
|
|
||||||
|
|
||||||
class TrackManager(context: Context) {
|
class TrackManager(context: Context) {
|
||||||
|
|
||||||
@ -32,5 +32,4 @@ class TrackManager(context: Context) {
|
|||||||
fun getService(id: Int) = services.find { it.id == id }
|
fun getService(id: Int) = services.find { it.id == id }
|
||||||
|
|
||||||
fun hasLoggedServices() = services.any { it.isLogged }
|
fun hasLoggedServices() = services.any { it.isLogged }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ package eu.kanade.tachiyomi.data.track
|
|||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
@ -7,7 +7,6 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
@ -144,7 +143,6 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
|
|||||||
track.copyPersonalFrom(remoteTrack)
|
track.copyPersonalFrom(remoteTrack)
|
||||||
track.total_chapters = remoteTrack.total_chapters
|
track.total_chapters = remoteTrack.total_chapters
|
||||||
return track
|
return track
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun login(username: String, password: String) = login(password)
|
override suspend fun login(username: String, password: String) = login(password)
|
||||||
@ -184,7 +182,6 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val READING = 1
|
const val READING = 1
|
||||||
const val COMPLETED = 2
|
const val COMPLETED = 2
|
||||||
@ -202,6 +199,4 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
|
|||||||
const val POINT_5 = "POINT_5"
|
const val POINT_5 = "POINT_5"
|
||||||
const val POINT_3 = "POINT_3"
|
const val POINT_3 = "POINT_3"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@ import com.google.gson.JsonParser
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.network.jsonType
|
import eu.kanade.tachiyomi.network.jsonType
|
||||||
|
import java.util.Calendar
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import okhttp3.MediaType
|
import okhttp3.MediaType
|
||||||
@ -19,8 +21,6 @@ import okhttp3.OkHttpClient
|
|||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import java.util.Calendar
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.track.anilist
|
|||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
|
||||||
|
|
||||||
class AnilistInterceptor(private val anilist: Anilist, private var token: String?) : Interceptor {
|
class AnilistInterceptor(private val anilist: Anilist, private var token: String?) : Interceptor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,5 +53,4 @@ class AnilistInterceptor(private val anilist: Anilist, private var token: String
|
|||||||
this.oauth = oauth
|
this.oauth = oauth
|
||||||
anilist.saveOAuth(oauth)
|
anilist.saveOAuth(oauth)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -5,15 +5,16 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
|||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
data class OAuth(
|
data class OAuth(
|
||||||
val access_token: String,
|
val access_token: String,
|
||||||
val token_type: String,
|
val token_type: String,
|
||||||
val expires: Long,
|
val expires: Long,
|
||||||
val expires_in: Long) {
|
val expires_in: Long
|
||||||
|
) {
|
||||||
|
|
||||||
fun isExpired() = System.currentTimeMillis() > expires
|
fun isExpired() = System.currentTimeMillis() > expires
|
||||||
}
|
}
|
||||||
@ -26,7 +27,8 @@ data class ALManga(
|
|||||||
val type: String,
|
val type: String,
|
||||||
val publishing_status: String,
|
val publishing_status: String,
|
||||||
val start_date_fuzzy: Long,
|
val start_date_fuzzy: Long,
|
||||||
val total_chapters: Int) {
|
val total_chapters: Int
|
||||||
|
) {
|
||||||
|
|
||||||
fun toTrack() = TrackSearch.create(TrackManager.ANILIST).apply {
|
fun toTrack() = TrackSearch.create(TrackManager.ANILIST).apply {
|
||||||
media_id = this@ALManga.media_id
|
media_id = this@ALManga.media_id
|
||||||
|
@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.data.track.TrackManager
|
|||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.network.await
|
import eu.kanade.tachiyomi.network.await
|
||||||
|
import java.net.URLEncoder
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import okhttp3.CacheControl
|
import okhttp3.CacheControl
|
||||||
@ -18,7 +19,6 @@ import okhttp3.FormBody
|
|||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.net.URLEncoder
|
|
||||||
|
|
||||||
class BangumiApi(private val client: OkHttpClient, interceptor: BangumiInterceptor) {
|
class BangumiApi(private val client: OkHttpClient, interceptor: BangumiInterceptor) {
|
||||||
|
|
||||||
@ -26,14 +26,10 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
|
|||||||
private val authClient = client.newBuilder().addInterceptor(interceptor).build()
|
private val authClient = client.newBuilder().addInterceptor(interceptor).build()
|
||||||
|
|
||||||
suspend fun addLibManga(track: Track): Track {
|
suspend fun addLibManga(track: Track): Track {
|
||||||
val body = FormBody.Builder()
|
val body = FormBody.Builder().add("rating", track.score.toInt().toString())
|
||||||
.add("rating", track.score.toInt().toString())
|
.add("status", track.toBangumiStatus()).build()
|
||||||
.add("status", track.toBangumiStatus())
|
val request =
|
||||||
.build()
|
Request.Builder().url("$apiUrl/collection/${track.media_id}/update").post(body).build()
|
||||||
val request = Request.Builder()
|
|
||||||
.url("$apiUrl/collection/${track.media_id}/update")
|
|
||||||
.post(body)
|
|
||||||
.build()
|
|
||||||
val response = authClient.newCall(request).await()
|
val response = authClient.newCall(request).await()
|
||||||
return track
|
return track
|
||||||
}
|
}
|
||||||
@ -41,21 +37,16 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
|
|||||||
suspend fun updateLibManga(track: Track): Track {
|
suspend fun updateLibManga(track: Track): Track {
|
||||||
// chapter update
|
// chapter update
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val body = FormBody.Builder()
|
val body =
|
||||||
.add("watched_eps", track.last_chapter_read.toString())
|
FormBody.Builder().add("watched_eps", track.last_chapter_read.toString()).build()
|
||||||
.build()
|
val request =
|
||||||
val request = Request.Builder()
|
Request.Builder().url("$apiUrl/subject/${track.media_id}/update/watched_eps")
|
||||||
.url("$apiUrl/subject/${track.media_id}/update/watched_eps")
|
.post(body).build()
|
||||||
.post(body)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
// read status update
|
// read status update
|
||||||
val sbody = FormBody.Builder()
|
val sbody = FormBody.Builder().add("status", track.toBangumiStatus()).build()
|
||||||
.add("status", track.toBangumiStatus())
|
val srequest =
|
||||||
.build()
|
Request.Builder().url("$apiUrl/collection/${track.media_id}/update").post(sbody)
|
||||||
val srequest = Request.Builder()
|
|
||||||
.url("$apiUrl/collection/${track.media_id}/update")
|
|
||||||
.post(sbody)
|
|
||||||
.build()
|
.build()
|
||||||
authClient.newCall(srequest).execute()
|
authClient.newCall(srequest).execute()
|
||||||
authClient.newCall(request).execute()
|
authClient.newCall(request).execute()
|
||||||
@ -67,13 +58,8 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
|
|||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val url = Uri.parse(
|
val url = Uri.parse(
|
||||||
"$apiUrl/search/subject/${URLEncoder.encode(search, Charsets.UTF_8.name())}"
|
"$apiUrl/search/subject/${URLEncoder.encode(search, Charsets.UTF_8.name())}"
|
||||||
).buildUpon()
|
).buildUpon().appendQueryParameter("max_results", "20").build()
|
||||||
.appendQueryParameter("max_results", "20")
|
val request = Request.Builder().url(url.toString()).get().build()
|
||||||
.build()
|
|
||||||
val request = Request.Builder()
|
|
||||||
.url(url.toString())
|
|
||||||
.get()
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val netResponse = authClient.newCall(request).await()
|
val netResponse = authClient.newCall(request).await()
|
||||||
var responseBody = netResponse.body?.string().orEmpty()
|
var responseBody = netResponse.body?.string().orEmpty()
|
||||||
@ -106,8 +92,8 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
|
|||||||
return Track.create(TrackManager.BANGUMI).apply {
|
return Track.create(TrackManager.BANGUMI).apply {
|
||||||
title = mangas["name"].asString
|
title = mangas["name"].asString
|
||||||
media_id = mangas["id"].asInt
|
media_id = mangas["id"].asInt
|
||||||
score = if (mangas["rating"] != null)
|
score =
|
||||||
(if (mangas["rating"].isJsonObject) mangas["rating"].obj["score"].asFloat else 0f)
|
if (mangas["rating"] != null) (if (mangas["rating"].isJsonObject) mangas["rating"].obj["score"].asFloat else 0f)
|
||||||
else 0f
|
else 0f
|
||||||
status = Bangumi.DEFAULT_STATUS
|
status = Bangumi.DEFAULT_STATUS
|
||||||
tracking_url = mangas["url"].asString
|
tracking_url = mangas["url"].asString
|
||||||
@ -117,10 +103,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
|
|||||||
suspend fun findLibManga(track: Track): Track? {
|
suspend fun findLibManga(track: Track): Track? {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val urlMangas = "$apiUrl/subject/${track.media_id}"
|
val urlMangas = "$apiUrl/subject/${track.media_id}"
|
||||||
val requestMangas = Request.Builder()
|
val requestMangas = Request.Builder().url(urlMangas).get().build()
|
||||||
.url(urlMangas)
|
|
||||||
.get()
|
|
||||||
.build()
|
|
||||||
val netResponse = authClient.newCall(requestMangas).execute()
|
val netResponse = authClient.newCall(requestMangas).execute()
|
||||||
val responseBody = netResponse.body?.string().orEmpty()
|
val responseBody = netResponse.body?.string().orEmpty()
|
||||||
jsonToTrack(JsonParser.parseString(responseBody).obj)
|
jsonToTrack(JsonParser.parseString(responseBody).obj)
|
||||||
@ -129,10 +112,8 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
|
|||||||
|
|
||||||
suspend fun statusLibManga(track: Track): Track? {
|
suspend fun statusLibManga(track: Track): Track? {
|
||||||
val urlUserRead = "$apiUrl/collection/${track.media_id}"
|
val urlUserRead = "$apiUrl/collection/${track.media_id}"
|
||||||
val requestUserRead = Request.Builder()
|
val requestUserRead =
|
||||||
.url(urlUserRead)
|
Request.Builder().url(urlUserRead).cacheControl(CacheControl.FORCE_NETWORK).get()
|
||||||
.cacheControl(CacheControl.FORCE_NETWORK)
|
|
||||||
.get()
|
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
// todo get user readed chapter here
|
// todo get user readed chapter here
|
||||||
@ -157,12 +138,8 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
|
|||||||
|
|
||||||
private fun accessTokenRequest(code: String) = POST(
|
private fun accessTokenRequest(code: String) = POST(
|
||||||
oauthUrl,
|
oauthUrl,
|
||||||
body = FormBody.Builder()
|
body = FormBody.Builder().add("grant_type", "authorization_code").add("client_id", clientId)
|
||||||
.add("grant_type", "authorization_code")
|
.add("client_secret", clientSecret).add("code", code).add("redirect_uri", redirectUrl)
|
||||||
.add("client_id", clientId)
|
|
||||||
.add("client_secret", clientSecret)
|
|
||||||
.add("code", code)
|
|
||||||
.add("redirect_uri", redirectUrl)
|
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -182,22 +159,15 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
|
|||||||
return "$baseMangaUrl/$remoteId"
|
return "$baseMangaUrl/$remoteId"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun authUrl() =
|
fun authUrl() = Uri.parse(loginUrl).buildUpon().appendQueryParameter("client_id", clientId)
|
||||||
Uri.parse(loginUrl).buildUpon()
|
|
||||||
.appendQueryParameter("client_id", clientId)
|
|
||||||
.appendQueryParameter("response_type", "code")
|
.appendQueryParameter("response_type", "code")
|
||||||
.appendQueryParameter("redirect_uri", redirectUrl)
|
.appendQueryParameter("redirect_uri", redirectUrl).build()
|
||||||
.build()
|
|
||||||
|
|
||||||
fun refreshTokenRequest(token: String) = POST(
|
fun refreshTokenRequest(token: String) = POST(
|
||||||
oauthUrl,
|
oauthUrl,
|
||||||
body = FormBody.Builder()
|
body = FormBody.Builder().add("grant_type", "refresh_token").add("client_id", clientId)
|
||||||
.add("grant_type", "refresh_token")
|
.add("client_secret", clientSecret).add("refresh_token", token)
|
||||||
.add("client_id", clientId)
|
.add("redirect_uri", redirectUrl).build()
|
||||||
.add("client_secret", clientSecret)
|
|
||||||
.add("refresh_token", token)
|
|
||||||
.add("redirect_uri", redirectUrl)
|
|
||||||
.build()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,5 +45,3 @@ data class Avatar(
|
|||||||
val medium: String? = "",
|
val medium: String? = "",
|
||||||
val small: String? = ""
|
val small: String? = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
|
import java.text.DecimalFormat
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.DecimalFormat
|
|
||||||
|
|
||||||
class Kitsu(private val context: Context, id: Int) : TrackService(id) {
|
class Kitsu(private val context: Context, id: Int) : TrackService(id) {
|
||||||
|
|
||||||
|
@ -42,5 +42,4 @@ class KitsuInterceptor(val kitsu: Kitsu, val gson: Gson) : Interceptor {
|
|||||||
this.oauth = oauth
|
this.oauth = oauth
|
||||||
kitsu.saveToken(oauth)
|
kitsu.saveToken(oauth)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
package eu.kanade.tachiyomi.data.track.kitsu
|
package eu.kanade.tachiyomi.data.track.kitsu
|
||||||
|
|
||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import com.github.salomonbrys.kotson.*
|
import com.github.salomonbrys.kotson.byInt
|
||||||
|
import com.github.salomonbrys.kotson.byString
|
||||||
|
import com.github.salomonbrys.kotson.nullInt
|
||||||
|
import com.github.salomonbrys.kotson.nullObj
|
||||||
|
import com.github.salomonbrys.kotson.nullString
|
||||||
|
import com.github.salomonbrys.kotson.obj
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class KitsuSearchManga(obj: JsonObject) {
|
class KitsuSearchManga(obj: JsonObject) {
|
||||||
val id by obj.byInt
|
val id by obj.byInt
|
||||||
@ -40,7 +46,6 @@ class KitsuSearchManga(obj: JsonObject) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class KitsuLibManga(obj: JsonObject, manga: JsonObject) {
|
class KitsuLibManga(obj: JsonObject, manga: JsonObject) {
|
||||||
val id by manga.byInt
|
val id by manga.byInt
|
||||||
private val canonicalTitle by manga["attributes"].byString
|
private val canonicalTitle by manga["attributes"].byString
|
||||||
@ -77,7 +82,6 @@ class KitsuLibManga(obj: JsonObject, manga: JsonObject) {
|
|||||||
"planned" -> Kitsu.PLAN_TO_READ
|
"planned" -> Kitsu.PLAN_TO_READ
|
||||||
else -> throw Exception("Unknown status")
|
else -> throw Exception("Unknown status")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Track.toKitsuStatus() = when (status) {
|
fun Track.toKitsuStatus() = when (status) {
|
||||||
|
@ -5,7 +5,8 @@ data class OAuth(
|
|||||||
val token_type: String,
|
val token_type: String,
|
||||||
val created_at: Long,
|
val created_at: Long,
|
||||||
val expires_in: Long,
|
val expires_in: Long,
|
||||||
val refresh_token: String?) {
|
val refresh_token: String?
|
||||||
|
) {
|
||||||
|
|
||||||
fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600)
|
fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600)
|
||||||
}
|
}
|
@ -58,7 +58,5 @@ class TrackSearch : Track {
|
|||||||
fun create(serviceId: Int): TrackSearch = TrackSearch().apply {
|
fun create(serviceId: Int): TrackSearch = TrackSearch().apply {
|
||||||
sync_id = serviceId
|
sync_id = serviceId
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -131,8 +131,7 @@ class MyAnimeList(private val context: Context, id: Int) : TrackService(id) {
|
|||||||
var ckCount = 0
|
var ckCount = 0
|
||||||
val url = BASE_URL.toHttpUrlOrNull()!!
|
val url = BASE_URL.toHttpUrlOrNull()!!
|
||||||
for (ck in networkService.cookieManager.get(url)) {
|
for (ck in networkService.cookieManager.get(url)) {
|
||||||
if (ck.name == USER_SESSION_COOKIE || ck.name == LOGGED_IN_COOKIE)
|
if (ck.name == USER_SESSION_COOKIE || ck.name == LOGGED_IN_COOKIE) ckCount++
|
||||||
ckCount++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ckCount == 2
|
return ckCount == 2
|
||||||
|
@ -36,12 +36,10 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
val realQuery = query.take(100)
|
val realQuery = query.take(100)
|
||||||
val response = client.newCall(GET(searchUrl(realQuery))).await()
|
val response = client.newCall(GET(searchUrl(realQuery))).await()
|
||||||
val matches = Jsoup.parse(response.consumeBody())
|
val matches = Jsoup.parse(response.consumeBody())
|
||||||
.select("div.js-categories-seasonal.js-block-list.list")
|
.select("div.js-categories-seasonal.js-block-list.list").select("table")
|
||||||
.select("table").select("tbody")
|
.select("tbody").select("tr").drop(1)
|
||||||
.select("tr").drop(1)
|
|
||||||
|
|
||||||
matches.filter { row -> row.select(TD)[2].text() != "Novel" }
|
matches.filter { row -> row.select(TD)[2].text() != "Novel" }.map { row ->
|
||||||
.map { row ->
|
|
||||||
TrackSearch.create(TrackManager.MYANIMELIST).apply {
|
TrackSearch.create(TrackManager.MYANIMELIST).apply {
|
||||||
title = row.searchTitle()
|
title = row.searchTitle()
|
||||||
media_id = row.searchMediaId()
|
media_id = row.searchMediaId()
|
||||||
@ -53,8 +51,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
publishing_type = row.searchPublishingType()
|
publishing_type = row.searchPublishingType()
|
||||||
start_date = row.searchStartDate()
|
start_date = row.searchStartDate()
|
||||||
}
|
}
|
||||||
}
|
}.toList()
|
||||||
.toList()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,9 +114,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
private suspend fun getSessionInfo(): String {
|
private suspend fun getSessionInfo(): String {
|
||||||
val response = client.newCall(GET(loginUrl())).execute()
|
val response = client.newCall(GET(loginUrl())).execute()
|
||||||
|
|
||||||
return Jsoup.parse(response.consumeBody())
|
return Jsoup.parse(response.consumeBody()).select("meta[name=csrf_token]").attr("content")
|
||||||
.select("meta[name=csrf_token]")
|
|
||||||
.attr("content")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun login(username: String, password: String, csrf: String) {
|
private suspend fun login(username: String, password: String, csrf: String) {
|
||||||
@ -147,8 +142,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
total_chapters = it.selectInt("manga_chapters")
|
total_chapters = it.selectInt("manga_chapters")
|
||||||
tracking_url = mangaUrl(media_id)
|
tracking_url = mangaUrl(media_id)
|
||||||
}
|
}
|
||||||
}
|
}.toList()
|
||||||
.toList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getListUrl(): String {
|
private suspend fun getListUrl(): String {
|
||||||
@ -156,9 +150,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
val response =
|
val response =
|
||||||
authClient.newCall(POST(url = exportListUrl(), body = exportPostBody())).execute()
|
authClient.newCall(POST(url = exportListUrl(), body = exportPostBody())).execute()
|
||||||
|
|
||||||
baseUrl + Jsoup.parse(response.consumeBody())
|
baseUrl + Jsoup.parse(response.consumeBody()).select("div.goodresult").select("a")
|
||||||
.select("div.goodresult")
|
|
||||||
.select("a")
|
|
||||||
.attr("href")
|
.attr("href")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,66 +171,43 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
|
|
||||||
private fun mangaUrl(remoteId: Int) = baseMangaUrl + remoteId
|
private fun mangaUrl(remoteId: Int) = baseMangaUrl + remoteId
|
||||||
|
|
||||||
private fun loginUrl() = Uri.parse(baseUrl).buildUpon()
|
private fun loginUrl() = Uri.parse(baseUrl).buildUpon().appendPath("login.php").toString()
|
||||||
.appendPath("login.php")
|
|
||||||
.toString()
|
|
||||||
|
|
||||||
private fun searchUrl(query: String): String {
|
private fun searchUrl(query: String): String {
|
||||||
val col = "c[]"
|
val col = "c[]"
|
||||||
return Uri.parse(baseUrl).buildUpon()
|
return Uri.parse(baseUrl).buildUpon().appendPath("manga.php")
|
||||||
.appendPath("manga.php")
|
.appendQueryParameter("q", query).appendQueryParameter(col, "a")
|
||||||
.appendQueryParameter("q", query)
|
.appendQueryParameter(col, "b").appendQueryParameter(col, "c")
|
||||||
.appendQueryParameter(col, "a")
|
.appendQueryParameter(col, "d").appendQueryParameter(col, "e")
|
||||||
.appendQueryParameter(col, "b")
|
.appendQueryParameter(col, "g").toString()
|
||||||
.appendQueryParameter(col, "c")
|
|
||||||
.appendQueryParameter(col, "d")
|
|
||||||
.appendQueryParameter(col, "e")
|
|
||||||
.appendQueryParameter(col, "g")
|
|
||||||
.toString()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun exportListUrl() = Uri.parse(baseUrl).buildUpon()
|
private fun exportListUrl() = Uri.parse(baseUrl).buildUpon().appendPath("panel.php")
|
||||||
.appendPath("panel.php")
|
.appendQueryParameter("go", "export").toString()
|
||||||
.appendQueryParameter("go", "export")
|
|
||||||
.toString()
|
|
||||||
|
|
||||||
private fun updateUrl() = Uri.parse(baseModifyListUrl).buildUpon()
|
private fun updateUrl() =
|
||||||
.appendPath("edit.json")
|
Uri.parse(baseModifyListUrl).buildUpon().appendPath("edit.json").toString()
|
||||||
.toString()
|
|
||||||
|
|
||||||
private fun addUrl() = Uri.parse(baseModifyListUrl).buildUpon()
|
private fun addUrl() =
|
||||||
.appendPath("add.json")
|
Uri.parse(baseModifyListUrl).buildUpon().appendPath("add.json").toString()
|
||||||
.toString()
|
|
||||||
|
|
||||||
private fun listEntryUrl(mediaId: Int) = Uri.parse(baseModifyListUrl).buildUpon()
|
private fun listEntryUrl(mediaId: Int) =
|
||||||
.appendPath(mediaId.toString())
|
Uri.parse(baseModifyListUrl).buildUpon().appendPath(mediaId.toString())
|
||||||
.appendPath("edit")
|
.appendPath("edit").toString()
|
||||||
.toString()
|
|
||||||
|
|
||||||
private fun loginPostBody(username: String, password: String, csrf: String): RequestBody {
|
private fun loginPostBody(username: String, password: String, csrf: String): RequestBody {
|
||||||
return FormBody.Builder()
|
return FormBody.Builder().add("user_name", username).add("password", password)
|
||||||
.add("user_name", username)
|
.add("cookie", "1").add("sublogin", "Login").add("submit", "1").add(CSRF, csrf)
|
||||||
.add("password", password)
|
|
||||||
.add("cookie", "1")
|
|
||||||
.add("sublogin", "Login")
|
|
||||||
.add("submit", "1")
|
|
||||||
.add(CSRF, csrf)
|
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun exportPostBody(): RequestBody {
|
private fun exportPostBody(): RequestBody {
|
||||||
return FormBody.Builder()
|
return FormBody.Builder().add("type", "2").add("subexport", "Export My List").build()
|
||||||
.add("type", "2")
|
|
||||||
.add("subexport", "Export My List")
|
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mangaPostPayload(track: Track): RequestBody {
|
private fun mangaPostPayload(track: Track): RequestBody {
|
||||||
val body = JSONObject()
|
val body = JSONObject().put("manga_id", track.media_id).put("status", track.status)
|
||||||
.put("manga_id", track.media_id)
|
.put("score", track.score).put("num_read_chapters", track.last_chapter_read)
|
||||||
.put("status", track.status)
|
|
||||||
.put("score", track.score)
|
|
||||||
.put("num_read_chapters", track.last_chapter_read)
|
|
||||||
|
|
||||||
return body.toString()
|
return body.toString()
|
||||||
.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
|
.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
|
||||||
@ -249,19 +218,13 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
|
|||||||
private fun Element.searchTotalChapters() =
|
private fun Element.searchTotalChapters() =
|
||||||
if (select(TD)[4].text() == "-") 0 else select(TD)[4].text().toInt()
|
if (select(TD)[4].text() == "-") 0 else select(TD)[4].text().toInt()
|
||||||
|
|
||||||
private fun Element.searchCoverUrl() = select("img")
|
private fun Element.searchCoverUrl() =
|
||||||
.attr("data-src")
|
select("img").attr("data-src").split("\\?")[0].replace("/r/50x70/", "/")
|
||||||
.split("\\?")[0]
|
|
||||||
.replace("/r/50x70/", "/")
|
|
||||||
|
|
||||||
private fun Element.searchMediaId() = select("div.picSurround")
|
private fun Element.searchMediaId() =
|
||||||
.select("a").attr("id")
|
select("div.picSurround").select("a").attr("id").replace("sarea", "").toInt()
|
||||||
.replace("sarea", "")
|
|
||||||
.toInt()
|
|
||||||
|
|
||||||
private fun Element.searchSummary() = select("div.pt4")
|
private fun Element.searchSummary() = select("div.pt4").first().ownText()!!
|
||||||
.first()
|
|
||||||
.ownText()!!
|
|
||||||
|
|
||||||
private fun Element.searchPublishingStatus() =
|
private fun Element.searchPublishingStatus() =
|
||||||
if (select(TD).last().text() == "-") "Publishing" else "Finished"
|
if (select(TD).last().text() == "-") "Publishing" else "Finished"
|
||||||
|
@ -22,7 +22,6 @@ class MyAnimeListInterceptor(private val myanimelist: MyAnimeList) : Interceptor
|
|||||||
}
|
}
|
||||||
val request = chain.request()
|
val request = chain.request()
|
||||||
return chain.proceed(updateRequest(request))
|
return chain.proceed(updateRequest(request))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateRequest(request: Request): Request {
|
private fun updateRequest(request: Request): Request {
|
||||||
|
@ -6,7 +6,6 @@ import com.google.gson.Gson
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@ import eu.kanade.tachiyomi.data.track.TrackManager
|
|||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
@ -44,10 +43,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
val body = payload.toString().toRequestBody(jsonime)
|
val body = payload.toString().toRequestBody(jsonime)
|
||||||
val request = Request.Builder()
|
val request = Request.Builder().url("$apiUrl/v2/user_rates").post(body).build()
|
||||||
.url("$apiUrl/v2/user_rates")
|
|
||||||
.post(body)
|
|
||||||
.build()
|
|
||||||
authClient.newCall(request).execute()
|
authClient.newCall(request).execute()
|
||||||
track
|
track
|
||||||
}
|
}
|
||||||
@ -55,15 +51,11 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
|
|||||||
|
|
||||||
suspend fun search(search: String): List<TrackSearch> {
|
suspend fun search(search: String): List<TrackSearch> {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val url = Uri.parse("$apiUrl/mangas").buildUpon()
|
val url =
|
||||||
.appendQueryParameter("order", "popularity")
|
Uri.parse("$apiUrl/mangas").buildUpon().appendQueryParameter("order", "popularity")
|
||||||
.appendQueryParameter("search", search)
|
.appendQueryParameter("search", search).appendQueryParameter("limit", "20")
|
||||||
.appendQueryParameter("limit", "20")
|
|
||||||
.build()
|
|
||||||
val request = Request.Builder()
|
|
||||||
.url(url.toString())
|
|
||||||
.get()
|
|
||||||
.build()
|
.build()
|
||||||
|
val request = Request.Builder().url(url.toString()).get().build()
|
||||||
val netResponse = authClient.newCall(request).execute()
|
val netResponse = authClient.newCall(request).execute()
|
||||||
|
|
||||||
val responseBody = netResponse.body?.string().orEmpty()
|
val responseBody = netResponse.body?.string().orEmpty()
|
||||||
@ -73,7 +65,6 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
|
|||||||
val response = JsonParser.parseString(responseBody).array
|
val response = JsonParser.parseString(responseBody).array
|
||||||
|
|
||||||
response.map { jsonToSearch(it.obj) }
|
response.map { jsonToSearch(it.obj) }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,20 +99,13 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
|
|||||||
val url = Uri.parse("$apiUrl/v2/user_rates").buildUpon()
|
val url = Uri.parse("$apiUrl/v2/user_rates").buildUpon()
|
||||||
.appendQueryParameter("user_id", user_id)
|
.appendQueryParameter("user_id", user_id)
|
||||||
.appendQueryParameter("target_id", track.media_id.toString())
|
.appendQueryParameter("target_id", track.media_id.toString())
|
||||||
.appendQueryParameter("target_type", "Manga")
|
.appendQueryParameter("target_type", "Manga").build()
|
||||||
.build()
|
val request = Request.Builder().url(url.toString()).get().build()
|
||||||
val request = Request.Builder()
|
|
||||||
.url(url.toString())
|
|
||||||
.get()
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val urlMangas = Uri.parse("$apiUrl/mangas").buildUpon()
|
val urlMangas =
|
||||||
.appendPath(track.media_id.toString())
|
Uri.parse("$apiUrl/mangas").buildUpon().appendPath(track.media_id.toString())
|
||||||
.build()
|
|
||||||
val requestMangas = Request.Builder()
|
|
||||||
.url(urlMangas.toString())
|
|
||||||
.get()
|
|
||||||
.build()
|
.build()
|
||||||
|
val requestMangas = Request.Builder().url(urlMangas.toString()).get().build()
|
||||||
|
|
||||||
val requestMangasResponse = authClient.newCall(requestMangas).execute()
|
val requestMangasResponse = authClient.newCall(requestMangas).execute()
|
||||||
val requestMangasBody = requestMangasResponse.body?.string().orEmpty()
|
val requestMangasBody = requestMangasResponse.body?.string().orEmpty()
|
||||||
@ -162,12 +146,8 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
|
|||||||
|
|
||||||
private fun accessTokenRequest(code: String) = POST(
|
private fun accessTokenRequest(code: String) = POST(
|
||||||
oauthUrl,
|
oauthUrl,
|
||||||
body = FormBody.Builder()
|
body = FormBody.Builder().add("grant_type", "authorization_code").add("client_id", clientId)
|
||||||
.add("grant_type", "authorization_code")
|
.add("client_secret", clientSecret).add("code", code).add("redirect_uri", redirectUrl)
|
||||||
.add("client_id", clientId)
|
|
||||||
.add("client_secret", clientSecret)
|
|
||||||
.add("code", code)
|
|
||||||
.add("redirect_uri", redirectUrl)
|
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -189,21 +169,14 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
|
|||||||
return "$baseMangaUrl/$remoteId"
|
return "$baseMangaUrl/$remoteId"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun authUrl() =
|
fun authUrl() = Uri.parse(loginUrl).buildUpon().appendQueryParameter("client_id", clientId)
|
||||||
Uri.parse(loginUrl).buildUpon()
|
|
||||||
.appendQueryParameter("client_id", clientId)
|
|
||||||
.appendQueryParameter("redirect_uri", redirectUrl)
|
.appendQueryParameter("redirect_uri", redirectUrl)
|
||||||
.appendQueryParameter("response_type", "code")
|
.appendQueryParameter("response_type", "code").build()
|
||||||
.build()
|
|
||||||
|
|
||||||
fun refreshTokenRequest(token: String) = POST(
|
fun refreshTokenRequest(token: String) = POST(
|
||||||
oauthUrl,
|
oauthUrl,
|
||||||
body = FormBody.Builder()
|
body = FormBody.Builder().add("grant_type", "refresh_token").add("client_id", clientId)
|
||||||
.add("grant_type", "refresh_token")
|
.add("client_secret", clientSecret).add("refresh_token", token).build()
|
||||||
.add("client_id", clientId)
|
|
||||||
.add("client_secret", clientSecret)
|
|
||||||
.add("refresh_token", token)
|
|
||||||
.build()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,9 @@ data class OAuth(
|
|||||||
val token_type: String,
|
val token_type: String,
|
||||||
val created_at: Long,
|
val created_at: Long,
|
||||||
val expires_in: Long,
|
val expires_in: Long,
|
||||||
val refresh_token: String?) {
|
val refresh_token: String?
|
||||||
|
) {
|
||||||
|
|
||||||
// Access token lives 1 day
|
// Access token lives 1 day
|
||||||
fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600)
|
fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,5 +9,4 @@ interface Release {
|
|||||||
* @return download link of latest release.
|
* @return download link of latest release.
|
||||||
*/
|
*/
|
||||||
val downloadLink: String
|
val downloadLink: String
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,4 @@ abstract class UpdateChecker {
|
|||||||
* Returns suspended result containing release information
|
* Returns suspended result containing release information
|
||||||
*/
|
*/
|
||||||
abstract suspend fun checkForUpdate(): UpdateResult
|
abstract suspend fun checkForUpdate(): UpdateResult
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,4 @@ abstract class UpdateResult {
|
|||||||
|
|
||||||
open class NewUpdate<T : Release>(val release: T) : UpdateResult()
|
open class NewUpdate<T : Release>(val release: T) : UpdateResult()
|
||||||
open class NoNewUpdate : UpdateResult()
|
open class NoNewUpdate : UpdateResult()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,17 +10,16 @@ import com.evernote.android.job.JobRequest
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
|
|
||||||
class UpdaterJob : Job() {
|
class UpdaterJob : Job() {
|
||||||
|
|
||||||
override fun onRunJob(params: Params): Result {
|
override fun onRunJob(params: Params): Result {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
val result = try { UpdateChecker.getUpdateChecker().checkForUpdate() }
|
val result = try { UpdateChecker.getUpdateChecker().checkForUpdate() } catch (e: Exception) { return@launch }
|
||||||
catch (e: Exception) { return@launch }
|
|
||||||
if (result is UpdateResult.NewUpdate<*>) {
|
if (result is UpdateResult.NewUpdate<*>) {
|
||||||
val url = result.release.downloadLink
|
val url = result.release.downloadLink
|
||||||
|
|
||||||
@ -73,5 +72,4 @@ class UpdaterJob : Job() {
|
|||||||
JobManager.instance().cancelAllForTag(TAG)
|
JobManager.instance().cancelAllForTag(TAG)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,9 @@ import eu.kanade.tachiyomi.network.ProgressListener
|
|||||||
import eu.kanade.tachiyomi.network.newCallWithProgress
|
import eu.kanade.tachiyomi.network.newCallWithProgress
|
||||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||||
import eu.kanade.tachiyomi.util.storage.saveTo
|
import eu.kanade.tachiyomi.util.storage.saveTo
|
||||||
|
import java.io.File
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class UpdaterService : IntentService(UpdaterService::class.java.name) {
|
class UpdaterService : IntentService(UpdaterService::class.java.name) {
|
||||||
|
|
||||||
@ -119,5 +119,3 @@ class UpdaterService : IntentService(UpdaterService::class.java.name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user