mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 16:18:55 +01:00 
			
		
		
		
	Run linter
This commit is contained in:
		@@ -90,5 +90,4 @@ open class App : Application(), LifecycleObserver {
 | 
			
		||||
    protected open fun setupNotificationChannels() {
 | 
			
		||||
        Notifications.createChannels(this)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,5 @@ class AppModule(val app: Application) : InjektModule {
 | 
			
		||||
        GlobalScope.launch { get<DatabaseHelper>() }
 | 
			
		||||
 | 
			
		||||
        GlobalScope.launch { get<DownloadManager>() }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -59,5 +59,4 @@ object Migrations {
 | 
			
		||||
        }
 | 
			
		||||
        return false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.data.backup
 | 
			
		||||
 | 
			
		||||
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
object BackupConst {
 | 
			
		||||
 | 
			
		||||
    const val INTENT_FILTER = "SettingsBackupFragment"
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,8 @@ import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
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.data.database.models.Manga
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * [IntentService] used to backup [Manga] information to [JsonArray]
 | 
			
		||||
@@ -45,7 +45,6 @@ class BackupCreateService : IntentService(NAME) {
 | 
			
		||||
            }
 | 
			
		||||
            context.startService(intent)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val backupManager by lazy { BackupManager(this) }
 | 
			
		||||
@@ -59,5 +58,4 @@ class BackupCreateService : IntentService(NAME) {
 | 
			
		||||
        // Create backup
 | 
			
		||||
        backupManager.createBackup(uri, flags, false)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -32,10 +32,10 @@ import eu.kanade.tachiyomi.source.Source
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.sendLocalBroadcast
 | 
			
		||||
import kotlin.math.max
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import kotlin.math.max
 | 
			
		||||
 | 
			
		||||
class BackupManager(val context: Context, version: Int = CURRENT_VERSION) {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,17 +26,17 @@ import eu.kanade.tachiyomi.source.Source
 | 
			
		||||
import eu.kanade.tachiyomi.util.lang.chop
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.isServiceRunning
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.sendLocalBroadcast
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import rx.Subscription
 | 
			
		||||
import rx.schedulers.Schedulers
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.io.File
 | 
			
		||||
import java.text.SimpleDateFormat
 | 
			
		||||
import java.util.Date
 | 
			
		||||
import java.util.Locale
 | 
			
		||||
import java.util.concurrent.ExecutorService
 | 
			
		||||
import java.util.concurrent.Executors
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import rx.Subscription
 | 
			
		||||
import rx.schedulers.Schedulers
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Restores backup from json file
 | 
			
		||||
@@ -119,7 +119,6 @@ class BackupRestoreService : Service() {
 | 
			
		||||
     */
 | 
			
		||||
    internal val trackManager: TrackManager by injectLazy()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private lateinit var executor: ExecutorService
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -250,7 +249,6 @@ class BackupRestoreService : Service() {
 | 
			
		||||
                        putExtra(BackupConst.ACTION, BackupConst.ACTION_RESTORE_COMPLETED_DIALOG)
 | 
			
		||||
                    }
 | 
			
		||||
                    sendLocalBroadcast(completeIntent)
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                .doOnError { error ->
 | 
			
		||||
                    Timber.e(error)
 | 
			
		||||
@@ -296,9 +294,13 @@ class BackupRestoreService : Service() {
 | 
			
		||||
     * @param tracks tracking data from json
 | 
			
		||||
     * @return [Observable] containing manga restore information
 | 
			
		||||
     */
 | 
			
		||||
    private fun getMangaRestoreObservable(manga: Manga, chapters: List<Chapter>,
 | 
			
		||||
                                          categories: List<String>, history: List<DHistory>,
 | 
			
		||||
                                          tracks: List<Track>): Observable<Manga>? {
 | 
			
		||||
    private fun getMangaRestoreObservable(
 | 
			
		||||
        manga: Manga,
 | 
			
		||||
        chapters: List<Chapter>,
 | 
			
		||||
        categories: List<String>,
 | 
			
		||||
        history: List<DHistory>,
 | 
			
		||||
        tracks: List<Track>
 | 
			
		||||
    ): Observable<Manga>? {
 | 
			
		||||
        // Get source
 | 
			
		||||
        val source = backupManager.sourceManager.getOrStub(manga.source)
 | 
			
		||||
        val dbManga = backupManager.getMangaFromDatabase(manga)
 | 
			
		||||
@@ -321,9 +323,14 @@ class BackupRestoreService : Service() {
 | 
			
		||||
     * @param chapters chapters of manga that needs updating
 | 
			
		||||
     * @param categories categories that need updating
 | 
			
		||||
     */
 | 
			
		||||
    private fun mangaFetchObservable(source: Source, manga: Manga, chapters: List<Chapter>,
 | 
			
		||||
                                     categories: List<String>, history: List<DHistory>,
 | 
			
		||||
                                     tracks: List<Track>): Observable<Manga> {
 | 
			
		||||
    private fun mangaFetchObservable(
 | 
			
		||||
        source: Source,
 | 
			
		||||
        manga: Manga,
 | 
			
		||||
        chapters: List<Chapter>,
 | 
			
		||||
        categories: List<String>,
 | 
			
		||||
        history: List<DHistory>,
 | 
			
		||||
        tracks: List<Track>
 | 
			
		||||
    ): Observable<Manga> {
 | 
			
		||||
        return backupManager.restoreMangaFetchObservable(source, manga)
 | 
			
		||||
                .onErrorReturn {
 | 
			
		||||
                    errors.add(Date() to "${manga.title} - ${it.message}")
 | 
			
		||||
@@ -349,9 +356,14 @@ class BackupRestoreService : Service() {
 | 
			
		||||
                }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun mangaNoFetchObservable(source: Source, backupManga: Manga, chapters: List<Chapter>,
 | 
			
		||||
                                       categories: List<String>, history: List<DHistory>,
 | 
			
		||||
                                       tracks: List<Track>): Observable<Manga> {
 | 
			
		||||
    private fun mangaNoFetchObservable(
 | 
			
		||||
        source: Source,
 | 
			
		||||
        backupManga: Manga,
 | 
			
		||||
        chapters: List<Chapter>,
 | 
			
		||||
        categories: List<String>,
 | 
			
		||||
        history: List<DHistory>,
 | 
			
		||||
        tracks: List<Track>
 | 
			
		||||
    ): Observable<Manga> {
 | 
			
		||||
 | 
			
		||||
        return Observable.just(backupManga)
 | 
			
		||||
                .flatMap { manga ->
 | 
			
		||||
@@ -434,8 +446,13 @@ class BackupRestoreService : Service() {
 | 
			
		||||
     * @param amount total restoreAmount of manga
 | 
			
		||||
     * @param title title of restored manga
 | 
			
		||||
     */
 | 
			
		||||
    private fun showRestoreProgress(progress: Int, amount: Int, title: String, errors: Int,
 | 
			
		||||
                                    content: String = getString(R.string.dialog_restoring_backup, title.chop(15))) {
 | 
			
		||||
    private fun showRestoreProgress(
 | 
			
		||||
        progress: Int,
 | 
			
		||||
        amount: Int,
 | 
			
		||||
        title: String,
 | 
			
		||||
        errors: Int,
 | 
			
		||||
        content: String = getString(R.string.dialog_restoring_backup, title.chop(15))
 | 
			
		||||
    ) {
 | 
			
		||||
        val intent = Intent(BackupConst.INTENT_FILTER).apply {
 | 
			
		||||
            putExtra(BackupConst.EXTRA_PROGRESS, progress)
 | 
			
		||||
            putExtra(BackupConst.EXTRA_AMOUNT, amount)
 | 
			
		||||
@@ -445,5 +462,4 @@ class BackupRestoreService : Service() {
 | 
			
		||||
        }
 | 
			
		||||
        sendLocalBroadcast(intent)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,4 +28,4 @@ object CategoryTypeAdapter {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,4 +29,4 @@ object HistoryTypeAdapter {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -34,4 +34,4 @@ object MangaTypeAdapter {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,13 +9,13 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.Page
 | 
			
		||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
 | 
			
		||||
import eu.kanade.tachiyomi.util.storage.saveTo
 | 
			
		||||
import java.io.File
 | 
			
		||||
import java.io.IOException
 | 
			
		||||
import okhttp3.Response
 | 
			
		||||
import okio.buffer
 | 
			
		||||
import okio.sink
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.io.File
 | 
			
		||||
import java.io.IOException
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class used to create chapter cache
 | 
			
		||||
@@ -135,7 +135,6 @@ class ChapterCache(private val context: Context) {
 | 
			
		||||
            diskCache.flush()
 | 
			
		||||
            editor.commit()
 | 
			
		||||
            editor.abortUnlessCommitted()
 | 
			
		||||
 | 
			
		||||
        } catch (e: Exception) {
 | 
			
		||||
            // Ignore.
 | 
			
		||||
        } finally {
 | 
			
		||||
@@ -201,4 +200,3 @@ class ChapterCache(private val context: Context) {
 | 
			
		||||
        return "${chapter.manga_id}${chapter.url}"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@ class CoverCache(private val context: Context) {
 | 
			
		||||
     * Copy the given stream to this cache.
 | 
			
		||||
     *
 | 
			
		||||
     * @param thumbnailUrl url of the thumbnail.
 | 
			
		||||
     * @param inputStream  the stream to copy.
 | 
			
		||||
     * @param inputStream the stream to copy.
 | 
			
		||||
     * @throws IOException if there's any error.
 | 
			
		||||
     */
 | 
			
		||||
    @Throws(IOException::class)
 | 
			
		||||
@@ -63,5 +63,4 @@ class CoverCache(private val context: Context) {
 | 
			
		||||
        val file = getCoverFile(thumbnailUrl)
 | 
			
		||||
        return file.exists() && file.delete()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,8 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory
 | 
			
		||||
/**
 | 
			
		||||
 * This class provides operations to manage the database through its interfaces.
 | 
			
		||||
 */
 | 
			
		||||
open class DatabaseHelper(context: Context)
 | 
			
		||||
    : MangaQueries, ChapterQueries, TrackQueries, CategoryQueries, MangaCategoryQueries, HistoryQueries {
 | 
			
		||||
open class DatabaseHelper(context: Context) :
 | 
			
		||||
    MangaQueries, ChapterQueries, TrackQueries, CategoryQueries, MangaCategoryQueries, HistoryQueries {
 | 
			
		||||
 | 
			
		||||
    private val configuration = SupportSQLiteOpenHelper.Configuration.builder(context)
 | 
			
		||||
            .name(DbOpenCallback.DATABASE_NAME)
 | 
			
		||||
@@ -32,5 +32,4 @@ open class DatabaseHelper(context: Context)
 | 
			
		||||
    inline fun inTransaction(block: () -> Unit) = db.inTransaction(block)
 | 
			
		||||
 | 
			
		||||
    fun lowLevel() = db.lowLevel()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,4 +22,3 @@ inline fun <T> StorIOSQLite.inTransactionReturn(block: () -> T): T {
 | 
			
		||||
        lowLevel().endTransaction()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -69,5 +69,4 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
 | 
			
		||||
    override fun onConfigure(db: SupportSQLiteDatabase) {
 | 
			
		||||
        db.setForeignKeyConstraintsEnabled(true)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,5 +5,4 @@ import com.pushtorefresh.storio.sqlite.impl.DefaultStorIOSQLite
 | 
			
		||||
interface DbProvider {
 | 
			
		||||
 | 
			
		||||
    val db: DefaultStorIOSQLite
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -85,4 +85,3 @@ class ChapterDeleteResolver : DefaultDeleteResolver<Chapter>() {
 | 
			
		||||
            .whereArgs(obj.id)
 | 
			
		||||
            .build()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,6 @@ class TrackPutResolver : DefaultPutResolver<Track>() {
 | 
			
		||||
        put(COL_STATUS, obj.status)
 | 
			
		||||
        put(COL_TRACKING_URL, obj.tracking_url)
 | 
			
		||||
        put(COL_SCORE, obj.score)
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,5 +23,4 @@ interface Category : Serializable {
 | 
			
		||||
 | 
			
		||||
        fun createDefault(): Category = create("Default").apply { id = 0 }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,5 +22,4 @@ class CategoryImpl : Category {
 | 
			
		||||
    override fun hashCode(): Int {
 | 
			
		||||
        return name.hashCode()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -37,5 +37,4 @@ class ChapterImpl : Chapter {
 | 
			
		||||
    override fun hashCode(): Int {
 | 
			
		||||
        return url.hashCode()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,5 +5,4 @@ class LibraryManga : MangaImpl() {
 | 
			
		||||
    var unread: Int = 0
 | 
			
		||||
 | 
			
		||||
    var category: Int = 0
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -88,5 +88,4 @@ interface Manga : SManga {
 | 
			
		||||
            this.source = source
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -17,5 +17,4 @@ class MangaCategory {
 | 
			
		||||
            return mc
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,6 @@ package eu.kanade.tachiyomi.data.database.models
 | 
			
		||||
 *
 | 
			
		||||
 * @param manga object containing manga
 | 
			
		||||
 * @param chapter object containing chater
 | 
			
		||||
 * @param history      object containing history
 | 
			
		||||
 * @param history object containing history
 | 
			
		||||
 */
 | 
			
		||||
data class MangaChapterHistory(val manga: Manga, val chapter: Chapter, val history: History)
 | 
			
		||||
 
 | 
			
		||||
@@ -39,11 +39,9 @@ open class MangaImpl : Manga {
 | 
			
		||||
        val manga = other as Manga
 | 
			
		||||
 | 
			
		||||
        return url == manga.url
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun hashCode(): Int {
 | 
			
		||||
        return url.hashCode()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -37,5 +37,4 @@ interface Track : Serializable {
 | 
			
		||||
            sync_id = serviceId
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,5 +41,4 @@ class TrackImpl : Track {
 | 
			
		||||
        result = 31 * result + media_id
 | 
			
		||||
        return result
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -32,5 +32,4 @@ interface CategoryQueries : DbProvider {
 | 
			
		||||
    fun deleteCategory(category: Category) = db.delete().`object`(category).prepare()
 | 
			
		||||
 | 
			
		||||
    fun deleteCategories(categories: List<Category>) = db.delete().objects(categories).prepare()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -88,5 +88,4 @@ interface ChapterQueries : DbProvider {
 | 
			
		||||
            .objects(chapters)
 | 
			
		||||
            .withPutResolver(ChapterSourceOrderPutResolver())
 | 
			
		||||
            .prepare()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,5 +28,4 @@ interface MangaCategoryQueries : DbProvider {
 | 
			
		||||
            insertMangasCategories(mangasCategories).executeAsBlocking()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -119,4 +119,4 @@ fun getCategoriesForMangaQuery() = """
 | 
			
		||||
    JOIN ${MangaCategory.TABLE} ON ${Category.TABLE}.${Category.COL_ID} =
 | 
			
		||||
    ${MangaCategory.TABLE}.${MangaCategory.COL_CATEGORY_ID}
 | 
			
		||||
    WHERE ${MangaCategory.COL_MANGA_ID} = ?
 | 
			
		||||
"""
 | 
			
		||||
"""
 | 
			
		||||
 
 | 
			
		||||
@@ -30,5 +30,4 @@ interface TrackQueries : DbProvider {
 | 
			
		||||
                    .whereArgs(manga.id, sync.id)
 | 
			
		||||
                    .build())
 | 
			
		||||
            .prepare()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,4 @@ class ChapterBackupPutResolver : PutResolver<Chapter>() {
 | 
			
		||||
        put(ChapterTable.COL_BOOKMARK, chapter.bookmark)
 | 
			
		||||
        put(ChapterTable.COL_LAST_PAGE_READ, chapter.last_page_read)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,4 @@ class ChapterProgressPutResolver : PutResolver<Chapter>() {
 | 
			
		||||
        put(ChapterTable.COL_BOOKMARK, chapter.bookmark)
 | 
			
		||||
        put(ChapterTable.COL_LAST_PAGE_READ, chapter.last_page_read)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,5 +28,4 @@ class ChapterSourceOrderPutResolver : PutResolver<Chapter>() {
 | 
			
		||||
    fun mapToContentValues(chapter: Chapter) = ContentValues(1).apply {
 | 
			
		||||
        put(ChapterTable.COL_SOURCE_ORDER, chapter.source_order)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -60,5 +60,4 @@ class HistoryLastReadPutResolver : HistoryPutResolver() {
 | 
			
		||||
    fun mapToUpdateContentValues(history: History) = ContentValues(1).apply {
 | 
			
		||||
        put(HistoryTable.COL_LAST_READ, history.last_read)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,5 +21,4 @@ class LibraryMangaGetResolver : DefaultGetResolver<LibraryManga>(), BaseMangaGet
 | 
			
		||||
 | 
			
		||||
        return manga
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -24,5 +24,4 @@ class MangaChapterGetResolver : DefaultGetResolver<MangaChapter>() {
 | 
			
		||||
 | 
			
		||||
        return MangaChapter(manga, chapter)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,4 @@ class MangaFavoritePutResolver : PutResolver<Manga>() {
 | 
			
		||||
    fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
 | 
			
		||||
        put(MangaTable.COL_FAVORITE, manga.favorite)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,4 @@ class MangaFlagsPutResolver : PutResolver<Manga>() {
 | 
			
		||||
    fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
 | 
			
		||||
        put(MangaTable.COL_CHAPTER_FLAGS, manga.chapter_flags)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,4 @@ class MangaLastUpdatedPutResolver : PutResolver<Manga>() {
 | 
			
		||||
    fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
 | 
			
		||||
        put(MangaTable.COL_LAST_UPDATE, manga.last_update)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,5 +28,4 @@ class MangaTitlePutResolver : PutResolver<Manga>() {
 | 
			
		||||
    fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
 | 
			
		||||
        put(MangaTable.COL_TITLE, manga.title)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,5 +28,4 @@ class MangaViewerPutResolver : PutResolver<Manga>() {
 | 
			
		||||
    fun mapToContentValues(manga: Manga) = ContentValues(1).apply {
 | 
			
		||||
        put(MangaTable.COL_VIEWER, manga.viewer)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,5 +19,4 @@ object CategoryTable {
 | 
			
		||||
            $COL_ORDER INTEGER NOT NULL,
 | 
			
		||||
            $COL_FLAGS INTEGER NOT NULL
 | 
			
		||||
            )"""
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -61,5 +61,4 @@ object ChapterTable {
 | 
			
		||||
 | 
			
		||||
    val addScanlator: String
 | 
			
		||||
        get() = "ALTER TABLE $TABLE ADD COLUMN $COL_SCANLATOR TEXT DEFAULT NULL"
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,5 +20,4 @@ object MangaCategoryTable {
 | 
			
		||||
            FOREIGN KEY($COL_MANGA_ID) REFERENCES ${MangaTable.TABLE} (${MangaTable.COL_ID})
 | 
			
		||||
            ON DELETE CASCADE
 | 
			
		||||
            )"""
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,9 +8,9 @@ import eu.kanade.tachiyomi.data.database.models.Manga
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import java.util.concurrent.TimeUnit
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
import java.util.concurrent.TimeUnit
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cache where we dump the downloads directory from the filesystem. This class is needed because
 | 
			
		||||
@@ -24,10 +24,10 @@ import java.util.concurrent.TimeUnit
 | 
			
		||||
 * @param preferences the preferences of the app.
 | 
			
		||||
 */
 | 
			
		||||
class DownloadCache(
 | 
			
		||||
        private val context: Context,
 | 
			
		||||
        private val provider: DownloadProvider,
 | 
			
		||||
        private val sourceManager: SourceManager,
 | 
			
		||||
        private val preferences: PreferencesHelper = Injekt.get()
 | 
			
		||||
    private val context: Context,
 | 
			
		||||
    private val provider: DownloadProvider,
 | 
			
		||||
    private val sourceManager: SourceManager,
 | 
			
		||||
    private val preferences: PreferencesHelper = Injekt.get()
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -233,20 +233,26 @@ class DownloadCache(
 | 
			
		||||
    /**
 | 
			
		||||
     * Class to store the files under the root downloads directory.
 | 
			
		||||
     */
 | 
			
		||||
    private class RootDirectory(val dir: UniFile,
 | 
			
		||||
                                var files: Map<Long, SourceDirectory> = hashMapOf())
 | 
			
		||||
    private class RootDirectory(
 | 
			
		||||
        val dir: UniFile,
 | 
			
		||||
        var files: Map<Long, SourceDirectory> = hashMapOf()
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Class to store the files under a source directory.
 | 
			
		||||
     */
 | 
			
		||||
    private class SourceDirectory(val dir: UniFile,
 | 
			
		||||
                                  var files: Map<String, MangaDirectory> = hashMapOf())
 | 
			
		||||
    private class SourceDirectory(
 | 
			
		||||
        val dir: UniFile,
 | 
			
		||||
        var files: Map<String, MangaDirectory> = hashMapOf()
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Class to store the files under a manga directory.
 | 
			
		||||
     */
 | 
			
		||||
    private class MangaDirectory(val dir: UniFile,
 | 
			
		||||
                                 var files: Set<String> = hashSetOf())
 | 
			
		||||
    private class MangaDirectory(
 | 
			
		||||
        val dir: UniFile,
 | 
			
		||||
        var files: Set<String> = hashSetOf()
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns a new map containing only the key entries of [transform] that are not null.
 | 
			
		||||
@@ -270,5 +276,4 @@ class DownloadCache(
 | 
			
		||||
        }
 | 
			
		||||
        return destination
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -206,5 +206,4 @@ class DownloadManager(context: Context) {
 | 
			
		||||
            deleteChapters(chapters, manga, source)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -117,7 +117,7 @@ internal class DownloadNotifier(private val context: Context) {
 | 
			
		||||
            addAction(R.drawable.ic_play_arrow_white_24dp,
 | 
			
		||||
                    context.getString(R.string.action_resume),
 | 
			
		||||
                    NotificationReceiver.resumeDownloadsPendingBroadcast(context))
 | 
			
		||||
            //Clear action
 | 
			
		||||
            // Clear action
 | 
			
		||||
            addAction(R.drawable.ic_close_white_24dp,
 | 
			
		||||
                    context.getString(R.string.action_cancel_all),
 | 
			
		||||
                    NotificationReceiver.clearDownloadsPendingBroadcast(context))
 | 
			
		||||
 
 | 
			
		||||
@@ -120,27 +120,27 @@ class DownloadPendingDeleter(context: Context) {
 | 
			
		||||
     * Class used to save an entry of chapters with their manga into preferences.
 | 
			
		||||
     */
 | 
			
		||||
    private data class Entry(
 | 
			
		||||
            val chapters: List<ChapterEntry>,
 | 
			
		||||
            val manga: MangaEntry
 | 
			
		||||
        val chapters: List<ChapterEntry>,
 | 
			
		||||
        val manga: MangaEntry
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Class used to save an entry for a chapter into preferences.
 | 
			
		||||
     */
 | 
			
		||||
    private data class ChapterEntry(
 | 
			
		||||
            val id: Long,
 | 
			
		||||
            val url: String,
 | 
			
		||||
            val name: String
 | 
			
		||||
        val id: Long,
 | 
			
		||||
        val url: String,
 | 
			
		||||
        val name: String
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Class used to save an entry for a manga into preferences.
 | 
			
		||||
     */
 | 
			
		||||
    private data class MangaEntry(
 | 
			
		||||
            val id: Long,
 | 
			
		||||
            val url: String,
 | 
			
		||||
            val title: String,
 | 
			
		||||
            val source: Long
 | 
			
		||||
        val id: Long,
 | 
			
		||||
        val url: String,
 | 
			
		||||
        val title: String,
 | 
			
		||||
        val source: Long
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -176,5 +176,4 @@ class DownloadPendingDeleter(context: Context) {
 | 
			
		||||
            it.name = name
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -126,5 +126,4 @@ class DownloadProvider(private val context: Context) {
 | 
			
		||||
    fun getChapterDirName(chapter: Chapter): String {
 | 
			
		||||
        return DiskUtil.buildValidFilename(chapter.name)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -194,5 +194,4 @@ class DownloadService : Service() {
 | 
			
		||||
            setContentTitle(getString(R.string.download_notifier_downloader_title))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,8 @@ import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 * @param context the application context.
 | 
			
		||||
 */
 | 
			
		||||
class DownloadStore(
 | 
			
		||||
        context: Context,
 | 
			
		||||
        private val sourceManager: SourceManager
 | 
			
		||||
    context: Context,
 | 
			
		||||
    private val sourceManager: SourceManager
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -133,5 +133,4 @@ class DownloadStore(
 | 
			
		||||
     * @param order the order of the download in the queue.
 | 
			
		||||
     */
 | 
			
		||||
    data class DownloadObject(val mangaId: Long, val chapterId: Long, val order: Int)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -43,10 +43,10 @@ import timber.log.Timber
 | 
			
		||||
 * @param sourceManager the source manager.
 | 
			
		||||
 */
 | 
			
		||||
class Downloader(
 | 
			
		||||
        private val context: Context,
 | 
			
		||||
        private val provider: DownloadProvider,
 | 
			
		||||
        private val cache: DownloadCache,
 | 
			
		||||
        private val sourceManager: SourceManager
 | 
			
		||||
    private val context: Context,
 | 
			
		||||
    private val provider: DownloadProvider,
 | 
			
		||||
    private val cache: DownloadCache,
 | 
			
		||||
    private val sourceManager: SourceManager
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -152,7 +152,7 @@ class Downloader(
 | 
			
		||||
    fun clearQueue(isNotification: Boolean = false) {
 | 
			
		||||
        destroySubscriptions()
 | 
			
		||||
 | 
			
		||||
        //Needed to update the chapter view
 | 
			
		||||
        // Needed to update the chapter view
 | 
			
		||||
        if (isNotification) {
 | 
			
		||||
            queue
 | 
			
		||||
                    .filter { it.status == Download.QUEUE }
 | 
			
		||||
@@ -291,7 +291,6 @@ class Downloader(
 | 
			
		||||
                    notifier.onError(error.message, download.chapter.name)
 | 
			
		||||
                    download
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -394,8 +393,12 @@ class Downloader(
 | 
			
		||||
     * @param tmpDir the directory where the download is currently stored.
 | 
			
		||||
     * @param dirname the real (non temporary) directory name of the download.
 | 
			
		||||
     */
 | 
			
		||||
    private fun ensureSuccessfulDownload(download: Download, mangaDir: UniFile,
 | 
			
		||||
                                         tmpDir: UniFile, dirname: String) {
 | 
			
		||||
    private fun ensureSuccessfulDownload(
 | 
			
		||||
        download: Download,
 | 
			
		||||
        mangaDir: UniFile,
 | 
			
		||||
        tmpDir: UniFile,
 | 
			
		||||
        dirname: String
 | 
			
		||||
    ) {
 | 
			
		||||
 | 
			
		||||
        // Ensure that the chapter folder has all the images.
 | 
			
		||||
        val downloadedImages = tmpDir.listFiles().orEmpty().filterNot { it.name!!.endsWith(".tmp") }
 | 
			
		||||
@@ -439,5 +442,4 @@ class Downloader(
 | 
			
		||||
    companion object {
 | 
			
		||||
        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.download.DownloadStore
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.Page
 | 
			
		||||
import java.util.concurrent.CopyOnWriteArrayList
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import rx.subjects.PublishSubject
 | 
			
		||||
import java.util.concurrent.CopyOnWriteArrayList
 | 
			
		||||
 | 
			
		||||
class DownloadQueue(
 | 
			
		||||
        private val store: DownloadStore,
 | 
			
		||||
        private val queue: MutableList<Download> = CopyOnWriteArrayList<Download>())
 | 
			
		||||
    : List<Download> by queue {
 | 
			
		||||
    private val store: DownloadStore,
 | 
			
		||||
    private val queue: MutableList<Download> = CopyOnWriteArrayList<Download>()
 | 
			
		||||
) :
 | 
			
		||||
    List<Download> by queue {
 | 
			
		||||
 | 
			
		||||
    private val statusSubject = PublishSubject.create<Download>()
 | 
			
		||||
 | 
			
		||||
@@ -80,7 +81,6 @@ class DownloadQueue(
 | 
			
		||||
                                .onBackpressureBuffer()
 | 
			
		||||
                                .filter { it == Page.READY }
 | 
			
		||||
                                .map { download }
 | 
			
		||||
 | 
			
		||||
                    } else if (download.status == Download.DOWNLOADED || download.status == Download.ERROR) {
 | 
			
		||||
                        setPagesSubject(download.pages, null)
 | 
			
		||||
                    }
 | 
			
		||||
@@ -96,5 +96,4 @@ class DownloadQueue(
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -48,4 +48,4 @@ open class FileFetcher(private val file: File) : DataFetcher<InputStream> {
 | 
			
		||||
    override fun getDataSource(): DataSource {
 | 
			
		||||
        return DataSource.LOCAL
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,10 +16,12 @@ import java.io.InputStream
 | 
			
		||||
 * @param manga the manga of the cover to load.
 | 
			
		||||
 * @param file the file where this cover should be. It may exists or not.
 | 
			
		||||
 */
 | 
			
		||||
class LibraryMangaUrlFetcher(private val networkFetcher: DataFetcher<InputStream>,
 | 
			
		||||
                             private val manga: Manga,
 | 
			
		||||
                             private val file: File)
 | 
			
		||||
    : FileFetcher(file) {
 | 
			
		||||
class LibraryMangaUrlFetcher(
 | 
			
		||||
    private val networkFetcher: DataFetcher<InputStream>,
 | 
			
		||||
    private val manga: Manga,
 | 
			
		||||
    private val file: File
 | 
			
		||||
) :
 | 
			
		||||
    FileFetcher(file) {
 | 
			
		||||
 | 
			
		||||
    override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
 | 
			
		||||
        if (!file.exists()) {
 | 
			
		||||
@@ -52,7 +54,6 @@ class LibraryMangaUrlFetcher(private val networkFetcher: DataFetcher<InputStream
 | 
			
		||||
                override fun onLoadFailed(e: Exception) {
 | 
			
		||||
                    callback.onLoadFailed(e)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            })
 | 
			
		||||
        } else {
 | 
			
		||||
            loadFromFile(callback)
 | 
			
		||||
@@ -68,5 +69,4 @@ class LibraryMangaUrlFetcher(private val networkFetcher: DataFetcher<InputStream
 | 
			
		||||
        super.cancel()
 | 
			
		||||
        networkFetcher.cancel()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,12 +9,11 @@ import eu.kanade.tachiyomi.data.database.models.Manga
 | 
			
		||||
import eu.kanade.tachiyomi.network.NetworkHelper
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.HttpSource
 | 
			
		||||
import java.io.File
 | 
			
		||||
import java.io.InputStream
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
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.
 | 
			
		||||
@@ -78,8 +77,12 @@ class MangaModelLoader : ModelLoader<Manga, InputStream> {
 | 
			
		||||
     * @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.
 | 
			
		||||
     */
 | 
			
		||||
    override fun buildLoadData(manga: Manga, width: Int, height: Int,
 | 
			
		||||
                               options: Options): ModelLoader.LoadData<InputStream>? {
 | 
			
		||||
    override fun buildLoadData(
 | 
			
		||||
        manga: Manga,
 | 
			
		||||
        width: Int,
 | 
			
		||||
        height: Int,
 | 
			
		||||
        options: Options
 | 
			
		||||
    ): ModelLoader.LoadData<InputStream>? {
 | 
			
		||||
        // Check thumbnail is not null or empty
 | 
			
		||||
        val url = manga.thumbnail_url
 | 
			
		||||
        if (url == null || url.isEmpty()) {
 | 
			
		||||
@@ -142,5 +145,4 @@ class MangaModelLoader : ModelLoader<Manga, InputStream> {
 | 
			
		||||
            value
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -24,4 +24,4 @@ class MangaSignature(manga: Manga, file: File) : Key {
 | 
			
		||||
    override fun updateDiskCacheKey(md: MessageDigest) {
 | 
			
		||||
        md.update(key.toByteArray(Key.CHARSET))
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,10 +14,10 @@ import java.io.InputStream
 | 
			
		||||
class PassthroughModelLoader : ModelLoader<InputStream, InputStream> {
 | 
			
		||||
 | 
			
		||||
    override fun buildLoadData(
 | 
			
		||||
            model: InputStream,
 | 
			
		||||
            width: Int,
 | 
			
		||||
            height: Int,
 | 
			
		||||
            options: Options
 | 
			
		||||
        model: InputStream,
 | 
			
		||||
        width: Int,
 | 
			
		||||
        height: Int,
 | 
			
		||||
        options: Options
 | 
			
		||||
    ): ModelLoader.LoadData<InputStream>? {
 | 
			
		||||
        return ModelLoader.LoadData(ObjectKey(model), Fetcher(model))
 | 
			
		||||
    }
 | 
			
		||||
@@ -49,12 +49,11 @@ class PassthroughModelLoader : ModelLoader<InputStream, InputStream> {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        override fun loadData(
 | 
			
		||||
                priority: Priority,
 | 
			
		||||
                callback: DataFetcher.DataCallback<in InputStream>
 | 
			
		||||
            priority: Priority,
 | 
			
		||||
            callback: DataFetcher.DataCallback<in InputStream>
 | 
			
		||||
        ) {
 | 
			
		||||
            callback.onDataReady(stream)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -63,12 +62,11 @@ class PassthroughModelLoader : ModelLoader<InputStream, InputStream> {
 | 
			
		||||
    class Factory : ModelLoaderFactory<InputStream, InputStream> {
 | 
			
		||||
 | 
			
		||||
        override fun build(
 | 
			
		||||
                multiFactory: MultiModelLoaderFactory
 | 
			
		||||
            multiFactory: MultiModelLoaderFactory
 | 
			
		||||
        ): ModelLoader<InputStream, InputStream> {
 | 
			
		||||
            return PassthroughModelLoader()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        override fun teardown() {}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,9 +15,9 @@ import com.bumptech.glide.module.AppGlideModule
 | 
			
		||||
import com.bumptech.glide.request.RequestOptions
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Manga
 | 
			
		||||
import eu.kanade.tachiyomi.network.NetworkHelper
 | 
			
		||||
import java.io.InputStream
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
import java.io.InputStream
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class used to update Glide module settings
 | 
			
		||||
 
 | 
			
		||||
@@ -39,5 +39,4 @@ object LibraryUpdateRanker {
 | 
			
		||||
            compareValues(mangaFirst.title, mangaSecond.title)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -39,16 +39,16 @@ import eu.kanade.tachiyomi.util.system.isServiceRunning
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.notification
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.notificationBuilder
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.notificationManager
 | 
			
		||||
import java.text.DecimalFormat
 | 
			
		||||
import java.text.DecimalFormatSymbols
 | 
			
		||||
import java.util.ArrayList
 | 
			
		||||
import java.util.concurrent.atomic.AtomicInteger
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import rx.Subscription
 | 
			
		||||
import rx.schedulers.Schedulers
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
import java.text.DecimalFormat
 | 
			
		||||
import java.text.DecimalFormatSymbols
 | 
			
		||||
import java.util.ArrayList
 | 
			
		||||
import java.util.concurrent.atomic.AtomicInteger
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class will take care of updating the chapters of the manga from the library. It can be
 | 
			
		||||
@@ -59,11 +59,11 @@ import java.util.concurrent.atomic.AtomicInteger
 | 
			
		||||
 * destroyed.
 | 
			
		||||
 */
 | 
			
		||||
class LibraryUpdateService(
 | 
			
		||||
        val db: DatabaseHelper = Injekt.get(),
 | 
			
		||||
        val sourceManager: SourceManager = Injekt.get(),
 | 
			
		||||
        val preferences: PreferencesHelper = Injekt.get(),
 | 
			
		||||
        val downloadManager: DownloadManager = Injekt.get(),
 | 
			
		||||
        val trackManager: TrackManager = Injekt.get()
 | 
			
		||||
    val db: DatabaseHelper = Injekt.get(),
 | 
			
		||||
    val sourceManager: SourceManager = Injekt.get(),
 | 
			
		||||
    val preferences: PreferencesHelper = Injekt.get(),
 | 
			
		||||
    val downloadManager: DownloadManager = Injekt.get(),
 | 
			
		||||
    val trackManager: TrackManager = Injekt.get()
 | 
			
		||||
) : Service() {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -109,8 +109,8 @@ class LibraryUpdateService(
 | 
			
		||||
     */
 | 
			
		||||
    enum class Target {
 | 
			
		||||
        CHAPTERS, // Manga chapters
 | 
			
		||||
        DETAILS,  // Manga metadata
 | 
			
		||||
        TRACKING  // Tracking metadata
 | 
			
		||||
        DETAILS, // Manga metadata
 | 
			
		||||
        TRACKING // Tracking metadata
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
@@ -169,7 +169,6 @@ class LibraryUpdateService(
 | 
			
		||||
        fun stop(context: Context) {
 | 
			
		||||
            context.stopService(Intent(context, LibraryUpdateService::class.java))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -589,5 +588,4 @@ class LibraryUpdateService(
 | 
			
		||||
        }
 | 
			
		||||
        return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.os.Build
 | 
			
		||||
import android.os.Handler
 | 
			
		||||
import eu.kanade.tachiyomi.BuildConfig.APPLICATION_ID as ID
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Chapter
 | 
			
		||||
@@ -23,11 +24,10 @@ import eu.kanade.tachiyomi.util.storage.DiskUtil
 | 
			
		||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.notificationManager
 | 
			
		||||
import eu.kanade.tachiyomi.util.system.toast
 | 
			
		||||
import java.io.File
 | 
			
		||||
import uy.kohesive.injekt.Injekt
 | 
			
		||||
import uy.kohesive.injekt.api.get
 | 
			
		||||
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
 | 
			
		||||
@@ -407,8 +407,13 @@ class NotificationReceiver : BroadcastReceiver() {
 | 
			
		||||
         * @param context context of application
 | 
			
		||||
         * @param manga manga of chapter
 | 
			
		||||
         */
 | 
			
		||||
        internal fun markAsReadPendingBroadcast(context: Context, manga: Manga, chapters:
 | 
			
		||||
        Array<Chapter>, groupId: Int):
 | 
			
		||||
        internal fun markAsReadPendingBroadcast(
 | 
			
		||||
            context: Context,
 | 
			
		||||
            manga: Manga,
 | 
			
		||||
            chapters:            
 | 
			
		||||
                    Array<Chapter>,
 | 
			
		||||
            groupId: Int
 | 
			
		||||
        ):
 | 
			
		||||
                PendingIntent {
 | 
			
		||||
            val newIntent = Intent(context, NotificationReceiver::class.java).apply {
 | 
			
		||||
                action = ACTION_MARK_AS_READ
 | 
			
		||||
 
 | 
			
		||||
@@ -144,5 +144,4 @@ object PreferenceKeys {
 | 
			
		||||
    fun trackPassword(syncId: Int) = "pref_mangasync_password_$syncId"
 | 
			
		||||
 | 
			
		||||
    fun trackToken(syncId: Int) = "track_token_$syncId"
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,5 +12,4 @@ object PreferenceValues {
 | 
			
		||||
    const val THEME_DARK_DEFAULT = "default"
 | 
			
		||||
    const val THEME_DARK_BLUE = "blue"
 | 
			
		||||
    const val THEME_DARK_AMOLED = "amoled"
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,14 +8,14 @@ import android.preference.PreferenceManager
 | 
			
		||||
import com.f2prateek.rx.preferences.Preference
 | 
			
		||||
import com.f2prateek.rx.preferences.RxSharedPreferences
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues as Values
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.TrackService
 | 
			
		||||
import eu.kanade.tachiyomi.source.Source
 | 
			
		||||
import java.io.File
 | 
			
		||||
import java.text.DateFormat
 | 
			
		||||
import java.text.SimpleDateFormat
 | 
			
		||||
import java.util.Locale
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferenceValues as Values
 | 
			
		||||
 | 
			
		||||
fun <T> Preference<T>.getOrDefault(): T = get() ?: defaultValue()!!
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -32,5 +32,4 @@ class TrackManager(private val context: Context) {
 | 
			
		||||
    fun getService(id: Int) = services.find { it.id == id }
 | 
			
		||||
 | 
			
		||||
    fun hasLoggedServices() = services.any { it.isLogged }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -209,6 +209,4 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
 | 
			
		||||
            null
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,13 +7,12 @@ import com.google.gson.JsonParser
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Track
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
 | 
			
		||||
import eu.kanade.tachiyomi.network.asObservableSuccess
 | 
			
		||||
import java.util.Calendar
 | 
			
		||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
 | 
			
		||||
import okhttp3.OkHttpClient
 | 
			
		||||
import okhttp3.Request
 | 
			
		||||
import okhttp3.RequestBody.Companion.toRequestBody
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import java.util.Calendar
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
 | 
			
		||||
 | 
			
		||||
@@ -143,7 +142,6 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
 | 
			
		||||
                }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    fun findLibManga(track: Track, userid: Int): Observable<Track?> {
 | 
			
		||||
        val query = """
 | 
			
		||||
            |query (${'$'}id: Int!, ${'$'}manga_id: Int!) {
 | 
			
		||||
@@ -201,7 +199,6 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
 | 
			
		||||
                    val media = page["mediaList"].array
 | 
			
		||||
                    val entries = media.map { jsonToALUserManga(it.obj) }
 | 
			
		||||
                    entries.firstOrNull()?.toTrack()
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -283,5 +280,4 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
 | 
			
		||||
                .appendQueryParameter("response_type", "token")
 | 
			
		||||
                .build()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.track.anilist
 | 
			
		||||
import okhttp3.Interceptor
 | 
			
		||||
import okhttp3.Response
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AnilistInterceptor(val anilist: Anilist, private var token: String?) : Interceptor {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -54,5 +53,4 @@ class AnilistInterceptor(val anilist: Anilist, private var token: String?) : Int
 | 
			
		||||
        this.oauth = oauth
 | 
			
		||||
        anilist.saveOAuth(oauth)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,19 +5,20 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.TrackManager
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.text.SimpleDateFormat
 | 
			
		||||
import java.util.Locale
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 | 
			
		||||
data class ALManga(
 | 
			
		||||
        val media_id: Int,
 | 
			
		||||
        val title_romaji: String,
 | 
			
		||||
        val image_url_lge: String,
 | 
			
		||||
        val description: String?,
 | 
			
		||||
        val type: String,
 | 
			
		||||
        val publishing_status: String,
 | 
			
		||||
        val start_date_fuzzy: Long,
 | 
			
		||||
        val total_chapters: Int) {
 | 
			
		||||
    val media_id: Int,
 | 
			
		||||
    val title_romaji: String,
 | 
			
		||||
    val image_url_lge: String,
 | 
			
		||||
    val description: String?,
 | 
			
		||||
    val type: String,
 | 
			
		||||
    val publishing_status: String,
 | 
			
		||||
    val start_date_fuzzy: Long,
 | 
			
		||||
    val total_chapters: Int
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    fun toTrack() = TrackSearch.create(TrackManager.ANILIST).apply {
 | 
			
		||||
        media_id = this@ALManga.media_id
 | 
			
		||||
@@ -40,11 +41,12 @@ data class ALManga(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
data class ALUserManga(
 | 
			
		||||
        val library_id: Long,
 | 
			
		||||
        val list_status: String,
 | 
			
		||||
        val score_raw: Int,
 | 
			
		||||
        val chapters_read: Int,
 | 
			
		||||
        val manga: ALManga) {
 | 
			
		||||
    val library_id: Long,
 | 
			
		||||
    val list_status: String,
 | 
			
		||||
    val score_raw: Int,
 | 
			
		||||
    val chapters_read: Int,
 | 
			
		||||
    val manga: ALManga
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    fun toTrack() = Track.create(TrackManager.ANILIST).apply {
 | 
			
		||||
        media_id = manga.media_id
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,11 @@
 | 
			
		||||
package eu.kanade.tachiyomi.data.track.anilist
 | 
			
		||||
 | 
			
		||||
data class OAuth(
 | 
			
		||||
        val access_token: String,
 | 
			
		||||
        val token_type: String,
 | 
			
		||||
        val expires: Long,
 | 
			
		||||
        val expires_in: Long) {
 | 
			
		||||
    val access_token: String,
 | 
			
		||||
    val token_type: String,
 | 
			
		||||
    val expires: Long,
 | 
			
		||||
    val expires_in: Long
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    fun isExpired() = System.currentTimeMillis() > expires
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
package eu.kanade.tachiyomi.data.track.bangumi
 | 
			
		||||
 | 
			
		||||
data class Avatar(
 | 
			
		||||
        val large: String? = "",
 | 
			
		||||
        val medium: String? = "",
 | 
			
		||||
        val small: String? = ""
 | 
			
		||||
    val large: String? = "",
 | 
			
		||||
    val medium: String? = "",
 | 
			
		||||
    val small: String? = ""
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -11,13 +11,13 @@ import eu.kanade.tachiyomi.data.track.TrackManager
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
 | 
			
		||||
import eu.kanade.tachiyomi.network.POST
 | 
			
		||||
import eu.kanade.tachiyomi.network.asObservableSuccess
 | 
			
		||||
import java.net.URLEncoder
 | 
			
		||||
import okhttp3.CacheControl
 | 
			
		||||
import okhttp3.FormBody
 | 
			
		||||
import okhttp3.OkHttpClient
 | 
			
		||||
import okhttp3.Request
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.net.URLEncoder
 | 
			
		||||
 | 
			
		||||
class BangumiApi(private val client: OkHttpClient, interceptor: BangumiInterceptor) {
 | 
			
		||||
 | 
			
		||||
@@ -94,7 +94,6 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
 | 
			
		||||
                    val response = parser.parse(responseBody).obj["list"]?.array
 | 
			
		||||
                    response?.filter { it.obj["type"].asInt == 1 }?.map { jsonToSearch(it.obj) }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun jsonToSearch(obj: JsonObject): TrackSearch {
 | 
			
		||||
@@ -207,5 +206,4 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
 | 
			
		||||
                        .add("redirect_uri", redirectUrl)
 | 
			
		||||
                        .build())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
package eu.kanade.tachiyomi.data.track.bangumi
 | 
			
		||||
 | 
			
		||||
data class Collection(
 | 
			
		||||
        val `private`: Int? = 0,
 | 
			
		||||
        val comment: String? = "",
 | 
			
		||||
        val ep_status: Int? = 0,
 | 
			
		||||
        val lasttouch: Int? = 0,
 | 
			
		||||
        val rating: Int? = 0,
 | 
			
		||||
        val status: Status? = Status(),
 | 
			
		||||
        val tag: List<String?>? = listOf(),
 | 
			
		||||
        val user: User? = User(),
 | 
			
		||||
        val vol_status: Int? = 0
 | 
			
		||||
    val `private`: Int? = 0,
 | 
			
		||||
    val comment: String? = "",
 | 
			
		||||
    val ep_status: Int? = 0,
 | 
			
		||||
    val lasttouch: Int? = 0,
 | 
			
		||||
    val rating: Int? = 0,
 | 
			
		||||
    val status: Status? = Status(),
 | 
			
		||||
    val tag: List<String?>? = listOf(),
 | 
			
		||||
    val user: User? = User(),
 | 
			
		||||
    val vol_status: Int? = 0
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,14 @@
 | 
			
		||||
package eu.kanade.tachiyomi.data.track.bangumi
 | 
			
		||||
 | 
			
		||||
data class OAuth(
 | 
			
		||||
        val access_token: String,
 | 
			
		||||
        val token_type: String,
 | 
			
		||||
        val created_at: Long,
 | 
			
		||||
        val expires_in: Long,
 | 
			
		||||
        val refresh_token: String?,
 | 
			
		||||
        val user_id: Long?
 | 
			
		||||
    val access_token: String,
 | 
			
		||||
    val token_type: String,
 | 
			
		||||
    val created_at: Long,
 | 
			
		||||
    val expires_in: Long,
 | 
			
		||||
    val refresh_token: String?,
 | 
			
		||||
    val user_id: Long?
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    // Access token refresh before expired
 | 
			
		||||
    fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
package eu.kanade.tachiyomi.data.track.bangumi
 | 
			
		||||
 | 
			
		||||
data class Status(
 | 
			
		||||
        val id: Int? = 0,
 | 
			
		||||
        val name: String? = "",
 | 
			
		||||
        val type: String? = ""
 | 
			
		||||
    val id: Int? = 0,
 | 
			
		||||
    val name: String? = "",
 | 
			
		||||
    val type: String? = ""
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
package eu.kanade.tachiyomi.data.track.bangumi
 | 
			
		||||
 | 
			
		||||
data class User(
 | 
			
		||||
        val avatar: Avatar? = Avatar(),
 | 
			
		||||
        val id: Int? = 0,
 | 
			
		||||
        val nickname: String? = "",
 | 
			
		||||
        val sign: String? = "",
 | 
			
		||||
        val url: String? = "",
 | 
			
		||||
        val usergroup: Int? = 0,
 | 
			
		||||
        val username: String? = ""
 | 
			
		||||
    val avatar: Avatar? = Avatar(),
 | 
			
		||||
    val id: Int? = 0,
 | 
			
		||||
    val nickname: String? = "",
 | 
			
		||||
    val sign: String? = "",
 | 
			
		||||
    val url: String? = "",
 | 
			
		||||
    val usergroup: Int? = 0,
 | 
			
		||||
    val username: String? = ""
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -7,10 +7,10 @@ import eu.kanade.tachiyomi.R
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Track
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.TrackService
 | 
			
		||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
 | 
			
		||||
import java.text.DecimalFormat
 | 
			
		||||
import rx.Completable
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.text.DecimalFormat
 | 
			
		||||
 | 
			
		||||
class Kitsu(private val context: Context, id: Int) : TrackService(id) {
 | 
			
		||||
 | 
			
		||||
@@ -140,5 +140,4 @@ class Kitsu(private val context: Context, id: Int) : TrackService(id) {
 | 
			
		||||
            null
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -94,7 +94,6 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    fun search(query: String): Observable<List<TrackSearch>> {
 | 
			
		||||
        return searchRest
 | 
			
		||||
                .getKey().map { json ->
 | 
			
		||||
@@ -104,7 +103,6 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
                }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private fun algoliaSearch(key: String, query: String): Observable<List<TrackSearch>> {
 | 
			
		||||
        val jsonObject = jsonObject("params" to "query=$query$algoliaFilter")
 | 
			
		||||
        return algoliaRest
 | 
			
		||||
@@ -163,35 +161,33 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
        @Headers("Content-Type: application/vnd.api+json")
 | 
			
		||||
        @POST("library-entries")
 | 
			
		||||
        fun addLibManga(
 | 
			
		||||
                @Body data: JsonObject
 | 
			
		||||
            @Body data: JsonObject
 | 
			
		||||
        ): Observable<JsonObject>
 | 
			
		||||
 | 
			
		||||
        @Headers("Content-Type: application/vnd.api+json")
 | 
			
		||||
        @PATCH("library-entries/{id}")
 | 
			
		||||
        fun updateLibManga(
 | 
			
		||||
                @Path("id") remoteId: Int,
 | 
			
		||||
                @Body data: JsonObject
 | 
			
		||||
            @Path("id") remoteId: Int,
 | 
			
		||||
            @Body data: JsonObject
 | 
			
		||||
        ): Observable<JsonObject>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        @GET("library-entries")
 | 
			
		||||
        fun findLibManga(
 | 
			
		||||
                @Query("filter[manga_id]", encoded = true) remoteId: Int,
 | 
			
		||||
                @Query("filter[user_id]", encoded = true) userId: String,
 | 
			
		||||
                @Query("include") includes: String = "manga"
 | 
			
		||||
            @Query("filter[manga_id]", encoded = true) remoteId: Int,
 | 
			
		||||
            @Query("filter[user_id]", encoded = true) userId: String,
 | 
			
		||||
            @Query("include") includes: String = "manga"
 | 
			
		||||
        ): Observable<JsonObject>
 | 
			
		||||
 | 
			
		||||
        @GET("library-entries")
 | 
			
		||||
        fun getLibManga(
 | 
			
		||||
                @Query("filter[id]", encoded = true) remoteId: Int,
 | 
			
		||||
                @Query("include") includes: String = "manga"
 | 
			
		||||
            @Query("filter[id]", encoded = true) remoteId: Int,
 | 
			
		||||
            @Query("include") includes: String = "manga"
 | 
			
		||||
        ): Observable<JsonObject>
 | 
			
		||||
 | 
			
		||||
        @GET("users")
 | 
			
		||||
        fun getCurrentUser(
 | 
			
		||||
                @Query("filter[self]", encoded = true) self: Boolean = true
 | 
			
		||||
            @Query("filter[self]", encoded = true) self: Boolean = true
 | 
			
		||||
        ): Observable<JsonObject>
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private interface SearchKeyRest {
 | 
			
		||||
@@ -209,13 +205,12 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
        @FormUrlEncoded
 | 
			
		||||
        @POST("oauth/token")
 | 
			
		||||
        fun requestAccessToken(
 | 
			
		||||
                @Field("username") username: String,
 | 
			
		||||
                @Field("password") password: String,
 | 
			
		||||
                @Field("grant_type") grantType: String = "password",
 | 
			
		||||
                @Field("client_id") client_id: String = clientId,
 | 
			
		||||
                @Field("client_secret") client_secret: String = clientSecret
 | 
			
		||||
            @Field("username") username: String,
 | 
			
		||||
            @Field("password") password: String,
 | 
			
		||||
            @Field("grant_type") grantType: String = "password",
 | 
			
		||||
            @Field("client_id") client_id: String = clientId,
 | 
			
		||||
            @Field("client_secret") client_secret: String = clientSecret
 | 
			
		||||
        ): Observable<OAuth>
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
@@ -229,12 +224,10 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
        private const val algoliaAppId = "AWQO5J657S"
 | 
			
		||||
        private const val algoliaFilter = "&facetFilters=%5B%22kind%3Amanga%22%5D&attributesToRetrieve=%5B%22synopsis%22%2C%22canonicalTitle%22%2C%22chapterCount%22%2C%22posterImage%22%2C%22startDate%22%2C%22subtype%22%2C%22endDate%22%2C%20%22id%22%5D"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        fun mangaUrl(remoteId: Int): String {
 | 
			
		||||
            return baseMangaUrl + remoteId
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        fun refreshTokenRequest(token: String) = POST("${loginUrl}oauth/token",
 | 
			
		||||
                body = FormBody.Builder()
 | 
			
		||||
                        .add("grant_type", "refresh_token")
 | 
			
		||||
@@ -242,7 +235,5 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 | 
			
		||||
                        .add("client_secret", clientSecret)
 | 
			
		||||
                        .add("refresh_token", token)
 | 
			
		||||
                        .build())
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -42,5 +42,4 @@ class KitsuInterceptor(val kitsu: Kitsu, val gson: Gson) : Interceptor {
 | 
			
		||||
        this.oauth = oauth
 | 
			
		||||
        kitsu.saveToken(oauth)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,6 @@ class KitsuSearchManga(obj: JsonObject) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class KitsuLibManga(obj: JsonObject, manga: JsonObject) {
 | 
			
		||||
    val id by manga.byInt
 | 
			
		||||
    private val canonicalTitle by manga["attributes"].byString
 | 
			
		||||
@@ -78,7 +77,6 @@ class KitsuLibManga(obj: JsonObject, manga: JsonObject) {
 | 
			
		||||
        "planned" -> Kitsu.PLAN_TO_READ
 | 
			
		||||
        else -> throw Exception("Unknown status")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fun Track.toKitsuStatus() = when (status) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,12 @@
 | 
			
		||||
package eu.kanade.tachiyomi.data.track.kitsu
 | 
			
		||||
 | 
			
		||||
data class OAuth(
 | 
			
		||||
        val access_token: String,
 | 
			
		||||
        val token_type: String,
 | 
			
		||||
        val created_at: Long,
 | 
			
		||||
        val expires_in: Long,
 | 
			
		||||
        val refresh_token: String?) {
 | 
			
		||||
    val access_token: String,
 | 
			
		||||
    val token_type: String,
 | 
			
		||||
    val created_at: Long,
 | 
			
		||||
    val expires_in: Long,
 | 
			
		||||
    val refresh_token: String?
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600)
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -59,5 +59,4 @@ class TrackSearch : Track {
 | 
			
		||||
            sync_id = serviceId
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -159,5 +159,4 @@ class Myanimelist(private val context: Context, id: Int) : TrackService(id) {
 | 
			
		||||
 | 
			
		||||
        return ckCount == 2
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,9 @@ import eu.kanade.tachiyomi.network.asObservable
 | 
			
		||||
import eu.kanade.tachiyomi.network.asObservableSuccess
 | 
			
		||||
import eu.kanade.tachiyomi.util.selectInt
 | 
			
		||||
import eu.kanade.tachiyomi.util.selectText
 | 
			
		||||
import java.io.BufferedReader
 | 
			
		||||
import java.io.InputStreamReader
 | 
			
		||||
import java.util.zip.GZIPInputStream
 | 
			
		||||
import okhttp3.FormBody
 | 
			
		||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
 | 
			
		||||
import okhttp3.OkHttpClient
 | 
			
		||||
@@ -22,10 +25,6 @@ import org.jsoup.nodes.Document
 | 
			
		||||
import org.jsoup.nodes.Element
 | 
			
		||||
import org.jsoup.parser.Parser
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import java.io.BufferedReader
 | 
			
		||||
import java.io.InputStreamReader
 | 
			
		||||
import java.util.zip.GZIPInputStream
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListInterceptor) {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
package eu.kanade.tachiyomi.data.track.shikimori
 | 
			
		||||
 | 
			
		||||
data class OAuth(
 | 
			
		||||
        val access_token: String,
 | 
			
		||||
        val token_type: String,
 | 
			
		||||
        val created_at: Long,
 | 
			
		||||
        val expires_in: Long,
 | 
			
		||||
        val refresh_token: String?) {
 | 
			
		||||
    val access_token: String,
 | 
			
		||||
    val token_type: String,
 | 
			
		||||
    val created_at: Long,
 | 
			
		||||
    val expires_in: Long,
 | 
			
		||||
    val refresh_token: String?
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    // Access token lives 1 day
 | 
			
		||||
    fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,6 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
 | 
			
		||||
                    val response = parser.parse(responseBody).array
 | 
			
		||||
                    response.map { jsonToSearch(it.obj) }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun jsonToSearch(obj: JsonObject): TrackSearch {
 | 
			
		||||
@@ -171,7 +170,6 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
 | 
			
		||||
                    .build()
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        private const val clientId = "1aaf4cf232372708e98b5abc813d795b539c5a916dbbfe9ac61bf02a360832cc"
 | 
			
		||||
        private const val clientSecret = "229942c742dd4cde803125d17d64501d91c0b12e14cb1e5120184d77d67024c0"
 | 
			
		||||
@@ -195,7 +193,6 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
 | 
			
		||||
                        .appendQueryParameter("response_type", "code")
 | 
			
		||||
                        .build()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        fun refreshTokenRequest(token: String) = POST(oauthUrl,
 | 
			
		||||
                body = FormBody.Builder()
 | 
			
		||||
                        .add("grant_type", "refresh_token")
 | 
			
		||||
@@ -203,7 +200,5 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
 | 
			
		||||
                        .add("client_secret", clientSecret)
 | 
			
		||||
                        .add("refresh_token", token)
 | 
			
		||||
                        .build())
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,5 +9,4 @@ interface Release {
 | 
			
		||||
     * @return download link of latest release.
 | 
			
		||||
     */
 | 
			
		||||
    val downloadLink: String
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,5 +20,4 @@ abstract class UpdateChecker {
 | 
			
		||||
     * Returns observable containing release information
 | 
			
		||||
     */
 | 
			
		||||
    abstract suspend fun checkForUpdate(): UpdateResult
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,5 +4,4 @@ abstract class UpdateResult {
 | 
			
		||||
 | 
			
		||||
    open class NewUpdate<T : Release>(val release: T) : UpdateResult()
 | 
			
		||||
    open class NoNewUpdate : UpdateResult()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -64,5 +64,4 @@ class UpdaterJob : Job() {
 | 
			
		||||
            JobManager.instance().cancelAllForTag(TAG)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,9 +12,9 @@ import eu.kanade.tachiyomi.network.ProgressListener
 | 
			
		||||
import eu.kanade.tachiyomi.network.newCallWithProgress
 | 
			
		||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
 | 
			
		||||
import eu.kanade.tachiyomi.util.storage.saveTo
 | 
			
		||||
import java.io.File
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.io.File
 | 
			
		||||
 | 
			
		||||
class UpdaterService : IntentService(UpdaterService::class.java.name) {
 | 
			
		||||
 | 
			
		||||
@@ -119,5 +119,3 @@ class UpdaterService : IntentService(UpdaterService::class.java.name) {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,5 +10,4 @@ class DevRepoRelease(override val info: String) : Release {
 | 
			
		||||
    companion object {
 | 
			
		||||
        const val LATEST_URL = "https://tachiyomi.kanade.eu/latest"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -38,5 +38,4 @@ class DevRepoUpdateChecker : UpdateChecker() {
 | 
			
		||||
            DevRepoUpdateResult.NoNewUpdate()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,5 +6,4 @@ sealed class DevRepoUpdateResult : UpdateResult() {
 | 
			
		||||
 | 
			
		||||
    class NewUpdate(release: DevRepoRelease) : UpdateResult.NewUpdate<DevRepoRelease>(release)
 | 
			
		||||
    class NoNewUpdate : UpdateResult.NoNewUpdate()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,11 @@ import eu.kanade.tachiyomi.data.updater.Release
 | 
			
		||||
 * @param info log of latest release.
 | 
			
		||||
 * @param assets assets of latest release.
 | 
			
		||||
 */
 | 
			
		||||
class GithubRelease(@SerializedName("tag_name") val version: String,
 | 
			
		||||
                    @SerializedName("body") override val info: String,
 | 
			
		||||
                    @SerializedName("assets") private val assets: List<Assets>) : Release {
 | 
			
		||||
class GithubRelease(
 | 
			
		||||
    @SerializedName("tag_name") val version: String,
 | 
			
		||||
    @SerializedName("body") override val info: String,
 | 
			
		||||
    @SerializedName("assets") private val assets: List<Assets>
 | 
			
		||||
) : Release {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get download link of latest release from the assets.
 | 
			
		||||
@@ -28,4 +30,3 @@ class GithubRelease(@SerializedName("tag_name") val version: String,
 | 
			
		||||
     */
 | 
			
		||||
    inner class Assets(@SerializedName("browser_download_url") val downloadLink: String)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,5 +26,4 @@ interface GithubService {
 | 
			
		||||
 | 
			
		||||
    @GET("/repos/inorichi/tachiyomi/releases/latest")
 | 
			
		||||
    suspend fun getLatestVersion(): GithubRelease
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user