from dataclasses import dataclass from flask import Flask, render_template from pathlib import Path import commonmark import os import subprocess root = Path(os.environ['HOME'])/'devil' app = Flask(__name__) @app.route('/') def list_repos(): repos = find_repos().values() return render_template('repo-list.html', title='Shadowbox', repos=repos) @app.route('/') def show_repo(name): repo = find_repos()[name] cmd = '/usr/bin/git log --oneline' commits = subprocess.run(cmd, cwd=root/name, shell=True, capture_output=True, text=True).stdout.splitlines() readme = get_readme(name) return render_template('repo.html', title=f'{repo.name} - {repo.description}', repo=repo, commits=commits, readme=readme) def get_readme(name): path = root/name/'README.md' if path.exists(): with(root/name/'README.md').open() as f: content = f.read() ast = commonmark.Parser().parse(content) readme = commonmark.HtmlRenderer().render(ast) return readme else: return None @dataclass class Repo: name: str description: str last_update: str # date def find_repos() -> dict[Repo]: # iterate through all subdirectories, looking for things that look like git repos cmd = '/usr/bin/find . -type d -execdir /usr/bin/git -C {} rev-parse ";" -printf "%P\n" -prune' repo_folders = subprocess.run(cmd, cwd=root, shell=True, capture_output=True, text=True).stdout.splitlines() repos = {} for folder in repo_folders: # description is at ./description for bare repos, ./.git/description for normal repos loc = root/folder/'description' if (root/folder/'description').exists() else root/folder/'.git'/'description' with loc.open() as f: desc = f.readline() cmd = '/usr/bin/git show --no-patch --format="%cr"' last = subprocess.run(cmd, cwd=root/folder, shell=True, capture_output=True, text=True).stdout repos[folder] = Repo(folder, desc, last) return repos