Importing: Import from zip in a background thread
Signed-off-by: Roopesh Chander <roop@roopc.net>
This commit is contained in:
parent
203d6b4596
commit
b1ae13652c
|
@ -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)
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue