aboutsummaryrefslogtreecommitdiff
path: root/Captura/Data
diff options
context:
space:
mode:
authorRuben Beltran del Rio <git@r.bdr.sh>2024-09-16 11:07:46 +0200
committerRuben Beltran del Rio <git@r.bdr.sh>2024-09-16 11:07:46 +0200
commit505c1e620497828ffb914e05dd76d9ab124f144a (patch)
tree0d93162c4228dbee9e29c35e9f97f58daa5e3eef /Captura/Data
parent5802c153cae64142d84e3cd5f762939501ee7e53 (diff)
Format the code
Diffstat (limited to 'Captura/Data')
-rw-r--r--Captura/Data/BackendResponse.swift3
-rw-r--r--Captura/Data/CapturaFile.swift22
-rw-r--r--Captura/Data/CapturaSettings.swift25
-rw-r--r--Captura/Data/CapturaURLDecoder.swift137
-rw-r--r--Captura/Data/GifRenderer.swift18
-rw-r--r--Captura/Data/OutputFormatSetting.swift12
-rw-r--r--Captura/Data/Persistence.swift52
7 files changed, 142 insertions, 127 deletions
diff --git a/Captura/Data/BackendResponse.swift b/Captura/Data/BackendResponse.swift
index f4316de..92636f0 100644
--- a/Captura/Data/BackendResponse.swift
+++ b/Captura/Data/BackendResponse.swift
@@ -15,6 +15,7 @@
along with this program. If not, see https://captura.tranquil.systems.
*/
import Foundation
+
struct BackendResponse: Decodable {
- let url: URL
+ let url: URL
}
diff --git a/Captura/Data/CapturaFile.swift b/Captura/Data/CapturaFile.swift
index 798c510..125e904 100644
--- a/Captura/Data/CapturaFile.swift
+++ b/Captura/Data/CapturaFile.swift
@@ -17,34 +17,36 @@
import Foundation
struct CapturaFile {
-
+
let name: String
let baseDirectory: URL
let appDirectory: String = "captura"
-
+
private var baseURL: URL {
baseDirectory.appendingPathComponent("\(appDirectory)/\(name)")
}
-
+
var mp4URL: URL {
return baseURL.appendingPathExtension("mp4")
}
-
+
var gifURL: URL {
return baseURL.appendingPathExtension("gif")
}
-
+
init() {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .medium
dateFormatter.locale = Locale.current
let dateString = dateFormatter.string(from: Date()).replacingOccurrences(of: ":", with: ".")
-
+
self.name = "Captura \(dateString)"
- self.baseDirectory = FileManager.default.urls(for: .picturesDirectory, in: .userDomainMask).first!
- try? FileManager.default.createDirectory(at: self.baseDirectory.appendingPathComponent(appDirectory),
- withIntermediateDirectories: true,
- attributes: nil)
+ self.baseDirectory = FileManager.default.urls(for: .picturesDirectory, in: .userDomainMask)
+ .first!
+ try? FileManager.default.createDirectory(
+ at: self.baseDirectory.appendingPathComponent(appDirectory),
+ withIntermediateDirectories: true,
+ attributes: nil)
}
}
diff --git a/Captura/Data/CapturaSettings.swift b/Captura/Data/CapturaSettings.swift
index c8af096..bfaa1ce 100644
--- a/Captura/Data/CapturaSettings.swift
+++ b/Captura/Data/CapturaSettings.swift
@@ -29,7 +29,7 @@ struct CapturaSettings {
UserDefaults.standard.setValue(newValue, forKey: "frameRate")
}
}
-
+
static var outputFormats: OutputFormatSetting {
get {
OutputFormatSetting(rawValue: UserDefaults.standard.integer(forKey: "outputFormats")) ?? .all
@@ -38,27 +38,27 @@ struct CapturaSettings {
UserDefaults.standard.setValue(newValue.rawValue, forKey: "outputFormats")
}
}
-
+
static var shouldSaveMp4: Bool {
outputFormats.shouldSaveMp4() || (shouldUseBackend && shouldUploadMp4)
}
-
+
static var shouldSaveGif: Bool {
outputFormats.shouldSaveGif() || (shouldUseBackend && shouldUploadGif)
}
-
+
static var shouldUploadGif: Bool {
backendFormat.shouldSaveGif()
}
-
+
static var shouldUploadMp4: Bool {
backendFormat.shouldSaveMp4()
}
-
+
static var shouldUseBackend: Bool {
backend != nil
}
-
+
static var backend: URL? {
get {
if let url = UserDefaults.standard.string(forKey: "backendUrl") {
@@ -70,16 +70,17 @@ struct CapturaSettings {
UserDefaults.standard.setValue(newValue?.absoluteString, forKey: "backendUrl")
}
}
-
+
static var backendFormat: OutputFormatSetting {
get {
- OutputFormatSetting(rawValue: UserDefaults.standard.integer(forKey: "backendFormat")) ?? .gifOnly
+ OutputFormatSetting(rawValue: UserDefaults.standard.integer(forKey: "backendFormat"))
+ ?? .gifOnly
}
set {
UserDefaults.standard.setValue(newValue.rawValue, forKey: "backendFormat")
}
}
-
+
static var shouldKeepLocalFiles: Bool {
get {
if UserDefaults.standard.object(forKey: "keepFiles") == nil {
@@ -92,7 +93,7 @@ struct CapturaSettings {
UserDefaults.standard.set(newValue, forKey: "keepFiles")
}
}
-
+
static var shouldAllowURLAutomation: Bool {
get {
UserDefaults.standard.bool(forKey: "allowURLAutomation")
@@ -101,7 +102,7 @@ struct CapturaSettings {
UserDefaults.standard.setValue(newValue, forKey: "allowURLAutomation")
}
}
-
+
static func apply(_ config: ConfigureAction) {
if let fps = config.fps {
frameRate = fps
diff --git a/Captura/Data/CapturaURLDecoder.swift b/Captura/Data/CapturaURLDecoder.swift
index cbb8a05..a325dbe 100644
--- a/Captura/Data/CapturaURLDecoder.swift
+++ b/Captura/Data/CapturaURLDecoder.swift
@@ -27,7 +27,7 @@ protocol ConfigureActionProtocol {
protocol RecordActionProtocol {
var action: String { get }
-
+
var x: Int? { get }
var y: Int? { get }
var width: Int? { get }
@@ -73,45 +73,47 @@ struct RecordAction: RecordActionProtocol {
}
enum CapturaAction {
- case record(RecordAction)
- case configure(ConfigureAction)
+ case record(RecordAction)
+ case configure(ConfigureAction)
}
struct CapturaURLDecoder {
-
+
static func decodeParams(url: URL) -> CapturaAction? {
- guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
- let params = components.queryItems else {
- return nil
- }
+ guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
+ let params = components.queryItems
+ else {
+ return nil
+ }
+
+ var paramsDict = [String: Any]()
+
+ params.forEach { item in
+ paramsDict[item.name] = item.value
+ }
+
+ guard let action = paramsDict["action"] as? String else {
+ return nil
+ }
- var paramsDict = [String: Any]()
+ switch action {
+ case "configure":
+ var fps = Int(paramsDict["fps"] as? String ?? "")
+ let backend = URL(string: paramsDict["backend"] as? String ?? "")
+ let keepLocalFiles = Bool(paramsDict["keep_local_files"] as? String ?? "")
+ let outputs = OutputFormatSetting(paramsDict["outputs"] as? String ?? "")
+ var backendOutput = OutputFormatSetting(paramsDict["backend_output"] as? String ?? "")
- params.forEach { item in
- paramsDict[item.name] = item.value
+ if fps != nil {
+ fps = min(10, max(4, fps!))
}
- guard let action = paramsDict["action"] as? String else {
- return nil
+ if backendOutput == .all {
+ backendOutput = .gifOnly
}
- switch action {
- case "configure":
- var fps = Int(paramsDict["fps"] as? String ?? "")
- let backend = URL(string: paramsDict["backend"] as? String ?? "")
- let keepLocalFiles = Bool(paramsDict["keep_local_files"] as? String ?? "")
- let outputs = OutputFormatSetting(paramsDict["outputs"] as? String ?? "")
- var backendOutput = OutputFormatSetting(paramsDict["backend_output"] as? String ?? "")
-
- if fps != nil {
- fps = min(10, max(4, fps!))
- }
-
- if backendOutput == .all {
- backendOutput = .gifOnly
- }
-
- return .configure(ConfigureAction(
+ return .configure(
+ ConfigureAction(
action: action,
fps: fps,
outputs: outputs,
@@ -120,41 +122,42 @@ struct CapturaURLDecoder {
keepLocalFiles: keepLocalFiles
))
- case "record":
- let x = Int(paramsDict["x"] as? String ?? "")
- let y = Int(paramsDict["y"] as? String ?? "")
- let width = Int(paramsDict["width"] as? String ?? "")
- let height = Int(paramsDict["height"] as? String ?? "")
- let preventResize = Bool(paramsDict["prevent_resize"] as? String ?? "")
- let preventMove = Bool(paramsDict["prevent_move"] as? String ?? "")
- var fps = Int(paramsDict["fps"] as? String ?? "")
- let backend = URL(string: paramsDict["backend"] as? String ?? "")
- let keepLocalFiles = Bool(paramsDict["keep_local_files"] as? String ?? "")
- let outputs = OutputFormatSetting(paramsDict["outputs"] as? String ?? "")
- var backendOutput = OutputFormatSetting(paramsDict["backend_output"] as? String ?? "")
- let autoStart = Bool(paramsDict["auto_start"] as? String ?? "")
- var maxLength = Int(paramsDict["max_length"] as? String ?? "")
-
- if fps != nil {
- fps = min(10, max(4, fps!))
- }
-
- if maxLength != nil {
- maxLength = min(300, max(1, fps!))
- }
-
- if backendOutput == .all {
- backendOutput = .gifOnly
- }
-
- var skipBackend = false
- if let backendString = paramsDict["backend"] as? String {
- if backendString == "" {
- skipBackend = true
- }
+ case "record":
+ let x = Int(paramsDict["x"] as? String ?? "")
+ let y = Int(paramsDict["y"] as? String ?? "")
+ let width = Int(paramsDict["width"] as? String ?? "")
+ let height = Int(paramsDict["height"] as? String ?? "")
+ let preventResize = Bool(paramsDict["prevent_resize"] as? String ?? "")
+ let preventMove = Bool(paramsDict["prevent_move"] as? String ?? "")
+ var fps = Int(paramsDict["fps"] as? String ?? "")
+ let backend = URL(string: paramsDict["backend"] as? String ?? "")
+ let keepLocalFiles = Bool(paramsDict["keep_local_files"] as? String ?? "")
+ let outputs = OutputFormatSetting(paramsDict["outputs"] as? String ?? "")
+ var backendOutput = OutputFormatSetting(paramsDict["backend_output"] as? String ?? "")
+ let autoStart = Bool(paramsDict["auto_start"] as? String ?? "")
+ var maxLength = Int(paramsDict["max_length"] as? String ?? "")
+
+ if fps != nil {
+ fps = min(10, max(4, fps!))
+ }
+
+ if maxLength != nil {
+ maxLength = min(300, max(1, fps!))
+ }
+
+ if backendOutput == .all {
+ backendOutput = .gifOnly
+ }
+
+ var skipBackend = false
+ if let backendString = paramsDict["backend"] as? String {
+ if backendString == "" {
+ skipBackend = true
}
-
- return .record(RecordAction(
+ }
+
+ return .record(
+ RecordAction(
action: action,
x: x,
y: y,
@@ -172,8 +175,8 @@ struct CapturaURLDecoder {
maxLength: maxLength
))
- default:
- return nil
- }
+ default:
+ return nil
+ }
}
}
diff --git a/Captura/Data/GifRenderer.swift b/Captura/Data/GifRenderer.swift
index bfbb289..2435cb4 100644
--- a/Captura/Data/GifRenderer.swift
+++ b/Captura/Data/GifRenderer.swift
@@ -1,3 +1,5 @@
+import CoreGraphics
+import SwiftUI
/*
Copyright (C) 2024 Rubén Beltrán del Río
@@ -15,16 +17,22 @@
along with this program. If not, see https://captura.tranquil.systems.
*/
import UniformTypeIdentifiers
-import SwiftUI
-import CoreGraphics
struct GifRenderer {
static func render(_ images: [CGImage], at fps: Int, to url: URL) async {
let framedelay = String(format: "%.3f", 1.0 / Double(fps))
- let fileProperties = [kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFLoopCount as String: 0]]
- let gifProperties = [kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFUnclampedDelayTime as String: framedelay]]
+ let fileProperties = [
+ kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFLoopCount as String: 0]
+ ]
+ let gifProperties = [
+ kCGImagePropertyGIFDictionary as String: [
+ kCGImagePropertyGIFUnclampedDelayTime as String: framedelay
+ ]
+ ]
let cfURL = url as CFURL
- if let destination = CGImageDestinationCreateWithURL(cfURL, UTType.gif.identifier as CFString, images.count, nil) {
+ if let destination = CGImageDestinationCreateWithURL(
+ cfURL, UTType.gif.identifier as CFString, images.count, nil)
+ {
CGImageDestinationSetProperties(destination, fileProperties as CFDictionary?)
for image in images {
CGImageDestinationAddImage(destination, image, gifProperties as CFDictionary?)
diff --git a/Captura/Data/OutputFormatSetting.swift b/Captura/Data/OutputFormatSetting.swift
index fd48f2f..2131caa 100644
--- a/Captura/Data/OutputFormatSetting.swift
+++ b/Captura/Data/OutputFormatSetting.swift
@@ -20,9 +20,9 @@ enum OutputFormatSetting: Int {
case gifOnly = 0
case mp4Only = 1
case all = 2
-
+
init?(_ string: String) {
- switch(string) {
+ switch string {
case "gif":
self = .gifOnly
case "mp4":
@@ -33,17 +33,17 @@ enum OutputFormatSetting: Int {
return nil
}
}
-
+
func shouldSaveGif() -> Bool {
return self == .gifOnly || self == .all
}
-
+
func shouldSaveMp4() -> Bool {
return self == .mp4Only || self == .all
}
-
+
func toString() -> String {
- switch(self) {
+ switch self {
case .gifOnly:
return "gif"
case .mp4Only:
diff --git a/Captura/Data/Persistence.swift b/Captura/Data/Persistence.swift
index 3ae66c3..55dee56 100644
--- a/Captura/Data/Persistence.swift
+++ b/Captura/Data/Persistence.swift
@@ -17,36 +17,36 @@
import CoreData
struct PersistenceController {
- static let shared = PersistenceController()
+ static let shared = PersistenceController()
- static var preview: PersistenceController = {
- let result = PersistenceController(inMemory: true)
- return result
- }()
+ static var preview: PersistenceController = {
+ let result = PersistenceController(inMemory: true)
+ return result
+ }()
- let container: NSPersistentCloudKitContainer
+ let container: NSPersistentCloudKitContainer
+
+ init(inMemory: Bool = false) {
+ container = NSPersistentCloudKitContainer(name: "Captura")
- init(inMemory: Bool = false) {
- container = NSPersistentCloudKitContainer(name: "Captura")
-
#if DEBUG
- do {
+ do {
// Use the container to initialize the development schema.
try container.initializeCloudKitSchema(options: [])
- } catch {
+ } catch {
// Handle any errors.
- }
+ }
#endif
-
- if inMemory {
- container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
- }
- container.loadPersistentStores(completionHandler: { (storeDescription, error) in
- if let error = error as NSError? {
- // Replace this implementation with code to handle the error appropriately.
- // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
- /*
+ if inMemory {
+ container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
+ }
+ container.loadPersistentStores(completionHandler: { (storeDescription, error) in
+ if let error = error as NSError? {
+ // Replace this implementation with code to handle the error appropriately.
+ // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
+
+ /*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
@@ -54,9 +54,9 @@ struct PersistenceController {
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
- fatalError("Unresolved error \(error), \(error.userInfo)")
- }
- })
- container.viewContext.automaticallyMergesChangesFromParent = true
- }
+ fatalError("Unresolved error \(error), \(error.userInfo)")
+ }
+ })
+ container.viewContext.automaticallyMergesChangesFromParent = true
+ }
}