Skip to content

Commit e982486

Browse files
committed
Revert async changes.
#361 (comment)
1 parent 72a599e commit e982486

File tree

1 file changed

+92
-83
lines changed

1 file changed

+92
-83
lines changed

Scripts/DowloadPortalItemData.swift

Lines changed: 92 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -126,50 +126,61 @@ func uncompressArchive(at sourceURL: URL, to destinationURL: URL) throws {
126126
process.waitUntilExit()
127127
}
128128

129-
/// Downloads a file from a given portal and writes it to a given path.
129+
/// Downloads file from portal and write the file(s) to appropriate path(s).
130130
/// - Parameters:
131131
/// - sourceURL: The portal URL to the resource.
132-
/// - downloadDirectory: The directory to store the downloaded data in.
133-
/// - Throws: Exceptions when downloading and moving the file.
134-
/// - Returns: The name of the downloaded file.
135-
func downloadFile(from sourceURL: URL, to downloadDirectory: URL) async throws -> String {
136-
let portalURLRequest = URLRequest(url: sourceURL)
137-
let (temporaryURL, response) = try await URLSession.shared.download(for: portalURLRequest)
138-
139-
guard let suggestedFilename = response.suggestedFilename else { return "" }
140-
let isArchive = NSString(string: suggestedFilename).pathExtension == "zip"
141-
142-
let downloadName: String = try {
143-
// If the downloaded file is an archive and contains
144-
// - 1 file, use the name of that file.
145-
// - multiple files, use the suggested filename (*.zip).
146-
// If it is not an archive, use the server suggested filename.
147-
if isArchive,
148-
try count(ofFilesInArchiveAt: temporaryURL) == 1 {
149-
return try name(ofFileInArchiveAt: temporaryURL)
150-
} else {
151-
return suggestedFilename
132+
/// - downloadDirectory: The directory that stores downloaded data.
133+
/// - completion: A closure to handle the results.
134+
func downloadFile(at sourceURL: URL, to downloadDirectory: URL, completion: @escaping (Result<URL, Error>) -> Void) {
135+
let downloadTaskCompleted = { (temporaryURL: URL?, response: URLResponse?, error: Error?) in
136+
if let temporaryURL = temporaryURL,
137+
let response = response,
138+
let suggestedFilename = response.suggestedFilename {
139+
do {
140+
let downloadName: String
141+
let isArchive = (suggestedFilename as NSString).pathExtension == "zip"
142+
// If the downloaded file is an archive and contains
143+
// - 1 file, use the name of that file.
144+
// - multiple files, use the suggested filename (*.zip).
145+
// If it is not an archive, use the server suggested filename.
146+
if isArchive {
147+
let count = try count(ofFilesInArchiveAt: temporaryURL)
148+
if count == 1 {
149+
downloadName = try name(ofFileInArchiveAt: temporaryURL)
150+
} else {
151+
downloadName = suggestedFilename
152+
}
153+
} else {
154+
downloadName = suggestedFilename
155+
}
156+
157+
let downloadURL = downloadDirectory.appendingPathComponent(downloadName, isDirectory: false)
158+
159+
if FileManager.default.fileExists(atPath: downloadURL.path) {
160+
try FileManager.default.removeItem(at: downloadURL)
161+
}
162+
163+
if isArchive {
164+
let extractURL = downloadURL.pathExtension == "zip"
165+
// Uncompresses to directory named after archive.
166+
? downloadURL.deletingPathExtension()
167+
// Uncompresses to appropriate subdirectory.
168+
: downloadURL.deletingLastPathComponent()
169+
try uncompressArchive(at: temporaryURL, to: extractURL)
170+
} else {
171+
try FileManager.default.moveItem(at: temporaryURL, to: downloadURL)
172+
}
173+
174+
completion(.success(downloadURL))
175+
} catch {
176+
completion(.failure(error))
177+
}
178+
} else if let error = error {
179+
completion(.failure(error))
152180
}
153-
}()
154-
let downloadURL = downloadDirectory.appendingPathComponent(downloadName, isDirectory: false)
155-
156-
if FileManager.default.fileExists(atPath: downloadURL.path) {
157-
try FileManager.default.removeItem(at: downloadURL)
158-
}
159-
160-
if isArchive {
161-
let extractURL = downloadURL.pathExtension == "zip"
162-
// Uncompresses to directory named after archive.
163-
? downloadURL.deletingPathExtension()
164-
// Uncompresses to appropriate subdirectory.
165-
: downloadURL.deletingLastPathComponent()
166-
167-
try uncompressArchive(at: temporaryURL, to: extractURL)
168-
} else {
169-
try FileManager.default.moveItem(at: temporaryURL, to: downloadURL)
170181
}
171-
172-
return downloadName
182+
let downloadTask = URLSession.shared.downloadTask(with: sourceURL, completionHandler: downloadTaskCompleted)
183+
downloadTask.resume()
173184
}
174185

175186
// MARK: Script Entry
@@ -231,56 +242,54 @@ let previousDownloadedItems: DownloadedItems = {
231242
}()
232243
var downloadedItems = previousDownloadedItems
233244

234-
await withTaskGroup(of: Void.self) { group in
235-
for portalItem in portalItems {
236-
// Checks to see if an item is already downloaded.
237-
guard !downloadedItems.keys.contains(portalItem.identifier) else {
238-
print("note: Item already downloaded: \(portalItem.identifier)")
239-
continue
240-
}
241-
242-
let destinationURL = downloadDirectoryURL.appendingPathComponent(portalItem.identifier, isDirectory: true)
243-
244-
// Deletes the directory if it already exists.
245-
// This happens when the item is not in the plist and needs to be redownloaded.
246-
if FileManager.default.fileExists(atPath: destinationURL.path) {
247-
do {
248-
print("note: Deleting directory: \(portalItem.identifier)")
249-
try FileManager.default.removeItem(at: destinationURL)
250-
} catch {
251-
print("error: Error deleting downloaded directory: \(error.localizedDescription)")
252-
exit(1)
253-
}
254-
}
255-
245+
// Asynchronously downloads portal items.
246+
let dispatchGroup = DispatchGroup()
247+
248+
portalItems.forEach { portalItem in
249+
// Checks to see if an item is already downloaded.
250+
guard !downloadedItems.keys.contains(portalItem.identifier) else {
251+
print("note: Item already downloaded: \(portalItem.identifier)")
252+
return
253+
}
254+
255+
let destinationURL = downloadDirectoryURL.appendingPathComponent(portalItem.identifier, isDirectory: true)
256+
257+
// Deletes the directory if it already exists.
258+
// This happens when the item is not in the plist and needs to be redownloaded.
259+
if FileManager.default.fileExists(atPath: destinationURL.path) {
256260
do {
257-
// Creates an enclosing directory with portal item ID as its name.
258-
try FileManager.default.createDirectory(at: destinationURL, withIntermediateDirectories: false)
261+
print("note: Deleting directory: \(portalItem.identifier)")
262+
try FileManager.default.removeItem(at: destinationURL)
259263
} catch {
260-
print("error: Error creating download directory: \(error.localizedDescription)")
264+
print("error: Error deleting downloaded directory: \(error.localizedDescription)")
261265
exit(1)
262266
}
263-
264-
print("note: Downloading item: \(portalItem.identifier)")
265-
fflush(stdout)
266-
267-
group.addTask {
268-
do {
269-
let downloadName = try await downloadFile(from: portalItem.dataURL, to: destinationURL)
270-
print("note: Downloaded item: \(portalItem.identifier)")
271-
fflush(stdout)
272-
273-
await MainActor.run {
274-
downloadedItems[portalItem.identifier] = downloadName
275-
}
276-
} catch {
277-
print("error: Error downloading item \(portalItem.identifier): \(error.localizedDescription)")
278-
URLSession.shared.invalidateAndCancel()
279-
exit(1)
280-
}
267+
}
268+
269+
do {
270+
// Creates an enclosing directory with portal item ID as its name.
271+
try FileManager.default.createDirectory(at: destinationURL, withIntermediateDirectories: false)
272+
} catch {
273+
print("error: Error creating download directory: \(error.localizedDescription)")
274+
exit(1)
275+
}
276+
277+
print("note: Downloading item \(portalItem.identifier)")
278+
fflush(stdout)
279+
dispatchGroup.enter()
280+
downloadFile(at: portalItem.dataURL, to: destinationURL) { result in
281+
switch result {
282+
case .success(let url):
283+
downloadedItems[portalItem.identifier] = url.lastPathComponent
284+
dispatchGroup.leave()
285+
case .failure(let error):
286+
print("error: Error downloading item \(portalItem.identifier): \(error.localizedDescription)")
287+
URLSession.shared.invalidateAndCancel()
288+
exit(1)
281289
}
282290
}
283291
}
292+
dispatchGroup.wait()
284293

285294
// Updates the downloaded items property list record if needed.
286295
if downloadedItems != previousDownloadedItems {

0 commit comments

Comments
 (0)