mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-10 22:35:06 +01:00
Starting shift to 1.x sources
This commit is contained in:
parent
7963a607b8
commit
73df525939
@ -24,8 +24,9 @@ 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.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.source.fetchMangaDetailsAsync
|
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import eu.kanade.tachiyomi.source.model.toMangaInfo
|
||||||
|
import eu.kanade.tachiyomi.source.model.toSManga
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||||
@ -92,10 +93,10 @@ class LibraryUpdateService(
|
|||||||
|
|
||||||
// List containing categories that get included in downloads.
|
// List containing categories that get included in downloads.
|
||||||
private val categoriesToDownload =
|
private val categoriesToDownload =
|
||||||
preferences.downloadNewCategories().getOrDefault().map(String::toInt)
|
preferences.downloadNewCategories().get().map(String::toInt)
|
||||||
|
|
||||||
// Boolean to determine if user wants to automatically download new chapters.
|
// Boolean to determine if user wants to automatically download new chapters.
|
||||||
private val downloadNew: Boolean = preferences.downloadNew().getOrDefault()
|
private val downloadNew: Boolean = preferences.downloadNew().get()
|
||||||
|
|
||||||
// Boolean to determine if DownloadManager has downloads
|
// Boolean to determine if DownloadManager has downloads
|
||||||
private var hasDownloads = false
|
private var hasDownloads = false
|
||||||
@ -198,7 +199,7 @@ class LibraryUpdateService(
|
|||||||
db.getLibraryMangas().executeAsBlocking().filter { it.category == categoryId }
|
db.getLibraryMangas().executeAsBlocking().filter { it.category == categoryId }
|
||||||
} else {
|
} else {
|
||||||
val categoriesToUpdate =
|
val categoriesToUpdate =
|
||||||
preferences.libraryUpdateCategories().getOrDefault().map(String::toInt)
|
preferences.libraryUpdateCategories().get().map(String::toInt)
|
||||||
if (categoriesToUpdate.isNotEmpty()) {
|
if (categoriesToUpdate.isNotEmpty()) {
|
||||||
categoryIds.addAll(categoriesToUpdate)
|
categoryIds.addAll(categoriesToUpdate)
|
||||||
db.getLibraryMangas().executeAsBlocking()
|
db.getLibraryMangas().executeAsBlocking()
|
||||||
@ -451,7 +452,7 @@ class LibraryUpdateService(
|
|||||||
)
|
)
|
||||||
|
|
||||||
val networkManga = try {
|
val networkManga = try {
|
||||||
source.fetchMangaDetailsAsync(manga)
|
source.getMangaDetails(manga.toMangaInfo()).toSManga()
|
||||||
} catch (e: java.lang.Exception) {
|
} catch (e: java.lang.Exception) {
|
||||||
Timber.e(e)
|
Timber.e(e)
|
||||||
null
|
null
|
||||||
|
@ -174,7 +174,7 @@ class PreferencesHelper(val context: Context) {
|
|||||||
|
|
||||||
fun libraryUpdateRestriction() = prefs.getStringSet(Keys.libraryUpdateRestriction, emptySet())
|
fun libraryUpdateRestriction() = prefs.getStringSet(Keys.libraryUpdateRestriction, emptySet())
|
||||||
|
|
||||||
fun libraryUpdateCategories() = rxPrefs.getStringSet(Keys.libraryUpdateCategories, emptySet())
|
fun libraryUpdateCategories() = flowPrefs.getStringSet(Keys.libraryUpdateCategories, emptySet())
|
||||||
|
|
||||||
fun libraryUpdatePrioritization() = rxPrefs.getInteger(Keys.libraryUpdatePrioritization, 0)
|
fun libraryUpdatePrioritization() = rxPrefs.getInteger(Keys.libraryUpdatePrioritization, 0)
|
||||||
|
|
||||||
@ -212,9 +212,9 @@ class PreferencesHelper(val context: Context) {
|
|||||||
|
|
||||||
fun pinnedCatalogues() = rxPrefs.getStringSet("pinned_catalogues", emptySet())
|
fun pinnedCatalogues() = rxPrefs.getStringSet("pinned_catalogues", emptySet())
|
||||||
|
|
||||||
fun downloadNew() = rxPrefs.getBoolean(Keys.downloadNew, false)
|
fun downloadNew() = flowPrefs.getBoolean(Keys.downloadNew, false)
|
||||||
|
|
||||||
fun downloadNewCategories() = rxPrefs.getStringSet(Keys.downloadNewCategories, emptySet())
|
fun downloadNewCategories() = flowPrefs.getStringSet(Keys.downloadNewCategories, emptySet())
|
||||||
|
|
||||||
fun lang() = prefs.getString(Keys.lang, "")
|
fun lang() = prefs.getString(Keys.lang, "")
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ interface Source : tachiyomi.source.Source {
|
|||||||
*
|
*
|
||||||
* @param manga the manga to update.
|
* @param manga the manga to update.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Use getMangaDetails instead")
|
||||||
fun fetchMangaDetails(manga: SManga): Observable<SManga>
|
fun fetchMangaDetails(manga: SManga): Observable<SManga>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,6 +49,7 @@ interface Source : tachiyomi.source.Source {
|
|||||||
*
|
*
|
||||||
* @param manga the manga to update.
|
* @param manga the manga to update.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Use getChapterList instead")
|
||||||
fun fetchChapterList(manga: SManga): Observable<List<SChapter>>
|
fun fetchChapterList(manga: SManga): Observable<List<SChapter>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,6 +57,7 @@ interface Source : tachiyomi.source.Source {
|
|||||||
*
|
*
|
||||||
* @param chapter the chapter.
|
* @param chapter the chapter.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Use getPageList instead")
|
||||||
fun fetchPageList(chapter: SChapter): Observable<List<Page>>
|
fun fetchPageList(chapter: SChapter): Observable<List<Page>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,17 +95,5 @@ interface Source : tachiyomi.source.Source {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun Source.fetchMangaDetailsAsync(manga: SManga): SManga? {
|
|
||||||
return withContext(Dispatchers.IO) {
|
|
||||||
fetchMangaDetails(manga).toBlocking().single()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun Source.fetchChapterListAsync(manga: SManga): List<SChapter>? {
|
|
||||||
return withContext(Dispatchers.IO) {
|
|
||||||
fetchChapterList(manga).toBlocking().single()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Source.icon(): Drawable? =
|
fun Source.icon(): Drawable? =
|
||||||
Injekt.get<ExtensionManager>().getAppIconForSource(this)
|
Injekt.get<ExtensionManager>().getAppIconForSource(this)
|
||||||
|
@ -5,9 +5,11 @@ import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
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.database.models.MangaImpl
|
import eu.kanade.tachiyomi.data.database.models.MangaImpl
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.source.fetchChapterListAsync
|
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
import eu.kanade.tachiyomi.source.model.toSChapter
|
||||||
|
import eu.kanade.tachiyomi.source.model.toSManga
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
abstract class DelegatedHttpSource {
|
abstract class DelegatedHttpSource {
|
||||||
@ -24,10 +26,10 @@ abstract class DelegatedHttpSource {
|
|||||||
open fun pageNumber(uri: Uri): Int? = uri.pathSegments.lastOrNull()?.toIntOrNull()
|
open fun pageNumber(uri: Uri): Int? = uri.pathSegments.lastOrNull()?.toIntOrNull()
|
||||||
abstract suspend fun fetchMangaFromChapterUrl(uri: Uri): Triple<Chapter, Manga, List<SChapter>>?
|
abstract suspend fun fetchMangaFromChapterUrl(uri: Uri): Triple<Chapter, Manga, List<SChapter>>?
|
||||||
|
|
||||||
protected open fun getMangaInfo(url: String): Manga? {
|
protected open suspend fun getMangaInfo(url: String): Manga? {
|
||||||
val id = delegate?.id ?: return null
|
val id = delegate?.id ?: return null
|
||||||
val manga = Manga.create(url, "", id)
|
val manga = Manga.create(url, "", id)
|
||||||
val networkManga = delegate?.fetchMangaDetails(manga)?.toBlocking()?.single() ?: return null
|
val networkManga = delegate?.getMangaDetails(manga.toMangaInfo())?.toSManga() ?: return null
|
||||||
val newManga = MangaImpl().apply {
|
val newManga = MangaImpl().apply {
|
||||||
this.url = url
|
this.url = url
|
||||||
title = try { networkManga.title } catch (e: Exception) { "" }
|
title = try { networkManga.title } catch (e: Exception) { "" }
|
||||||
@ -40,6 +42,6 @@ abstract class DelegatedHttpSource {
|
|||||||
suspend fun getChapters(url: String): List<SChapter>? {
|
suspend fun getChapters(url: String): List<SChapter>? {
|
||||||
val id = delegate?.id ?: return null
|
val id = delegate?.id ?: return null
|
||||||
val manga = Manga.create(url, "", id)
|
val manga = Manga.create(url, "", id)
|
||||||
return delegate?.fetchChapterListAsync(manga)
|
return delegate?.getChapterList(manga.toMangaInfo())?.map { it.toSChapter() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import android.view.View
|
|||||||
import android.widget.CompoundButton
|
import android.widget.CompoundButton
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.afollestad.materialdialogs.customview.customView
|
import com.afollestad.materialdialogs.customview.customView
|
||||||
import com.f2prateek.rx.preferences.Preference
|
import com.tfcporciuncula.flow.Preference
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
@ -99,18 +99,18 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
|
|||||||
}
|
}
|
||||||
view.title.hint = category.name
|
view.title.hint = category.name
|
||||||
view.title.append(category.name)
|
view.title.append(category.name)
|
||||||
val downloadNew = preferences.downloadNew().getOrDefault()
|
val downloadNew = preferences.downloadNew().get()
|
||||||
setCheckbox(
|
setCheckbox(
|
||||||
view.download_new,
|
view.download_new,
|
||||||
preferences.downloadNewCategories(),
|
preferences.downloadNewCategories(),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
if (downloadNew && preferences.downloadNewCategories().getOrDefault().isEmpty())
|
if (downloadNew && preferences.downloadNewCategories().get().isEmpty())
|
||||||
view.download_new.gone()
|
view.download_new.gone()
|
||||||
else if (!downloadNew)
|
else if (!downloadNew)
|
||||||
view.download_new.visible()
|
view.download_new.visible()
|
||||||
view.download_new.isChecked =
|
view.download_new.isChecked =
|
||||||
preferences.downloadNew().getOrDefault() && view.download_new.isChecked
|
preferences.downloadNew().get() && view.download_new.isChecked
|
||||||
setCheckbox(
|
setCheckbox(
|
||||||
view.include_global,
|
view.include_global,
|
||||||
preferences.libraryUpdateCategories(),
|
preferences.libraryUpdateCategories(),
|
||||||
@ -121,7 +121,7 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
|
|||||||
/** Update a pref based on checkbox, and return if the pref is not empty */
|
/** Update a pref based on checkbox, and return if the pref is not empty */
|
||||||
private fun updatePref(categories: Preference<Set<String>>, box: CompoundButton): Boolean {
|
private fun updatePref(categories: Preference<Set<String>>, box: CompoundButton): Boolean {
|
||||||
val categoryId = category.id ?: return true
|
val categoryId = category.id ?: return true
|
||||||
val updateCategories = categories.getOrDefault().toMutableSet()
|
val updateCategories = categories.get().toMutableSet()
|
||||||
if (box.isChecked) {
|
if (box.isChecked) {
|
||||||
updateCategories.add(categoryId.toString())
|
updateCategories.add(categoryId.toString())
|
||||||
} else {
|
} else {
|
||||||
@ -136,7 +136,7 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
|
|||||||
categories: Preference<Set<String>>,
|
categories: Preference<Set<String>>,
|
||||||
shouldShow: Boolean
|
shouldShow: Boolean
|
||||||
) {
|
) {
|
||||||
val updateCategories = categories.getOrDefault()
|
val updateCategories = categories.get()
|
||||||
box.visibleIf(updateCategories.isNotEmpty() && shouldShow)
|
box.visibleIf(updateCategories.isNotEmpty() && shouldShow)
|
||||||
if (updateCategories.isNotEmpty() && shouldShow) box.isChecked =
|
if (updateCategories.isNotEmpty() && shouldShow) box.isChecked =
|
||||||
updateCategories.any { category.id == it.toIntOrNull() }
|
updateCategories.any { category.id == it.toIntOrNull() }
|
||||||
|
@ -13,6 +13,7 @@ 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.models.MangaCategory
|
import eu.kanade.tachiyomi.data.database.models.MangaCategory
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.download.model.Download
|
import eu.kanade.tachiyomi.data.download.model.Download
|
||||||
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
|
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
|
||||||
@ -25,9 +26,8 @@ import eu.kanade.tachiyomi.data.track.TrackManager
|
|||||||
import eu.kanade.tachiyomi.data.track.TrackService
|
import eu.kanade.tachiyomi.data.track.TrackService
|
||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
import eu.kanade.tachiyomi.source.Source
|
import eu.kanade.tachiyomi.source.Source
|
||||||
import eu.kanade.tachiyomi.source.fetchChapterListAsync
|
import eu.kanade.tachiyomi.source.model.toSChapter
|
||||||
import eu.kanade.tachiyomi.source.fetchMangaDetailsAsync
|
import eu.kanade.tachiyomi.source.model.toSManga
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
|
||||||
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem
|
||||||
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
|
||||||
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
import eu.kanade.tachiyomi.ui.security.SecureActivityDelegate
|
||||||
@ -35,6 +35,7 @@ import eu.kanade.tachiyomi.util.chapter.ChapterFilter
|
|||||||
import eu.kanade.tachiyomi.util.chapter.ChapterUtil
|
import eu.kanade.tachiyomi.util.chapter.ChapterUtil
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
import eu.kanade.tachiyomi.util.lang.trimOrNull
|
import eu.kanade.tachiyomi.util.lang.trimOrNull
|
||||||
|
import eu.kanade.tachiyomi.util.shouldDownloadNewChapters
|
||||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
import eu.kanade.tachiyomi.util.system.ImageUtil
|
import eu.kanade.tachiyomi.util.system.ImageUtil
|
||||||
import eu.kanade.tachiyomi.util.system.executeOnIO
|
import eu.kanade.tachiyomi.util.system.executeOnIO
|
||||||
@ -316,16 +317,16 @@ class MangaDetailsPresenter(
|
|||||||
var chapterError: java.lang.Exception? = null
|
var chapterError: java.lang.Exception? = null
|
||||||
val chapters = async(Dispatchers.IO) {
|
val chapters = async(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
source.fetchChapterListAsync(manga)
|
source.getChapterList(manga.toMangaInfo()).map { it.toSChapter() }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
chapterError = e
|
chapterError = e
|
||||||
emptyList<SChapter>()
|
emptyList()
|
||||||
} ?: emptyList()
|
}
|
||||||
}
|
}
|
||||||
val thumbnailUrl = manga.thumbnail_url
|
val thumbnailUrl = manga.thumbnail_url
|
||||||
val nManga = async(Dispatchers.IO) {
|
val nManga = async(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
source.fetchMangaDetailsAsync(manga)
|
source.getMangaDetails(manga.toMangaInfo()).toSManga()
|
||||||
} catch (e: java.lang.Exception) {
|
} catch (e: java.lang.Exception) {
|
||||||
mangaError = e
|
mangaError = e
|
||||||
null
|
null
|
||||||
@ -350,18 +351,13 @@ class MangaDetailsPresenter(
|
|||||||
if (finChapters.isNotEmpty()) {
|
if (finChapters.isNotEmpty()) {
|
||||||
val newChapters = syncChaptersWithSource(db, finChapters, manga, source)
|
val newChapters = syncChaptersWithSource(db, finChapters, manga, source)
|
||||||
if (newChapters.first.isNotEmpty()) {
|
if (newChapters.first.isNotEmpty()) {
|
||||||
val downloadNew = preferences.downloadNew().getOrDefault()
|
if (manga.shouldDownloadNewChapters(db, preferences)) {
|
||||||
if (downloadNew && !controller.fromCatalogue && mangaWasInitalized) {
|
|
||||||
val categoriesToDownload = preferences.downloadNewCategories().getOrDefault().map(String::toInt)
|
|
||||||
val shouldDownload = categoriesToDownload.isEmpty() || getMangaCategoryIds().any { it in categoriesToDownload }
|
|
||||||
if (shouldDownload) {
|
|
||||||
downloadChapters(
|
downloadChapters(
|
||||||
newChapters.first.sortedBy { it.chapter_number }
|
newChapters.first.sortedBy { it.chapter_number }
|
||||||
.map { it.toModel() }
|
.map { it.toModel() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (newChapters.second.isNotEmpty()) {
|
if (newChapters.second.isNotEmpty()) {
|
||||||
val removedChaptersId = newChapters.second.map { it.id }
|
val removedChaptersId = newChapters.second.map { it.id }
|
||||||
val removedChapters = this@MangaDetailsPresenter.chapters.filter {
|
val removedChapters = this@MangaDetailsPresenter.chapters.filter {
|
||||||
@ -403,7 +399,7 @@ class MangaDetailsPresenter(
|
|||||||
|
|
||||||
scope.launch(Dispatchers.IO) {
|
scope.launch(Dispatchers.IO) {
|
||||||
val chapters = try {
|
val chapters = try {
|
||||||
source.fetchChapterListAsync(manga)
|
source.getChapterList(manga.toMangaInfo()).map { it.toSChapter() }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
withContext(Dispatchers.Main) { controller.showError(trimException(e)) }
|
withContext(Dispatchers.Main) { controller.showError(trimException(e)) }
|
||||||
return@launch
|
return@launch
|
||||||
|
@ -18,6 +18,7 @@ import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.toMangaInfo
|
||||||
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.smartsearch.SmartSearchEngine
|
import eu.kanade.tachiyomi.smartsearch.SmartSearchEngine
|
||||||
@ -25,6 +26,8 @@ import eu.kanade.tachiyomi.source.CatalogueSource
|
|||||||
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 eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
|
import eu.kanade.tachiyomi.source.model.toSChapter
|
||||||
|
import eu.kanade.tachiyomi.source.model.toSManga
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||||
import eu.kanade.tachiyomi.ui.main.BottomNavBarInterface
|
import eu.kanade.tachiyomi.ui.main.BottomNavBarInterface
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
||||||
@ -184,10 +187,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
|||||||
source.id
|
source.id
|
||||||
)
|
)
|
||||||
val chapters =
|
val chapters =
|
||||||
source.fetchChapterList(localManga).toSingle()
|
source.getChapterList(localManga.toMangaInfo()).map { it.toSChapter() }
|
||||||
.await(
|
|
||||||
Schedulers.io()
|
|
||||||
)
|
|
||||||
try {
|
try {
|
||||||
syncChaptersWithSource(
|
syncChaptersWithSource(
|
||||||
db,
|
db,
|
||||||
@ -226,8 +226,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
|||||||
source.id
|
source.id
|
||||||
)
|
)
|
||||||
val chapters = try {
|
val chapters = try {
|
||||||
source.fetchChapterList(localManga).toSingle()
|
source.getChapterList(localManga.toMangaInfo()).map { it.toSChapter() }
|
||||||
.await(Schedulers.io())
|
|
||||||
} catch (e: java.lang.Exception) {
|
} catch (e: java.lang.Exception) {
|
||||||
Timber.e(e)
|
Timber.e(e)
|
||||||
emptyList<SChapter>()
|
emptyList<SChapter>()
|
||||||
@ -260,8 +259,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
|||||||
if (result != null && result.thumbnail_url == null) {
|
if (result != null && result.thumbnail_url == null) {
|
||||||
try {
|
try {
|
||||||
val newManga =
|
val newManga =
|
||||||
sourceManager.getOrStub(result.source).fetchMangaDetails(result)
|
sourceManager.getOrStub(result.source).getMangaDetails(result.toMangaInfo()).toSManga()
|
||||||
.toSingle().await()
|
|
||||||
result.copyFrom(newManga)
|
result.copyFrom(newManga)
|
||||||
|
|
||||||
db.insertManga(result).executeAsBlocking()
|
db.insertManga(result).executeAsBlocking()
|
||||||
@ -366,9 +364,7 @@ class MigrationListController(bundle: Bundle? = null) :
|
|||||||
launchUI {
|
launchUI {
|
||||||
val result = CoroutineScope(migratingManga.manga.migrationJob).async {
|
val result = CoroutineScope(migratingManga.manga.migrationJob).async {
|
||||||
val localManga = smartSearchEngine.networkToLocalManga(manga, source.id)
|
val localManga = smartSearchEngine.networkToLocalManga(manga, source.id)
|
||||||
val chapters = source.fetchChapterList(localManga).toSingle().await(
|
val chapters = source.getChapterList(localManga.toMangaInfo()).map { it.toSChapter() }
|
||||||
Schedulers.io()
|
|
||||||
)
|
|
||||||
try {
|
try {
|
||||||
syncChaptersWithSource(db, chapters, localManga, source)
|
syncChaptersWithSource(db, chapters, localManga, source)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@ -380,8 +376,8 @@ class MigrationListController(bundle: Bundle? = null) :
|
|||||||
if (result != null) {
|
if (result != null) {
|
||||||
try {
|
try {
|
||||||
val newManga =
|
val newManga =
|
||||||
sourceManager.getOrStub(result.source).fetchMangaDetails(result).toSingle()
|
sourceManager.getOrStub(result.source).getMangaDetails(result.toMangaInfo())
|
||||||
.await()
|
.toSManga()
|
||||||
result.copyFrom(newManga)
|
result.copyFrom(newManga)
|
||||||
|
|
||||||
db.insertManga(result).executeAsBlocking()
|
db.insertManga(result).executeAsBlocking()
|
||||||
|
@ -16,6 +16,7 @@ import com.hippo.unifile.UniFile
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
import eu.kanade.tachiyomi.util.system.getFilePicker
|
import eu.kanade.tachiyomi.util.system.getFilePicker
|
||||||
@ -93,12 +94,10 @@ class SettingsDownloadController : SettingsController() {
|
|||||||
entryValues = dbCategories.map { it.id.toString() }
|
entryValues = dbCategories.map { it.id.toString() }
|
||||||
allSelectionRes = R.string.all
|
allSelectionRes = R.string.all
|
||||||
|
|
||||||
preferences.downloadNew().asObservable()
|
preferences.downloadNew().asImmediateFlow { isVisible = it }
|
||||||
.subscribeUntilDestroy { isVisible = it }
|
|
||||||
|
|
||||||
preferences.downloadNewCategories().asObservable()
|
preferences.downloadNewCategories().asImmediateFlow { list ->
|
||||||
.subscribeUntilDestroy {
|
val selectedCategories = list
|
||||||
val selectedCategories = it
|
|
||||||
.mapNotNull { id -> dbCategories.find { it.id == id.toInt() } }
|
.mapNotNull { id -> dbCategories.find { it.id == id.toInt() } }
|
||||||
.sortedBy { it.order }
|
.sortedBy { it.order }
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
||||||
|
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
|
||||||
import eu.kanade.tachiyomi.ui.category.CategoryController
|
import eu.kanade.tachiyomi.ui.category.CategoryController
|
||||||
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
@ -133,9 +134,9 @@ class SettingsLibraryController : SettingsController() {
|
|||||||
entryValues = dbCategories.map { it.id.toString() }
|
entryValues = dbCategories.map { it.id.toString() }
|
||||||
allSelectionRes = R.string.all
|
allSelectionRes = R.string.all
|
||||||
|
|
||||||
preferences.libraryUpdateCategories().asObservable().subscribeUntilDestroy {
|
preferences.libraryUpdateCategories().asImmediateFlow { list ->
|
||||||
val selectedCategories =
|
val selectedCategories =
|
||||||
it.mapNotNull { id -> dbCategories.find { it.id == id.toInt() } }
|
list.mapNotNull { id -> dbCategories.find { it.id == id.toInt() } }
|
||||||
.sortedBy { it.order }
|
.sortedBy { it.order }
|
||||||
|
|
||||||
customSummary =
|
customSummary =
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
package eu.kanade.tachiyomi.util
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
fun Manga.isLocal() = source == LocalSource.ID
|
||||||
|
|
||||||
|
/*
|
||||||
|
/**
|
||||||
|
* Call before updating [Manga.thumbnail_url] to ensure old cover can be cleared from cache
|
||||||
|
*/
|
||||||
|
fun Manga.prepUpdateCover(coverCache: CoverCache, remoteManga: SManga, refreshSameUrl: Boolean) {
|
||||||
|
// Never refresh covers if the new url is null, as the current url has possibly become invalid
|
||||||
|
val newUrl = remoteManga.thumbnail_url ?: return
|
||||||
|
|
||||||
|
// Never refresh covers if the url is empty to avoid "losing" existing covers
|
||||||
|
if (newUrl.isEmpty()) return
|
||||||
|
|
||||||
|
if (!refreshSameUrl && thumbnail_url == newUrl) return
|
||||||
|
|
||||||
|
when {
|
||||||
|
isLocal() -> {
|
||||||
|
cover_last_modified = Date().time
|
||||||
|
}
|
||||||
|
hasCustomCover(coverCache) -> {
|
||||||
|
coverCache.deleteFromCache(this, false)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
cover_last_modified = Date().time
|
||||||
|
coverCache.deleteFromCache(this, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Manga.hasCustomCover(coverCache: CoverCache): Boolean {
|
||||||
|
return coverCache.getCustomCoverFile(this).exists()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Manga.removeCovers(coverCache: CoverCache) {
|
||||||
|
if (isLocal()) return
|
||||||
|
|
||||||
|
cover_last_modified = Date().time
|
||||||
|
coverCache.deleteFromCache(this, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Manga.updateCoverLastModified(db: DatabaseHelper) {
|
||||||
|
cover_last_modified = Date().time
|
||||||
|
db.updateMangaCoverLastModified(this).executeAsBlocking()
|
||||||
|
}*/
|
||||||
|
|
||||||
|
fun Manga.shouldDownloadNewChapters(db: DatabaseHelper, prefs: PreferencesHelper): Boolean {
|
||||||
|
if (!favorite) return false
|
||||||
|
|
||||||
|
// Boolean to determine if user wants to automatically download new chapters.
|
||||||
|
val downloadNew = prefs.downloadNew().get()
|
||||||
|
if (!downloadNew) return false
|
||||||
|
|
||||||
|
val categoriesToDownload = prefs.downloadNewCategories().get().map(String::toInt)
|
||||||
|
if (categoriesToDownload.isEmpty()) return true
|
||||||
|
|
||||||
|
// Get all categories, else default category (0)
|
||||||
|
val categoriesForManga =
|
||||||
|
db.getCategoriesForManga(this).executeAsBlocking()
|
||||||
|
.mapNotNull { it.id }
|
||||||
|
.takeUnless { it.isEmpty() } ?: listOf(0)
|
||||||
|
|
||||||
|
return categoriesForManga.intersect(categoriesToDownload).isNotEmpty()
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.data.backup
|
package eu.kanade.tachiyomi.data.backup
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.app.backup.BackupManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
import com.github.salomonbrys.kotson.fromJson
|
||||||
@ -8,8 +9,9 @@ import com.google.gson.JsonArray
|
|||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
import eu.kanade.tachiyomi.CustomRobolectricGradleTestRunner
|
import eu.kanade.tachiyomi.CustomRobolectricGradleTestRunner
|
||||||
import eu.kanade.tachiyomi.data.backup.models.Backup
|
import eu.kanade.tachiyomi.data.backup.legacy.LegacyBackupManager
|
||||||
import eu.kanade.tachiyomi.data.backup.models.DHistory
|
import eu.kanade.tachiyomi.data.backup.legacy.models.Backup
|
||||||
|
import eu.kanade.tachiyomi.data.backup.legacy.models.DHistory
|
||||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
@ -62,7 +64,7 @@ class BackupTest {
|
|||||||
lateinit var context: Context
|
lateinit var context: Context
|
||||||
lateinit var source: HttpSource
|
lateinit var source: HttpSource
|
||||||
|
|
||||||
lateinit var backupManager: BackupManager
|
lateinit var backupManager: LegacyBackupManager
|
||||||
|
|
||||||
lateinit var db: DatabaseHelper
|
lateinit var db: DatabaseHelper
|
||||||
|
|
||||||
@ -70,7 +72,7 @@ class BackupTest {
|
|||||||
fun setup() {
|
fun setup() {
|
||||||
app = RuntimeEnvironment.application
|
app = RuntimeEnvironment.application
|
||||||
context = app.applicationContext
|
context = app.applicationContext
|
||||||
backupManager = BackupManager(context)
|
backupManager = LegacyBackupManager(context)
|
||||||
db = backupManager.databaseHelper
|
db = backupManager.databaseHelper
|
||||||
|
|
||||||
// Mock the source manager
|
// Mock the source manager
|
||||||
@ -93,9 +95,6 @@ class BackupTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun testRestoreEmptyCategory() {
|
fun testRestoreEmptyCategory() {
|
||||||
// Initialize json with version 2
|
|
||||||
initializeJsonTest(2)
|
|
||||||
|
|
||||||
// Create backup of empty database
|
// Create backup of empty database
|
||||||
backupManager.backupCategories(categoryEntries)
|
backupManager.backupCategories(categoryEntries)
|
||||||
|
|
||||||
@ -112,9 +111,6 @@ class BackupTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun testRestoreSingleCategory() {
|
fun testRestoreSingleCategory() {
|
||||||
// Initialize json with version 2
|
|
||||||
initializeJsonTest(2)
|
|
||||||
|
|
||||||
// Create category and add to json
|
// Create category and add to json
|
||||||
val category = addSingleCategory("category")
|
val category = addSingleCategory("category")
|
||||||
|
|
||||||
@ -132,9 +128,6 @@ class BackupTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun testRestoreMultipleCategories() {
|
fun testRestoreMultipleCategories() {
|
||||||
// Initialize json with version 2
|
|
||||||
initializeJsonTest(2)
|
|
||||||
|
|
||||||
// Create category and add to json
|
// Create category and add to json
|
||||||
val category = addSingleCategory("category")
|
val category = addSingleCategory("category")
|
||||||
val category2 = addSingleCategory("category2")
|
val category2 = addSingleCategory("category2")
|
||||||
@ -163,9 +156,6 @@ class BackupTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun testRestoreManga() {
|
fun testRestoreManga() {
|
||||||
// Initialize json with version 2
|
|
||||||
initializeJsonTest(2)
|
|
||||||
|
|
||||||
// Add manga to database
|
// Add manga to database
|
||||||
val manga = getSingleManga("One Piece")
|
val manga = getSingleManga("One Piece")
|
||||||
manga.viewer = 3
|
manga.viewer = 3
|
||||||
@ -215,7 +205,7 @@ class BackupTest {
|
|||||||
|
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
try {
|
try {
|
||||||
backupManager.restoreMangaFetch(source, jsonManga)
|
backupManager.fetchManga(source, jsonManga)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
fail("Unexpected onError events")
|
fail("Unexpected onError events")
|
||||||
}
|
}
|
||||||
@ -233,9 +223,6 @@ class BackupTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun testRestoreChapters() {
|
fun testRestoreChapters() {
|
||||||
// Initialize json with version 2
|
|
||||||
initializeJsonTest(2)
|
|
||||||
|
|
||||||
// Insert manga
|
// Insert manga
|
||||||
val manga = getSingleManga("One Piece")
|
val manga = getSingleManga("One Piece")
|
||||||
manga.id = backupManager.databaseHelper.insertManga(manga).executeAsBlocking().insertedId()
|
manga.id = backupManager.databaseHelper.insertManga(manga).executeAsBlocking().insertedId()
|
||||||
@ -261,7 +248,7 @@ class BackupTest {
|
|||||||
// Call restoreChapterFetchObservable
|
// Call restoreChapterFetchObservable
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
try {
|
try {
|
||||||
backupManager.restoreChapterFetch(source, manga, restoredChapters)
|
backupManager.restoreChapters(source, manga, restoredChapters)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
fail("Unexpected onError events")
|
fail("Unexpected onError events")
|
||||||
}
|
}
|
||||||
@ -277,9 +264,6 @@ class BackupTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun restoreHistoryForManga() {
|
fun restoreHistoryForManga() {
|
||||||
// Initialize json with version 2
|
|
||||||
initializeJsonTest(2)
|
|
||||||
|
|
||||||
val manga = getSingleManga("One Piece")
|
val manga = getSingleManga("One Piece")
|
||||||
manga.id = backupManager.databaseHelper.insertManga(manga).executeAsBlocking().insertedId()
|
manga.id = backupManager.databaseHelper.insertManga(manga).executeAsBlocking().insertedId()
|
||||||
|
|
||||||
@ -311,9 +295,6 @@ class BackupTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
fun restoreTrackForManga() {
|
fun restoreTrackForManga() {
|
||||||
// Initialize json with version 2
|
|
||||||
initializeJsonTest(2)
|
|
||||||
|
|
||||||
// Create mangas
|
// Create mangas
|
||||||
val manga = getSingleManga("One Piece")
|
val manga = getSingleManga("One Piece")
|
||||||
val manga2 = getSingleManga("Bleach")
|
val manga2 = getSingleManga("Bleach")
|
||||||
@ -377,11 +358,6 @@ class BackupTest {
|
|||||||
categoryEntries = JsonArray()
|
categoryEntries = JsonArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun initializeJsonTest(version: Int) {
|
|
||||||
clearJson()
|
|
||||||
backupManager.setVersion(version)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addSingleCategory(name: String): Category {
|
fun addSingleCategory(name: String): Category {
|
||||||
val category = Category.create(name)
|
val category = Category.create(name)
|
||||||
val catJson = backupManager.parser.toJsonTree(category)
|
val catJson = backupManager.parser.toJsonTree(category)
|
||||||
|
Loading…
Reference in New Issue
Block a user