~edwargix/git.sr.ht

9bddf293d9ee1f5ab9430590778f3d277dbac8e7 — Drew DeVault 8 years ago bf7b4d0
Add user repo list
7 files changed, 112 insertions(+), 31 deletions(-)

M git/app.py
D git/blueprints/cgit.py
M git/blueprints/manage.py
A git/blueprints/public.py
M git/types/repository.py
M templates/manage.html
A templates/user.html
M git/app.py => git/app.py +2 -2
@@ 34,11 34,11 @@ def oauth_url(return_to):
        urllib.parse.quote_plus(return_to))

from git.blueprints.auth import auth
from git.blueprints.cgit import cgit
from git.blueprints.public import public
from git.blueprints.manage import manage

app.register_blueprint(auth)
app.register_blueprint(cgit)
app.register_blueprint(public)
app.register_blueprint(manage)

@app.context_processor

D git/blueprints/cgit.py => git/blueprints/cgit.py +0 -23
@@ 1,23 0,0 @@
from flask import Blueprint, Response, request, render_template
import requests
from srht.config import cfg

cgit = Blueprint('cgit', __name__)

upstream = cfg("cgit", "remote")

@cgit.route("/~<user>/<repo>", defaults={ "cgit_path": "" })
@cgit.route("/~<user>/<repo>/", defaults={ "cgit_path": "" })
@cgit.route("/~<user>/<repo>/<path:cgit_path>")
def cgit_passthrough(user, repo, cgit_path):
    r = requests.get("{}/{}".format(upstream, request.full_path))
    return render_template("cgit.html",
            cgit_html=r.text,
            owner_name="~" + user,
            repo_name=repo)

@cgit.route("/~<user>/<repo>/patch")
@cgit.route("/~<user>/<repo>/patch/")
def cgit_plain(user, repo):
    r = requests.get("{}/{}".format(upstream, request.full_path))
    return Response(r.text, mimetype="text/plain")

M git/blueprints/manage.py => git/blueprints/manage.py +7 -5
@@ 16,7 16,7 @@ repos_path = cfg("cgit", "repos")
@loginrequired
def index():
    repos = Repository.query.filter(Repository.owner_id == current_user.id)\
            .order_by(Repository.updated).all()
            .order_by(Repository.updated.desc()).all()
    return render_template("manage.html", repos=repos)

@manage.route("/manage/create", methods=["POST"])


@@ 26,13 26,12 @@ def create():
    repo_name = valid.require("repo-name", friendly_name="Name")
    valid.expect(not repo_name or re.match(r'^[a-z._-][a-z0-9._-]*$', repo_name),
            "Name must match [a-z._-][a-z0-9._-]*", field="repo-name")
    description = valid.optional("repo-description")
    visibility = valid.require("repo-visibility", friendly_name="Visibility")
    valid.expect(not visibility or visibility in [m[0] for m in RepoVisibility.__members__.items()],
            "Expected one of public, private, unlisted for visibility", field="repo-visibility")

    repos = Repository.query.filter(Repository.owner_id == current_user.id)\
            .order_by(Repository.updated).all()

            .order_by(Repository.updated.desc()).all()
    valid.expect(not repo_name or not repo_name in [r.name for r in repos],
            "This name is already in use.", field="repo-name")



@@ 40,10 39,13 @@ def create():
        return render_template("manage.html",
                valid=valid,
                repos=repos,
                repo_name=repo_name)
                repo_name=repo_name,
                repo_description=description,
                visibility=visibility)

    repo = Repository()
    repo.name = repo_name
    repo.description = description
    repo.owner_id = current_user.id
    repo.visibility = RepoVisibility[visibility]
    db.session.add(repo)

A git/blueprints/public.py => git/blueprints/public.py +43 -0
@@ 0,0 1,43 @@
from flask import Blueprint, Response, request, render_template
import requests
from srht.config import cfg
from git.types import User, Repository, RepoVisibility

public = Blueprint('cgit', __name__)

upstream = cfg("cgit", "remote")
meta_uri = cfg("network", "meta")

@public.route("/~<user>/<repo>", defaults={ "cgit_path": "" })
@public.route("/~<user>/<repo>/", defaults={ "cgit_path": "" })
@public.route("/~<user>/<repo>/<path:cgit_path>")
def cgit_passthrough(user, repo, cgit_path):
    r = requests.get("{}/{}".format(upstream, request.full_path))
    return render_template("cgit.html",
            cgit_html=r.text,
            owner_name="~" + user,
            repo_name=repo)

@public.route("/~<user>/<repo>/patch")
@public.route("/~<user>/<repo>/patch/")
def cgit_plain(user, repo):
    r = requests.get("{}/{}".format(upstream, request.full_path))
    return Response(r.text, mimetype="text/plain")

@public.route("/~<username>")
def user_index(username):
    user = User.query.filter(User.username == username).first()
    if not user:
        abort(404)
    repos = Repository.query\
            .filter(Repository.owner_id == user.id)\
            .filter(Repository.visibility == RepoVisibility.public)\
            .order_by(Repository.updated.desc()).all()
    r = requests.get(meta_uri + "/api/user/profile", headers={
        "Authorization": "token " + user.oauth_token
    }) # TODO: cache
    if r.status_code == 200:
        profile = r.json()
    else:
        profile = None
    return render_template("user.html", user=user, repos=repos, profile=profile)

M git/types/repository.py => git/types/repository.py +1 -0
@@ 14,6 14,7 @@ class Repository(Base):
    created = sa.Column(sa.DateTime, nullable=False)
    updated = sa.Column(sa.DateTime, nullable=False)
    name = sa.Column(sa.Unicode(256), nullable=False)
    description = sa.Column(sa.Unicode(1024))
    owner_id = sa.Column(sa.Integer, sa.ForeignKey('user.id'), nullable=False)
    owner = sa.orm.relationship('User', backref=sa.orm.backref('repos'))
    visibility = sa.Column(

M templates/manage.html => templates/manage.html +17 -1
@@ 13,6 13,12 @@
            </a>
          </dt>
          <dd>
            {% if not repo.description %}
            <em>This repository has no description</em>
            {% else %}
            {{ repo.description }}
            {% endif %}
            <br />
            <a href="#">Edit details</a>
            &mdash;
            <a href="#">Manage collaborators</a>


@@ 25,7 31,7 @@
      <h3>Create new repository</h3>
      <form method="POST" action="/manage/create">
        <div class="form-group {{valid.cls("repo-name")}}">
          <label for="client-name">Name</label>
          <label for="repo-name">Name</label>
          <input
            type="text"
            name="repo-name"


@@ 34,6 40,16 @@
            value="{{ repo_name or "" }}" />
          {{valid.summary("repo-name")}}
        </div>
        <div class="form-group {{valid.cls("repo-description")}}">
          <label for="repo-description">Description</label>
          <input
            type="text"
            name="repo-description"
            id="repo-description"
            class="form-control"
            value="{{ repo_description or "" }}" />
          {{valid.summary("repo-description")}}
        </div>
        <fieldset class="form-group">
          <legend>Visibility</legend>
          <div class="form-check form-check-inline">

A templates/user.html => templates/user.html +42 -0
@@ 0,0 1,42 @@
{% extends "git.html" %}
{% block content %}
<div class="container">
  <div class="row">
    <section class="col-md-4">
      <h2>~{{ user.username }}</h2>
      {% if profile.get("location") %}
      <p>{{profile["location"]}}</p>
      {% endif %}
      {% if profile.get("url") %}
      <p>
        <a href="{{profile["url"]}}" target="_blank">
          {{profile["url"]}}
        </a>
      </p>
      {% endif %}
      {% if profile.get("bio") %}
      <p>{{profile["bio"]}}</p>
      {% endif %}
    </section>
    <section class="col-md-8">
      {% if len(repos) == 0 %}
      <p>This user has no repositories.</p>
      {% else %}
      {% for repo in repos %}
        <h4>
          <a href="/~{{current_user.username}}/{{repo.name}}">
            ~{{current_user.username}}/{{repo.name}}
          </a>
        </h4>
        {% if not repo.description %}
        <em>This repository has no description</em>
        {% else %}
        {{ repo.description }}
        {% endif %}
        <p><em>Last updated {{ repo.updated | date }}</em></p>
      {% endfor %}
      {% endif %}
    </section>
  </div>
</div>
{% endblock %}