mirror of
https://github.com/godotengine/issue-stats.git
synced 2026-01-01 01:48:12 +03:00
Begin work on web interface
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,7 +1,10 @@
|
|||||||
# Python virtualenv
|
# Python virtualenv.
|
||||||
venv/
|
venv/
|
||||||
|
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
|
|
||||||
# Environment variables (contains credentials).
|
# Environment variables (contains credentials).
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
# JSON file output by running `main.py`.
|
||||||
|
statistics.json
|
||||||
|
|||||||
61
index.html
Normal file
61
index.html
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
<link rel="stylesheet" href="thirdparty/water.min.css">
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script src="thirdparty/frappe-charts.umd.min.js"></script>
|
||||||
|
<script src="thirdparty/ky.umd.min.js"></script>
|
||||||
|
<script type="module">
|
||||||
|
document.addEventListener("DOMContentLoaded", async function () {
|
||||||
|
const statistics = await ky.get('statistics.json').json();
|
||||||
|
|
||||||
|
const colorAmd = "#b91c1c";
|
||||||
|
const colorIntel = "#2074d9";
|
||||||
|
const colorNvidia = "#65a30d";
|
||||||
|
|
||||||
|
// Function that sums all values in an array (use with `reduce()`).
|
||||||
|
const sum = (partialSum, value) => partialSum + value;
|
||||||
|
|
||||||
|
new frappe.Chart("#chart-cpu-vendor", {
|
||||||
|
data: {
|
||||||
|
labels: ["AMD", "Intel"],
|
||||||
|
datasets: [{ values: [Object.values(statistics.cpu.amd).reduce(sum, 0), Object.values(statistics.cpu.intel).reduce(sum, 0)] }],
|
||||||
|
},
|
||||||
|
type: "percentage",
|
||||||
|
colors: [colorAmd, colorIntel],
|
||||||
|
});
|
||||||
|
|
||||||
|
new frappe.Chart("#chart-gpu-vendor", {
|
||||||
|
data: {
|
||||||
|
labels: ["AMD", "Intel", "NVIDIA"],
|
||||||
|
datasets: [{ values: [Object.values(statistics.gpu.amd).reduce(sum, 0), Object.values(statistics.gpu.intel).reduce(sum, 0), Object.values(statistics.gpu.nvidia).reduce(sum, 0)] }],
|
||||||
|
},
|
||||||
|
type: "percentage",
|
||||||
|
colors: [colorAmd, colorIntel, colorNvidia],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>Statistics</h1>
|
||||||
|
|
||||||
|
<h2>CPU vendor</h2>
|
||||||
|
<div id="chart-cpu-vendor"></div>
|
||||||
|
|
||||||
|
<h2>GPU vendor</h2>
|
||||||
|
<div id="chart-gpu-vendor"></div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
© 2023-present Hugo Locurcio and contributors<br>
|
||||||
|
<a href="https://github.com/godot-issues-stats/godot-issues-stats.github.io">Website source on GitHub</a>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
26
main.py
26
main.py
@@ -3,6 +3,7 @@ from gql import gql, Client
|
|||||||
from gql.transport.aiohttp import AIOHTTPTransport
|
from gql.transport.aiohttp import AIOHTTPTransport
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import os
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
@@ -18,9 +19,11 @@ def main() -> None:
|
|||||||
|
|
||||||
results = []
|
results = []
|
||||||
cursor = None
|
cursor = None
|
||||||
# Get the 10×100 = 1000 last issues.
|
# Get the 30×100 = 3,000 last issues.
|
||||||
# TODO: Retry requests a few times if they fail.
|
# TODO: Retry requests a few times if they fail.
|
||||||
for _ in range(10):
|
num_queries = 30
|
||||||
|
for i in range(num_queries):
|
||||||
|
print(f"Running query #{i + 1} of {num_queries}...")
|
||||||
query = gql(
|
query = gql(
|
||||||
"""
|
"""
|
||||||
query($cursor: String) {
|
query($cursor: String) {
|
||||||
@@ -343,7 +346,6 @@ def main() -> None:
|
|||||||
"pro", ""
|
"pro", ""
|
||||||
) # Makes it easier to parse "Ryzen PRO" (these are very close to their non-PRO counterparts).
|
) # Makes it easier to parse "Ryzen PRO" (these are very close to their non-PRO counterparts).
|
||||||
)
|
)
|
||||||
print(system_information_trimmed)
|
|
||||||
|
|
||||||
# Gather statistics for each issue reported.
|
# Gather statistics for each issue reported.
|
||||||
if "windows11" in system_information_trimmed:
|
if "windows11" in system_information_trimmed:
|
||||||
@@ -2943,12 +2945,20 @@ def main() -> None:
|
|||||||
):
|
):
|
||||||
statistics["gpu"]["intel"]["unknown"].add(user)
|
statistics["gpu"]["intel"]["unknown"].add(user)
|
||||||
|
|
||||||
for info in user_system_infos:
|
|
||||||
print(info["user"], " \t", info["system_information"])
|
|
||||||
|
|
||||||
print(f"Number of scannable reports: {len(user_system_infos)}")
|
print(f"Number of scannable reports: {len(user_system_infos)}")
|
||||||
print()
|
|
||||||
print(statistics)
|
output_path = "statistics.json"
|
||||||
|
with open(output_path, "w") as out_file:
|
||||||
|
# Serialize Python sets as their length as an integer, since we only need to know how many users
|
||||||
|
# match each metric (and not who exactly).
|
||||||
|
def set_default(obj):
|
||||||
|
if isinstance(obj, set):
|
||||||
|
return len(obj)
|
||||||
|
raise TypeError
|
||||||
|
|
||||||
|
json.dump(statistics, out_file, default=set_default)
|
||||||
|
|
||||||
|
print(f"Wrote statistics to: {output_path}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
2
thirdparty/frappe-charts.umd.min.js
vendored
Normal file
2
thirdparty/frappe-charts.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
thirdparty/ky.umd.min.js
vendored
Normal file
8
thirdparty/ky.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
thirdparty/water.min.css
vendored
Normal file
1
thirdparty/water.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user