iOS thumbnails: progress logging + newest-first loading order
Sort photos by dateTaken descending before pre-fetching so most recent photos get thumbnails first — the ones most likely to import. Log progress after each batch: 'iOS thumbnails: 30/600 loaded (batch 1/20)'. Log skip count for already-cached photos on subsequent launches.
This commit is contained in:
@@ -183,20 +183,28 @@ class AppState(private val configStore: ConfigStore) {
|
||||
val tmpDir = java.nio.file.Paths.get(System.getProperty("java.io.tmpdir"), "photophetch-thumbs")
|
||||
if (!tmpDir.toFile().exists()) tmpDir.toFile().mkdirs()
|
||||
|
||||
// Only fetch photos not already cached
|
||||
val needed = photos.filter { photo ->
|
||||
val ext = photo.filename.substringAfterLast(".", "").lowercase()
|
||||
if (ext in setOf("mp4", "mov", "3gp", "avi", "mkv", "m4v", "webm")) return@filter false
|
||||
val hash = (cacheKey + photo.devicePath).hashCode().toString(16)
|
||||
val cachePath = cacheDir.resolve("$hash.jpg")
|
||||
!cachePath.toFile().exists() || cachePath.toFile().length() == 0L
|
||||
}
|
||||
// Only fetch photos not already cached, sorted newest first
|
||||
val needed = photos
|
||||
.sortedByDescending { it.dateTaken }
|
||||
.filter { photo ->
|
||||
val ext = photo.filename.substringAfterLast(".", "").lowercase()
|
||||
if (ext in setOf("mp4", "mov", "3gp", "avi", "mkv", "m4v", "webm")) return@filter false
|
||||
val hash = (cacheKey + photo.devicePath).hashCode().toString(16)
|
||||
val cachePath = cacheDir.resolve("$hash.jpg")
|
||||
!cachePath.toFile().exists() || cachePath.toFile().length() == 0L
|
||||
}
|
||||
|
||||
if (needed.isEmpty()) return
|
||||
log.info("Pre-fetching ${needed.size} iOS thumbnails...")
|
||||
if (needed.isEmpty()) {
|
||||
log.info("iOS thumbnails: all ${photos.size} already cached")
|
||||
return
|
||||
}
|
||||
log.info("iOS thumbnails: pre-fetching ${needed.size} / ${photos.size} (${photos.size - needed.size} already cached)")
|
||||
|
||||
var loaded = 0
|
||||
val batchSize = 30
|
||||
|
||||
// Build pairs JSON and run batch-thumbs command
|
||||
needed.chunked(30).forEach { batch ->
|
||||
needed.chunked(batchSize).forEachIndexed { batchIdx, batch ->
|
||||
val pairs = batch.joinToString(",") { photo ->
|
||||
val ext = photo.filename.substringAfterLast(".", "").lowercase()
|
||||
val hash = (cacheKey + photo.devicePath).hashCode().toString(16)
|
||||
@@ -210,11 +218,12 @@ class AppState(private val configStore: ConfigStore) {
|
||||
try {
|
||||
val process = ProcessBuilder(connector.pythonBin, connector.helperScript, "batch-thumbs", pairsJson)
|
||||
.redirectErrorStream(false).start()
|
||||
process.inputStream.readBytes() // stdout
|
||||
process.errorStream.readBytes() // stderr
|
||||
process.inputStream.readBytes()
|
||||
process.errorStream.readBytes()
|
||||
process.waitFor()
|
||||
|
||||
// Run sips on each successfully pulled file
|
||||
var batchLoaded = 0
|
||||
batch.forEach { photo ->
|
||||
val ext = photo.filename.substringAfterLast(".", "").lowercase()
|
||||
val hash = (cacheKey + photo.devicePath).hashCode().toString(16)
|
||||
@@ -227,13 +236,16 @@ class AppState(private val configStore: ConfigStore) {
|
||||
sips.inputStream.readBytes()
|
||||
sips.waitFor()
|
||||
tmpFile.toFile().delete()
|
||||
if (cachePath.toFile().exists()) batchLoaded++
|
||||
}
|
||||
}
|
||||
loaded += batchLoaded
|
||||
log.info("iOS thumbnails: $loaded / ${needed.size} loaded (batch ${batchIdx + 1}/${(needed.size + batchSize - 1) / batchSize})")
|
||||
} catch (e: Exception) {
|
||||
log.warn("iOS thumbnail batch failed: ${e.message}")
|
||||
log.warn("iOS thumbnail batch ${batchIdx + 1} failed: ${e.message}")
|
||||
}
|
||||
}
|
||||
log.info("iOS thumbnail pre-fetch complete")
|
||||
log.info("iOS thumbnails: done — $loaded / ${needed.size} loaded successfully")
|
||||
}
|
||||
|
||||
fun selectFolder(folderName: String?) {
|
||||
|
||||
Reference in New Issue
Block a user