Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -114,19 +114,22 @@ class SyncChaptersWithSource(
downloadManager.isChapterDownloaded(
dbChapter.name,
dbChapter.scanlator,
dbChapter.url,
manga.title,
manga.source,
)

if (shouldRenameChapter) {
downloadManager.renameChapter(source, manga, dbChapter, chapter)
}

var toChangeChapter = dbChapter.copy(
name = chapter.name,
chapterNumber = chapter.chapterNumber,
scanlator = chapter.scanlator,
sourceOrder = chapter.sourceOrder,
)

if (chapter.dateUpload != 0L) {
toChangeChapter = toChangeChapter.copy(dateUpload = chapter.dateUpload)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ fun List<Chapter>.applyFilters(manga: Manga, downloadManager: DownloadManager):
val downloaded = downloadManager.isChapterDownloaded(
chapter.name,
chapter.scanlator,
chapter.url,
manga.title,
manga.source,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,20 +128,22 @@ class DownloadCache(
*
* @param chapterName the name of the chapter to query.
* @param chapterScanlator scanlator of the chapter to query
* @param chapterUrl the url 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(
chapterName: String,
chapterScanlator: String?,
chapterUrl: String,
mangaTitle: String,
sourceId: Long,
skipCache: Boolean,
): Boolean {
if (skipCache) {
val source = sourceManager.getOrStub(sourceId)
return provider.findChapterDir(chapterName, chapterScanlator, mangaTitle, source) != null
return provider.findChapterDir(chapterName, chapterScanlator, chapterUrl, mangaTitle, source) != null
}

renewCache()
Expand All @@ -153,6 +155,7 @@ class DownloadCache(
return provider.getValidChapterDirNames(
chapterName,
chapterScanlator,
chapterUrl,
).any { it in mangaDir.chapterDirs }
}
}
Expand Down Expand Up @@ -233,7 +236,7 @@ class DownloadCache(
rootDownloadsDirMutex.withLock {
val sourceDir = rootDownloadsDir.sourceDirs[manga.source] ?: return
val mangaDir = sourceDir.mangaDirs[provider.getMangaDirName(manga.title)] ?: return
provider.getValidChapterDirNames(chapter.name, chapter.scanlator).forEach {
provider.getValidChapterDirNames(chapter.name, chapter.scanlator, chapter.url).forEach {
if (it in mangaDir.chapterDirs) {
mangaDir.chapterDirs -= it
}
Expand All @@ -254,7 +257,7 @@ class DownloadCache(
val sourceDir = rootDownloadsDir.sourceDirs[manga.source] ?: return
val mangaDir = sourceDir.mangaDirs[provider.getMangaDirName(manga.title)] ?: return
chapters.forEach { chapter ->
provider.getValidChapterDirNames(chapter.name, chapter.scanlator).forEach {
provider.getValidChapterDirNames(chapter.name, chapter.scanlator, chapter.url).forEach {
if (it in mangaDir.chapterDirs) {
mangaDir.chapterDirs -= it
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class DownloadManager(
* @return the list of pages from the chapter.
*/
fun buildPageList(source: Source, manga: Manga, chapter: Chapter): List<Page> {
val chapterDir = provider.findChapterDir(chapter.name, chapter.scanlator, manga.title, source)
val chapterDir = provider.findChapterDir(chapter.name, chapter.scanlator, chapter.url, manga.title, source)
val files = chapterDir?.listFiles().orEmpty()
.filter { it.isFile && ImageUtil.isImage(it.name) { it.openInputStream() } }

Expand All @@ -185,11 +185,12 @@ class DownloadManager(
fun isChapterDownloaded(
chapterName: String,
chapterScanlator: String?,
chapterUrl: String,
mangaTitle: String,
sourceId: Long,
skipCache: Boolean = false,
): Boolean {
return cache.isChapterDownloaded(chapterName, chapterScanlator, mangaTitle, sourceId, skipCache)
return cache.isChapterDownloaded(chapterName, chapterScanlator, chapterUrl, mangaTitle, sourceId, skipCache)
}

/**
Expand Down Expand Up @@ -368,7 +369,7 @@ class DownloadManager(
* @param newChapter the target chapter with the new name.
*/
suspend fun renameChapter(source: Source, manga: Manga, oldChapter: Chapter, newChapter: Chapter) {
val oldNames = provider.getValidChapterDirNames(oldChapter.name, oldChapter.scanlator)
val oldNames = provider.getValidChapterDirNames(oldChapter.name, oldChapter.scanlator, oldChapter.url)
val mangaDir = provider.getMangaDir(manga.title, source).getOrElse { e ->
logcat(LogPriority.ERROR, e) { "Manga download folder doesn't exist. Skipping renaming after source sync" }
return
Expand All @@ -379,7 +380,7 @@ class DownloadManager(
.mapNotNull { mangaDir.findFile(it) }
.firstOrNull() ?: return

var newName = provider.getChapterDirName(newChapter.name, newChapter.scanlator)
var newName = provider.getChapterDirName(newChapter.name, newChapter.scanlator, newChapter.url)
if (oldDownload.isFile && oldDownload.extension == "cbz") {
newName += ".cbz"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.download
import android.content.Context
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.util.lang.Hash.md5
import eu.kanade.tachiyomi.util.storage.DiskUtil
import logcat.LogPriority
import tachiyomi.core.common.i18n.stringResource
Expand Down Expand Up @@ -96,9 +97,9 @@ class DownloadProvider(
* @param mangaTitle the title of the manga to query.
* @param source the source of the chapter.
*/
fun findChapterDir(chapterName: String, chapterScanlator: String?, mangaTitle: String, source: Source): UniFile? {
fun findChapterDir(chapterName: String, chapterScanlator: String?, chapterUrl: String, mangaTitle: String, source: Source): UniFile? {
val mangaDir = findMangaDir(mangaTitle, source)
return getValidChapterDirNames(chapterName, chapterScanlator).asSequence()
return getValidChapterDirNames(chapterName, chapterScanlator, chapterUrl).asSequence()
.mapNotNull { mangaDir?.findFile(it) }
.firstOrNull()
}
Expand All @@ -113,7 +114,7 @@ class DownloadProvider(
fun findChapterDirs(chapters: List<Chapter>, manga: Manga, source: Source): Pair<UniFile?, List<UniFile>> {
val mangaDir = findMangaDir(manga.title, source) ?: return null to emptyList()
return mangaDir to chapters.mapNotNull { chapter ->
getValidChapterDirNames(chapter.name, chapter.scanlator).asSequence()
getValidChapterDirNames(chapter.name, chapter.scanlator, chapter.url).asSequence()
.mapNotNull { mangaDir.findFile(it) }
.firstOrNull()
}
Expand All @@ -140,19 +141,39 @@ class DownloadProvider(
/**
* Returns the chapter directory name for a chapter.
*
* @param chapterName the name of the chapter to query.
* @param chapterScanlator scanlator of the chapter to query
* @param chapter the chapter
*/
fun getChapterDirName(chapterName: String, chapterScanlator: String?): String {
val newChapterName = sanitizeChapterName(chapterName)
fun getChapterDirName(chapterName: String, chapterScanlator: String?, chapterUrl: String): String {
val newChapterName = sanitizeChapterName(chapterName) + "_" + md5(chapterUrl).takeLast(6)
return DiskUtil.buildValidFilename(
when {
!chapterScanlator.isNullOrBlank() -> "${chapterScanlator}_$newChapterName"
else -> newChapterName
!chapterScanlator.isNullOrBlank() -> "${chapterScanlator}_${newChapterName}"
else -> "${newChapterName}"
},
)
}

/**
* Returns the chapter directory name for a chapter.
* Add to this list if naming pattern ever changes.
*
* @param chapter the chapter
*/
private fun getLegacyChapterDirNames(chapterName: String, chapterScanlator: String?): List<String> {
val sanitizedChapterName = sanitizeChapterName(chapterName)
val chapterNameV1 = DiskUtil.buildValidFilename(
when {
!chapterScanlator.isNullOrBlank() -> "${chapterScanlator}_$sanitizedChapterName"
else -> sanitizedChapterName
})

return buildList(1) {
// Chapter name without hash (unable to handle duplicate
// chapter names)
add(chapterNameV1)
}
}

/**
* Return the new name for the chapter (in case it's empty or blank)
*
Expand All @@ -165,24 +186,29 @@ class DownloadProvider(
}

fun isChapterDirNameChanged(oldChapter: Chapter, newChapter: Chapter): Boolean {
return oldChapter.name != newChapter.name ||
oldChapter.scanlator?.takeIf { it.isNotBlank() } != newChapter.scanlator?.takeIf { it.isNotBlank() }
return getChapterDirName(oldChapter.name, oldChapter.scanlator, oldChapter.url) != getChapterDirName(newChapter.name, newChapter.scanlator, newChapter.url)
}

/**
* Returns valid downloaded chapter directory names.
*
* @param chapterName the name of the chapter to query.
* @param chapterScanlator scanlator of the chapter to query
* @param chapter the domain chapter object.
*/
fun getValidChapterDirNames(chapterName: String, chapterScanlator: String?): List<String> {
val chapterDirName = getChapterDirName(chapterName, chapterScanlator)
return buildList(2) {
fun getValidChapterDirNames(chapterName: String, chapterScanlator: String?, chapterUrl: String): List<String> {
val chapterDirName = getChapterDirName(chapterName, chapterScanlator, chapterUrl)
val legacyChapterDirNames = getLegacyChapterDirNames(chapterName, chapterScanlator)

return buildList {
// Folder of images
add(chapterDirName)

// Archived chapters
add("$chapterDirName.cbz")

// any legacy names
legacyChapterDirNames.forEach {
add(it)
add("${it}.cbz")
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ class Downloader(
val wasEmpty = queueState.value.isEmpty()
val chaptersToQueue = chapters.asSequence()
// Filter out those already downloaded.
.filter { provider.findChapterDir(it.name, it.scanlator, manga.title, source) == null }
.filter { provider.findChapterDir(it.name, it.scanlator, it.url, manga.title, source) == null }
// Add chapters to queue from the start.
.sortedByDescending { it.sourceOrder }
// Filter out those already enqueued.
Expand Down Expand Up @@ -333,7 +333,7 @@ class Downloader(
return
}

val chapterDirname = provider.getChapterDirName(download.chapter.name, download.chapter.scanlator)
val chapterDirname = provider.getChapterDirName(download.chapter.name, download.chapter.scanlator, download.chapter.url)
val tmpDir = mangaDir.createDirectory(chapterDirname + TMP_DIR_SUFFIX)!!

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ class LibraryScreenModel(
downloadManager.isChapterDownloaded(
chapter.name,
chapter.scanlator,
chapter.url,
manga.title,
manga.source,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ class MangaScreenModel(
val downloaded = if (isLocal) {
true
} else {
downloadManager.isChapterDownloaded(chapter.name, chapter.scanlator, manga.title, manga.source)
downloadManager.isChapterDownloaded(chapter.name, chapter.scanlator, chapter.url, manga.title, manga.source)
}
val downloadState = when {
activeDownload != null -> activeDownload.status
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class ReaderViewModel @JvmOverloads constructor(
!downloadManager.isChapterDownloaded(
it.name,
it.scanlator,
it.url,
manga.title,
manga.source,
)
Expand All @@ -184,6 +185,7 @@ class ReaderViewModel @JvmOverloads constructor(
downloadManager.isChapterDownloaded(
it.name,
it.scanlator,
it.url,
manga.title,
manga.source,
)
Expand Down Expand Up @@ -397,6 +399,7 @@ class ReaderViewModel @JvmOverloads constructor(
val isDownloaded = downloadManager.isChapterDownloaded(
dbChapter.name,
dbChapter.scanlator,
dbChapter.url,
manga.title,
manga.source,
skipCache = true,
Expand Down Expand Up @@ -473,6 +476,7 @@ class ReaderViewModel @JvmOverloads constructor(
val isNextChapterDownloaded = downloadManager.isChapterDownloaded(
nextChapter.name,
nextChapter.scanlator,
nextChapter.url,
manga.title,
manga.source,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class ChapterLoader(
val isDownloaded = downloadManager.isChapterDownloaded(
dbChapter.name,
dbChapter.scanlator,
dbChapter.url,
manga.title,
manga.source,
skipCache = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal class DownloadPageLoader(

override suspend fun getPages(): List<ReaderPage> {
val dbChapter = chapter.chapter
val chapterPath = downloadProvider.findChapterDir(dbChapter.name, dbChapter.scanlator, manga.title, source)
val chapterPath = downloadProvider.findChapterDir(dbChapter.name, dbChapter.scanlator, dbChapter.url, manga.title, source)
return if (chapterPath?.isFile == true) {
getPagesFromArchive(chapterPath)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At
downloadManager.isChapterDownloaded(
chapterName = goingToChapter.name,
chapterScanlator = goingToChapter.scanlator,
chapterUrl = goingToChapter.url,
mangaTitle = manga.title,
sourceId = manga.source,
skipCache = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class UpdatesScreenModel(
val downloaded = downloadManager.isChapterDownloaded(
update.chapterName,
update.scanlator,
update.chapterUrl,
update.mangaTitle,
update.sourceId,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ fun List<Chapter>.filterDownloaded(manga: Manga): List<Chapter> {

val downloadCache: DownloadCache = Injekt.get()

return filter { downloadCache.isChapterDownloaded(it.name, it.scanlator, manga.title, manga.source, false) }
return filter { downloadCache.isChapterDownloaded(it.name, it.scanlator, it.url, manga.title, manga.source, false) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class UpdatesRepositoryImpl(
chapterId: Long,
chapterName: String,
scanlator: String?,
chapterUrl: String,
read: Boolean,
bookmark: Boolean,
lastPageRead: Long,
Expand All @@ -67,6 +68,7 @@ class UpdatesRepositoryImpl(
chapterId = chapterId,
chapterName = chapterName,
scanlator = scanlator,
chapterUrl = chapterUrl,
read = read,
bookmark = bookmark,
lastPageRead = lastPageRead,
Expand Down
25 changes: 25 additions & 0 deletions data/src/main/sqldelight/tachiyomi/migrations/6.sqm
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- Add chapter urls to updates view
-- Can't update views, have to drop and re-create
DROP VIEW IF EXISTS updatesView;
CREATE VIEW updatesView AS
SELECT
mangas._id AS mangaId,
mangas.title AS mangaTitle,
chapters._id AS chapterId,
chapters.name AS chapterName,
chapters.scanlator,
chapters.url AS chapterUrl,
chapters.read,
chapters.bookmark,
chapters.last_page_read,
mangas.source,
mangas.favorite,
mangas.thumbnail_url AS thumbnailUrl,
mangas.cover_last_modified AS coverLastModified,
chapters.date_upload AS dateUpload,
chapters.date_fetch AS datefetch
FROM mangas JOIN chapters
ON mangas._id = chapters.manga_id
WHERE favorite = 1
AND date_fetch > date_added
ORDER BY date_fetch DESC;
3 changes: 2 additions & 1 deletion data/src/main/sqldelight/tachiyomi/view/updatesView.sq
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ SELECT
chapters._id AS chapterId,
chapters.name AS chapterName,
chapters.scanlator,
chapters.url AS chapterUrl,
chapters.read,
chapters.bookmark,
chapters.last_page_read,
Expand All @@ -31,4 +32,4 @@ SELECT *
FROM updatesView
WHERE read = :read
AND dateUpload > :after
LIMIT :limit;
LIMIT :limit;
Loading