summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2018-11-24 14:23:43 -0500
committerDrew DeVault <sir@cmpwn.com>2018-11-24 14:23:43 -0500
commit31c9eff0540cbd7e0ee727bfcb4118e9ffff0afa (patch)
treec5c78919ba7a3aebb859d7f6d1e7abf05027b339
parente95fbad612e6041dbde5ff1232bc2752f2de4b62 (diff)
Tweaks to contributors page
-rw-r--r--gitsrht/app.py2
-rw-r--r--gitsrht/blueprints/repo.py90
-rw-r--r--gitsrht/blueprints/stats.py81
-rw-r--r--gitsrht/repos.py21
-rw-r--r--gitsrht/templates/contributors.html21
-rw-r--r--gitsrht/templates/repo.html2
-rwxr-xr-xsetup.py1
7 files changed, 118 insertions, 100 deletions
diff --git a/gitsrht/app.py b/gitsrht/app.py
index 491801b..9c6a3a9 100644
--- a/gitsrht/app.py
+++ b/gitsrht/app.py
@@ -29,11 +29,13 @@ class GitApp(SrhtFlask):
from gitsrht.blueprints.api import api
from gitsrht.blueprints.public import public
from gitsrht.blueprints.repo import repo
+ from gitsrht.blueprints.stats import stats
from gitsrht.blueprints.manage import manage
self.register_blueprint(api)
self.register_blueprint(public)
self.register_blueprint(repo)
+ self.register_blueprint(stats)
self.register_blueprint(manage)
meta_client_id = cfg("git.sr.ht", "oauth-client-id")
diff --git a/gitsrht/blueprints/repo.py b/gitsrht/blueprints/repo.py
index 98e044c..2648b2b 100644
--- a/gitsrht/blueprints/repo.py
+++ b/gitsrht/blueprints/repo.py
@@ -16,8 +16,9 @@ from gitsrht.editorconfig import EditorConfig
from gitsrht.redis import redis
from gitsrht.git import Repository as GitRepository, commit_time, annotate_tree
from gitsrht.git import diffstat
-from gitsrht.types import User, Repository, Redirect
+from gitsrht.repos import get_repo_or_redir
from gitsrht.rss import generate_feed
+from gitsrht.types import User, Repository, Redirect
from io import BytesIO
from pygments import highlight
from pygments.lexers import guess_lexer, guess_lexer_for_filename, TextLexer
@@ -94,23 +95,6 @@ def _highlight_file(name, data, blob_id):
redis.setex(key, html, timedelta(days=7))
return Markup(html)
-def get_repo_or_redir(owner, repo):
- owner, repo = get_repo(owner, repo)
- if not repo:
- abort(404)
- if not has_access(repo, UserAccess.read):
- abort(401)
- if isinstance(repo, Redirect):
- view_args = request.view_args
- if not "repo" in view_args or not "owner" in view_args:
- return redirect(url_for(".summary",
- owner=repo.new_repo.owner.canonical_name,
- repo=repo.new_repo.name))
- view_args["owner"] = repo.new_repo.owner.canonical_name
- view_args["repo"] = repo.new_repo.name
- abort(redirect(url_for(request.endpoint, **view_args)))
- return owner, repo
-
def get_last_3_commits(commit):
commits = [commit]
for parent in commit.parents:
@@ -471,73 +455,3 @@ def ref(owner, repo, ref):
abort(404)
return render_template("ref.html", view="refs",
owner=owner, repo=repo, git_repo=git_repo, tag=tag)
-
-def _week(time):
- """Used to group contributions by week"""
- return time.strftime('%Y/%W')
-
-@lru_cache(maxsize=256)
-def _user(email):
- """Used to grouped contributions by either username or email."""
- email = email.lower()
- user = User.query.filter_by(email=email).one_or_none()
- return (None, user.username) if user else (email, None)
-
-def get_contributions(git_repo, tip, since):
- contributions = defaultdict(lambda: {
- "commits": 0,
- "weekly": defaultdict(lambda: 0)
- })
-
- since_ts = since.timestamp()
- for commit in git_repo.walk(tip.id, pygit2.GIT_SORT_TIME):
- timestamp = commit.commit_time + commit.commit_time_offset
- if timestamp < since_ts:
- break
-
- week = _week(datetime.fromtimestamp(timestamp))
- user = _user(commit.author.email)
- contributions[user]['commits'] += 1
- contributions[user]['weekly'][week] += 1
-
- return contributions
-
-def get_contrib_chart_data(contributions):
- # Max number of commits by a contributor in a single week
- max_commits = max(
- max(commits for _, commits in data['weekly'].items())
- for _, data in contributions.items())
-
- all_weeks = [_week(date.today() - timedelta(weeks=51 - n))
- for n in range(52)]
-
- def bars(contributions):
- bars = list()
- for ordinal, week in enumerate(all_weeks):
- if week in contributions:
- week_commits = contributions[week]
- bars.append({
- "ordinal": ordinal,
- "week": week,
- "commits": week_commits,
- "height": 100 * week_commits // max_commits
- })
- return bars
-
- chart_data = [(email, username, data['commits'], bars(data['weekly']))
- for (email, username), data in contributions.items()]
- return sorted(chart_data, key=lambda x: x[2], reverse=True)
-
-@repo.route("/<owner>/<repo>/contributors")
-def contributors(owner, repo):
- owner, repo = get_repo_or_redir(owner, repo)
- since = datetime.now() - timedelta(weeks=52)
-
- with GitRepository(repo.path) as git_repo:
- default_branch = git_repo.default_branch()
- tip = git_repo.get(default_branch.target)
- contributions = get_contributions(git_repo, tip, since)
- chart_data = get_contrib_chart_data(contributions)
-
- return render_template("contributors.html", view="contributors",
- owner=owner, repo=repo, chart_data=chart_data)
diff --git a/gitsrht/blueprints/stats.py b/gitsrht/blueprints/stats.py
new file mode 100644
index 0000000..e9315f5
--- /dev/null
+++ b/gitsrht/blueprints/stats.py
@@ -0,0 +1,81 @@
+import pygit2
+from collections import defaultdict
+from datetime import date, datetime, timedelta
+from flask import Blueprint, render_template
+from functools import lru_cache
+from gitsrht.git import Repository as GitRepository
+from gitsrht.repos import get_repo_or_redir
+from gitsrht.types import User
+
+stats = Blueprint('stats', __name__)
+
+def _week(time):
+ """Used to group contributions by week"""
+ return time.strftime('%Y/%W')
+
+@lru_cache(maxsize=256)
+def _user(email, name):
+ """Used to grouped contributions by either username or email."""
+ email = email.lower()
+ user = User.query.filter_by(email=email).one_or_none()
+ return (None, name, user.username) if user else (email, name, None)
+
+def get_contributions(git_repo, tip, since):
+ contributions = defaultdict(lambda: {
+ "commits": 0,
+ "weekly": defaultdict(lambda: 0)
+ })
+
+ since_ts = since.timestamp()
+ for commit in git_repo.walk(tip.id, pygit2.GIT_SORT_TIME):
+ timestamp = commit.commit_time + commit.commit_time_offset
+ if timestamp < since_ts:
+ break
+
+ week = _week(datetime.fromtimestamp(timestamp))
+ user = _user(commit.author.email, commit.author.name)
+ contributions[user]['commits'] += 1
+ contributions[user]['weekly'][week] += 1
+
+ return contributions
+
+def get_contrib_chart_data(contributions):
+ # Max number of commits by a contributor in a single week
+ max_commits = max(
+ max(commits for _, commits in data['weekly'].items())
+ for _, data in contributions.items())
+
+ all_weeks = [_week(date.today() - timedelta(weeks=51 - n))
+ for n in range(52)]
+
+ def bars(contributions):
+ bars = list()
+ for ordinal, week in enumerate(all_weeks):
+ if week in contributions:
+ week_commits = contributions[week]
+ bars.append({
+ "ordinal": ordinal,
+ "week": week,
+ "commits": week_commits,
+ "height": 100 * week_commits // max_commits
+ })
+ return bars
+
+ chart_data = [
+ (email, full_name, username, data['commits'], bars(data['weekly']))
+ for (email, full_name, username), data in contributions.items()]
+ return sorted(chart_data, key=lambda x: x[3], reverse=True)
+
+@stats.route("/<owner>/<repo>/contributors")
+def contributors(owner, repo):
+ owner, repo = get_repo_or_redir(owner, repo)
+ since = datetime.now() - timedelta(weeks=52)
+
+ with GitRepository(repo.path) as git_repo:
+ default_branch = git_repo.default_branch()
+ tip = git_repo.get(default_branch.target)
+ contributions = get_contributions(git_repo, tip, since)
+ chart_data = get_contrib_chart_data(contributions)
+
+ return render_template("contributors.html", view="contributors",
+ owner=owner, repo=repo, chart_data=chart_data)
diff --git a/gitsrht/repos.py b/gitsrht/repos.py
index 8e617e2..2749e10 100644
--- a/gitsrht/repos.py
+++ b/gitsrht/repos.py
@@ -1,7 +1,9 @@
import subprocess
+from flask import redirect, abort, url_for
+from gitsrht.access import get_repo, has_access, UserAccess
+from gitsrht.types import User, Repository, RepoVisibility, Redirect
from srht.database import db
from srht.config import cfg
-from gitsrht.types import Repository, RepoVisibility, Redirect
import shutil
import re
import os
@@ -94,3 +96,20 @@ def delete_repo(repo):
pass
db.session.delete(repo)
db.session.commit()
+
+def get_repo_or_redir(owner, repo):
+ owner, repo = get_repo(owner, repo)
+ if not repo:
+ abort(404)
+ if not has_access(repo, UserAccess.read):
+ abort(401)
+ if isinstance(repo, Redirect):
+ view_args = request.view_args
+ if not "repo" in view_args or not "owner" in view_args:
+ return redirect(url_for(".summary",
+ owner=repo.new_repo.owner.canonical_name,
+ repo=repo.new_repo.name))
+ view_args["owner"] = repo.new_repo.owner.canonical_name
+ view_args["repo"] = repo.new_repo.name
+ abort(redirect(url_for(request.endpoint, **view_args)))
+ return owner, repo
diff --git a/gitsrht/templates/contributors.html b/gitsrht/templates/contributors.html
index 4d0d43d..be71d93 100644
--- a/gitsrht/templates/contributors.html
+++ b/gitsrht/templates/contributors.html
@@ -10,17 +10,19 @@
{% block head %}
<style type="text/css">
svg { background-color: WhiteSmoke }
- rect { fill: #007bff }
+ rect { fill: #116bdd }
rect:hover { fill: #dc3545 }
</style>
{% endblock %}
{% block content %}
<div class="container">
- <p>Contributions in the last 52 weeks</p>
-
+ <p>
+ Contributions to {{repo.owner.canonical_name}}/{{repo.name}}
+ in the last 52 weeks:
+ </p>
<div class="row">
- {% for email, username, commits, bars in chart_data %}
+ {% for email, full_name, username, commits, bars in chart_data %}
<div class="col-md-6">
<h3>
{% if username %}
@@ -28,8 +30,9 @@
~{{ username }}
</a>
{% else %}
- {{ email }}
+ {{ full_name }}
{% endif %}
+ <small>{{ commits }} commits</small>
</h3>
<svg
@@ -42,15 +45,15 @@
<rect
x="{{ bar.ordinal * 10 }}"
y="{{ 100 - bar.height }}%"
- width="10"
+ width="11"
height="{{ bar.height }}%"
>
- <title>{{ bar.commits }} commits in week {{ bar.week }}</title>
+ <title>
+ {{ bar.commits }} commits in the week of {{ bar.week }}
+ </title>
</rect>
{% endfor %}
</svg>
-
- <p>Commits: {{ commits }}</p>
</div>
{% endfor %}
</div>
diff --git a/gitsrht/templates/repo.html b/gitsrht/templates/repo.html
index c0cba9d..1d1fbde 100644
--- a/gitsrht/templates/repo.html
+++ b/gitsrht/templates/repo.html
@@ -36,7 +36,7 @@
repo=repo.name), "refs")}}
</li>
<li class="nav-item">
- {{link(url_for("repo.contributors",
+ {{link(url_for("stats.contributors",
owner=repo.owner.canonical_name,
repo=repo.name), "contributors")}}
</li>
diff --git a/setup.py b/setup.py
index 4c61272..0bf0a27 100755
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python3
from setuptools import setup
import subprocess
-import glob
import os
import site
import sys