Fix concurrent creation of the same directory
This commit is contained in:
1 parent
ae3a66903a
commit
7bfa5be53c
4 files changed
+32
-33
No files matched your search
@@ -7,9 +7,9 @@ import com.hippo.ehviewer.EhApplication.Companion.imageCache
|
||||
import com.hippo.ehviewer.download.downloadLocation
|
||||
import com.hippo.ehviewer.spider.DownloadInfoMagics.decodeMagicRequestOrUrl
|
||||
import com.hippo.ehviewer.util.sendTo
|
||||
import com.hippo.files.isDirectory
|
||||
import com.hippo.files.isFile
|
||||
import com.hippo.files.toUri
|
||||
import eu.kanade.tachiyomi.util.lang.withIOContext
|
||||
|
||||
object DownloadThumbInterceptor : Interceptor {
|
||||
private const val THUMB_FILE = "thumb.jpg"
|
||||
@@ -18,22 +18,20 @@ object DownloadThumbInterceptor : Interceptor {
|
||||
if (magicOrUrl != null) {
|
||||
val (url, location) = decodeMagicRequestOrUrl(magicOrUrl)
|
||||
if (location != null) {
|
||||
val thumb = withIOContext { downloadLocation / location / THUMB_FILE }
|
||||
if (withIOContext { thumb.isFile }) {
|
||||
val thumb = downloadLocation / location / THUMB_FILE
|
||||
if (thumb.isFile) {
|
||||
val new = chain.request.newBuilder().data(thumb.toUri()).build()
|
||||
val result = chain.withRequest(new).proceed()
|
||||
if (result is SuccessResult) return result
|
||||
}
|
||||
val new = chain.request.newBuilder().data(url).build()
|
||||
val result = chain.withRequest(new).proceed()
|
||||
if (result is SuccessResult) {
|
||||
withIOContext {
|
||||
// Accessing the recreated file immediately after deleting it throws
|
||||
// FileNotFoundException, so we just overwrite the existing file.
|
||||
val key = requireNotNull(chain.request.memoryCacheKey)
|
||||
imageCache.read(key) {
|
||||
data sendTo thumb
|
||||
}
|
||||
if (result is SuccessResult && thumb.parent?.isDirectory == true) {
|
||||
// Accessing the recreated file immediately after deleting it throws
|
||||
// FileNotFoundException, so we just overwrite the existing file.
|
||||
val key = requireNotNull(chain.request.memoryCacheKey)
|
||||
imageCache.read(key) {
|
||||
data sendTo thumb
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
||||
@@ -46,6 +46,7 @@ import com.hippo.files.exists
|
||||
import com.hippo.files.find
|
||||
import com.hippo.files.isDirectory
|
||||
import com.hippo.files.list
|
||||
import com.hippo.files.mkdirs
|
||||
import com.hippo.files.moveTo
|
||||
import com.hippo.files.openFileDescriptor
|
||||
import com.hippo.files.openOutputStream
|
||||
@@ -91,10 +92,10 @@ class SpiderDen(val info: GalleryInfo) {
|
||||
mode = value
|
||||
if (mode == SpiderQueen.MODE_DOWNLOAD) {
|
||||
if (downloadDir == null) {
|
||||
downloadDir = getGalleryDownloadDir(info)
|
||||
downloadDir = getGalleryDownloadDir(info).apply { mkdirs() }
|
||||
}
|
||||
if (saveAsCbz && tempDownloadDir == null) {
|
||||
tempDownloadDir = info.tempDownloadDir!!
|
||||
tempDownloadDir = info.tempDownloadDir!!.apply { mkdirs() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -342,7 +343,7 @@ class SpiderDen(val info: GalleryInfo) {
|
||||
}
|
||||
|
||||
suspend fun initDownloadDir() {
|
||||
downloadDir = getGalleryDownloadDir(info)
|
||||
downloadDir = getGalleryDownloadDir(info).apply { mkdirs() }
|
||||
}
|
||||
|
||||
suspend fun writeComicInfo(fetchMetadata: Boolean = true) {
|
||||
|
||||
@@ -30,8 +30,9 @@ class AndroidFileSystem(context: Context) : FileSystem() {
|
||||
return physicalFileSystem.atomicMove(source, target)
|
||||
}
|
||||
|
||||
DocumentsContract.renameDocument(contentResolver, source.toUri(), target.name)
|
||||
?: throw IOException("Failed to move $source to $target")
|
||||
source.runCatching {
|
||||
DocumentsContract.renameDocument(contentResolver, toUri(), target.name)
|
||||
}.getOrNull() ?: throw IOException("Failed to move $source to $target")
|
||||
}
|
||||
|
||||
override fun canonicalize(path: Path): Path {
|
||||
@@ -52,9 +53,9 @@ class AndroidFileSystem(context: Context) : FileSystem() {
|
||||
}
|
||||
}
|
||||
|
||||
dir.parent?.let {
|
||||
DocumentsContract.createDocument(contentResolver, it.toUri(), Document.MIME_TYPE_DIR, dir.name)
|
||||
} ?: throw IOException("Failed to create directory: $dir")
|
||||
dir.parent?.runCatching {
|
||||
DocumentsContract.createDocument(contentResolver, toUri(), Document.MIME_TYPE_DIR, dir.name)
|
||||
}?.getOrNull() ?: throw IOException("Failed to create directory: $dir")
|
||||
}
|
||||
|
||||
override fun createSymlink(source: Path, target: Path) {
|
||||
@@ -74,7 +75,9 @@ class AndroidFileSystem(context: Context) : FileSystem() {
|
||||
uri = DocumentsContract.buildDocumentUriUsingTree(uri, DocumentsContract.getDocumentId(uri) + '/')
|
||||
}
|
||||
|
||||
val deleted = DocumentsContract.deleteDocument(contentResolver, uri)
|
||||
val deleted = runCatching {
|
||||
DocumentsContract.deleteDocument(contentResolver, uri)
|
||||
}.getOrDefault(false)
|
||||
if (!deleted) {
|
||||
throw IOException("Failed to delete $path")
|
||||
}
|
||||
@@ -173,25 +176,20 @@ class AndroidFileSystem(context: Context) : FileSystem() {
|
||||
}
|
||||
|
||||
fun openFileDescriptor(path: Path, mode: String): ParcelFileDescriptor {
|
||||
if (path.isPhysicalFile()) {
|
||||
return ParcelFileDescriptor.open(path.toFile(), ParcelFileDescriptor.parseMode(mode))
|
||||
}
|
||||
|
||||
if ('w' in mode && !exists(path)) {
|
||||
val parent = path.parent ?: throw IOException("Failed to open file: $path")
|
||||
createDirectories(parent)
|
||||
if (path.isPhysicalFile()) {
|
||||
physicalFileSystem.openReadWrite(path).close()
|
||||
} else {
|
||||
path.parent?.runCatching {
|
||||
val displayName = path.name
|
||||
val extension = displayName.substringAfterLast('.', "").ifEmpty { null }?.lowercase()
|
||||
val mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) ?: "application/octet-stream"
|
||||
DocumentsContract.createDocument(contentResolver, parent.toUri(), mimeType, displayName)
|
||||
?: throw IOException("Failed to open file: $path")
|
||||
}
|
||||
DocumentsContract.createDocument(contentResolver, toUri(), mimeType, displayName)
|
||||
}?.getOrNull() ?: throw IOException("Failed to open file: $path")
|
||||
}
|
||||
|
||||
return if (path.isPhysicalFile()) {
|
||||
ParcelFileDescriptor.open(path.toFile(), ParcelFileDescriptor.parseMode(mode))
|
||||
} else {
|
||||
contentResolver.openFileDescriptor(path.toUri(), mode)
|
||||
} ?: throw IOException("Failed to open file: $path")
|
||||
return contentResolver.openFileDescriptor(path.toUri(), mode) ?: throw IOException("Failed to open file: $path")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ fun Path.delete() = SystemFileSystem.deleteRecursively(this)
|
||||
|
||||
fun Path.list() = SystemFileSystem.listOrNull(this).orEmpty()
|
||||
|
||||
fun Path.mkdirs() = SystemFileSystem.createDirectories(this)
|
||||
|
||||
fun Path.moveTo(target: Path) = SystemFileSystem.atomicMove(this, target)
|
||||
|
||||
fun Path.openFileDescriptor(mode: String) = SystemFileSystem.openFileDescriptor(this, mode)
|
||||
|
||||
Reference in new issue
Block a user