diff scid/page-index.c @ 29:695637f1d8a7

scid: first index page in javascript
author David Demelier <markand@malikania.fr>
date Thu, 04 Aug 2022 14:13:58 +0200
parents 4c16bb25e4f1
children 43333d18e4b8
line wrap: on
line diff
--- a/scid/page-index.c	Thu Aug 04 06:09:54 2022 +0200
+++ b/scid/page-index.c	Thu Aug 04 14:13:58 2022 +0200
@@ -19,13 +19,13 @@
 #include <errno.h>
 #include <string.h>
 
-#include "log.h"
 #include "config.h"
 #include "db.h"
-#include "page.h"
+#include "log.h"
+#include "pageutil.h"
 #include "scid.h"
+#include "theme.h"
 #include "util.h"
-#include "theme.h"
 
 #if 0
 
@@ -36,111 +36,114 @@
  *   "projects: [
  *     {
  *       "name": "project name",
- *       "description": "project short description",
+ *       "desc": "project short description",
  *       "url": "project URL or homepage",
  *       "jobs": [
  *         {
  *           "job": job-id,
  *           "tag": "job tag / revision",
- *           "success": true,                   // on success (absent otherwise)
- *           "failed: true                      // on failure (absent otherwise)
+ *           "status": "failed / success"        // failed if at least one has failed
  *         }
  *       ]
+ *       "n-failed": number of failed jobs
+ *       "n-succes": number of successful jobs
  *     }
  *   ]
  * }
  */
 
-static json_t *
-make_job(const struct job *job)
-{
-	struct jobresult res[SCI_WORKER_MAX];
-	ssize_t resz;
-	json_t *doc = NULL;
-
-	doc = json_pack("{sI ss}",
-		"id",   (json_int_t)job->id,
-		"tag",  job->tag
-        );
-
-        /* Find every job result associated to see if there are failures. */
-	resz = db_jobresult_list_by_job_group(res, UTIL_SIZE(res), job->id);
-
-	for (ssize_t i = 0; i < resz; ++i)
-		if (res[i].exitcode)
-			json_object_set_new(doc, "failed", json_true());
-
-	if (!json_object_get(doc, "failed"))
-		json_object_set_new(doc, "success", json_true());
-
-	return doc;
-}
-
-static json_t *
-make_jobs(const char *project)
-{
-	struct job jobs[10];
-	ssize_t jobsz;
-	json_t *array = NULL, *obj;
-
-	if ((jobsz = db_job_list(jobs, UTIL_SIZE(jobs), project)) >= 0) {
-		if (!(array = json_array()))
-			return NULL;
-		for (ssize_t i = 0; i < jobsz; ++i)
-			if ((obj = make_job(&jobs[i])))
-				json_array_append(array, obj);
-	}
-
-	return array;
-}
-
-static json_t *
-make_project(const struct project *project)
-{
-	return json_pack("{ss ss ss so*}",
-		"name",         project->name,
-		"description",  project->desc,
-		"url",          project->url,
-		"jobs",         make_jobs(project->name)
-	);
-}
-
 #endif
 
 static void
-get(struct kreq *r)
+fill_jobresults(json_t *project, json_t *job, json_t *jobresults)
 {
-#if 0
-	(void)r;
-	struct project projects[SCI_PROJECT_MAX] = {0};
-	ssize_t projectsz = 0;
-	json_t *array;
+	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");
 
-        /* 'projects' array. */
-        if (!(array = json_array()))
-		log_die("page-index: %s", strerror(ENOMEM));
+	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
+fill_jobs(json_t *project, json_t *jobs)
+{
+	json_t *iter, *jobresults;
+	json_int_t job_id;
+	size_t i;
 
-        projectsz = db_project_list(projects, UTIL_SIZE(projects));
+	json_array_foreach(jobs, i, iter) {
+		/*
+		 * 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);
 
-        for (ssize_t i = 0; i < projectsz; ++i)
-                json_array_append(array, make_project(&projects[i]));
+		if (!(jobresults = db_jobresult_list_by_job_group(job_id)))
+			continue;
 
-	page(r, KHTTP_200, KMIME_TEXT_HTML, "pages/index.html", json_pack("{so}",
-		"projects", array
-	));
-	json_t *array;
+		fill_jobresults(project, iter, jobresults);
+		json_decref(jobresults);
+	}
+
+	json_object_set_new(project, "jobs", jobs);
+}
+
+static void
+fill_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);
 
-	if (!(db_project_list())) {
-		log_warn("page-index: %s", db.error);
-		page();
+		/* Find jobs for this project. */
+		if (!(jobs = db_job_list(name)))
+			continue;
+
+		fill_jobs(iter, jobs);
+	}
+}
+
+static void
+get(struct kreq *req)
+{
+	json_t *projects, *root;
+	char *data;
+
+	/* First, fetch all projects. */
+	if ((projects = db_project_list())) {
+		fill_projects(projects);
+
+		root = json_pack("{so}", "projects", projects);
+		printf("===\n%s\n===\n", json_dumps(root, JSON_INDENT(4)));
+		data = theme_page_index(scid.theme, root);
+		pageutil_render(req, KHTTP_200, KMIME_TEXT_HTML, data);
+		json_decref(projects);
 	} else
-		render(array);
-#endif
-	khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_TEXT_HTML]);
-	khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]);
-	khttp_body(r);
-	khttp_printf(r, "%s", theme_render_index(scid.theme, "{}"));
-	khttp_free(r);
+		pageutil_status(req, KHTTP_500);
 }
 
 void
@@ -153,7 +156,7 @@
 		get(r);
 		break;
 	default:
-		page(r, KHTTP_400, KMIME_TEXT_HTML, "pages/400.html", NULL);
+		pageutil_status(r, KHTTP_400);
 		break;
 	}
 }