diff scid/page-projects.c @ 44:576f4b1ec79f

scid: implement API authentication
author David Demelier <markand@malikania.fr>
date Thu, 11 Aug 2022 21:24:07 +0200
parents
children 7a4112eec15b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scid/page-projects.c	Thu Aug 11 21:24:07 2022 +0200
@@ -0,0 +1,138 @@
+/*
+ * page-projects.c -- page /projects route
+ *
+ * Copyright (c) 2021-2022 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <string.h>
+
+#include "db.h"
+#include "pageutil.h"
+#include "scid.h"
+#include "theme.h"
+#include "util.h"
+
+static void
+set_job_status(json_t *project, json_t *job, json_t *jobresults)
+{
+	json_t *iter, *status;
+	int exitcode, sigcode;
+	size_t i, ns = 0, nf = 0;
+
+	json_array_foreach(jobresults, i, iter) {
+		json_unpack(iter, "{si si}", "exitcode", &exitcode, "sigcode", &sigcode);
+
+		if (exitcode == 0 && sigcode == 0)
+			ns++;
+		else
+			nf++;
+	}
+
+	if (nf)
+		status = json_string("failed");
+	else
+		status = json_string("success");
+
+	json_object_set_new(job, "status", status);
+	json_object_set_new(project, "n-failed", json_integer(nf));
+	json_object_set_new(project, "n-success", json_integer(ns));
+}
+
+static void
+set_project_jobs(json_t *project, json_t *jobs)
+{
+	json_t *iter, *jobresults;
+	json_int_t job_id;
+	size_t i;
+
+	json_array_foreach(jobs, i, iter) {
+		/* Don't populate too much. */
+		if (i + 1 >= 10)
+			break;
+
+		/*
+		 * For this job, find all jobresult to check how many have
+		 * failed or not.
+		 *
+		 * Also, since we have the project name, we can remove it.
+		 */
+		json_object_del(iter, "project_name");
+		json_unpack(iter, "{sI}", "id", &job_id);
+
+		if (!(jobresults = db_jobresult_list_by_job_group(job_id)))
+			continue;
+
+		set_job_status(project, iter, jobresults);
+		json_decref(jobresults);
+	}
+
+	json_object_set_new(project, "jobs", jobs);
+}
+
+/*
+ * For every projects, find their jobs and add them as 'jobs' property.
+ */
+static void
+update_projects(json_t *projects)
+{
+	json_t *jobs, *iter;
+	const char *name;
+	size_t i;
+
+	json_array_foreach(projects, i, iter) {
+		/* Script is not necessary at this point. */
+		json_object_del(iter, "script");
+		json_unpack(iter, "{ss}", "name", &name);
+
+		/* Find jobs for this project. */
+		if (!(jobs = db_job_list(name)))
+			continue;
+
+		set_project_jobs(iter, jobs);
+	}
+}
+
+static void
+get(struct kreq *req)
+{
+	json_t *projects, *root;
+	char *data;
+
+	/* First, fetch all projects. */
+	if ((projects = db_project_list())) {
+		root = json_pack("{so}", "projects", projects);
+		data = theme_page_index(root);
+		pageutil_render(req, KHTTP_200, KMIME_TEXT_HTML, data);
+		free(data);
+		json_decref(root);
+	} else
+		pageutil_status(req, KHTTP_500);
+}
+
+void
+page_projects(struct kreq *r)
+{
+	(void)r;
+
+	switch (r->method) {
+	case KMETHOD_GET:
+		get(r);
+		break;
+	default:
+		pageutil_status(r, KHTTP_400);
+		break;
+	}
+}