Last active
June 21, 2021 08:15
-
-
Save Frityet/d19b8e57963279a648e875f45a1146b0 to your computer and use it in GitHub Desktop.
I made this project on a boring car ride. It gets the download information of important H3VR mods and prints them to the console
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation; | |
import PlaygroundSupport; | |
//We use async in this program, it needs to go inf | |
PlaygroundPage.current.needsIndefiniteExecution = true; | |
///Struct for a Github Asset (file inside the release) | |
struct GithubReleaseAsset : Decodable { | |
///Name of the asset | |
let fileName: String; | |
///Number of downloads | |
let downloadCount: Int32; | |
enum CodingKeys : String, CodingKey { | |
case fileName = "name"; | |
case downloadCount = "download_count"; | |
} | |
} | |
///Struct for a GitHub release, | |
struct GithubReleaseTag : Decodable { | |
///Version of the tag, also known as the tagname | |
let tagVersion: String; | |
///Title of the release | |
let tagName: String; | |
///All of the assets (files) in this release | |
let assets: [GithubReleaseAsset]; | |
enum CodingKeys : String, CodingKey { | |
case tagVersion = "tag_name"; | |
case tagName = "name"; | |
case assets = "assets"; | |
} | |
} | |
///Data about a mod | |
class Mod { | |
///Name of the mod. I could extract this from the path but I am lazy | |
let name: String; | |
///GitHub repo path to the mod. Needs to be in format {USER/ORGANISATION}/{REPOSITORY NAME} | |
let path: String; | |
///Number of downloads the most downloaded asset of every release is | |
var downloads: Int32 = 0; | |
init (name: String, path: String) { | |
self.name = name; | |
self.path = path; | |
let url: String = "https://api.github.com/repos/" + path + "/releases"; | |
var request = URLRequest(url: URL(string: url)!); | |
request.httpMethod = "GET"; | |
var downloads: Int32 = 0; | |
//Because swift async breaks everything we run this in a Semaphore so its in sync | |
let sync = DispatchSemaphore(value: 0); | |
let task = URLSession.shared.dataTask(with: request) { data, response, error in | |
defer { sync.signal(); } | |
guard let data = data, error == nil else { | |
print("error=\(String(describing: error))"); | |
return; | |
} | |
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { | |
print("statusCode should be 200, but is (httpStatus.statusCode)"); | |
print("response = \(String(describing: response))"); | |
} | |
if let body_response = String(data: data, encoding: String.Encoding.utf8) { | |
//Deserialise the raw JSON from the GitHub API | |
let deserialised: [GithubReleaseTag] = try! JSONDecoder().decode([GithubReleaseTag].self, from: body_response.data(using: .utf8)!); | |
for release in deserialised { | |
//We make an array of integers to count every download count of each asset, to get the one with most downloads | |
//I am aware this is very inefficient | |
var assetDlCounts: [Int32] = []; | |
for asset in release.assets { | |
assetDlCounts.append(asset.downloadCount); | |
} | |
assetDlCounts.sort(); | |
downloads += assetDlCounts.last!; | |
} | |
} | |
} | |
task.resume(); | |
sync.wait(); | |
self.downloads = downloads; | |
} | |
} | |
print("Getting H3VR Mod statistics..."); | |
let mods: [Mod] = [ | |
Mod(name: "Deli", path: "Deli-Collective/Deli"), | |
Mod(name: "BetterHands", path: "Maiq-The-Dude/BetterHands"), | |
Mod(name: "WurstMod", path: "WurstModders/WurstMod") | |
]; | |
for mod in mods { | |
print("\(mod.name) has \(String(describing: mod.downloads)) downloads"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment