Skip to content

Instantly share code, notes, and snippets.

@jwmaher
Created November 7, 2018 06:04
Show Gist options
  • Save jwmaher/40c1b1907132bf971fc0eefce16589e4 to your computer and use it in GitHub Desktop.
Save jwmaher/40c1b1907132bf971fc0eefce16589e4 to your computer and use it in GitHub Desktop.
import Foundation
import RAPCore
struct Storage {
static let saveDir: URL = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent("jsondb")
static func verify() {
let audioFiles = try! FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: "/dir/to/cafs"), includingPropertiesForKeys: nil, options: FileManager.DirectoryEnumerationOptions.skipsHiddenFiles)
.filter { $0.pathExtension == "caf" }
write(audioFiles)
*> read().forEach { ds in
ds.forEach { d in
print(d.audio.lastPathComponent, d.validQuickCheck, d.validFull)
}
}
}
static func write(_ audioFiles: [URL]) -> Result<[()]> {
return traverse(audioFiles.map(audioData), writeToFile)
}
static func read() -> Result<[AudioData<BEAdultMetadata>]> {
return jsonContents()
>>| stringContents
|> AudioData.decode
}
}
// writing
extension Storage {
static func audioData(_ u: URL) -> AudioData<BEAdultMetadata> {
let m = BEAdultMetadata(age: "7", gender: "M")
let hash = u.sha256()?.hexRepresentation
let size = u.fileSize
let modificationDate = u.modificationDate
return AudioData(metadata: m, hash: hash!, fileSize: size, modificationDate: modificationDate!, audio: u)
}
static func fileModificationDate(url: URL) -> Date? {
do {
let attr = try FileManager.default.attributesOfItem(atPath: url.path)
return attr[FileAttributeKey.modificationDate] as? Date
} catch {
return nil
}
}
static func writeToFile(_ storage: AudioData<BEAdultMetadata>) -> Result<()> {
let location = saveDir.appendingPathComponent("\(storage.audio.lastPathComponent).json")
return .wrap {
try storage.encoded.write(to: location, atomically: true, encoding: .utf8)
}
}
}
// reading
extension Storage {
static func jsonContents() -> Result<[URL]> {
return .wrap {
try FileManager.default.contentsOfDirectory(at: saveDir, includingPropertiesForKeys: nil, options: FileManager.DirectoryEnumerationOptions.skipsHiddenFiles)
}
}
static func stringContents(_ u: URL) -> Result<String> {
return .wrap {
return try String(contentsOf: u, encoding: .utf8)
}
}
}
struct AudioData<T: Codable>: Codable {
let metadata: T
let hash: String
let fileSize: UInt64
let modificationDate: Date
let audio: URL
var validQuickCheck: Bool {
return fileSize == audio.fileSize && modificationDate == audio.modificationDate
}
var validFull: Bool {
return hash == audio.sha256()?.hexRepresentation
}
var encoded: String {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(self)
return String(data: data, encoding: .utf8)!
}
static func decode(_ json: String) -> AudioData<T> {
let jsonData = json.data(using: .utf8)!
let decoder = JSONDecoder()
return try! decoder.decode(AudioData<T>.self, from: jsonData)
}
}
struct BEAdultMetadata: Codable {
let age: String
let gender: String
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment