Skip to content

Commit 9e2b98d

Browse files
committed
Remove GCD from script.
1 parent 9e041ab commit 9e2b98d

File tree

1 file changed

+84
-86
lines changed

1 file changed

+84
-86
lines changed

Scripts/DowloadPortalItemData.swift

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

129-
/// Downloads file from portal and write the file(s) to appropriate path(s).
129+
/// Downloads a file from a given portal and writes it to a given path.
130130
/// - Parameters:
131131
/// - sourceURL: The portal URL to the resource.
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))
132+
/// - downloadDirectory: The directory to store the downloaded data in.
133+
/// - Throws: Exceptions when downloading, naming, uncompressing, 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 (temporaryURL, response) = try await URLSession.shared.download(from: sourceURL)
137+
138+
guard let suggestedFilename = response.suggestedFilename else { return nil }
139+
let isArchive = NSString(string: suggestedFilename).pathExtension == "zip"
140+
141+
let downloadName: String = try {
142+
// If the downloaded file is an archive and contains
143+
// - 1 file, use the name of that file.
144+
// - multiple files, use the server suggested filename (*.zip).
145+
// If it is not an archive, use the server suggested filename.
146+
if isArchive,
147+
try count(ofFilesInArchiveAt: temporaryURL) == 1 {
148+
return try name(ofFileInArchiveAt: temporaryURL)
149+
} else {
150+
return suggestedFilename
180151
}
152+
}()
153+
let downloadURL = downloadDirectory.appendingPathComponent(downloadName, isDirectory: false)
154+
155+
try? FileManager.default.removeItem(at: downloadURL)
156+
157+
if isArchive {
158+
let extractURL = downloadURL.pathExtension == "zip"
159+
// Uncompresses to directory named after archive.
160+
? downloadURL.deletingPathExtension()
161+
// Uncompresses to appropriate subdirectory.
162+
: downloadURL.deletingLastPathComponent()
163+
164+
try uncompressArchive(at: temporaryURL, to: extractURL)
165+
} else {
166+
try FileManager.default.moveItem(at: temporaryURL, to: downloadURL)
181167
}
182-
let downloadTask = URLSession.shared.downloadTask(with: sourceURL, completionHandler: downloadTaskCompleted)
183-
downloadTask.resume()
168+
169+
return downloadName
184170
}
185171

186172
// MARK: Script Entry
@@ -242,45 +228,57 @@ let previousDownloadedItems: DownloadedItems = {
242228
}()
243229
var downloadedItems = previousDownloadedItems
244230

245-
// Asynchronously downloads portal items.
246-
let dispatchGroup = DispatchGroup()
247-
248-
for portalItem in portalItems {
249-
// Checks to see if an item is already downloaded.
250-
guard downloadedItems[portalItem.identifier] == nil else {
251-
print("note: Item already downloaded: \(portalItem.identifier)")
252-
continue
253-
}
254-
255-
let destinationURL = downloadDirectoryURL.appendingPathComponent(portalItem.identifier, isDirectory: true)
256-
257-
// Deletes the directory when the item is not in the plist.
258-
try? FileManager.default.removeItem(at: destinationURL)
259-
260-
do {
261-
// Creates an enclosing directory with portal item ID as its name.
262-
try FileManager.default.createDirectory(at: destinationURL, withIntermediateDirectories: false)
263-
} catch {
264-
print("error: Error creating download directory: \(error.localizedDescription)")
265-
exit(1)
266-
}
267-
268-
print("note: Downloading item \(portalItem.identifier)")
269-
fflush(stdout)
270-
dispatchGroup.enter()
271-
downloadFile(at: portalItem.dataURL, to: destinationURL) { result in
272-
switch result {
273-
case .success(let url):
274-
downloadedItems[portalItem.identifier] = url.lastPathComponent
275-
dispatchGroup.leave()
276-
case .failure(let error):
277-
print("error: Error downloading item \(portalItem.identifier): \(error.localizedDescription)")
278-
URLSession.shared.invalidateAndCancel()
231+
await withTaskGroup(of: (Identifier, Filename?).self) { group in
232+
for portalItem in portalItems {
233+
// Checks to see if an item is already downloaded.
234+
guard downloadedItems[portalItem.identifier] == nil else {
235+
print("note: Item already downloaded: \(portalItem.identifier)")
236+
continue
237+
}
238+
239+
let destinationURL = downloadDirectoryURL.appendingPathComponent(
240+
portalItem.identifier,
241+
isDirectory: true
242+
)
243+
244+
// Deletes the directory when the item is not in the plist.
245+
try? FileManager.default.removeItem(at: destinationURL)
246+
247+
do {
248+
// Creates an enclosing directory with the portal item ID as its name.
249+
try FileManager.default.createDirectory(
250+
at: destinationURL,
251+
withIntermediateDirectories: false
252+
)
253+
} catch {
254+
print("error: Error creating download directory: \(error.localizedDescription)")
279255
exit(1)
280256
}
257+
258+
print("note: Downloading item \(portalItem.identifier)")
259+
fflush(stdout)
260+
group.addTask {
261+
do {
262+
let downloadName = try await downloadFile(
263+
from: portalItem.dataURL,
264+
to: destinationURL
265+
)
266+
return (portalItem.identifier, downloadName)
267+
} catch {
268+
print("error: Error downloading item \(portalItem.identifier): \(error.localizedDescription)")
269+
URLSession.shared.invalidateAndCancel()
270+
exit(1)
271+
}
272+
}
273+
}
274+
275+
for await (identifier, filename) in group {
276+
downloadedItems[identifier] = filename
277+
278+
print("note: Downloaded item: \(identifier)")
279+
fflush(stdout)
281280
}
282281
}
283-
dispatchGroup.wait()
284282

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

0 commit comments

Comments
 (0)