Importing: Import from zip in a background thread

Signed-off-by: Roopesh Chander <roop@roopc.net>
This commit is contained in:
Roopesh Chander 2018-11-14 19:03:33 +05:30
parent 203d6b4596
commit b1ae13652c
2 changed files with 45 additions and 44 deletions

View File

@ -160,20 +160,18 @@ class TunnelsListTableViewController: UIViewController {
func importFromFile(url: URL) { func importFromFile(url: URL) {
guard let tunnelsManager = tunnelsManager else { return } guard let tunnelsManager = tunnelsManager else { return }
if (url.pathExtension == "zip") { if (url.pathExtension == "zip") {
let zipImporter = ZipImporter(url: url) ZipImporter.importConfigFiles(from: url) { (configs, error) in
let configs: [TunnelConfiguration?] if let error = error {
do { ErrorPresenter.showErrorAlert(error: error, from: self)
configs = try zipImporter.importConfigFiles()
} catch (let error) {
ErrorPresenter.showErrorAlert(error: error, from: self)
return
}
tunnelsManager.addMultiple(tunnelConfigurations: configs.compactMap { $0 }) { [weak self] (numberSuccessful) in
if numberSuccessful == configs.count {
return return
} }
self?.showErrorAlert(title: "Created \(numberSuccessful) tunnels", tunnelsManager.addMultiple(tunnelConfigurations: configs.compactMap { $0 }) { [weak self] (numberSuccessful) in
message: "Created \(numberSuccessful) of \(configs.count) tunnels from zip archive") if numberSuccessful == configs.count {
return
}
self?.showErrorAlert(title: "Created \(numberSuccessful) tunnels",
message: "Created \(numberSuccessful) of \(configs.count) tunnels from zip archive")
}
} }
} else /* if (url.pathExtension == "conf") -- we assume everything else is a conf */ { } else /* if (url.pathExtension == "conf") -- we assume everything else is a conf */ {
let fileBaseName = url.deletingPathExtension().lastPathComponent.trimmingCharacters(in: .whitespacesAndNewlines) let fileBaseName = url.deletingPathExtension().lastPathComponent.trimmingCharacters(in: .whitespacesAndNewlines)

View File

@ -8,41 +8,44 @@ enum ZipImporterError: Error {
} }
class ZipImporter { class ZipImporter {
let url: URL static func importConfigFiles(from url: URL, completion: @escaping ([TunnelConfiguration?], Error?) -> Void) {
init(url: URL) { DispatchQueue.global(qos: .userInitiated).async {
self.url = url var unarchivedFiles: [(fileName: String, contents: Data)]
} do {
unarchivedFiles = try ZipArchive.unarchive(url: url, requiredFileExtensions: ["conf"])
func importConfigFiles() throws -> [TunnelConfiguration?] { for (i, unarchivedFile) in unarchivedFiles.enumerated().reversed() {
var unarchivedFiles: [(fileName: String, contents: Data)] = try ZipArchive.unarchive(url: url, requiredFileExtensions: ["conf"]) let fileBaseName = URL(string: unarchivedFile.fileName)?.deletingPathExtension().lastPathComponent
if let trimmedName = fileBaseName?.trimmingCharacters(in: .whitespacesAndNewlines), !trimmedName.isEmpty {
unarchivedFiles[i].fileName = trimmedName
} else {
unarchivedFiles.remove(at: i)
}
}
for (i, unarchivedFile) in unarchivedFiles.enumerated().reversed() { if (unarchivedFiles.isEmpty) {
let fileBaseName = URL(string: unarchivedFile.fileName)?.deletingPathExtension().lastPathComponent throw ZipImporterError.noTunnelsInZipArchive
if let trimmedName = fileBaseName?.trimmingCharacters(in: .whitespacesAndNewlines), !trimmedName.isEmpty { }
unarchivedFiles[i].fileName = trimmedName } catch (let error) {
} else { DispatchQueue.main.async { completion([], error) }
unarchivedFiles.remove(at: i) return
} }
unarchivedFiles.sort { $0.fileName < $1.fileName }
var configs = Array<TunnelConfiguration?>(repeating: nil, count: unarchivedFiles.count)
for (i, file) in unarchivedFiles.enumerated() {
if (i > 0 && file == unarchivedFiles[i - 1]) {
continue
}
guard let fileContents = String(data: file.contents, encoding: .utf8) else {
continue
}
guard let tunnelConfig = try? WgQuickConfigFileParser.parse(fileContents, name: file.fileName) else {
continue
}
configs[i] = tunnelConfig
}
DispatchQueue.main.async { completion(configs, nil) }
} }
if (unarchivedFiles.isEmpty) {
throw ZipImporterError.noTunnelsInZipArchive
}
unarchivedFiles.sort { $0.fileName < $1.fileName }
var configs = Array<TunnelConfiguration?>(repeating: nil, count: unarchivedFiles.count)
for (i, file) in unarchivedFiles.enumerated() {
if (i > 0 && file == unarchivedFiles[i - 1]) {
continue
}
guard let fileContents = String(data: file.contents, encoding: .utf8) else {
continue
}
guard let tunnelConfig = try? WgQuickConfigFileParser.parse(fileContents, name: file.fileName) else {
continue
}
configs[i] = tunnelConfig
}
return configs
} }
} }