Use typed DocumentFile predicates in SSD tree import
ober
b81528fd9772f737027c98a76974f89e156d29f1
--- a/templates/ssd-review.ss +++ b/templates/ssd-review.ss @@ -3894,7 +3894,8 @@ boxTypeFallbackName boxTypeLabelMatches defaultBoxTypeLabel isGenericGuessLabel isSsdPdfName shouldIncludeSsdPdfChoiceName shouldIncludeSsdPdfFile - shouldStopSsdPdfTreeScan ssdPdfDocumentIsDirectory + shouldStopSsdPdfTreeScan documentFileIsDirectory + documentFileIsRegular ssdPdfDocumentIsDirectory shouldIncludeSsdPdfDocument trimmedNonBlankLines trimmedNonBlankPathParts sourceBaseName canonicalSourceName isUsefulGuessLabel isErrorStatus @@ -4082,13 +4083,17 @@ (maxDepth : Int32)) : Bool (or (> depth maxDepth) (>= currentChoices limit))) - (def (ssdPdfDocumentIsDirectory (file : DocumentFile)) : Bool + (def (documentFileIsDirectory (file : DocumentFile)) : Bool (documentFileIsDirectoryRaw file)) + (def (documentFileIsRegular (file : DocumentFile)) : Bool + (documentFileIsFile file)) + (def (ssdPdfDocumentIsDirectory (file : DocumentFile)) : Bool + (documentFileIsDirectory file)) (def (shouldIncludeSsdPdfDocument (file : DocumentFile) (name : String) (currentChoices : Int32) (limit : Int32)) : Bool - (and (documentFileIsFile file) + (and (documentFileIsRegular file) (shouldIncludeSsdPdfChoiceName name currentChoices limit))) (def (trimmedNonBlankLines (text : String)) : (MutableList String) (let ((lines (stringLines text))) @@ -5307,7 +5312,8 @@ (export safePathComponent safeLeaf safeZipEntryName validSourceKey validatedSourceKey treeFileMime safeTreePathParts treePathLeaf treePathDirectoryParts - safeImportLeafEntryName zipEntryRootName zipEntryLeafName) + safeImportLeafEntryName zipEntryRootName zipEntryLeafName + jsonLinesFileName) (type Int32) (type Char) (extern (stringSplitChar (text : String) @@ -5323,6 +5329,8 @@ (and (safePathComponent name) (or (string-ends-with? name ".json") (string-ends-with? name ".jsonl")))) + (def (jsonLinesFileName (name : String)) : Bool + (string-ends-with? name ".jsonl")) (def (treeFileMime (name : String)) : String (if (string-ends-with? name ".json") "application/json" @@ -8495,7 +8503,7 @@ " listOf(\"ground_truth\", \"learned\", \"events\", \"reviews\").forEach { name ->" " val sourceDir = tree.findFile(name)" " val localDir = File(root, name)" - " if (sourceDir != null && sourceDir.isDirectory) {" + " if (sourceDir != null && documentFileIsDirectory(sourceDir)) {" " count += importTreeDir(sourceDir, localDir, 0, budget)" " }" " }" @@ -8514,11 +8522,11 @@ " sourceDir.listFiles().forEach { child ->" " budget.entries += 1" " if (budget.entries > MAX_ZIP_ENTRIES) throw IllegalStateException(\"Import tree exceeds entry limit\")" - " if (child.isDirectory) {" + " if (documentFileIsDirectory(child)) {" " val directoryName = child.name ?: return@forEach" " if (!safePathComponent(directoryName)) throw IllegalStateException(\"Unsafe import directory\")" " count += importTreeDir(child, File(localDir, directoryName), depth + 1, budget)" - " } else if (child.isFile) {" + " } else if (documentFileIsRegular(child)) {" " val name = child.name ?: return@forEach" " if (!safeLeaf(name)) return@forEach" " val remaining = MAX_ZIP_TOTAL_BYTES - budget.expandedBytes" @@ -8530,7 +8538,7 @@ " budget.expandedBytes += bytes.size.toLong()" " validateImportedText(name, bytes.decodeToString())" " val dest = containedImportPath(root.toPath().relativize(File(localDir, name).toPath()).toString())" - " if (name.endsWith(\".jsonl\")) {" + " if (jsonLinesFileName(name)) {" " mergeJsonLines(dest, bytes.decodeToString())" " count += 1" " } else if (shouldReplaceLocal(dest, bytes.decodeToString(), child.lastModified())) {" @@ -8544,7 +8552,7 @@ "" " private fun ensureTreeDir(parent: DocumentFile, name: String): DocumentFile =" " parent.findFile(name.takeIf { safePathComponent(it) }" - " ?: throw IllegalArgumentException(\"Unsafe tree directory\"))?.takeIf { it.isDirectory } ?: parent.createDirectory(name)" + " ?: throw IllegalArgumentException(\"Unsafe tree directory\"))?.takeIf { documentFileIsDirectory(it) } ?: parent.createDirectory(name)" " ?: throw IllegalStateException(unableToCreateSyncFolderMessage(name))" "" " private fun writeTreeFile(parent: DocumentFile, relativeName: String, source: File) {"