limit = self.get_argument_int("limit", None) or 25
# Filters
+ name = self.get_argument("name", None)
user = self.get_argument_user("user", None)
# Fetch the most recent builds
if user:
- builds = self.backend.builds.get_by_user(user, limit=limit, offset=offset)
+ builds = user.get_builds(name, limit=limit, offset=offset)
else:
- builds = self.backend.builds.get_recent(limit=limit, offset=offset)
+ builds = self.backend.builds.get_recent(name=name, limit=limit, offset=offset)
# Group builds by date
builds = misc.group(builds, lambda build: build.created_at.date())
- self.render("builds/index.html", builds=builds, user=user,
+ self.render("builds/index.html", builds=builds, name=name, user=user,
limit=limit, offset=offset)
+class QueueHandler(base.BaseHandler):
+ def get(self):
+ self.render("builds/queue.html", queue=self.backend.jobs.queue)
+
+
class ShowHandler(base.BaseHandler):
async def get(self, uuid):
build = self.backend.builds.get_by_uuid(uuid)
distro=build.distro, bugs=bugs)
+class CloneHandler(base.BaseHandler):
+ @tornado.web.authenticated
+ def get(self, uuid):
+ build = self.backend.builds.get_by_uuid(uuid)
+ if not build:
+ raise tornado.web.HTTPError(404, "Could not find build %s" % uuid)
+
+ # Fetch repositories
+ try:
+ repos = self.current_user.repos[build.distro]
+ except KeyError:
+ repos = []
+
+ self.render("builds/clone.html", build=build, repos=repos)
+
+ @tornado.web.authenticated
+ async def post(self, uuid):
+ build = self.backend.builds.get_by_uuid(uuid)
+ if not build:
+ raise tornado.web.HTTPError(404, "Could not find build %s" % uuid)
+
+ # Fetch the repository
+ repo = self.current_user.get_repo(build.distro, self.get_argument("repo"))
+
+ # Clone the build
+ with self.db.transaction():
+ clone = await self.backend.builds.create(
+ repo=repo, package=build.pkg, owner=self.current_user,
+ )
+
+ # Launch all jobs (in the background)
+ self.backend.run_task(self.backend.builds.launch, [clone])
+
+ self.redirect("/builds/%s" % clone.uuid)
+
+
class DeleteHandler(base.BaseHandler):
@tornado.web.authenticated
def get(self, uuid):
class CommentHandler(base.BaseHandler):
@tornado.web.authenticated
- def post(self, uuid):
+ async def post(self, uuid):
build = self.backend.builds.get_by_uuid(uuid)
if not build:
raise tornado.web.HTTPError(404, "Could not find build %s" % uuid)
# Add a new comment to the build
with self.db.transaction():
- build.comment(self.current_user, text)
+ await build.comment(self.current_user, text)
# Redirect to the build
self.redirect("/builds/%s" % build.uuid)
+class BugHandler(base.BaseHandler):
+ @tornado.web.authenticated
+ async def get(self, uuid):
+ build = self.backend.builds.get_by_uuid(uuid)
+ if not build:
+ raise tornado.web.HTTPError(404, "Could not find build %s" % uuid)
+
+ # Fetch fields
+ fields = await self.backend.bugzilla.fields
+
+ self.render("builds/bug.html", build=build, fields=fields)
+
+ @tornado.web.authenticated
+ async def post(self, uuid):
+ build = self.backend.builds.get_by_uuid(uuid)
+ if not build:
+ raise tornado.web.HTTPError(404, "Could not find build %s" % uuid)
+
+ # Is the user connected to Bugzilla?
+ if not self.current_user.bugzilla:
+ raise tornado.web.HTTPError(400, "%s is not connected to Bugzilla" \
+ % self.current_user)
+
+ kwargs = {
+ # Summary & Description
+ "summary" : self.get_argument("summary"),
+ "description" : self.get_argument("description", None),
+ } | build.bugzilla_fields
+
+ # Create the bug
+ bug = await self.current_user.bugzilla.create_bug(**kwargs)
+
+ # Send the attachments
+ for job in build.jobs:
+ if not self.get_argument_bool("attach_log_%s" % job.uuid):
+ continue
+
+ # Open the logfile
+ try:
+ log = await job.open_log()
+ except FileNotFoundError as e:
+ log.warning("Could not open log file for %s" % job)
+ continue
+
+ # Attach it to the bug
+ await bug.attach(summary="Log file for %s" % job, filename="%s.log" % job,
+ data=log, content_type="text/plain")
+
+ self.render("builds/bug-created.html", build=build, bug=bug)
+
+
+class ReposAddHandler(base.BaseHandler):
+ @tornado.web.authenticated
+ def get(self, uuid):
+ build = self.backend.builds.get_by_uuid(uuid)
+ if not build:
+ raise tornado.web.HTTPError(404, "Could not find build %s" % uuid)
+
+ # Fetch all available repositories
+ try:
+ repos = self.current_user.repos[build.distro]
+ except KeyError:
+ repos = None
+
+ self.render("builds/repos/add.html", build=build, repos=repos)
+
+ @tornado.web.authenticated
+ async def post(self, uuid):
+ build = self.backend.builds.get_by_uuid(uuid)
+ if not build:
+ raise tornado.web.HTTPError(404, "Could not find build %s" % uuid)
+
+ slug = self.get_argument("repo")
+
+ # Fetch the repository
+ repo = self.current_user.get_repo(build.distro, slug)
+ if not repo:
+ raise tornado.web.HTTPError(400, "Could not find repository '%s'" % slug)
+
+ # Add the build to the repository
+ with self.db.transaction():
+ await repo.add_build(build, user=self.current_user)
+
+ self.redirect("/builds/%s" % build.uuid)
+
+
+class ReposRemoveHandler(base.BaseHandler):
+ @tornado.web.authenticated
+ def get(self, uuid):
+ build = self.backend.builds.get_by_uuid(uuid)
+ if not build:
+ raise tornado.web.HTTPError(404, "Could not find build %s" % uuid)
+
+ # Raise error when the build is in to repositories
+ if not build.repos:
+ raise tornado.web.HTTPError(400)
+
+ self.render("builds/repos/remove.html", build=build)
+
+ @tornado.web.authenticated
+ async def post(self, uuid):
+ build = self.backend.builds.get_by_uuid(uuid)
+ if not build:
+ raise tornado.web.HTTPError(404, "Could not find build %s" % uuid)
+
+ # Fetch all selected repos
+ repos = self.get_arguments("repo")
+
+ # Raise an error if nothing has been selected
+ if not repos:
+ raise tornado.web.HTTPError(400, "No repositories selected")
+
+ # Find all selected repositories
+ repos = [repo for repo in build.repos if repo.slug in repos]
+
+ # Remove build from all repositories
+ with self.db.transaction():
+ for repo in repos:
+ await repo.remove_build(build, user=self.current_user)
+
+ self.redirect("/builds/%s" % build.uuid)
+
+
class GroupShowHandler(base.BaseHandler):
def get(self, uuid):
group = self.backend.builds.groups.get_by_uuid(uuid)
class ListModule(ui_modules.UIModule):
- def render(self, builds):
- return self.render_string("builds/modules/list.html", builds=builds)
+ def render(self, builds, limit=None, more_url=None):
+ rest = None
+
+ # Limit builds
+ if limit:
+ builds, rest = builds[:limit], builds[limit:]
+
+ return self.render_string("builds/modules/list.html", builds=builds,
+ rest=rest, more_url=more_url)
class GroupListModule(ui_modules.UIModule):