diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2025-08-02 20:28:26 +0200 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2025-08-02 20:28:26 +0200 |
| commit | f871619d7fedbf973c249ad6e16c0fcf7e819cf8 (patch) | |
| tree | 93bcdeb6ffb45b12580a7890b0cc1d88ce977a32 /tools/projects.py | |
| parent | e326e848dc9e065af2cb4a324e3ebcf98ad9fb33 (diff) | |
| download | mitjafelicijan.com-f871619d7fedbf973c249ad6e16c0fcf7e819cf8.tar.gz | |
Update
Diffstat (limited to 'tools/projects.py')
| -rw-r--r-- | tools/projects.py | 149 |
1 files changed, 0 insertions, 149 deletions
diff --git a/tools/projects.py b/tools/projects.py deleted file mode 100644 index 65cea8d..0000000 --- a/tools/projects.py +++ /dev/null | |||
| @@ -1,149 +0,0 @@ | |||
| 1 | """Fetches my public repositories and downloads tagged versions.""" | ||
| 2 | from datetime import datetime | ||
| 3 | import sys | ||
| 4 | import json | ||
| 5 | import requests | ||
| 6 | |||
| 7 | USERNAME = "mitjafelicijan" | ||
| 8 | CACHE_BUSTER = int(datetime.now().timestamp()) | ||
| 9 | DOUBLE_NL = "\n\n" | ||
| 10 | |||
| 11 | headers = { | ||
| 12 | "Accept": "application/vnd.github.v3+json" | ||
| 13 | } | ||
| 14 | |||
| 15 | |||
| 16 | def 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("") | ||
| 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 | |||
| 81 | def 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 | |||
| 90 | def 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 | |||
| 101 | def 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 | # Check if repository has "winc" topic. This means I want to include | ||
| 114 | # this repository on this page. | ||
| 115 | if "winc" in repo["topics"]: | ||
| 116 | include_repositories.append(repo) | ||
| 117 | else: | ||
| 118 | print(f"Failed to retrieve repositories: {response.status_code}") | ||
| 119 | sys.exit(1) | ||
| 120 | |||
| 121 | for repo in include_repositories: | ||
| 122 | print(f"Name: {repo['name']}, URL: {repo['html_url']}") | ||
| 123 | |||
| 124 | response = requests.get(f"https://api.github.com/repos/{USERNAME}/{repo['name']}/releases?ts={CACHE_BUSTER}", | ||
| 125 | headers=headers, | ||
| 126 | timeout=10) | ||
| 127 | |||
| 128 | assert_rate_limit(response) | ||
| 129 | |||
| 130 | if response.status_code == 200: | ||
| 131 | repo["releases"] = response.json() | ||
| 132 | for release in repo["releases"]: | ||
| 133 | release["filename"] = f"{repo['name']}-{release['tag_name']}.tar.gz" | ||
| 134 | print(f" > {release['tag_name']}, {release['name']}, {release['filename']}") | ||
| 135 | download_tarball(release["tarball_url"], f"../static/projects/{release['filename']}") | ||
| 136 | |||
| 137 | return include_repositories | ||
| 138 | |||
| 139 | |||
| 140 | include_repositories = fetch_github_data() | ||
| 141 | |||
| 142 | # with open("out.json", "w") as json_file: | ||
| 143 | # json.dump(include_repositories, json_file, indent=4) | ||
| 144 | |||
| 145 | generate_markdown_file(include_repositories) | ||
| 146 | |||
| 147 | # with open("out.json", "r") as fp: | ||
| 148 | # include_repositories = json.load(fp) | ||
| 149 | # generate_markdown_file(include_repositories) | ||
