-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathgenerate.py
executable file
·151 lines (131 loc) · 5.58 KB
/
generate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
""" generate html files """
import os
import json
from packaging import version
from jinja2 import Environment, FileSystemLoader
from lxml import html
import requests
import i18n
import settings
env = Environment(loader=FileSystemLoader("templates/"), extensions=["jinja2.ext.i18n"])
env.install_gettext_translations(i18n)
# pylint: disable=too-many-locals
def load_instances():
"""update the list of instances"""
with open("instances.json", "r", encoding="utf-8") as list_file:
instance_urls = json.load(list_file)
print(" Fetching instance statistics:")
instance_data = []
release = requests.get(settings.RELEASE_API, timeout=settings.TIMEOUT)
current_version = version.parse(release.json().get("tag_name", None))
for instance_url in instance_urls:
print(f" - Fetching: {instance_url}")
try:
response = requests.get(
f"{instance_url}api/v1/instance", timeout=settings.TIMEOUT
)
data = response.json()
version_number = data["version"]
parsed_version = version.parse(version_number)
if parsed_version < version.parse(settings.MINIMUM_VERSION):
raise Exception("Instance is out of date with version:", version_number)
# pylint: disable=consider-using-f-string
instance = {"path": instance_url}
instance["users"] = "{:,}".format(data["stats"]["user_count"])
instance["users_int"] = int(data["stats"]["user_count"])
instance["registration"] = (
"open"
if data["registrations"]
else "invite"
if data["approval_required"]
else "closed"
)
description_text = data["short_description"] or ""
if not description_text:
description = data["description"]
# pylint: disable=invalid-name
for p in str(html.fromstring(description).text_content()).split("\n"):
description_text += f"<p>{p}</p>" if p else ""
if len(description_text) > 80:
break
instance["description"] = description_text
instance["logo"] = data["thumbnail"]
instance["name"] = data["title"]
instance["version"] = data["version"]
# Determine a sort order
rank = 0
# reduce weight of user count
rank += instance["users_int"] ** 0.5
# distance between this version and current version (how up to date is it?)
rank -= (
(current_version.major - parsed_version.major) * 100
+ (current_version.minor - parsed_version.minor) * 10
+ (current_version.micro - parsed_version.micro)
)
# prioritize open instance
if instance["registration"] == "open":
rank += 10
elif instance["registration"] == "invite":
rank += 5
instance["rank"] = -1 * rank
except Exception as err: # pylint: disable=broad-except
print(f" ! {err}")
print(" - Site could possibly be down. Please check it manually:")
print(f" - Site url: {instance_url}")
instance = {"path": instance_url, "skip": True}
instance_data.append(instance)
instance_data = [i for i in instance_data if not i.get("skip")]
instance_data = sorted(instance_data, key=lambda i: i["rank"])
return instance_data
def generate_instances_api_endpoint(instance_list):
"""A json version of the instance list"""
keys = [
("path", "path"),
("users_int", "users"),
("registration", "registration"),
("description", "description"),
("name", "name"),
("version", "version"),
("logo", "logo"),
]
filtered = []
for instance in instance_list:
filtered.append({k: instance[l] for l, k in keys})
return json.dumps(filtered)
if __name__ == "__main__":
instances = load_instances()
paths = [
["index.html", lambda: {}],
["instances/index.html", lambda: {"instances": instances}],
["get-involved/index.html", lambda: {}],
]
print(" Generating API endpoint")
with open("site/instances.json", "w+", encoding="utf-8") as json_file:
json_file.write(generate_instances_api_endpoint(instances))
print("") # newline
for locale in i18n.locales_metadata:
i18n.setLocale(locale["code"])
LOCALIZED_SITE_PATH = "site/"
if not locale["code"] == "en_US":
LOCALIZED_SITE_PATH = f'site/{locale["slug"]}'
print(" Generating", LOCALIZED_SITE_PATH, end="")
for (path, data_loader) in paths:
print(".", end="")
with open(f"templates/{path}", "r", encoding="utf-8") as template_file:
template_string = template_file.read()
template = env.from_string(template_string)
localized_dirs = f"{LOCALIZED_SITE_PATH}{path}"
localized_dirs = localized_dirs[: localized_dirs.rfind("/")]
if not os.path.exists(localized_dirs):
os.makedirs(localized_dirs)
with open(
f"{LOCALIZED_SITE_PATH}{path}", "w+", encoding="utf-8"
) as render_file:
render_file.write(
template.render(
locale=locale,
locales_metadata=i18n.locales_metadata,
**data_loader(),
)
)
print("") # newline