Skip to content

Commit

Permalink
Use ditto to extract archives
Browse files Browse the repository at this point in the history
  • Loading branch information
tagavari committed Aug 13, 2022
1 parent f0e837f commit 9e8a3c9
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 74 deletions.
25 changes: 8 additions & 17 deletions AirMessage.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
ED28095725A20332009E7636 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED28095625A20332009E7636 /* OnboardingViewController.swift */; };
ED28095925A20333009E7636 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ED28095825A20333009E7636 /* Assets.xcassets */; };
ED28095C25A20333009E7636 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = ED28095A25A20333009E7636 /* Main.storyboard */; };
ED31446E28A7ECC4009FC28C /* ArchiveHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED31446D28A7ECC4009FC28C /* ArchiveHelper.swift */; };
ED31447028A7F284009FC28C /* ProcessHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED31446F28A7F284009FC28C /* ProcessHelper.swift */; };
ED440E0D269FAC6E00BFBEE5 /* ServerStateRecovery.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED440E0C269FAC6E00BFBEE5 /* ServerStateRecovery.swift */; };
ED440E0E269FB51F00BFBEE5 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = ED440E10269FB51F00BFBEE5 /* Localizable.stringsdict */; };
ED44738726A387DD006F5F0E /* KeychainManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED44738626A387DD006F5F0E /* KeychainManager.swift */; };
Expand All @@ -64,7 +66,6 @@
ED8F3A7E2749A3D50069F25D /* AppleScriptCodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED8F3A7D2749A3D50069F25D /* AppleScriptCodes.swift */; };
ED8F3A802749AC300069F25D /* FileDownloadRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED8F3A7F2749AC300069F25D /* FileDownloadRequest.swift */; };
ED98B3EF2711D8300029DD09 /* Ink in Frameworks */ = {isa = PBXBuildFile; productRef = ED98B3EE2711D8300029DD09 /* Ink */; };
ED98B3F22711D84E0029DD09 /* Zip in Frameworks */ = {isa = PBXBuildFile; productRef = ED98B3F12711D84E0029DD09 /* Zip */; };
ED9C293A2756684200EA07C8 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = ED9C29392756684200EA07C8 /* Sentry */; };
ED9FBBC627E13F430037DF16 /* Zlib in Frameworks */ = {isa = PBXBuildFile; productRef = ED9FBBC527E13F430037DF16 /* Zlib */; };
EDADEB1926A0E3D9001DA84A /* StorageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDADEB1826A0E3D9001DA84A /* StorageManager.swift */; };
Expand Down Expand Up @@ -304,6 +305,8 @@
ED28095B25A20333009E7636 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
ED28095D25A20333009E7636 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
ED28095E25A20333009E7636 /* AirMessage.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AirMessage.entitlements; sourceTree = "<group>"; };
ED31446D28A7ECC4009FC28C /* ArchiveHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArchiveHelper.swift; sourceTree = "<group>"; };
ED31446F28A7F284009FC28C /* ProcessHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProcessHelper.swift; sourceTree = "<group>"; };
ED440E0C269FAC6E00BFBEE5 /* ServerStateRecovery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerStateRecovery.swift; sourceTree = "<group>"; };
ED440E0F269FB51F00BFBEE5 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
ED44738626A387DD006F5F0E /* KeychainManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainManager.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -546,7 +549,6 @@
files = (
EDB04DBE273DDFDA00673AE4 /* SQLite in Frameworks */,
ED9C293A2756684200EA07C8 /* Sentry in Frameworks */,
ED98B3F22711D84E0029DD09 /* Zip in Frameworks */,
EDC898662752BF290081BDB7 /* OpenSSL.framework in Frameworks */,
ED456D99289EFE1E00729CF6 /* WebSocketKit in Frameworks */,
ED9FBBC627E13F430037DF16 /* Zlib in Frameworks */,
Expand Down Expand Up @@ -742,6 +744,7 @@
ED891A4625A30BAE002230EB /* Helper */ = {
isa = PBXGroup;
children = (
ED31446D28A7ECC4009FC28C /* ArchiveHelper.swift */,
ED8D56472846E00000B6DB6B /* AssertionHelper.swift */,
EDC1DAF7274DA24C00D32C6B /* AtomicValue.swift */,
2EAEE35ACA7C4D8977E66420 /* CompressionHelper.swift */,
Expand All @@ -755,6 +758,7 @@
ED15912226AC5484008F5304 /* LogManager.swift */,
ED891A4725A30BC6002230EB /* PasswordGrade.swift */,
2EAEEE327A491386A20EC729 /* PreferencesManager.swift */,
ED31446F28A7F284009FC28C /* ProcessHelper.swift */,
ED853E062744218900DCF446 /* ReadWriteLock.swift */,
EDD70D6B2699F56E00E8DC06 /* ServerLaunch.swift */,
EDADEB1826A0E3D9001DA84A /* StorageManager.swift */,
Expand Down Expand Up @@ -1199,7 +1203,6 @@
packageProductDependencies = (
EDDE47302688C2890029628B /* Swifter */,
ED98B3EE2711D8300029DD09 /* Ink */,
ED98B3F12711D84E0029DD09 /* Zip */,
EDB04DBD273DDFDA00673AE4 /* SQLite */,
ED9C29392756684200EA07C8 /* Sentry */,
ED9FBBC527E13F430037DF16 /* Zlib */,
Expand Down Expand Up @@ -1281,7 +1284,6 @@
packageReferences = (
EDDE472F2688C2890029628B /* XCRemoteSwiftPackageReference "swifter" */,
ED98B3ED2711D8300029DD09 /* XCRemoteSwiftPackageReference "ink" */,
ED98B3F02711D84E0029DD09 /* XCRemoteSwiftPackageReference "Zip" */,
EDB04DBC273DDFDA00673AE4 /* XCRemoteSwiftPackageReference "SQLite.swift" */,
ED9C29382756684200EA07C8 /* XCRemoteSwiftPackageReference "sentry-cocoa" */,
ED456D97289EFE1E00729CF6 /* XCRemoteSwiftPackageReference "websocket-kit-osx10" */,
Expand Down Expand Up @@ -1417,6 +1419,7 @@
2EAEE232C464EF7328584EA2 /* AccountType.swift in Sources */,
ED1E5684269A50360019CCD5 /* DraggableAppView.swift in Sources */,
ED8F3A792749A05D0069F25D /* MessageError.swift in Sources */,
ED31446E28A7ECC4009FC28C /* ArchiveHelper.swift in Sources */,
ED853E1027442BD900DCF446 /* FileHandleCompat.swift in Sources */,
ED15912326AC5484008F5304 /* LogManager.swift in Sources */,
2EAEE84D6A21D1570484C26A /* ServerState.swift in Sources */,
Expand Down Expand Up @@ -1452,6 +1455,7 @@
2EAEE263C6403206657014EB /* EncryptionManager.swift in Sources */,
EDDA7B87274333540027A82C /* FileNormalizationHelper.swift in Sources */,
ED8D56482846E00000B6DB6B /* AssertionHelper.swift in Sources */,
ED31447028A7F284009FC28C /* ProcessHelper.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -1869,14 +1873,6 @@
minimumVersion = 0.5.1;
};
};
ED98B3F02711D84E0029DD09 /* XCRemoteSwiftPackageReference "Zip" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/marmelroy/Zip.git";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 2.1.2;
};
};
ED9C29382756684200EA07C8 /* XCRemoteSwiftPackageReference "sentry-cocoa" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/getsentry/sentry-cocoa.git";
Expand Down Expand Up @@ -1914,11 +1910,6 @@
package = ED98B3ED2711D8300029DD09 /* XCRemoteSwiftPackageReference "ink" */;
productName = Ink;
};
ED98B3F12711D84E0029DD09 /* Zip */ = {
isa = XCSwiftPackageProductDependency;
package = ED98B3F02711D84E0029DD09 /* XCRemoteSwiftPackageReference "Zip" */;
productName = Zip;
};
ED9C29392756684200EA07C8 /* Sentry */ = {
isa = XCSwiftPackageProductDependency;
package = ED9C29382756684200EA07C8 /* XCRemoteSwiftPackageReference "sentry-cocoa" */;
Expand Down
1 change: 0 additions & 1 deletion AirMessage/Controllers/SoftwareUpdateViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Foundation
import AppKit
import WebKit
import Ink
import Zip

class SoftwareUpdateViewController: NSViewController {
//Outlets
Expand Down
20 changes: 20 additions & 0 deletions AirMessage/Helper/ArchiveHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// ArchiveHelper.swift
// AirMessage
//
// Created by Cole Feuer on 2022-08-13.
//

import Foundation

func decompressArchive(fromURL: URL, to toURL: URL) throws {
//Run ditto to extract the files
let process = Process()
if #available(macOS 10.13, *) {
process.executableURL = URL(fileURLWithPath: "/usr/bin/ditto")
} else {
process.launchPath = "/usr/bin/ditto"
}
process.arguments = ["-x", "-k", fromURL.path, toURL.path]
try runProcessCatchError(process)
}
62 changes: 8 additions & 54 deletions AirMessage/Helper/FileNormalizationHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@ func normalizeFile(url inputFile: URL, ext: String) -> NormalizedFile? {
let process = Process()
process.executableURL = URL(fileURLWithPath: "/usr/bin/sips")
process.arguments = ["--setProperty", "format", "jpeg", inputFile.path, "--out", tempFile.path]
let processResult = runProcessLogError(process)

//Check the process result
guard processResult else {
LogManager.log("Failed to convert file \(inputFile.path) from HEIC to JPEG", level: .info)
do {
try runProcessCatchError(process)
} catch {
LogManager.log("Failed to convert file \(inputFile.path) from HEIC to JPEG: \(error)", level: .info)
try? FileManager.default.removeItem(at: tempFile) //Clean up immediately
return nil
}
Expand All @@ -64,11 +63,10 @@ func normalizeFile(url inputFile: URL, ext: String) -> NormalizedFile? {
let process = Process()
process.executableURL = URL(fileURLWithPath: "/usr/bin/afconvert")
process.arguments = ["-f", "mp4f", "-d", "aac", inputFile.path, "-o", tempFile.path]
let processResult = runProcessLogError(process)

//Check the process result
guard processResult else {
LogManager.log("Failed to convert file \(inputFile.path) from CAF to MP4", level: .info)
do {
try runProcessCatchError(process)
} catch {
LogManager.log("Failed to convert file \(inputFile.path) from CAF to MP4: \(error)", level: .info)
try? FileManager.default.removeItem(at: tempFile) //Clean up immediately
return nil
}
Expand All @@ -81,47 +79,3 @@ func normalizeFile(url inputFile: URL, ext: String) -> NormalizedFile? {
return nil
}
}

/**
Starts a process, waits for it to finish, and logs any errors the process encountered while running
- Parameters:
- process: The process to start and monitor
- Returns: Whether the process ran successfully
*/
@available(macOS 10.13, *)
private func runProcessLogError(_ process: Process) -> Bool {
//Capture the process' error pipe
let errorPipe = Pipe()
process.standardOutput = nil
process.standardError = errorPipe

//Start the process
do {
try process.run()
} catch {
LogManager.log("An error occurred while running process: \(error)", level: .info)
SentrySDK.capture(error: error)
return false
}

//Wait for the process to exit
process.waitUntilExit()

//Check the output code
guard process.terminationStatus == 0 else {
let errorFileHandle = errorPipe.fileHandleForReading

let errorMessage: String?
if let data = try? errorFileHandle.readToEndCompat(), !data.isEmpty {
errorMessage = String(data: data, encoding: .utf8)
} else {
errorMessage = nil
}

LogManager.log("An error occurred while running process: \(errorMessage ?? "Unknown error")", level: .info)
SentrySDK.capture(message: "An error occurred while running process: \(errorMessage ?? "Unknown error")")
return false
}

return true
}
60 changes: 60 additions & 0 deletions AirMessage/Helper/ProcessHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//
// ProcessHelper.swift
// AirMessage
//
// Created by Cole Feuer on 2022-08-13.
//

import Foundation
import Sentry

///Starts a process, waits for it to finish, and logs any errors the process encountered while running
func runProcessCatchError(_ process: Process) throws {
//Capture the process' error pipe
let errorPipe = Pipe()
process.standardOutput = nil
process.standardError = errorPipe

//Start the process
if #available(macOS 10.13, *) {
try process.run()
} else {
process.launch()
}

//Wait for the process to exit
process.waitUntilExit()

//Check the output code
guard process.terminationStatus == 0 else {
let errorFileHandle = errorPipe.fileHandleForReading

let errorMessage: String?
if let data = try? errorFileHandle.readToEndCompat(), !data.isEmpty {
errorMessage = String(data: data, encoding: .utf8)
} else {
errorMessage = nil
}

//Throw a process error
throw ProcessError(exitCode: process.terminationStatus, message: errorMessage)
}
}

struct ProcessError: Error {
let exitCode: Int32
let message: String?

init(exitCode: Int32, message: String?) {
self.exitCode = exitCode
self.message = message
}

public var localizedDescription: String {
if let message = message {
return "Exit code \(exitCode): \(message)"
} else {
return "Exit code \(exitCode)"
}
}
}
3 changes: 1 addition & 2 deletions AirMessage/Helper/UpdateHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import Foundation
import AppKit
import Zip
import Sentry

class UpdateHelper {
Expand Down Expand Up @@ -423,7 +422,7 @@ private class UpdateDownloadURLDelegate: ForwardCompatURLSessionDelegate, URLSes
LogManager.log("Downloaded and moved update file to \(zippedFile.path)", level: .info)

//Unzip file
try Zip.unzipFile(zippedFile, destination: unzippedFolder, overwrite: true, password: nil)
try decompressArchive(fromURL: zippedFile, to: unzippedFolder)
LogManager.log("Decompressed update file to \(unzippedFolder.path)", level: .info)

//Find app file
Expand Down

0 comments on commit 9e8a3c9

Please sign in to comment.