name='RepositoryPermission',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('userid', models.CharField(max_length=255)),
+ ('userid', models.CharField(max_length=255, verbose_name="User id")),
('level', models.IntegerField(default=0, verbose_name='Permission', choices=[(0, 'Read'), (1, 'Write'), (2, 'Owner')])),
('repository', models.ForeignKey(to='adm.Repository', db_column='repository')),
],
verbose_name='Remote repository')
def ValidateOwnerPermissions(self, user):
- if self.repositorypermission_set.filter(userid=user.username, level=2).count() != 1:
+ if not self.repositorypermission_set.filter(userid=user.username, level=2).exists():
raise Exception('You need owner permissions to do that!')
def __str__(self):
class RepositoryPermission(models.Model):
repository = models.ForeignKey(Repository, db_column='repository')
- userid = models.CharField(max_length=255, blank=False)
+ userid = models.CharField(max_length=255, blank=False, verbose_name="User id")
level = models.IntegerField(default=0, verbose_name='Permission', choices=PERMISSION_CHOICES)
@property
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" dir="ltr">
- <head>
- <title>PostgreSQL Git Repository</title>
- <meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8" />
- <link rel="shortcut icon" href="/favicon.ico" />
- <style type="text/css" media="screen" title="Normal Text">@import url("/pgstatic/pggit.css");</style>
- <script language="javascript" src="/pgstatic/pggit.js"></script>
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
+
+ <link rel="stylesheet" href="/pgstatic/pggit.css">
</head>
<body>
- <div id="pggitWrap">
- <div id="pggitHeader">
- <div class="fl"><img src="https://www.postgresql.org/layout/images/hdr_left.png" alt="PostgreSQL" /></div>
- <div class="fr"><img width="210" height="80" src="https://www.postgresql.org/layout/images/hdr_right.png" alt="The world's most advanced open source database" /></div>
- <div class="cb"></div>
- </div> <!-- pggitHeader -->
- <div id="pggitMain">
-{%if user.is_authenticated %}
-<div style="float:right;"><a href="/adm/logout">Log out</a></div>
-{%endif%}
+ <div class="container">
+ <div class="row justify-content-md-center">
+ <div class="col">
+ <nav class="navbar fixed-top navbar-dark bg-dark navbar-expand-lg">
+ <a class="navbar-brand" href="/adm/">Git Administration</a>
+ <div class="collapse navbar-collapse" id="pgNavbar">
+ <ul class="navbar-nav">
+{%block headlinks%}{%endblock%}
+ </ul>
+ </div> <!-- pgNavBar -->
+ </nav>
+ </div> <!-- col -->
+ </div> <!-- row -->
+ <div class="row">
+ <div class="col-md-12">
{%if missing_sshkey %}
-<p><b>Note!</b> Your ssh key has not yet been registered with the system, or it has not yet replicated
-from the main server. Please upload your keys using the
-<a href="https://www.postgresql.org/account/">community account system</a>.</p>
+ <div class="alert alert-danger">Your ssh key has not yet been registered with the system,
+or it has not yet replicated from the main server. Please upload your keys using the
+<a href="https://www.postgresql.org/account/">community account system</a>.
+ </div>
+{%endif%}
+{%block content%}{%endblock%}
+ </div>
+ </div>
+ <div class="row mt-4 mb-2">
+ <div class="col-md-12">
+ <a href="/adm/logout/" class="btn btn-secondary mr-3">Log out</a>
+{%if user.is_superuser %}
+ <a href="/adm/admin/" class="btn btn-secondary mr-3">Django Admin</a>
{%endif%}
-{% block content %} {% endblock %}
- </div> <!-- pggitMain -->
- </div> <!-- pggitWrap -->
+ </div>
+ </div>
+ </div> <!-- container-fluid -->
+
+ <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
+ <script language="javascript" src="/pgstatic/pggit.js"></script>
</body>
</html>
<p>Are you <b>sure</b> you want to delete this repository? The repository contents will also be deleted!</p>
<form method="POST" action=".">
-<table class="leftalign">
-{{form}}
-</table>
-<input type="submit" value="Delete">
+{% csrf_token %}
+{%for field in form%}
+{%include "form_field.html"%}
+{%endfor%}
+<input type="submit" value="Delete" class="btn btn-danger">
</form>
-<a href="..">Back</a>
+<a class="btn btn-primary mt-2" href="..">Back</a>
{%endblock%}
--- /dev/null
+{%load formutil%}
+{%if not field.is_hidden%}
+<div class="form-group row">
+ {{field|label_class:"col-sm-3 col-form-label"}}
+ <div class="col-sm-9">
+ {%if field.errors %}
+ {%for e in field.errors%}
+ <div class="alert alert-danger">{{e}}</div>
+ {%endfor%}
+ {%endif%}
+{%if field|ischeckbox%}
+ <div class="form-check">{{field|field_class:"form-check-input"}}</div>
+{%else%}
+{{field|field_class:"form-control"}}
+{%endif%}
+{%if field.help_text%}<small class="form-text text-muted">{{field.help_text|safe}}</small>{%endif%}
+ </div>
+</div>
+ {%else%}{# field.is_hidden #}
+{{field}}
+ {%endif%}
{%extends "base.html"%}
{%block content%}
<p>You have access to the following git repositories:</p>
-<table border="1" cellspacing="0" cellpadding="1">
+<table class="table table-striped table-hover table-sm">
<tr>
<th>Name</th>
<th>Description</th>
- <th>gitweb</th>
- <th>gitserve</th>
+ <th>Gitweb</th>
+ <th>Git</th>
<th>Approved</th>
</tr>
{% for r in repos %}
<tr>
<td>{%if r.perm %}<a href="repo/{{r.repoid}}/">{{r.name}}</a>{%else%}{{r.name}}{%endif%}</td>
<td>{{r.description}}</td>
- <td>{%if r.web %}<a href="/gitweb?p={{r.name}}.git;a=summary">url</a>{%endif%}</td>
- <td>{%if r.anonymous %}<a href="git://git.postgresql.org/git/{{r.name}}">url</a>{%endif%}</td>
- <td>{{r.approved|yesno:"Yes,No"}}</td>
+ <td class="text-center">{%if r.web %}<a class="btn btn-primary btn-sm" href="/gitweb?p={{r.name}}.git;a=summary">Gitweb</a>{%else%}<span class="badge badge-secondary">Disabled</span>{%endif%}</td>
+ <td class="text-center">
+ <a class="badge badge-primary" href="ssh://git@git.postgresql.org/{{r.name}}.git" title="ssh://git@git.postgresql.org/{{r.name}},git">ssh</a>
+ {%if r.anonymous %}<br/><a class="badge badge-info" href="https://git.postgresql.org/git/{{r.name}}.git">http</a>{%endif%}
+ </td>
+ <td class="text-center"><span class="badge badge-{{r.approved|yesno:"primary,danger"}}">{{r.approved|yesno:"Yes,No"}}</span></td>
</tr>
{% endfor %}
</table>
<p>To request a new project, enter a name here. The name has to be 5-64 characters long and contain only lowercase
letters and numbers.</p>
-<form method="post" action="new/">
-<input type="text" name="reponame" maxlength="64">
-<input type="submit" value="Request new repository">
+<form class="form-inline" method="post" action="new/">
+ <input type="text" class="form-control mr-sm-2" name="reponame" maxlength="64" placeholder="Enter name of repository" required="true">
+ <input type="submit" class="btn btn-primary" value="Request new repository">
</form>
{%endblock%}
{%extends "base.html"%}
{%block content%}
-<h2>Repository: {{repo.name}}</h2>
+<h1>Repository: {{repo.name}}</h1>
{% if not repo.approved %}
-<p><strong>This repository has not yet been approved.</strong> This means you cannot access it through git or web yet.
+<h2>This repository has not yet been approved.</h2>
+<p>
+This means you cannot access it through git or web yet.
You can still update the description and set permissions - they will all start working automatically
when the repository is approved. Until approval you can also set it up to clone another repository
-automatically upon creation.</p>
+automatically upon creation.
+</p>
{%endif%}
{% if form_saved_at %}
<p>Your changes were successfully saved at {{form_saved_at|date:"Y-m-d H:i:s"}}.</p>
<p><b>Error:</b> The submitted form contains errors and could not be saved.</p>
{%endif%}
<form method="POST" action=".">
-<table class="leftalign">
-{{form}}
-</table>
-<p><a href="delete/">Delete this repository</a></p>
+{% csrf_token %}
+{%if form.non_field_errors%}
+ <div class="alert alert-danger">{{form.non_field_errors}}</div>
+{%endif%}
+{%for field in form%}
+{%include "form_field.html"%}
+{%endfor%}
<h3>Permissions</h3>
{{formset.management_form}}
-<table border="0" cellspacing="0" cellpadding="1">
-{% for f in formset.forms %}
+
+<table class="table table-striped table-sm">
+{% for form in formset.forms %}
<tr>
- <td class="rowform">
- {{f.as_p}}
- </td>
+ {%for field in form %}
+ <td>{%include "form_field.html"%}</td>
+ {%endfor%}
</tr>
{% endfor %}
</table>
-<input type="submit" value="Save">
+<input type="submit" value="Save" class="btn btn-primary mb-2">
</form>
-<a href="../..">Back</a>
+
+<a class="btn btn-warning mr-2" href="delete/">Delete this repository</a>
+<a class="btn btn-secondary" href="../..">Back</a>
{%endblock%}
--- /dev/null
+from django.template.defaultfilters import stringfilter
+from django import template
+
+register = template.Library()
+
+
+@register.filter(name='alertmap')
+@stringfilter
+def alertmap(value):
+ if value == 'error':
+ return 'alert-danger'
+ elif value == 'warning':
+ return 'alert-warning'
+ elif value == 'success':
+ return 'alert-success'
+ else:
+ return 'alert-info'
--- /dev/null
+from django import template
+
+register = template.Library()
+
+
+@register.filter(is_safe=True)
+def label_class(value, arg):
+ return value.label_tag(attrs={'class': arg})
+
+
+@register.filter(is_safe=True)
+def field_class(value, arg):
+ prevclass = value.field.widget.attrs.get('class', '')
+ if prevclass:
+ newclass = "{0} {1}".format(arg, prevclass)
+ else:
+ newclass = arg
+ return value.as_widget(attrs={"class": newclass})
+
+@register.filter(is_safe=True)
+def ischeckbox(obj):
+ return obj.field.widget.__class__.__name__ in ("CheckboxInput", "CheckboxSelectMultiple") and not getattr(obj.field, 'regular_field', False)
def editrepo(request, repoid):
repo = get_object_or_404(Repository, repoid=repoid)
repo.ValidateOwnerPermissions(request.user)
- savedat = None
form = None
formfactory = inlineformset_factory(Repository, RepositoryPermission, extra=1, fields=['userid', 'level'])
form.save()
formset.save()
- savedat = datetime.datetime.now()
- # Get a new copy of the repository to make sure it refreshes!
- repo = get_object_or_404(Repository, repoid=repoid)
+ return HttpResponseRedirect("../../")
except FormIsNotValid:
# Just continue as if the form wasn't valid, expect the caller
# to have set the required error fields
'formset': formset,
'repo': repo,
'repoperm': perm,
- 'form_saved_at': savedat,
})
body {
- font-family: verdana, sans-serif;
- color: #000000;
- background-color: #ffffff;
- margin: 0 0 0 0;
- padding: 0 0 0 0;
- font-size: 13px;
-}
-
-div#pggitHeader {
- width: 100%;
- background: url(https://www.postgresql.org/layout/images/hdr_fill.png);
- padding: 0 0 0 0;
- height: 80px;
- margin: 5px 0 2px 0;
-}
-
-div#pggitWrap {
- margin-left: 20px;
- margin-right: 20px;
-}
-
-div#pggitWrap img {
- /* applies to all images */
- border: none;
-}
-
-div#pggitMain {
- width: 100%;
-}
-
-div.fl { float: left; border: none; text-align: left; }
-div.fr { float: right; }
-div.cb { clear: both; }
-div.cl { clear: left; }
-
-a:link { color:#0085B0; text-decoration: underline; }
-a:visited { color:#004E66; text-decoration: underline; }
-a:active { color:#0085B0; text-decoration: underline; }
-a:hover { color:#000000; text-decoration: underline; }
-
+ padding-top: 4rem;
-td.rowform p {
- display: inline;
- padding-right: 20px;
+ font-weight: 400;
+ color: #515151;
+ font-size: 11.5pt;
}
-table.leftalign tr th {
- text-align: left;
+.table-nonfluid {
+ width: auto !important;
}