]> git.ipfire.org Git - pbs.git/commitdiff
repos: Fix creating custom repositories
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 22 Jan 2025 17:03:07 +0000 (17:03 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 22 Jan 2025 17:03:07 +0000 (17:03 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/buildservice/repos.py
src/templates/repos/create-custom.html
src/web/base.py
src/web/repos.py

index d2caca29ae74ab88ecd682d8f571b9f3bf5927e2..5276922e7406651d69afdc757136abb2115bef3a 100644 (file)
@@ -124,7 +124,7 @@ class Repos(base.Object):
                        Creates a new repository
                """
                # Generate a slug
-               slug = await self._make_slug(name, owner=owner)
+               slug = await self._make_slug(distro, name, owner=owner)
 
                # Generate a comment for the key
                comment = "%s - %s" % (distro, name)
@@ -132,48 +132,50 @@ class Repos(base.Object):
                        comment = "%s - %s" % (owner, comment)
 
                # Create a key for this repository
-               key = await self.backend.keys.create(comment=comment, user=owner)
-
-               repo = await self._get_repository("""
-                       INSERT INTO
-                               repositories
-                       (
-                               distro_id,
-                               owner_id,
-                               name,
-                               slug,
-                               key_id
-                       )
-                       VALUES (
-                               %s, %s, %s, %s, %s
-                       )
-                       RETURNING *""",
-                       distro,
-                       owner,
-                       name,
-                       slug,
-                       key,
-
-                       # Populate the cache
-                       key=key, owner=owner,
+               key = await self.backend.keys.create(
+                       comment = comment,
+                       user    = owner,
+               )
+
+               # Create the repository
+               repo = await self.db.insert(
+                       Repo,
+                       distro = distro,
+                       owner  = owner,
+                       name   = name,
+                       slug   = slug,
+                       key    = key,
                )
 
                return repo
 
-       async def _make_slug(self, name, owner=None):
+       async def _make_slug(self, distro, name, owner=None):
                for i in misc.infinity():
                        slug = misc.normalize(name, iteration=i)
 
-                       exists = await self.db.get("SELECT 1 FROM repositories \
-                               WHERE deleted_at IS NULL AND owner_id = %s AND slug = %s", owner, slug)
-                       if not exists:
-                               return slug
+                       stmt = (
+                               sqlalchemy
+                               .select(
+                                       Repo
+                               )
+                               .where(
+                                       Repo.deleted_at == None,
+                                       Repo.distro == distro,
+                                       Repo.slug == slug,
+                               )
+                       )
+
+                       # If a repository with this slug exists, we need to try again
+                       if await self.db.select_one(stmt):
+                               continue
+
+                       return slug
 
        async def write(self):
                """
                        Write/re-write all repositories
                """
-               for repo in self:
+               async for repo in self:
                        await repo.write()
 
 
index d6a166097bbf1aa9751900ecd0afb8fa9a61d082..1766ee5ea0990e5c1a7376c2a461a7ed786afa4b 100644 (file)
@@ -1,10 +1,11 @@
-{% extends "../base.html" %}
+{% extends "modal.html" %}
 
-{% block title %}{{ _("Repositories") }} - {{ _("Create") }}{% end block %}
 
-{% block container %}
-       <nav aria-label="{{ _("You are here:") }}" role="navigation">
-               <ul class="breadcrumbs">
+{% block title %}{{ _("Repositories") }} - {{ _("Create") }}{% endblock %}
+
+{% block breadcrumbs %}
+       <nav class="breadcrumb" aria-label="breadcrumbs">
+               <ul>
                        <li>
                                <a href="/">{{ _("Home") }}</a>
                        </li>
                        <li>
                                {{ _("Repositories") }}
                        </li>
-                       <li>
-                               <span class="show-for-sr">{{ _("Current") }}: </span> {{ _("Create") }}
+                       <li class="is-active">
+                               <a href="#" aria-current="page">{{ _("Create") }}</a>
                        </li>
                </ul>
        </nav>
+{% endblock %}
 
-       <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>
-                                               {{ _("Distribution") }}
-
-                                               <select name="distro" required>
-                                                       <option value="">{{ _("- Select -") }}</option>
+{% block modal_title %}
+       <h4 class="title is-4">{{ _("Create Repository") }}</h4>
+{% endblock %}
 
-                                                       {% for distro in distros %}
-                                                               <option value="{{ distro.slug }}">{{ distro }}</option>
-                                                       {% end %}
-                                               </select>
-                                       </label>
+{% block modal %}
+       <form method="POST" action="">
+               {{ xsrf_form_html() | safe }}
 
-                                       <label>
-                                               {{ _("Name") }}
-
-                                               <input type="text" name="name" required>
-                                       </label>
+               {# Distro #}
+               <div class="field">
+                       <label class="label">{{ _("Distribution") }}</label>
+                       <div class="control">
+                               <div class="select is-fullwidth">
+                                       <select name="distro">
+                                               {% for distro in distros %}
+                                                       <option value="{{ distro.slug }}">
+                                                               {{ distro }}
+                                                       </option>
+                                               {% endfor %}
+                                       </select>
                                </div>
+                       </div>
+               </div>
+
+               {# Name #}
+               <div class="field">
+                       <label class="label">{{ _("Name") }}</label>
+                       <div class="control">
+                               <input class="input" type="text" name="name">
+                       </div>
+               </div>
 
-                               <button class="success button expanded" type="submit">{{ _("Create Repository") }}</button>
-                       </form>
+               {# Submit! #}
+               <div class="field">
+                       <div class="control">
+                               <button class="button is-success is-link" type="submit">
+                                       {{ _("Create Repository") }}
+                               </button>
+                       </div>
                </div>
-       </div>
-{% end block %}
+       </form>
+{% endblock %}
index 4f0857efef920dc30b91d7fc6b98137f4eeabbfa..8d70eb537cdca6dedea2598023e1203671079ca3 100644 (file)
@@ -600,11 +600,11 @@ class BaseHandler(tornado.web.RequestHandler):
                if name:
                        return await self.backend.builders.get_by_name(name)
 
-       def get_argument_distro(self, *args, **kwargs):
+       async def get_argument_distro(self, *args, **kwargs):
                slug = self.get_argument(*args, **kwargs)
 
                if slug:
-                       return self.backend.distros.get_by_slug(slug)
+                       return await self.backend.distros.get_by_slug(slug)
 
        # Uploads
 
index f791e978b55a33c8cd1befcce7879392ac7a6bf9..f2d167a442a295833db9f35fbdbc393a2c2eea42 100644 (file)
@@ -151,33 +151,42 @@ class BuildsHandler(BaseHandler):
 
 class CreateCustomHandler(BaseHandler):
        @base.authenticated
-       def get(self, user_slug):
-               user = self.backend.users.get_by_name(user_slug)
+       async def get(self, user_slug):
+               # Fetch current user
+               current_user = await self.get_current_user()
+
+               # Fetch user
+               user = await self.backend.users.get_by_name(user_slug)
                if not user:
                        raise tornado.web.HTTPError(404, "Could not find user: %s" % user_slug)
 
                # Check for permissions
-               if not user.has_perm(self.current_user):
+               if not user.has_perm(current_user):
                        raise tornado.web.HTTPError(403)
 
-               self.render("repos/create-custom.html", user=user, distros=self.backend.distros)
+               await self.render("repos/create-custom.html", user=user, distros=self.backend.distros)
 
        @base.authenticated
        async def post(self, user_slug):
-               user = self.backend.users.get_by_name(user_slug)
+               # Fetch current user
+               current_user = await self.get_current_user()
+
+               # Fetch user
+               user = await self.backend.users.get_by_name(user_slug)
                if not user:
                        raise tornado.web.HTTPError(404, "Could not find user: %s" % user_slug)
 
                # Check for permissions
-               if not user.has_perm(self.current_user):
+               if not user.has_perm(current_user):
                        raise tornado.web.HTTPError(403)
 
-               # Fetch arguments
-               name   = self.get_argument("name")
-               distro = self.get_argument_distro("distro")
-
-               with self.db.transaction():
-                       repo = await self.backend.repos.create(distro, name, owner=user)
+               # Create the repository
+               async with await self.db.transaction():
+                       repo = await self.backend.repos.create(
+                               distro = await self.get_argument_distro("distro"),
+                               name   = self.get_argument("name"),
+                               owner  = user,
+                       )
 
                        # Write repository metadata
                        await repo.write()