Mercurial > sci
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; + } +}