my nixos/home-manager configuration
1#!/usr/bin/env nix-shell
2#!nix-shell -i python3 -p python3
3
4from enum import StrEnum
5from typing import List, Tuple
6from subprocess import PIPE, Popen
7import json
8import urllib.request
9import re
10import os.path
11
12SRC_NAME = "source"
13
14VERSION_REGEX = re.compile(r"\/([\d.]+)\/")
15
16
17class Platform(StrEnum):
18 LINUX = "linux"
19 MACOS = "osx"
20
21 def format_type(self):
22 if self.value == Platform.LINUX.value:
23 return "tar.gz"
24 elif self.value == Platform.MACOS.value:
25 return "dmg"
26 raise RuntimeError("Invalid platform")
27
28
29class Branch(StrEnum):
30 STABLE = "stable"
31 PTB = "ptb"
32 CANARY = "canary"
33 DEVELOPMENT = "development"
34
35
36Variant = Tuple[Platform, Branch]
37
38
39def serialize_variant(variant: Variant) -> str:
40 platform, branch = variant
41 return f"{platform}-{branch}"
42
43
44def url_for_variant(variant: Variant) -> str:
45 platform, branch = variant
46
47 return f"https://discord.com/api/download/{branch.value}?platform={platform.value}&format={platform.format_type()}"
48
49
50def fetch_redirect_url(url: str) -> str:
51 headers = {"user-agent": "Nixpkgs-Discord-Update-Script/0.0.0"}
52 # note that urllib follows redirects by default. So we can extract the final url from the response object
53 req = urllib.request.Request(url, headers=headers)
54 with urllib.request.urlopen(req) as response:
55 return response.url
56
57
58def version_from_url(url: str) -> str:
59 matches = VERSION_REGEX.search(url)
60 assert matches, f"Url {url} must contain version number"
61 version = matches.group(1)
62 assert version
63 return version
64
65
66def prefetch(url: str) -> str:
67 with Popen(["nix-prefetch-url", "--name", "source", url], stdout=PIPE) as p:
68 assert p.stdout
69 b32_hash = p.stdout.read().decode("utf-8").strip()
70 with Popen(
71 ["nix-hash", "--to-sri", "--type", "sha256", b32_hash], stdout=PIPE
72 ) as p:
73 assert p.stdout
74 sri_hash = p.stdout.read().decode("utf-8").strip()
75 return sri_hash
76
77
78def main():
79 variants: List[Variant] = [
80 (Platform.LINUX, Branch.STABLE),
81 (Platform.LINUX, Branch.PTB),
82 (Platform.LINUX, Branch.CANARY),
83 (Platform.LINUX, Branch.DEVELOPMENT),
84 (Platform.MACOS, Branch.STABLE),
85 (Platform.MACOS, Branch.PTB),
86 (Platform.MACOS, Branch.CANARY),
87 (Platform.MACOS, Branch.DEVELOPMENT),
88 ]
89
90 sources = {}
91
92 for v in variants:
93 url = url_for_variant(v)
94 url = fetch_redirect_url(url)
95 version = version_from_url(url)
96 sri_hash = prefetch(url)
97
98 sources[serialize_variant(v)] = {
99 "url": url,
100 "version": version,
101 "hash": sri_hash,
102 }
103
104 with open(os.path.join(os.path.dirname(__file__), "sources.json"), "w") as f:
105 json.dump(sources, f, indent=2, sort_keys=True)
106 f.write("\n")
107
108
109if __name__ == "__main__":
110 main()