66 lines
2.2 KiB
Swift
66 lines
2.2 KiB
Swift
|
|
import Foundation
|
|
import PlaygroundSupport
|
|
import System
|
|
|
|
public enum SurveyLoader {
|
|
|
|
enum Failure {
|
|
case unableToDownloadSurveyContent
|
|
}
|
|
|
|
private static let localDataURL = playgroundSharedDataDirectory
|
|
.appending(component: "org.duckdb", directoryHint: .isDirectory)
|
|
.appending(component: "surveys")
|
|
|
|
public static func downloadSurveyCSV(forYear year: Int) async throws -> URL {
|
|
try await downloadSurveyIfNeeded(forYear: year)
|
|
return localSurveyDataURL(forYear: year)
|
|
.appending(component: "survey_results_public.csv")
|
|
}
|
|
|
|
public static func downloadSurveySchemaCSV(forYear year: Int) async throws -> URL {
|
|
try await downloadSurveyIfNeeded(forYear: year)
|
|
return localSurveyDataURL(forYear: year)
|
|
.appending(component: "survey_results_schema.csv")
|
|
}
|
|
|
|
public static func downloadSurveyIfNeeded(forYear year: Int) async throws {
|
|
let surveyDataURL = localSurveyDataURL(forYear: year)
|
|
if FileManager.default.fileExists(atPath: surveyDataURL.path) {
|
|
// survey already exists. skipping.
|
|
return
|
|
}
|
|
let surveyURL = remoteSurveyDataZipURL(forYear: year)
|
|
let (zipFileURL, _) = try await URLSession.shared.download(from: surveyURL)
|
|
try FileManager.default.createDirectory(
|
|
at: surveyDataURL, withIntermediateDirectories: true)
|
|
try Shell.execute("unzip '\(zipFileURL.path)' -d '\(surveyDataURL.path)'")
|
|
}
|
|
|
|
private static func localSurveyDataURL(forYear year: Int) -> URL {
|
|
localDataURL.appending(component: "\(year)")
|
|
}
|
|
|
|
private static func remoteSurveyDataZipURL(forYear year: Int) -> URL {
|
|
URL(string: "https://info.stackoverflowsolutions.com/rs/719-EMH-566/images/stack-overflow-developer-survey-\(year).zip")!
|
|
}
|
|
}
|
|
|
|
fileprivate enum Shell {
|
|
|
|
@discardableResult
|
|
static func execute(_ command: String) throws -> String {
|
|
let process = Process()
|
|
let pipe = Pipe()
|
|
process.executableURL = URL(fileURLWithPath: "/bin/zsh")
|
|
process.arguments = ["-c", command]
|
|
process.standardOutput = pipe
|
|
process.standardError = pipe
|
|
try process.run()
|
|
process.waitUntilExit()
|
|
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
|
return String(data: data, encoding: .utf8)!
|
|
}
|
|
}
|