Generate first feed pages, images
This commit is contained in:
44
CHDataManagement/Extensions/NSSize+Scaling.swift
Normal file
44
CHDataManagement/Extensions/NSSize+Scaling.swift
Normal file
@ -0,0 +1,44 @@
|
||||
import Foundation
|
||||
|
||||
extension NSSize {
|
||||
|
||||
/// Scales the current size to fit within the target size while maintaining the aspect ratio.
|
||||
/// - Parameter targetSize: The size to fit into.
|
||||
/// - Returns: A new `NSSize` that fits within the `targetSize`.
|
||||
func scaledToFit(in targetSize: NSSize) -> NSSize {
|
||||
guard self.width > 0 && self.height > 0 else {
|
||||
return .zero // Avoid division by zero if the size is invalid.
|
||||
}
|
||||
|
||||
let widthScale = targetSize.width / self.width
|
||||
let heightScale = targetSize.height / self.height
|
||||
|
||||
let scale = min(widthScale, heightScale)
|
||||
|
||||
return NSSize(width: self.width * scale, height: self.height * scale)
|
||||
}
|
||||
|
||||
func scaledDown(to desiredWidth: CGFloat) -> NSSize {
|
||||
if width == desiredWidth {
|
||||
return self
|
||||
}
|
||||
|
||||
if width < desiredWidth {
|
||||
// Don't scale larger
|
||||
return self
|
||||
}
|
||||
|
||||
let height = (height * desiredWidth / width).rounded(.down)
|
||||
return NSSize(width: desiredWidth, height: height)
|
||||
}
|
||||
}
|
||||
|
||||
extension NSSize {
|
||||
|
||||
var ratio: CGFloat {
|
||||
guard height != 0 else {
|
||||
return 0
|
||||
}
|
||||
return width / height
|
||||
}
|
||||
}
|
@ -13,3 +13,20 @@ extension String {
|
||||
isEmpty ? nil : self
|
||||
}
|
||||
}
|
||||
|
||||
extension String {
|
||||
|
||||
var fileExtension: String? {
|
||||
let parts = components(separatedBy: ".")
|
||||
guard parts.count > 1 else { return nil }
|
||||
return parts.last
|
||||
}
|
||||
|
||||
var fileNameAndExtension: (fileName: String, fileExtension: String?) {
|
||||
let parts = components(separatedBy: ".")
|
||||
guard parts.count > 1 else {
|
||||
return (self, nil)
|
||||
}
|
||||
return (fileName: parts.dropLast().joined(separator: "."), fileExtension: parts.last)
|
||||
}
|
||||
}
|
||||
|
72
CHDataManagement/Extensions/URL+Extensions.swift
Normal file
72
CHDataManagement/Extensions/URL+Extensions.swift
Normal file
@ -0,0 +1,72 @@
|
||||
import Foundation
|
||||
|
||||
extension URL {
|
||||
|
||||
func ensureParentFolderExistence() throws {
|
||||
try deletingLastPathComponent().ensureFolderExistence()
|
||||
}
|
||||
|
||||
func ensureFolderExistence() throws {
|
||||
guard !exists else {
|
||||
return
|
||||
}
|
||||
try FileManager.default.createDirectory(at: self, withIntermediateDirectories: true)
|
||||
}
|
||||
|
||||
var isDirectory: Bool {
|
||||
do {
|
||||
let resources = try resourceValues(forKeys: [.isDirectoryKey])
|
||||
guard let isDirectory = resources.isDirectory else {
|
||||
print("No isDirectory info for \(path)")
|
||||
return false
|
||||
}
|
||||
return isDirectory
|
||||
} catch {
|
||||
print("Failed to get directory information from \(path): \(error)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var exists: Bool {
|
||||
FileManager.default.fileExists(atPath: path)
|
||||
}
|
||||
|
||||
/**
|
||||
Delete the file at the url.
|
||||
*/
|
||||
func delete() throws {
|
||||
try FileManager.default.removeItem(at: self)
|
||||
}
|
||||
|
||||
func copy(to url: URL) throws {
|
||||
if url.exists {
|
||||
try url.delete()
|
||||
}
|
||||
try url.ensureParentFolderExistence()
|
||||
try FileManager.default.copyItem(at: self, to: url)
|
||||
}
|
||||
|
||||
var size: Int? {
|
||||
let attributes = try? FileManager.default.attributesOfItem(atPath: path)
|
||||
return (attributes?[.size] as? NSNumber)?.intValue
|
||||
}
|
||||
|
||||
func resolvingFolderTraversal() -> URL? {
|
||||
var components = [String]()
|
||||
absoluteString.components(separatedBy: "/").forEach { part in
|
||||
if part == ".." {
|
||||
if !components.isEmpty {
|
||||
_ = components.popLast()
|
||||
} else {
|
||||
components.append("..")
|
||||
}
|
||||
return
|
||||
}
|
||||
if part == "." {
|
||||
return
|
||||
}
|
||||
components.append(part)
|
||||
}
|
||||
return URL(string: components.joined(separator: "/"))
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user