diff --git a/Sources/App/CapServer.swift b/Sources/App/CapServer.swift index 9952e04..6c18a83 100644 --- a/Sources/App/CapServer.swift +++ b/Sources/App/CapServer.swift @@ -18,12 +18,17 @@ final class CapServer: ServerOwner { private let classifierFile: URL + private let changedImagesFile: URL + private let fm = FileManager.default // MARK: Caps private var writers: Set + /// The changed images not yet written to disk + private var unwrittenImageChanges: [(cap: Int, image: Int)] = [] + var classifierVersion: Int = 0 { didSet { writeClassifierVersion() @@ -70,6 +75,7 @@ final class CapServer: ServerOwner { self.htmlFile = folder.appendingPathComponent("count.html") self.classifierVersionFile = folder.appendingPathComponent("classifier.version") self.classifierFile = folder.appendingPathComponent("classifier.mlmodel") + self.changedImagesFile = folder.appendingPathComponent("changes.txt") self.writers = Set(writers) } @@ -243,9 +249,54 @@ final class CapServer: ServerOwner { } try data.write(to: f) caps[cap]!.count = try count(of: cap) + addChangedImageToLog(cap: cap, image: id) log("Added image \(id) for cap \(cap)") } + private func writeChangedImagesToDisk() throws { + guard !unwrittenImageChanges.isEmpty else { + return + } + if !fm.fileExists(atPath: changedImagesFile.path) { + try Data().write(to: changedImagesFile) + } + + let handle = try FileHandle(forWritingTo: changedImagesFile) + try handle.seekToEnd() + var entries = unwrittenImageChanges + defer { + unwrittenImageChanges = entries + try? handle.close() + } + let df = DateFormatter() + df.dateFormat = "yy-MM-dd-HH-mm-ss" + let dateString = df.string(from: Date()) + while let entry = entries.popLast() { + let content = "\(dateString):\(entry.cap):\(entry.image)".data(using: .utf8)! + try handle.write(contentsOf: content) + } + } + + private func addChangedImageToLog(cap: Int, image: Int) { + unwrittenImageChanges.append((cap, image)) + do { + try writeChangedImagesToDisk() + } catch { + log("Failed to save changed image list: \(error)") + } + } + + func deleteChangedImageListFile() { + guard fm.fileExists(atPath: changedImagesFile.path) else { + return + } + do { + try fm.removeItem(at: changedImagesFile) + } catch { + log("Failed to delete changed images file: \(error)") + } + } + func switchMainImage(to version: Int, for cap: Int) throws { let file2 = file(of: cap, version: version) guard fm.fileExists(atPath: file2.path) else { diff --git a/Sources/App/routes.swift b/Sources/App/routes.swift index 2d46b9d..5103ce5 100755 --- a/Sources/App/routes.swift +++ b/Sources/App/routes.swift @@ -78,4 +78,10 @@ func routes(_ app: Application) { } server.updateTrainedClasses(content: content) } + + // Reset the changed images list + app.postCatching("changes") { request in + try authorize(request) + server.deleteChangedImageListFile() + } }