comparison 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
comparison
equal deleted inserted replaced
43:6854efe15210 44:576f4b1ec79f
1 /*
2 * page-projects.c -- page /projects route
3 *
4 * Copyright (c) 2021-2022 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <errno.h>
20 #include <string.h>
21
22 #include "db.h"
23 #include "pageutil.h"
24 #include "scid.h"
25 #include "theme.h"
26 #include "util.h"
27
28 static void
29 set_job_status(json_t *project, json_t *job, json_t *jobresults)
30 {
31 json_t *iter, *status;
32 int exitcode, sigcode;
33 size_t i, ns = 0, nf = 0;
34
35 json_array_foreach(jobresults, i, iter) {
36 json_unpack(iter, "{si si}", "exitcode", &exitcode, "sigcode", &sigcode);
37
38 if (exitcode == 0 && sigcode == 0)
39 ns++;
40 else
41 nf++;
42 }
43
44 if (nf)
45 status = json_string("failed");
46 else
47 status = json_string("success");
48
49 json_object_set_new(job, "status", status);
50 json_object_set_new(project, "n-failed", json_integer(nf));
51 json_object_set_new(project, "n-success", json_integer(ns));
52 }
53
54 static void
55 set_project_jobs(json_t *project, json_t *jobs)
56 {
57 json_t *iter, *jobresults;
58 json_int_t job_id;
59 size_t i;
60
61 json_array_foreach(jobs, i, iter) {
62 /* Don't populate too much. */
63 if (i + 1 >= 10)
64 break;
65
66 /*
67 * For this job, find all jobresult to check how many have
68 * failed or not.
69 *
70 * Also, since we have the project name, we can remove it.
71 */
72 json_object_del(iter, "project_name");
73 json_unpack(iter, "{sI}", "id", &job_id);
74
75 if (!(jobresults = db_jobresult_list_by_job_group(job_id)))
76 continue;
77
78 set_job_status(project, iter, jobresults);
79 json_decref(jobresults);
80 }
81
82 json_object_set_new(project, "jobs", jobs);
83 }
84
85 /*
86 * For every projects, find their jobs and add them as 'jobs' property.
87 */
88 static void
89 update_projects(json_t *projects)
90 {
91 json_t *jobs, *iter;
92 const char *name;
93 size_t i;
94
95 json_array_foreach(projects, i, iter) {
96 /* Script is not necessary at this point. */
97 json_object_del(iter, "script");
98 json_unpack(iter, "{ss}", "name", &name);
99
100 /* Find jobs for this project. */
101 if (!(jobs = db_job_list(name)))
102 continue;
103
104 set_project_jobs(iter, jobs);
105 }
106 }
107
108 static void
109 get(struct kreq *req)
110 {
111 json_t *projects, *root;
112 char *data;
113
114 /* First, fetch all projects. */
115 if ((projects = db_project_list())) {
116 root = json_pack("{so}", "projects", projects);
117 data = theme_page_index(root);
118 pageutil_render(req, KHTTP_200, KMIME_TEXT_HTML, data);
119 free(data);
120 json_decref(root);
121 } else
122 pageutil_status(req, KHTTP_500);
123 }
124
125 void
126 page_projects(struct kreq *r)
127 {
128 (void)r;
129
130 switch (r->method) {
131 case KMETHOD_GET:
132 get(r);
133 break;
134 default:
135 pageutil_status(r, KHTTP_400);
136 break;
137 }
138 }