Add page listing source repos for project

This commit is contained in:
Drew DeVault 2020-03-24 12:11:20 -04:00
parent f8a9b84bc5
commit 2aedc53e7f
6 changed files with 127 additions and 54 deletions

View File

@ -4,6 +4,7 @@ from hubsrht.services import git
from hubsrht.types import Project, RepoType, SourceRepo, Visibility
from srht.config import get_origin
from srht.database import db
from srht.flask import paginate_query
from srht.oauth import current_user, loginrequired
from srht.validation import Validation
@ -11,7 +12,7 @@ projects = Blueprint("projects", __name__)
origin = get_origin("hub.sr.ht")
@projects.route("/<owner>/<project_name>")
def project_GET(owner, project_name):
def summary_GET(owner, project_name):
owner, project = get_project(owner, project_name, ProjectAccess.read)
summary = None
@ -55,13 +56,24 @@ def create_POST():
db.session.add(project)
db.session.commit()
return redirect(url_for("projects.project_GET",
return redirect(url_for("projects.summary_GET",
owner=current_user.canonical_name,
project_name=project.name))
@projects.route("/<owner>/<project_name>/sources")
@loginrequired
def sources_GET(owner, project_name):
owner, project = get_project(owner, project_name, ProjectAccess.read)
sources = (SourceRepo.query
.filter(SourceRepo.project_id == project.id)
.order_by(SourceRepo.updated.desc()))
sources, pagination = paginate_query(sources)
return render_template("project-sources.html", view="sources",
owner=owner, project=project, sources=sources, **pagination)
@projects.route("/<owner>/<project_name>/sources/new")
@loginrequired
def project_sources_new_GET(owner, project_name):
def sources_new_GET(owner, project_name):
# TODO: Redirect appropriately if this instance only has git or hg support
owner, project = get_project(owner, project_name, ProjectAccess.write)
return render_template("project-sources-new.html", view="new-resource",
@ -69,20 +81,20 @@ def project_sources_new_GET(owner, project_name):
@projects.route("/<owner>/<project_name>/sources/new", methods=["POST"])
@loginrequired
def project_sources_new_POST(owner, project_name):
def sources_new_POST(owner, project_name):
owner, project = get_project(owner, project_name, ProjectAccess.write)
valid = Validation(request)
if "git" in valid:
return redirect(url_for("projects.project_git_new_GET",
return redirect(url_for("projects.sources_git_new_GET",
owner=owner.canonical_name, project_name=project.name))
if "hg" in valid:
# TODO: Hg repos
return redirect(url_for("projects.project_hg_new_GET",
return redirect(url_for("projects.sources_hg_new_GET",
owner=owner.canonical_name, project_name=project.name))
@projects.route("/<owner>/<project_name>/git/new")
@loginrequired
def project_git_new_GET(owner, project_name):
def sources_git_new_GET(owner, project_name):
owner, project = get_project(owner, project_name, ProjectAccess.write)
# TODO: Pagination
repos = git.get_repos(owner)
@ -94,7 +106,7 @@ def project_git_new_GET(owner, project_name):
@projects.route("/<owner>/<project_name>/git/new", methods=["POST"])
@loginrequired
def project_git_new_POST(owner, project_name):
def sources_git_new_POST(owner, project_name):
owner, project = get_project(owner, project_name, ProjectAccess.write)
valid = Validation(request)
if "create" in valid:
@ -134,13 +146,13 @@ def project_git_new_POST(owner, project_name):
db.session.commit()
return redirect(url_for("projects.project_GET",
return redirect(url_for("projects.summary_GET",
owner=owner.canonical_name, project_name=project.name))
@projects.route("/<owner>/<project_name>/sources/set-summary/<int:repo_id>",
methods=["POST"])
@loginrequired
def project_set_summary_repo(owner, project_name, repo_id):
def set_summary_repo(owner, project_name, repo_id):
owner, project = get_project(owner, project_name, ProjectAccess.write)
repo = (SourceRepo.query
.filter(SourceRepo.id == repo_id)
@ -149,5 +161,5 @@ def project_set_summary_repo(owner, project_name, repo_id):
abort(404)
project.summary_repo_id = repo.id
db.session.commit()
return redirect(url_for("projects.project_GET",
return redirect(url_for("projects.summary_GET",
owner=owner.canonical_name, project_name=project.name))

View File

@ -0,0 +1,46 @@
<h2>
<a
href="{{url_for("users.user_summary_GET", username=owner.username)}}"
>{{owner.canonical_name}}</a>/{{project.name}}
</h2>
{% macro link(path, title, alternates, cls="") %}
<a
class="nav-link {% if view == title or view in alternates %}active{% endif %} {{cls}}"
href="{{ path }}">{{ title }}</a>
{% endmacro %}
<ul class="nav nav-tabs">
<li class="nav-item">
{{link(url_for("projects.summary_GET",
owner=owner.canonical_name,
project_name=project.name), "summary")}}
</li>
{% if any(project.source_repos) %}
<li class="nav-item">
{{link(url_for("projects.sources_GET",
owner=owner.canonical_name,
project_name=project.name), "sources")}}
</li>
{% endif %}
{# TODO
<li class="nav-item">
<a
class="nav-link" href="#"
>website&nbsp;{{icon('external-link-alt')}}</a>
</li>
<li class="nav-item">
{{link("#", "documentation")}}
</li>
<li class="nav-item">
{{link("#", "mailing lists")}}
</li>
<li class="nav-item">
{{link("#", "tickets")}}
</li>
#}
{% if view == "summary" and current_user and current_user.id == owner.id %}
<li class="flex-grow-1"></li>
<li class="nav-item">
{{link("#", "add +", cls="btn-primary")}}
</li>
{% endif %}
</ul>

View File

@ -16,7 +16,7 @@
<li class="nav-item">
<a
class="nav-link"
href="{{url_for("projects.project_GET",
href="{{url_for("projects.summary_GET",
owner=owner.canonical_name, project_name=project.name)}}"
>{{icon('caret-left')}}&nbsp;back</a>
</li>

View File

@ -0,0 +1,46 @@
{% extends "layout.html" %}
{% block body %}
<div class="header-tabbed">
<div class="container">
{% include 'project-nav.html' %}
</div>
</div>
{% if project.description %}
<div class="header-extension">
<div class="container">
{{ project.description }}
</div>
</div>
{% endif %}
<div class="container">
<div class="row">
<div class="col-md-10 event-list">
{% for repo in sources %}
<div class="event">
<h4>
<a href="{{repo.url()}}">~{{owner.username}}/{{repo.name}}</a>
<small class="pull-right">
{{ repo.repo_type.value }}
</small>
</h4>
{% if repo.description %}
<p>{{ repo.description }}</p>
{% endif %}
</div>
{% endfor %}
{{pagination()}}
</div>
{% if current_user and current_user.id == owner.id %}
<div class="col-md-2">
<a
href="{{url_for("projects.sources_new_GET",
owner=owner.canonical_name, project_name=project.name)}}"
class="btn btn-primary btn-block"
>
Add repository&nbsp;{{icon('caret-right')}}
</a>
</div>
{% endif %}
</div>
</div>
{% endblock %}

View File

@ -2,46 +2,7 @@
{% block body %}
<div class="header-tabbed">
<div class="container">
<h2>
<a
href="{{url_for("users.user_summary_GET", username=owner.username)}}"
>{{owner.canonical_name}}</a>/{{project.name}}
</h2>
{% macro link(path, title, alternates, cls="") %}
<a
class="nav-link {% if view == title or view in alternates %}active{% endif %} {{cls}}"
href="{{ path }}">{{ title }}</a>
{% endmacro %}
<ul class="nav nav-tabs">
<li class="nav-item">
{{link("#", "summary")}}
</li>
{% if any(project.source_repos) %}
<li class="nav-item">
{{link("#", "sources")}}
</li>
{% endif %}
{# TODO
<li class="nav-item">
<a
class="nav-link" href="#"
>website&nbsp;{{icon('external-link-alt')}}</a>
</li>
<li class="nav-item">
{{link("#", "documentation")}}
</li>
<li class="nav-item">
{{link("#", "mailing lists")}}
</li>
<li class="nav-item">
{{link("#", "tickets")}}
</li>
#}
<li class="flex-grow-1"></li>
<li class="nav-item">
{{link("#", "add +", cls="btn-primary")}}
</li>
</ul>
{% include 'project-nav.html' %}
</div>
</div>
{% if project.description %}
@ -74,7 +35,7 @@
{% else %}
{{icon('plus-square', cls='text-info')}}
<a
href="{{url_for("projects.project_sources_new_GET",
href="{{url_for("projects.sources_new_GET",
owner=owner.canonical_name, project_name=project.name)}}"
>Add source code repositories&nbsp;{{icon('arrow-right')}}</a>
<br />
@ -165,7 +126,7 @@
<form
class="event"
method="POST"
action="{{url_for("projects.project_set_summary_repo",
action="{{url_for("projects.set_summary_repo",
owner=project.owner.canonical_name,
project_name=project.name,
repo_id=repo.id)}}"

View File

@ -1,8 +1,12 @@
import sqlalchemy as sa
import sqlalchemy_utils as sau
from enum import Enum
from srht.config import get_origin
from srht.database import Base
_gitsrht = get_origin("git.sr.ht", external=True, default=None)
_hgsrht = get_origin("git.sr.ht", external=True, default=None)
class RepoType(Enum):
git = "git"
hg = "hg"
@ -29,3 +33,7 @@ class SourceRepo(Base):
description = sa.Column(sa.Unicode(512), nullable=False)
repo_type = sa.Column(sau.ChoiceType(RepoType, impl=sa.String()),
nullable=False)
def url(self):
origin = _gitsrht if self.repo_type == RepoType.git else _hgsrht
return f"{origin}/{self.owner.canonical_name}/{self.name}"