aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2025-04-09 08:11:05 +0200
committerMitja Felicijan <mitja.felicijan@gmail.com>2025-04-09 08:11:05 +0200
commitcd360009270a0a9b0501ed73fe327be84824ca29 (patch)
treeff438b4a229227a934fd5e05785bcd3d2aac7a27 /tools
parent7492a206dedf44ecb8ab64981f8d0ab40bcd9ead (diff)
downloadmitjafelicijan.com-cd360009270a0a9b0501ed73fe327be84824ca29.tar.gz
Style update
Diffstat (limited to 'tools')
-rw-r--r--tools/projects.py147
1 files changed, 147 insertions, 0 deletions
diff --git a/tools/projects.py b/tools/projects.py
new file mode 100644
index 0000000..2805bf2
--- /dev/null
+++ b/tools/projects.py
@@ -0,0 +1,147 @@
1"""Fetches my public repositories and downloads tagged versions."""
2from datetime import datetime
3import sys
4import json
5import requests
6
7USERNAME = "mitjafelicijan"
8CACHE_BUSTER = int(datetime.now().timestamp())
9DOUBLE_NL = "\n\n"
10
11headers = {
12 "Accept": "application/vnd.github.v3+json"
13}
14
15
16def generate_markdown_file(include_repositories):
17 file = open("../content/pages/projects.md", "w")
18
19 file.write("---\n")
20 file.write("title: Personal projects\n")
21 file.write("date: 2024-10-21T12:00:00+02:00\n")
22 file.write("url: projects.html\n")
23 file.write("type: page\n")
24 file.write("draft: false\n")
25 file.write("---")
26 file.write(DOUBLE_NL)
27
28 file.write("<div class='project-list'>")
29 file.write(DOUBLE_NL)
30
31 for repo in include_repositories:
32 file.write(f"- [{repo['name']}](#{repo['name'].lower()}) \n")
33
34 file.write(DOUBLE_NL)
35 file.write("</div>")
36 file.write(DOUBLE_NL)
37
38 for repo in include_repositories:
39 print(f"> {repo['name']}")
40
41 file.write(f"## {repo['name']}\n")
42 file.write(f"{repo['description']}\n")
43
44 file.write(DOUBLE_NL)
45 file.write("<div class='project-release'>")
46 file.write(DOUBLE_NL)
47 file.write("|Released|Description|Download|\n")
48 file.write("|--------|-----------|--------|\n")
49
50 for release in repo['releases']:
51 print(f" - {release['name']} - {release['created_at']}")
52 dt = datetime.strptime(release["created_at"], "%Y-%m-%dT%H:%M:%SZ")
53 file.write(f"|{dt.strftime('%Y-%m-%d')}|{release['name']}| [{release['filename']}](/projects/{release['filename']}) |\n")
54
55 file.write(DOUBLE_NL)
56 file.write("</div>")
57 file.write(DOUBLE_NL)
58
59 file.write("<div class='github-link'>")
60 file.write(DOUBLE_NL)
61 file.write("![](/assets/general/github.svg)")
62 file.write(f"[{USERNAME}/{repo['name']}](https://github.com/{USERNAME}/{repo['name']})")
63 file.write(DOUBLE_NL)
64 file.write("</div>")
65 file.write(DOUBLE_NL)
66
67 file.write(DOUBLE_NL)
68 file.write("<style>\n")
69 file.write(".project-release table tr td:last-child { text-align: right; }\n")
70 file.write(".project-release table tr th:last-child { text-align: right; }\n")
71 file.write(".project-list ul { column-count: 3; column-gap: 3em; }\n")
72 file.write(".github-link p { display: flex; align-items: center; gap: 0.3em; }\n")
73 file.write(".github-link p img { border: 0; padding: 0; height: 15px; }\n")
74 file.write("</style>")
75 file.write(DOUBLE_NL)
76
77 file.close()
78
79
80
81def download_tarball(url, filepath):
82 with requests.get(url, stream=True, timeout=30) as response:
83 response.raise_for_status()
84
85 with open(filepath, "wb") as file:
86 for chunk in response.iter_content(chunk_size=8192):
87 file.write(chunk)
88
89
90def assert_rate_limit(response):
91 rate_limit_limit = int(response.headers.get("x-ratelimit-limit"))
92 rate_limit_remaining = int(response.headers.get("x-ratelimit-remaining"))
93 rate_limit_reset = int(response.headers.get("x-ratelimit-reset"))
94 print(f"Rate limit: {rate_limit_remaining}/{rate_limit_limit}")
95 print(f"Reset time: {datetime.fromtimestamp(rate_limit_reset)}")
96
97 if rate_limit_remaining == 0:
98 sys.exit(1)
99
100
101def fetch_github_data():
102 include_repositories = []
103 print(headers)
104 response = requests.get(f"https://api.github.com/users/{USERNAME}/repos?ts={CACHE_BUSTER}&per_page=100",
105 headers=headers,
106 timeout=10)
107
108 assert_rate_limit(response)
109
110 if response.status_code == 200:
111 repos = response.json()
112 for repo in repos:
113 if "include" in repo["topics"]:
114 include_repositories.append(repo)
115 else:
116 print(f"Failed to retrieve repositories: {response.status_code}")
117 sys.exit(1)
118
119 for repo in include_repositories:
120 print(f"Name: {repo['name']}, URL: {repo['html_url']}")
121
122 response = requests.get(f"https://api.github.com/repos/{USERNAME}/{repo['name']}/releases?ts={CACHE_BUSTER}",
123 headers=headers,
124 timeout=10)
125
126 assert_rate_limit(response)
127
128 if response.status_code == 200:
129 repo["releases"] = response.json()
130 for release in repo["releases"]:
131 release["filename"] = f"{repo['name']}-{release['tag_name']}.tar.gz"
132 print(f" > {release['tag_name']}, {release['name']}, {release['filename']}")
133 download_tarball(release["tarball_url"], f"../static/projects/{release['filename']}")
134
135 return include_repositories
136
137
138# include_repositories = fetch_github_data()
139
140# with open("out.json", "w") as json_file:
141# json.dump(include_repositories, json_file, indent=4)
142
143# generate_markdown_file(include_repositories)
144
145with open("out.json", "r") as fp:
146 include_repositories = json.load(fp)
147 generate_markdown_file(include_repositories)