src/templates/package-detail-list.html \
src/templates/package-properties.html \
src/templates/queue.html \
- src/templates/repository-edit.html \
src/templates/search.html \
src/templates/source-list.html \
src/templates/updates-index.html \
dist_templates_repos_DATA = \
src/templates/repos/builds.html \
+ src/templates/repos/edit.html \
src/templates/repos/show.html
templates_reposdir = $(templatesdir)/repos
owner = property(get_owner, set_owner)
+ def has_perm(self, user):
+ """
+ Returns True if the user has permission to manage this repository
+ """
+ # Admins can edit anything
+ if user.is_admin():
+ return True
+
+ # If the user owns this repository, they may edit it
+ if self.owner == user:
+ return True
+
+ # Nope
+ return False
+
# Slug
@property
return "\n".join(lines)
- @property
- def name(self):
+ # Name
+
+ def get_name(self):
return self.data.name
+ def set_name(self, name):
+ self._set_attribute("name", name)
+
+ name = property(get_name, set_name)
+
@property
def summary(self):
lines = self.description.splitlines()
return "N/A"
- @property
- def description(self):
+ # Description
+
+ def get_description(self):
return self.data.description
+ def set_description(self, description):
+ self._set_attribute("description", description or "")
+
+ description = property(get_description, set_description)
+
@property
def parent_id(self):
return self.data.parent_id
mirrored = property(get_mirrored, set_mirrored)
+ # Listed
+
+ def get_listed(self):
+ return self.data.listed
+
+ def set_listed(self, listed):
+ self._set_attribute("listed", listed)
+
+ listed = property(get_listed, set_listed)
+
def _log_build(self, action, build, from_repo=None, to_repo=None, user=None):
user_id = None
if user:
--- /dev/null
+{% extends "../base.html" %}
+
+{% block title %}{{ _("Repositories") }} - {{ repo }} - {{ _("Edit") }}{% end block %}
+
+{% block container %}
+ <nav aria-label="{{ _("You are here:") }}" role="navigation">
+ <ul class="breadcrumbs">
+ <li>
+ <a href="/">{{ _("Home") }}</a>
+ </li>
+ {% if repo.owner %}
+ <li>
+ <a href="/users">{{ _("Users") }}</a>
+ </li>
+ <li>
+ <a href="/users/{{ repo.owner.name }}">{{ repo.owner }}</a>
+ </li>
+ {% else %}
+ <li>
+ <a href="/distros">{{ _("Distributions") }}</a>
+ </li>
+ <li>
+ <a href="/distros/{{ repo.distro.slug }}">{{ repo.distro }}</a>
+ </li>
+ {% end %}
+ <li>
+ {{ _("Repositories") }}
+ </li>
+ <li>
+ <a href="{% if repo.owner %}/users/{{ repo.owner.name }}{% else %}/distros/{{ repo.distro.slug }}{% end %}/repos/{{ repo.slug }}">
+ {{ repo }}
+ </a>
+ </li>
+ <li>
+ <span class="show-for-sr">{{ _("Current") }}: </span> {{ _("Edit") }}
+ </li>
+ </ul>
+ </nav>
+
+ <div class="grid-x grid-padding-x">
+ <div class="cell large-6 float-center">
+ <form method="POST" action="">
+ <div class="callout">
+ {% raw xsrf_form_html() %}
+
+ <label>
+ {{ _("Name") }}
+
+ <input type="text" name="name" value="{{ repo.name }}" required>
+ </label>
+
+ <label>
+ {{ _("Description") }}
+
+ <textarea name="description" rows="6" placeholder="{{ _("Description") }}"
+ aria-describedby="description-help">{{ repo.description }}</textarea>
+ </label>
+
+ <p class="help-text" id="description-help">
+ {{ _("Describe what this repository will contain") }}
+ </p>
+
+ <label>
+ {{ _("Priority") }}
+
+ <input type="number" name="priority" value="{{ repo.priority }}"
+ min="0" max="1000">
+ </label>
+
+ {% if repo.owner %}
+ <input id="listed" type="checkbox" name="listed"
+ {% if repo.listed %}checked{% end %} aria-describedby="listed-help">
+
+ <label for="listed">{{ _("Listed") }}</label>
+
+ <p class="help-text" id="listed-help">
+ {{ _("By unchecking this box, you can hide this repository from being listed") }}
+ </p>
+ {% end %}
+
+ {% if current_user.is_admin() %}
+ <input id="mirrored" type="checkbox" name="mirrored"
+ {% if repo.mirrored %}checked{% end %} aria-describedby="mirrored-help">
+
+ <label for="mirrored">{{ _("Enable Mirroring") }}</label>
+
+ <p class="help-text" id="mirrored-help">
+ {{ _("If enabled, this repository will be made available on mirror servers") }}
+ </p>
+ {% end %}
+ </div>
+
+ <button class="success button expanded" type="submit">{{ _("Save") }}</button>
+
+ <a class="small danger button expanded" href="{% if repo.owner %}/users/{{ repo.owner.name }}{% else %}/distros/{{ repo.distro.slug }}{% end %}/repos/{{ repo.slug }}/delete">
+ {{ _("Delete") }}
+ </a>
+ </form>
+ </div>
+ </div>
+{% end block %}
</div>
{% end %}
- <a class="secondary small expanded button" href="{% if repo.owner %}/users/{{ repo.owner.name }}{% else %}/distros/{{ distro.slug }}{% end %}/repos/{{ repo.slug }}.repo">
+ <a class="secondary expanded button" href="{% if repo.owner %}/users/{{ repo.owner.name }}{% else %}/distros/{{ distro.slug }}{% end %}/repos/{{ repo.slug }}.repo">
{{ _("Download Configuration") }}
</a>
+ <a class="warning expanded button" href="{% if repo.owner %}/users/{{ repo.owner.name }}{% else %}/distros/{{ distro.slug }}{% end %}/repos/{{ repo.slug }}/edit">
+ {{ _("Edit") }}
+ </a>
+
<div class="callout">
<h5>{{ _("Statistics") }}</h5>
+++ /dev/null
-{% extends "base.html" %}
-
-{% block title %}{{ _("Edit repository %s") % repo.name }}{% end block %}
-
-{% block body %}
- <h1>
- {{ _("Edit repository %s") % repo.name }}
- <span>- {{ _("Distribution") }}: {{ distro.name }}</span>
- </h1>
-
- <form method="post" action="">
- {% raw xsrf_form_html() %}
- <table class="form form3">
- <tr>
- <td class="col1">{{ _("Name") }}</td>
- <td class="col2">
- <input name="name" type="text" value="{{ repo.name }}" />
- </td>
- <td class="col3">
- {{ _("The name of the repository.") }}
- {{ _("Must only contain of the lowercase characters.") }}
- </td>
- </tr>
- <tr>
- <td class="col1">{{ _("Description") }}</td>
- <td colspan="2">
- <textarea name="description">{{ repo.description }}</textarea>
- </td>
- </tr>
- </table>
- <div style="clear: both;"> </div>
-
- <h2>{{ _("Score settings") }}</h2>
- <p>
- {{ _("These settings configure the automatic score feature.") }}
- {{ _("Builds that gained a certain score are moved to the next repository automatically and removed if the score is too bad.") }}
- </p>
- <table class="form form3">
- <tr>
- <td class="col1">{{ _("Needed score") }}</td>
- <td class="col2">
- <input name="name" type="text" value="{{ repo.score_needed }}" />
- </td>
- <td class="col3">
- {{ _("The score that is needed for builds to automatically be moved into this repository.") }}
- </td>
- </tr>
- <tr>
- <td class="col1">{{ _("Minimum time") }}</td>
- <td class="col2">
- <input name="name" type="text" value="{{ repo.time_min }}" />
- </td>
- <td class="col3">
- {{ _("Every build must stay a minimum time in a repository.") }}
- {{ _("This is to ensure that a package gets tested well.") }}
- {{ _("Enter zero to disable the feature.") }}
- </td>
- </tr>
- <tr>
- <td class="col1">{{ _("Maximum time") }}</td>
- <td class="col2">
- <input name="name" type="text" value="{{ repo.time_max }}" />
- </td>
- <td class="col3">
- {{ _("If a build is more than a certain amount of time in a repository, it will automatically be removed.") }}
- {{ _("This is to ensure that packages are not forgotten to be pushed.") }}
- {{ _("Enter zero to disable the feature.") }}
- </td>
- </tr>
- </table>
- <div style="clear: both;"> </div>
-
- <h2>{{ _("Build settings") }}</h2>
- <table class="form form3">
- <tr>
- <td class="col1">{{ _("Use package for builds?") }}</td>
- <td class="col2">
- <input type="checkbox" name="enabled_for_builds" {%if repo.enabled_for_builds %}checked="checked"{% end %} />
- </td>
- <td class="col3">
- {{ _("Should the package be selected for builds by default?") }}
- {{ _("Use with caution!") }}
- </td>
- </tr>
- </table>
- <div style="clear: both;"> </div>
-
- <table class="form form3">
- <tr>
- <td colspan="3" class="buttons">
- <input type="submit" value="{{ _("Save") }}" />
- </td>
- </tr>
- </table>
- </form>
-{% end block %}
repos.ConfigHandler),
(r"/users/(?P<user_slug>\w+)/repos/(?P<repo_slug>[A-Za-z0-9\-]+)/builds",
repos.BuildsHandler),
+ (r"/users/(?P<user_slug>\w+)/repos/(?P<repo_slug>[A-Za-z0-9\-]+)/edit",
+ repos.EditHandler),
(r"/users/(?P<user_slug>\w+)/repos/(?P<repo_slug>[A-Za-z0-9\-]+)/mirrorlist",
repos.MirrorlistHandler),
(r"/user/(\w+)/impersonate", users.UserImpersonateHandler),
repos.ConfigHandler),
(r"/distros/(?P<distro_slug>[A-Za-z0-9\-\.]+)/repos/(?P<repo_slug>[A-Za-z0-9\-]+)/builds",
repos.BuildsHandler),
+ (r"/distros/(?P<distro_slug>[A-Za-z0-9\-\.]+)/repos/(?P<repo_slug>[A-Za-z0-9\-]+)/edit",
+ repos.EditHandler),
(r"/distros/(?P<distro_slug>[A-Za-z0-9\-\.]+)/repos/(?P<repo_slug>[A-Za-z0-9\-]+)/mirrorlist",
repos.MirrorlistHandler),
- (r"/distro/([A-Za-z0-9\-\.]+)/repo/([A-Za-z0-9\-]+)/edit",
- RepositoryEditHandler),
-
(r"/distro/([A-Za-z0-9\-\.]+)/source/([A-Za-z0-9\-\.]+)",
distributions.DistroSourceDetailHandler),
(r"/distro/([A-Za-z0-9\-\.]+)/source/([A-Za-z0-9\-\.]+)/commits",
# Typed Arguments
+ def get_argument_bool(self, name):
+ arg = self.get_argument(name, default=None)
+
+ return arg == "on"
+
def get_argument_int(self, *args, **kwargs):
arg = self.get_argument(*args, **kwargs)
+ # Return nothing
+ if not arg:
+ return None
+
try:
return int(arg)
except (TypeError, ValueError):
self.render("log.html", log=self.backend.log)
-class RepositoryEditHandler(base.BaseHandler):
- @tornado.web.authenticated
- def get(self, distro, repo):
- distro = self.backend.distros.get_by_slug(distro)
- if not distro:
- raise tornado.web.HTTPError(404)
-
- repo = distro.get_repo(repo)
- if not repo:
- raise tornado.web.HTTPError(404)
-
- # XXX check if user has permissions to do this
-
- self.render("repository-edit.html", distro=distro, repo=repo)
-
-
class RepoActionHandler(base.BaseHandler):
@tornado.web.authenticated
def post(self, type):
self.finish(config)
+class EditHandler(BaseHandler):
+ @tornado.web.authenticated
+ def get(self, **kwargs):
+ # Fetch the repository
+ repo = self._get_repo(**kwargs)
+
+ # Check for permissions
+ if not repo.has_perm(self.current_user):
+ raise tornado.web.HTTPError(403, "%s cannot edit this repository" % self.current_user)
+
+ self.render("repos/edit.html", repo=repo)
+
+ @tornado.web.authenticated
+ def post(self, **kwargs):
+ # Fetch the repository
+ repo = self._get_repo(**kwargs)
+
+ # Check for permissions
+ if not repo.has_perm(self.current_user):
+ raise tornado.web.HTTPError(403, "%s cannot edit this repository" % self.current_user)
+
+ with self.db.transaction():
+ repo.name = self.get_argument("name")
+ repo.description = self.get_argument("description", None)
+ repo.priority = self.get_argument_int("priority", None)
+
+ # Attributes for custom repositories
+ if repo.owner:
+ repo.listed = self.get_argument_bool("listed")
+
+ # Admin settings
+ if self.current_user.is_admin():
+ repo.mirrored = self.get_argument_bool("mirrored")
+
+ if repo.owner:
+ url = "/users/%s/repos/%s" % (repo.owner.name, repo.slug)
+ else:
+ url = "/distros/%s/repos/%s" % (repo.distro.slug, repo.slug)
+
+ self.redirect(url)
+
+
class MirrorlistHandler(BaseHandler):
def get(self, **kwargs):
# Fetch the repository