diff --git a/app.py b/app.py
index 3b97a32..022c370 100644
--- a/app.py
+++ b/app.py
break
except:
pass
- return render_template("repo.html", repo_name=repo_name, refs=refs, commits=commits, readme=readme)
+ return render_template("overview.html", repo_name=repo_name, refs=refs, commits=commits, readme=readme)
@app.route("/<repo_name>/commits")
def repo_commits(repo_name):
diff --git a/git/db.py b/git/db.py
deleted file mode 100644
index 84e9510..0000000
--- a/git/db.py
+++ /dev/null
-import sqlite3
-
-def init_db(db_path):
- conn = sqlite3.connect(db_path)
- cursor = conn.cursor()
- cursor.execute('''
- CREATE TABLE IF NOT EXISTS repos (
- id INTEGER PRIMARY KEY,
- name TEXT UNIQUE,
- owner TEXT
- )
- ''')
- conn.commit()
- conn.close()
-
-def get_owner(db_path, repo_name):
- conn = sqlite3.connect(db_path)
- cursor = conn.cursor()
- cursor.execute('SELECT owner FROM repos WHERE name = ?', (repo_name,))
- row = cursor.fetchone()
- conn.close()
- return row[0] if row else None
\ No newline at end of file
diff --git a/git/reference.py b/git/reference.py
index c54d0fd..fd221b6 100644
--- a/git/reference.py
+++ b/git/reference.py
except git.GitError:
continue
+ author = None
+ commit_time = None
+ try:
+ target_obj = repo[ref.target]
+ commit_obj = None
+ if isinstance(target_obj, git.Commit):
+ commit_obj = target_obj
+ elif isinstance(target_obj, git.Tag):
+ # annotated tag, peel to commit
+ commit_obj = target_obj.peel(git.Commit)
+
+ if commit_obj is not None:
+ author = commit_obj.author
+ commit_time = commit_obj.author.time
+ except Exception:
+ pass
+
refs.append(
- {"name": ref.name, "shorthand": ref.shorthand, "target": str(ref.target)}
+ {
+ "name": ref.name,
+ "shorthand": ref.shorthand,
+ "target": str(ref.target),
+ "author": author,
+ "date": commit_time,
+ }
)
+ refs.sort(key=lambda ref: ref["date"] or 0, reverse=True)
return refs
diff --git a/highlight.py b/highlight.py
index dc193ed..8bab634 100644
--- a/highlight.py
+++ b/highlight.py
def _formatter(*, linenos=False, cssclass=None, nowrap=False):
- return HtmlFormatter(
- style=STYLE,
- nobackground=True,
- linenos=linenos,
- cssclass=cssclass,
- nowrap=nowrap,
- )
+ formatter_kwargs = {
+ "style": STYLE,
+ "nobackground": True,
+ "linenos": linenos,
+ "nowrap": nowrap,
+ }
+ if cssclass:
+ formatter_kwargs["cssclass"] = cssclass
+ return HtmlFormatter(**formatter_kwargs)
# highlight code with filename-based lexer
diff --git a/static/cat.png b/static/cat.png
deleted file mode 100644
index 055bd8e..0000000
Binary files a/static/cat.png and /dev/null differ
diff --git a/static/styles.css b/static/styles.css
deleted file mode 100644
index ffcb683..0000000
--- a/static/styles.css
+++ /dev/null
-body {
- margin: 0;
- line-height: 1.5;
- font-family: sans-serif;
-}
-
-h1, h2, h3 {
- font-weight: normal;
-}
-
-a {
- color: blue;
- text-decoration: none;
-}
-
-a:hover {
- text-decoration: underline;
-}
-
-nav {
- padding: 0.8em 2em;
- display: flex;
- gap: 1em;
- align-items: center;
- background-color: #f5f5f5;
- border-bottom: 1px solid lightgray;
-}
-
-nav a {
- color: black;
- margin-right: 1em;
-}
-
-nav a.active {
- font-weight: bold;
-}
-
-pre {
- font-family: monospace;
- font-size: 10pt;
-}
-
-.content {
- padding: 1.5em 2em;
-}
-
-h1 {
- font-size: 120%;
- margin: 0.5em 0;
-}
-
-h2 {
- font-size: 110%;
- margin: 1em 0 0.5em 0;
-}
-
-table {
- border-collapse: collapse;
- width: 100%;
-}
-
-.tree-table {
- width: auto;
- max-width: 100%;
-}
-
-th {
- background-color: #f0f0f0;
-}
-
-th, td {
- padding: 6px 12px;
- text-align: left;
- white-space: nowrap;
- border: 1px solid lightgray;
-}
-
-tbody tr:nth-child(even) {
- background-color: #f9f9f9;
-}
-
-/* commits table */
-table.commits-table {
- width: 100%;
- table-layout: auto;
-}
-
-table.commits-table td {
- white-space: nowrap;
-}
-
-table.commits-table .message-col {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: 400px;
-}
-
-.files-changed {
- color: grey;
-}
-
-.insertions {
- color: green;
-}
-
-.deletions {
- color: red;
-}
-
-.blame-code {
- background-color: #f9f9f9;
- border: 1px solid lightgray;
- overflow-x: auto;
-}
-
-.breadcrumbs {
- margin-bottom: 1em;
- font-size: 14px;
-}
-
-.breadcrumbs a {
- color: grey;
-}
-
-.tree-table td:first-child {
- white-space: normal;
- word-break: break-all;
-}
-
-.blob-content {
- margin: 0 -2em;
-}
-
-.blob-content pre {
- white-space: pre-wrap;
- overflow-x: auto;
-}
-
-.readme-box {
- border: 1px solid lightgray;
- padding: 1em;
- margin: 0.5em 0;
- background-color: #f9f9f9;
- border-radius: 4px;
- white-space: pre-wrap;
- overflow-x: auto;
-}
-
-.commit-message {
- margin: 1em 0;
-}
diff --git a/templates/base.html b/templates/base.html
index 16efd37..076527f 100644
--- a/templates/base.html
+++ b/templates/base.html
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lipasto</title>
- <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<nav>
- <div>
- <a href="/">Home</a>
- {% set repo_name = request.view_args.get('repo_name') %}
- {% if repo_name %}
- <a href="{{ url_for('repo_detail', repo_name=repo_name) }}?ref={{ current_ref }}" {% if request.endpoint == 'repo_detail' %}class="active"{% endif %}>Overview</a>
- <a href="{{ url_for('repo_commits', repo_name=repo_name) }}?ref={{ current_ref }}" {% if request.endpoint == 'repo_commits' %}class="active"{% endif %}>Commits</a>
- <a href="{{ url_for('repo_refs', repo_name=repo_name) }}" {% if request.endpoint == 'repo_refs' %}class="active"{% endif %}>Refs</a>
- <a href="{{ url_for('repo_tree_path', repo_name=repo_name) }}?ref={{ current_ref }}" {% if request.endpoint in ['repo_tree_path', 'repo_blob_path', 'repo_blame_path'] %}class="active"{% endif %}>Tree</a>
- <a href="{{ url_for('repo_diff', repo_name=repo_name) }}?ref={{ current_ref }}" {% if request.endpoint == 'repo_diff' %}class="active"{% endif %}>Diff</a>
- {% endif %}
- </div>
+ <a href="/">Home</a>
+ {% set repo_name = request.view_args.get('repo_name') %}
+ {% if repo_name %}
+ | <a href="{{ url_for('repo_detail', repo_name=repo_name) }}?ref={{ current_ref }}">Overview</a>
+ | <a href="{{ url_for('repo_commits', repo_name=repo_name) }}?ref={{ current_ref }}">Commits</a>
+ | <a href="{{ url_for('repo_refs', repo_name=repo_name) }}">Refs</a>
+ | <a href="{{ url_for('repo_tree_path', repo_name=repo_name) }}?ref={{ current_ref }}">Tree</a>
+ | <a href="{{ url_for('repo_diff', repo_name=repo_name) }}?ref={{ current_ref }}">Diff</a>
+ {% endif %}
{% if refs %}
- <select onchange="changeRef(this.value)">
- {% for ref in refs %}
- <option value="{{ ref.shorthand }}" {% if ref.shorthand == current_ref %}selected{% endif %}>{{ ref.name }}</option>
- {% endfor %}
- </select>
+ | Ref:
+ <select onchange="changeRef(this.value)">
+ {% for ref in refs %}
+ <option value="{{ ref.shorthand }}" {% if ref.shorthand == current_ref %}selected{% endif %}>{{ ref.name }}</option>
+ {% endfor %}
+ </select>
{% endif %}
</nav>
+ <main>
+ {% block content %}{% endblock %}
+ </main>
<script>
- function changeRef(newRef) {
- const url = new URL(window.location);
- url.searchParams.set('ref', newRef);
- window.location = url;
- }
+ function changeRef(newRef) {
+ const url = new URL(window.location);
+ url.searchParams.set('ref', newRef);
+ window.location = url;
+ }
</script>
- </nav>
- <div class="content">
- {% block content %}{% endblock %}
- </div>
-</body>
-</html>
</body>
</html>
diff --git a/templates/blame.html b/templates/blame.html
index 75d6f7d..19a587f 100644
--- a/templates/blame.html
+++ b/templates/blame.html
{% block content %}
<style id="blame-style"></style>
-<style>.blame-code pre { line-height: 0.7; }</style>
-<h1>Blame: {{ path }}</h1>
+<h2>Blame: {{ path }}</h2>
<div id="loading">Loading blame information, this may take a while for large files...</div>
<div id="pomeranian" style="display: none;">
<p>Server is taking its time... anyways, here's a tug of war match between two marshmallows:</p>
diff --git a/templates/blob.html b/templates/blob.html
index 22b2a5c..f7e675f 100644
--- a/templates/blob.html
+++ b/templates/blob.html
{% extends "base.html" %}
{% block content %}
-<h1>Blob: {{ blob.name }}</h1>
+<h2>Blob: {{ blob.name }}</h2>
<p>Blob id: {{ blob.id }}</p>
<p>Size: {{ blob.size | size }}</p>
<p><a href="{{ url_for('repo_blame_path', repo_name=repo_name, path=path) }}?ref={{ ref }}">Blame</a></p>
-<div class="blob-content">
+<div>
{% if blob.is_binary %}
<pre>Binary...</pre>
{% else %}
diff --git a/templates/commit.html b/templates/commit.html
index e5fe2f6..f469375 100644
--- a/templates/commit.html
+++ b/templates/commit.html
Parent: <a href="{{ url_for('commit_detail', repo_name=repo_name, commit_id=commit.parent_id) }}">{{ commit.parent_id }}</a>
{% endif %}<br>
Tree: <a href="{{ url_for('repo_tree_path', repo_name=repo_name, path='') }}?ref={{ commit.tree_id }}">{{ commit.tree_id }}</a>
- <div class="commit-message">
+ <div>
{{ commit.message }}
</div>
<a href="{{ url_for('repo_tree_path', repo_name=repo_name, path='') }}?ref={{ commit.id }}">View Tree</a>
{% if commit.diff %}
<h2>Changed Files</h2>
- <table class="changed-files-table">
+ <table>
<thead>
<tr>
<th>File</th>
{% for file in commit.changed_files %}
<tr>
<td><a href="{{ url_for('repo_blob_path', repo_name=repo_name, path=file.file) }}?ref={{ commit.id }}">{{ file.file }}</a></td>
- <td class="insertions">+{{ file.additions }}</td>
- <td class="deletions">-{{ file.deletions }}</td>
+ <td>+{{ file.additions }}</td>
+ <td>-{{ file.deletions }}</td>
<td>{{ file.status }}</td>
</tr>
{% endfor %}
diff --git a/templates/commits.html b/templates/commits.html
index 73d7872..933a96e 100644
--- a/templates/commits.html
+++ b/templates/commits.html
{% extends "base.html" %}
{% block content %}
- <h1>Commits for {{ repo_name }}</h1>
- <table class="commits-table">
+ <h2>Commits</h2>
+ <table width="100%">
<thead>
- <tr>
- <th class="commit-col">Commit</th>
- <th class="message-col">Message</th>
- <th class="author-col">Author</th>
- <th class="age-col">Age</th>
- <th class="changes-col">Changes</th>
+ <tr style="font-weight: bold;">
+ <td>Commit</td>
+ <td>Message</td>
+ <td>Author</td>
+ <td>Age</td>
+ <td>Changes</td>
</tr>
</thead>
<tbody>
{% for commit in commits %}
<tr>
- <td class="commit-col"><a href="{{ url_for('commit_detail', repo_name=repo_name, commit_id=commit.id) }}">{{ commit.id[:8] }}</a></td>
- <td class="message-col" title="{{ commit.message }}">{{ commit.message }}</td>
- <td class="author-col">{{ commit.author.name }}</td>
- <td class="age-col">{{ commit.date | age }}</td>
- <td class="changes-col">
- <span class="files-changed">{{ commit.diff_stats.files_changed }} file{% if commit.diff_stats.files_changed != 1 %}s{% endif %}</span>
- <span class="insertions">+{{ commit.diff_stats.insertions }}</span>
- <span class="deletions">-{{ commit.diff_stats.deletions }}</span>
- </td>
+ <td valign="top" nowrap><a href="{{ url_for('commit_detail', repo_name=repo_name, commit_id=commit.id) }}">{{ commit.id[:8] }}</a></td>
+ <td valign="top">{{ commit.message }}</td>
+ <td valign="top" nowrap>{{ commit.author.name }}</td>
+ <td valign="top" nowrap>{{ commit.date | age }}</td>
+ <td valign="top" nowrap>{{ commit.diff_stats.files_changed }} file{% if commit.diff_stats.files_changed != 1 %}s{% endif %}, <span style="color: green;">+{{ commit.diff_stats.insertions }}</span>, <span style="color: red;">-{{ commit.diff_stats.deletions }}</span></td>
</tr>
{% endfor %}
</tbody>
diff --git a/templates/diff.html b/templates/diff.html
index bf7d768..f683ee9 100644
--- a/templates/diff.html
+++ b/templates/diff.html
{% extends "base.html" %}
{% block content %}
-<h1>Diff</h1>
-
{% if error %}
-<p style="color: red;">Error: {{ error }}</p>
+<p>Error: {{ error }}</p>
{% endif %}
{% if diff %}
-<h1>Diff between {{ diff.ref1 }} ({{ diff.ref1_id[:7] }}) and {{ diff.ref2 }} ({{ diff.ref2_id[:7] }})</h1>
+<h2>Diff between {{ diff.ref1 }} and {{ diff.ref2 }}</h2>
<form method="get" action="">
<label for="id1">From:</label>
<button type="submit">Update Diff</button>
</form>
-<h2>Changed Files</h2>
+<h3>Changed Files</h3>
<table>
- <thead>
+ <thead style="font-weight: bold;">
<tr>
- <th>File</th>
- <th>Additions</th>
- <th>Deletions</th>
- <th>Status</th>
+ <td>File</td>
+ <td>Additions</td>
+ <td>Deletions</td>
+ <td>Status</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
-<h2>Full Patch</h2>
+<h3>Full Patch</h3>
<div>
{{ highlighted_patch|safe }}
</div>
diff --git a/templates/index.html b/templates/index.html
index 5ef7141..1898f59 100644
--- a/templates/index.html
+++ b/templates/index.html
<h2>Repositories</h2>
<table>
<thead>
- <tr>
- <th>Repository</th>
- <th>Owner</th>
- <th>Description</th>
+ <tr style="font-weight: bold;">
+ <td>Repository</td>
+ <td>Owner</td>
+ <td>Description</td>
</tr>
</thead>
<tbody>
diff --git a/templates/overview.html b/templates/overview.html
new file mode 100644
index 0000000..6db0064
--- /dev/null
+++ b/templates/overview.html
+{% extends "base.html" %}
+
+{% block content %}
+<h2>{{ repo_name }}</h2>
+<h3>Latest commits</h3>
+<table width="100%">
+ <thead>
+ <tr style="font-weight: bold;">
+ <td>Commit</td>
+ <td>Message</td>
+ <td>Author</td>
+ <td>Age</td>
+ <td>Changes</td>
+ </tr>
+ </thead>
+ <tbody>
+ {% for commit in commits %}
+ <tr>
+ <td valign="top" nowrap><a href="{{ url_for('commit_detail', repo_name=repo_name, commit_id=commit.id) }}">{{ commit.id[:8] }}</a></td>
+ <td valign="top">{{ commit.message }}</td>
+ <td valign="top" nowrap>{{ commit.author.name }}</td>
+ <td valign="top" nowrap>{{ commit.date | age }}</td>
+ <td valign="top" nowrap>{{ commit.diff_stats.files_changed }} file{% if commit.diff_stats.files_changed != 1 %}s{% endif %}, <span style="color: green;">+{{ commit.diff_stats.insertions }}</span>, <span style="color: red;">-{{ commit.diff_stats.deletions }}</span></td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+{% if readme %}
+<h3>README</h3>
+<pre>{{ readme }}</pre>
+{% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/templates/refs.html b/templates/refs.html
index 1789b6b..2ea4202 100644
--- a/templates/refs.html
+++ b/templates/refs.html
{% extends "base.html" %}
{% block content %}
- <h1>Refs for {{ repo_name }}</h1>
- <table class="list">
+ <h2>References</h2>
+ <table>
<thead>
- <tr>
- <th>Name</th>
- <th>Target</th>
- <th>Actions</th>
+ <tr style="font-weight: bold;">
+ <td>Name</td>
+ <td>Target</td>
+ <td>Author</td>
+ <td>Age</td>
+ <td>Actions</td>
</tr>
</thead>
<tbody>
{% for ref in refs %}
<tr>
- <td>{{ ref.name }}</td>
- <td>{{ ref.target }}</td>
- <td><a href="{{ url_for('repo_tree_path', repo_name=repo_name, path='') }}?ref={{ ref.shorthand }}">View Tree</a></td>
+ <td valign="top" nowrap>{{ ref.name }}</td>
+ <td valign="top" nowrap>{{ ref.target[:8] }}</td>
+ <td valign="top" nowrap>{{ ref.author.name if ref.author else 'N/A' }}</td>
+ <td valign="top" nowrap>{{ ref.date | age if ref.date else 'N/A' }}</td>
+ <td valign="top" nowrap><a href="{{ url_for('repo_tree_path', repo_name=repo_name, path='') }}?ref={{ ref.shorthand }}">View Tree</a></td>
</tr>
{% endfor %}
</tbody>
diff --git a/templates/repo.html b/templates/repo.html
deleted file mode 100644
index 6b4a0f7..0000000
--- a/templates/repo.html
+++ /dev/null
-{% extends "base.html" %}
-
-{% block content %}
-<h1>{{ repo_name }}</h1>
-<h2>Latest commits</h2>
-<table class="commits-table">
- <thead>
- <tr>
- <th class="commit-col">Commit</th>
- <th class="message-col">Message</th>
- <th class="author-col">Author</th>
- <th class="age-col">Age</th>
- <th class="changes-col">Changes</th>
- </tr>
- </thead>
- <tbody>
- {% for commit in commits %}
- <tr>
- <td class="commit-col"><a href="{{ url_for('commit_detail', repo_name=repo_name, commit_id=commit.id) }}">{{ commit.id[:8] }}</a></td>
- <td class="message-col">{{ commit.message }}</td>
- <td class="author-col">{{ commit.author.name }}</td>
- <td class="age-col">{{ commit.date | age }}</td>
- <td class="changes-col">
- <span class="files-changed">{{ commit.diff_stats.files_changed }} file{% if commit.diff_stats.files_changed != 1 %}s{% endif %}</span>
- <span class="insertions">+{{ commit.diff_stats.insertions }}</span>
- <span class="deletions">-{{ commit.diff_stats.deletions }}</span>
- </td>
- </tr>
- {% endfor %}
- </tbody>
-</table>
-{% if readme %}
-<h2>README</h2>
-<pre class="readme-box">{{ readme }}</pre>
-{% endif %}
-{% endblock %}
\ No newline at end of file
diff --git a/templates/tree.html b/templates/tree.html
index 5ad607d..8502ed8 100644
--- a/templates/tree.html
+++ b/templates/tree.html
{% extends "base.html" %}
{% block content %}
- <h1>Tree for {{ repo_name }} at {{ ref }}{% if path %} / {{ path }}{% endif %}</h1>
-
+ <h2>Tree</h2>
{% if path %}
- <div class="breadcrumbs">
+ <p>
<a href="{{ url_for('repo_tree_path', repo_name=repo_name) }}?ref={{ ref }}">root</a>
{% set parts = path.split('/') %}
{% for part in parts %}
/ <a href="{{ url_for('repo_tree_path', repo_name=repo_name, path=parts[:loop.index]|join('/')) }}?ref={{ ref }}">{{ part }}</a>
{% endfor %}
- </div>
+ </p>
{% endif %}
- <table class="list tree-table">
+ <table>
<thead>
- <tr>
- <th>Name</th>
- <th>Type</th>
- <th>Size</th>
+ <tr style="font-weight: bold;">
+ <td>Name</td>
+ <td>Type</td>
+ <td>Size</td>
</tr>
</thead>
<tbody>