diff --git a/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt b/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt index 23a1d81859..31c4187664 100644 --- a/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt +++ b/app/src/main/java/eu/kanade/domain/chapter/interactor/SyncChaptersWithSource.kt @@ -96,7 +96,7 @@ class SyncChaptersWithSource( toAdd.add(toAddChapter) } else { if (shouldUpdateDbChapter.await(dbChapter, chapter)) { - if (dbChapter.name != chapter.name && downloadManager.isChapterDownloaded(dbChapter.toDbChapter(), manga.toDbManga())) { + if (dbChapter.name != chapter.name && downloadManager.isChapterDownloaded(dbChapter.name, dbChapter.scanlator, manga.title, manga.source)) { downloadManager.renameChapter(source, manga.toDbManga(), dbChapter.toDbChapter(), chapter.toDbChapter()) } var toChangeChapter = dbChapter.copy( diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt index 4e3a3613de..fee03fa1cd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt @@ -65,23 +65,31 @@ class DownloadCache( /** * Returns true if the chapter is downloaded. * - * @param chapter the chapter to check. - * @param manga the manga of the chapter. + * @param chapterName the name of the chapter to query. + * @param chapterScanlator scanlator of the chapter to query + * @param mangaTitle the title of the manga to query. + * @param sourceId the id of the source of the chapter. * @param skipCache whether to skip the directory cache and check in the filesystem. */ - fun isChapterDownloaded(chapter: Chapter, manga: Manga, skipCache: Boolean): Boolean { + fun isChapterDownloaded( + chapterName: String, + chapterScanlator: String?, + mangaTitle: String, + sourceId: Long, + skipCache: Boolean, + ): Boolean { if (skipCache) { - val source = sourceManager.getOrStub(manga.source) - return provider.findChapterDir(chapter, manga, source) != null + val source = sourceManager.getOrStub(sourceId) + return provider.findChapterDir(chapterName, chapterScanlator, mangaTitle, source) != null } checkRenew() - val sourceDir = rootDir.files[manga.source] + val sourceDir = rootDir.files[sourceId] if (sourceDir != null) { - val mangaDir = sourceDir.files[provider.getMangaDirName(manga)] + val mangaDir = sourceDir.files[provider.getMangaDirName(mangaTitle)] if (mangaDir != null) { - return provider.getValidChapterDirNames(chapter).any { it in mangaDir.files } + return provider.getValidChapterDirNames(chapterName, chapterScanlator).any { it in mangaDir.files } } } return false @@ -97,7 +105,7 @@ class DownloadCache( val sourceDir = rootDir.files[manga.source] if (sourceDir != null) { - val mangaDir = sourceDir.files[provider.getMangaDirName(manga)] + val mangaDir = sourceDir.files[provider.getMangaDirName(manga.title)] if (mangaDir != null) { return mangaDir.files .filter { !it.endsWith(Downloader.TMP_DIR_SUFFIX) } @@ -174,7 +182,7 @@ class DownloadCache( } // Retrieve the cached manga directory or cache a new one - val mangaDirName = provider.getMangaDirName(manga) + val mangaDirName = provider.getMangaDirName(manga.title) var mangaDir = sourceDir.files[mangaDirName] if (mangaDir == null) { mangaDir = MangaDirectory(mangaUniFile) @@ -194,8 +202,8 @@ class DownloadCache( @Synchronized fun removeChapter(chapter: Chapter, manga: Manga) { val sourceDir = rootDir.files[manga.source] ?: return - val mangaDir = sourceDir.files[provider.getMangaDirName(manga)] ?: return - provider.getValidChapterDirNames(chapter).forEach { + val mangaDir = sourceDir.files[provider.getMangaDirName(manga.title)] ?: return + provider.getValidChapterDirNames(chapter.name, chapter.scanlator).forEach { if (it in mangaDir.files) { mangaDir.files -= it } @@ -211,9 +219,9 @@ class DownloadCache( @Synchronized fun removeChapters(chapters: List, manga: Manga) { val sourceDir = rootDir.files[manga.source] ?: return - val mangaDir = sourceDir.files[provider.getMangaDirName(manga)] ?: return + val mangaDir = sourceDir.files[provider.getMangaDirName(manga.title)] ?: return chapters.forEach { chapter -> - provider.getValidChapterDirNames(chapter).forEach { + provider.getValidChapterDirNames(chapter.name, chapter.scanlator).forEach { if (it in mangaDir.files) { mangaDir.files -= it } @@ -229,7 +237,7 @@ class DownloadCache( @Synchronized fun removeManga(manga: Manga) { val sourceDir = rootDir.files[manga.source] ?: return - val mangaDirName = provider.getMangaDirName(manga) + val mangaDirName = provider.getMangaDirName(manga.title) if (mangaDirName in sourceDir.files) { sourceDir.files -= mangaDirName } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt index 4ecdc039f3..c6706398f8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt @@ -163,7 +163,7 @@ class DownloadManager( * @return an observable containing the list of pages from the chapter. */ fun buildPageList(source: Source, manga: Manga, chapter: Chapter): Observable> { - return buildPageList(provider.findChapterDir(chapter, manga, source)) + return buildPageList(provider.findChapterDir(chapter.name, chapter.scanlator, manga.title, source)) } /** @@ -191,12 +191,20 @@ class DownloadManager( /** * Returns true if the chapter is downloaded. * - * @param chapter the chapter to check. - * @param manga the manga of the chapter. + * @param chapterName the name of the chapter to query. + * @param chapterScanlator scanlator of the chapter to query + * @param mangaTitle the title of the manga to query. + * @param sourceId the id of the source of the chapter. * @param skipCache whether to skip the directory cache and check in the filesystem. */ - fun isChapterDownloaded(chapter: Chapter, manga: Manga, skipCache: Boolean = false): Boolean { - return cache.isChapterDownloaded(chapter, manga, skipCache) + fun isChapterDownloaded( + chapterName: String, + chapterScanlator: String?, + mangaTitle: String, + sourceId: Long, + skipCache: Boolean = false, + ): Boolean { + return cache.isChapterDownloaded(chapterName, chapterScanlator, mangaTitle, sourceId, skipCache) } /** @@ -292,7 +300,7 @@ class DownloadManager( fun deleteManga(manga: Manga, source: Source) { launchIO { downloader.queue.remove(manga) - provider.findMangaDir(manga, source)?.delete() + provider.findMangaDir(manga.title, source)?.delete() cache.removeManga(manga) } } @@ -327,15 +335,15 @@ class DownloadManager( * @param newChapter the target chapter with the new name. */ fun renameChapter(source: Source, manga: Manga, oldChapter: Chapter, newChapter: Chapter) { - val oldNames = provider.getValidChapterDirNames(oldChapter) - val mangaDir = provider.getMangaDir(manga, source) + val oldNames = provider.getValidChapterDirNames(oldChapter.name, oldChapter.scanlator) + val mangaDir = provider.getMangaDir(manga.title, source) // Assume there's only 1 version of the chapter name formats present val oldDownload = oldNames.asSequence() .mapNotNull { mangaDir.findFile(it) } .firstOrNull() ?: return - var newName = provider.getChapterDirName(newChapter) + var newName = provider.getChapterDirName(newChapter.name, newChapter.scanlator) if (oldDownload.isFile && oldDownload.name?.endsWith(".cbz") == true) { newName += ".cbz" } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt index e7ea310f64..9aef158341 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt @@ -46,14 +46,14 @@ class DownloadProvider(private val context: Context) { /** * Returns the download directory for a manga. For internal use only. * - * @param manga the manga to query. + * @param mangaTitle the title of the manga to query. * @param source the source of the manga. */ - internal fun getMangaDir(manga: Manga, source: Source): UniFile { + internal fun getMangaDir(mangaTitle: String, source: Source): UniFile { try { return downloadsDir .createDirectory(getSourceDirName(source)) - .createDirectory(getMangaDirName(manga)) + .createDirectory(getMangaDirName(mangaTitle)) } catch (e: Throwable) { logcat(LogPriority.ERROR, e) { "Invalid download directory" } throw Exception(context.getString(R.string.invalid_download_dir)) @@ -72,24 +72,25 @@ class DownloadProvider(private val context: Context) { /** * Returns the download directory for a manga if it exists. * - * @param manga the manga to query. + * @param mangaTitle the title of the manga to query. * @param source the source of the manga. */ - fun findMangaDir(manga: Manga, source: Source): UniFile? { + fun findMangaDir(mangaTitle: String, source: Source): UniFile? { val sourceDir = findSourceDir(source) - return sourceDir?.findFile(getMangaDirName(manga), true) + return sourceDir?.findFile(getMangaDirName(mangaTitle), true) } /** * Returns the download directory for a chapter if it exists. * - * @param chapter the chapter to query. - * @param manga the manga of the chapter. + * @param chapterName the name of the chapter to query. + * @param chapterScanlator scanlator of the chapter to query + * @param mangaTitle the title of the manga to query. * @param source the source of the chapter. */ - fun findChapterDir(chapter: Chapter, manga: Manga, source: Source): UniFile? { - val mangaDir = findMangaDir(manga, source) - return getValidChapterDirNames(chapter).asSequence() + fun findChapterDir(chapterName: String, chapterScanlator: String?, mangaTitle: String, source: Source): UniFile? { + val mangaDir = findMangaDir(mangaTitle, source) + return getValidChapterDirNames(chapterName, chapterScanlator).asSequence() .mapNotNull { mangaDir?.findFile(it, true) } .firstOrNull() } @@ -102,9 +103,9 @@ class DownloadProvider(private val context: Context) { * @param source the source of the chapter. */ fun findChapterDirs(chapters: List, manga: Manga, source: Source): List { - val mangaDir = findMangaDir(manga, source) ?: return emptyList() + val mangaDir = findMangaDir(manga.title, source) ?: return emptyList() return chapters.mapNotNull { chapter -> - getValidChapterDirNames(chapter).asSequence() + getValidChapterDirNames(chapter.name, chapter.scanlator).asSequence() .mapNotNull { mangaDir.findFile(it) } .firstOrNull() } @@ -122,22 +123,23 @@ class DownloadProvider(private val context: Context) { /** * Returns the download directory name for a manga. * - * @param manga the manga to query. + * @param mangaTitle the title of the manga to query. */ - fun getMangaDirName(manga: Manga): String { - return DiskUtil.buildValidFilename(manga.title) + fun getMangaDirName(mangaTitle: String): String { + return DiskUtil.buildValidFilename(mangaTitle) } /** * Returns the chapter directory name for a chapter. * - * @param chapter the chapter to query. + * @param chapterName the name of the chapter to query. + * @param chapterScanlator scanlator of the chapter to query */ - fun getChapterDirName(chapter: Chapter): String { + fun getChapterDirName(chapterName: String, chapterScanlator: String?): String { return DiskUtil.buildValidFilename( when { - chapter.scanlator != null -> "${chapter.scanlator}_${chapter.name}" - else -> chapter.name + chapterScanlator != null -> "${chapterScanlator}_$chapterName" + else -> chapterName }, ) } @@ -145,19 +147,20 @@ class DownloadProvider(private val context: Context) { /** * Returns valid downloaded chapter directory names. * - * @param chapter the chapter to query. + * @param chapterName the name of the chapter to query. + * @param chapterScanlator scanlator of the chapter to query */ - fun getValidChapterDirNames(chapter: Chapter): List { - val chapterName = getChapterDirName(chapter) + fun getValidChapterDirNames(chapterName: String, chapterScanlator: String?): List { + val chapterDirName = getChapterDirName(chapterName, chapterScanlator) return listOf( // Folder of images - chapterName, + chapterDirName, // Archived chapters - "$chapterName.cbz", + "$chapterDirName.cbz", // Legacy chapter directory name used in v0.9.2 and before - DiskUtil.buildValidFilename(chapter.name), + DiskUtil.buildValidFilename(chapterName), ) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt index 74dee3cfac..936d2e10be 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -252,7 +252,7 @@ class Downloader( val chaptersWithoutDir = async { chapters // Filter out those already downloaded. - .filter { provider.findChapterDir(it, manga, source) == null } + .filter { provider.findChapterDir(it.name, it.scanlator, manga.title, source) == null } // Add chapters to queue from the start. .sortedByDescending { it.source_order } } @@ -303,7 +303,7 @@ class Downloader( * @param download the chapter to be downloaded. */ private fun downloadChapter(download: Download): Observable = Observable.defer { - val mangaDir = provider.getMangaDir(download.manga, download.source) + val mangaDir = provider.getMangaDir(download.manga.title, download.source) val availSpace = DiskUtil.getAvailableStorageSpace(mangaDir) if (availSpace != -1L && availSpace < MIN_DISK_SPACE) { @@ -312,7 +312,7 @@ class Downloader( return@defer Observable.just(download) } - val chapterDirname = provider.getChapterDirName(download.chapter) + val chapterDirname = provider.getChapterDirName(download.chapter.name, download.chapter.scanlator) val tmpDir = mangaDir.createDirectory(chapterDirname + TMP_DIR_SUFFIX) val pageListObservable = if (download.pages == null) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt index 52b09f8ea7..12e77fff95 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt @@ -435,7 +435,7 @@ class MangaPresenter( private fun List.toChapterItems(manga: DomainManga): List { return map { chapter -> val activeDownload = downloadManager.queue.find { chapter.id == it.chapter.id } - val downloaded = downloadManager.isChapterDownloaded(chapter.toDbChapter(), manga.toDbManga()) + val downloaded = downloadManager.isChapterDownloaded(chapter.name, chapter.scanlator, manga.title, manga.source) val downloadState = when { activeDownload != null -> activeDownload.status downloaded -> Download.State.DOWNLOADED diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index 47028628cc..2dd01568ba 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -131,8 +131,8 @@ class ReaderPresenter( preferences.skipFiltered() -> { (manga.readFilter == Manga.CHAPTER_SHOW_READ && !it.read) || (manga.readFilter == Manga.CHAPTER_SHOW_UNREAD && it.read) || - (manga.downloadedFilter == Manga.CHAPTER_SHOW_DOWNLOADED && !downloadManager.isChapterDownloaded(it, manga)) || - (manga.downloadedFilter == Manga.CHAPTER_SHOW_NOT_DOWNLOADED && downloadManager.isChapterDownloaded(it, manga)) || + (manga.downloadedFilter == Manga.CHAPTER_SHOW_DOWNLOADED && !downloadManager.isChapterDownloaded(it.name, it.scanlator, manga.title, manga.source)) || + (manga.downloadedFilter == Manga.CHAPTER_SHOW_NOT_DOWNLOADED && downloadManager.isChapterDownloaded(it.name, it.scanlator, manga.title, manga.source)) || (manga.bookmarkedFilter == Manga.CHAPTER_SHOW_BOOKMARKED && !it.bookmark) || (manga.bookmarkedFilter == Manga.CHAPTER_SHOW_NOT_BOOKMARKED && it.bookmark) } @@ -362,7 +362,8 @@ class ReaderPresenter( private fun preload(chapter: ReaderChapter) { if (chapter.pageLoader is HttpPageLoader) { val manga = manga ?: return - val isDownloaded = downloadManager.isChapterDownloaded(chapter.chapter, manga) + val dbChapter = chapter.chapter + val isDownloaded = downloadManager.isChapterDownloaded(dbChapter.name, dbChapter.scanlator, manga.title, manga.source) if (isDownloaded) { chapter.state = ReaderChapter.State.Wait } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt index eb423ade66..0fa480598d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/ChapterLoader.kt @@ -76,7 +76,8 @@ class ChapterLoader( * Returns the page loader to use for this [chapter]. */ private fun getPageLoader(chapter: ReaderChapter): PageLoader { - val isDownloaded = downloadManager.isChapterDownloaded(chapter.chapter, manga, true) + val dbChapter = chapter.chapter + val isDownloaded = downloadManager.isChapterDownloaded(dbChapter.name, dbChapter.scanlator, manga.title, manga.source, skipCache = true) return when { isDownloaded -> DownloadPageLoader(chapter, manga, source, downloadManager) source is HttpSource -> HttpPageLoader(chapter, source) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt index 9d6452eda2..543cdff9f8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/loader/DownloadPageLoader.kt @@ -30,7 +30,8 @@ class DownloadPageLoader( * Returns an observable containing the pages found on this downloaded chapter. */ override fun getPages(): Observable> { - val chapterPath = downloadManager.provider.findChapterDir(chapter.chapter, manga, source) + val dbChapter = chapter.chapter + val chapterPath = downloadManager.provider.findChapterDir(dbChapter.name, dbChapter.scanlator, manga.title, source) return if (chapterPath?.isFile == true) { getPagesFromArchive(chapterPath) } else { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt index 60567d7858..0dc601bcd1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesPresenter.kt @@ -121,7 +121,7 @@ class UpdatesPresenter : BasePresenter() { val manga = item.manga val chapter = item.chapter - if (downloadManager.isChapterDownloaded(chapter, manga)) { + if (downloadManager.isChapterDownloaded(chapter.name, chapter.scanlator, manga.title, manga.source)) { item.status = Download.State.DOWNLOADED } }