comparison 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
comparison
equal deleted inserted replaced
28:4c16bb25e4f1 29:695637f1d8a7
17 */ 17 */
18 18
19 #include <errno.h> 19 #include <errno.h>
20 #include <string.h> 20 #include <string.h>
21 21
22 #include "log.h"
23 #include "config.h" 22 #include "config.h"
24 #include "db.h" 23 #include "db.h"
25 #include "page.h" 24 #include "log.h"
25 #include "pageutil.h"
26 #include "scid.h" 26 #include "scid.h"
27 #include "theme.h"
27 #include "util.h" 28 #include "util.h"
28 #include "theme.h"
29 29
30 #if 0 30 #if 0
31 31
32 /* 32 /*
33 * Document we create for templatize. 33 * Document we create for templatize.
34 * 34 *
35 * { 35 * {
36 * "projects: [ 36 * "projects: [
37 * { 37 * {
38 * "name": "project name", 38 * "name": "project name",
39 * "description": "project short description", 39 * "desc": "project short description",
40 * "url": "project URL or homepage", 40 * "url": "project URL or homepage",
41 * "jobs": [ 41 * "jobs": [
42 * { 42 * {
43 * "job": job-id, 43 * "job": job-id,
44 * "tag": "job tag / revision", 44 * "tag": "job tag / revision",
45 * "success": true, // on success (absent otherwise) 45 * "status": "failed / success" // failed if at least one has failed
46 * "failed: true // on failure (absent otherwise)
47 * } 46 * }
48 * ] 47 * ]
48 * "n-failed": number of failed jobs
49 * "n-succes": number of successful jobs
49 * } 50 * }
50 * ] 51 * ]
51 * } 52 * }
52 */ 53 */
53 54
54 static json_t *
55 make_job(const struct job *job)
56 {
57 struct jobresult res[SCI_WORKER_MAX];
58 ssize_t resz;
59 json_t *doc = NULL;
60
61 doc = json_pack("{sI ss}",
62 "id", (json_int_t)job->id,
63 "tag", job->tag
64 );
65
66 /* Find every job result associated to see if there are failures. */
67 resz = db_jobresult_list_by_job_group(res, UTIL_SIZE(res), job->id);
68
69 for (ssize_t i = 0; i < resz; ++i)
70 if (res[i].exitcode)
71 json_object_set_new(doc, "failed", json_true());
72
73 if (!json_object_get(doc, "failed"))
74 json_object_set_new(doc, "success", json_true());
75
76 return doc;
77 }
78
79 static json_t *
80 make_jobs(const char *project)
81 {
82 struct job jobs[10];
83 ssize_t jobsz;
84 json_t *array = NULL, *obj;
85
86 if ((jobsz = db_job_list(jobs, UTIL_SIZE(jobs), project)) >= 0) {
87 if (!(array = json_array()))
88 return NULL;
89 for (ssize_t i = 0; i < jobsz; ++i)
90 if ((obj = make_job(&jobs[i])))
91 json_array_append(array, obj);
92 }
93
94 return array;
95 }
96
97 static json_t *
98 make_project(const struct project *project)
99 {
100 return json_pack("{ss ss ss so*}",
101 "name", project->name,
102 "description", project->desc,
103 "url", project->url,
104 "jobs", make_jobs(project->name)
105 );
106 }
107
108 #endif 55 #endif
109 56
110 static void 57 static void
111 get(struct kreq *r) 58 fill_jobresults(json_t *project, json_t *job, json_t *jobresults)
112 { 59 {
113 #if 0 60 json_t *iter, *status;
114 (void)r; 61 int exitcode, sigcode;
115 struct project projects[SCI_PROJECT_MAX] = {0}; 62 size_t i, ns = 0, nf = 0;
116 ssize_t projectsz = 0;
117 json_t *array;
118 63
119 /* 'projects' array. */ 64 json_array_foreach(jobresults, i, iter) {
120 if (!(array = json_array())) 65 json_unpack(iter, "{si si}", "exitcode", &exitcode, "sigcode", &sigcode);
121 log_die("page-index: %s", strerror(ENOMEM));
122 66
123 projectsz = db_project_list(projects, UTIL_SIZE(projects)); 67 if (exitcode == 0 && sigcode == 0)
68 ns++;
69 else
70 nf++;
71 }
124 72
125 for (ssize_t i = 0; i < projectsz; ++i) 73 if (nf)
126 json_array_append(array, make_project(&projects[i])); 74 status = json_string("failed");
75 else
76 status = json_string("success");
127 77
128 page(r, KHTTP_200, KMIME_TEXT_HTML, "pages/index.html", json_pack("{so}", 78 json_object_set_new(job, "status", status);
129 "projects", array 79 json_object_set_new(project, "n-failed", json_integer(nf));
130 )); 80 json_object_set_new(project, "n-success", json_integer(ns));
131 json_t *array; 81 }
132 82
133 if (!(db_project_list())) { 83 static void
134 log_warn("page-index: %s", db.error); 84 fill_jobs(json_t *project, json_t *jobs)
135 page(); 85 {
86 json_t *iter, *jobresults;
87 json_int_t job_id;
88 size_t i;
89
90 json_array_foreach(jobs, i, iter) {
91 /*
92 * For this job, find all jobresult to check how many have
93 * failed or not.
94 *
95 * Also, since we have the project name, we can remove it.
96 */
97 json_object_del(iter, "project_name");
98 json_unpack(iter, "{sI}", "id", &job_id);
99
100 if (!(jobresults = db_jobresult_list_by_job_group(job_id)))
101 continue;
102
103 fill_jobresults(project, iter, jobresults);
104 json_decref(jobresults);
105 }
106
107 json_object_set_new(project, "jobs", jobs);
108 }
109
110 static void
111 fill_projects(json_t *projects)
112 {
113 json_t *jobs, *iter;
114 const char *name;
115 size_t i;
116
117 json_array_foreach(projects, i, iter) {
118 /* Script is not necessary at this point. */
119 json_object_del(iter, "script");
120 json_unpack(iter, "{ss}", "name", &name);
121
122 /* Find jobs for this project. */
123 if (!(jobs = db_job_list(name)))
124 continue;
125
126 fill_jobs(iter, jobs);
127 }
128 }
129
130 static void
131 get(struct kreq *req)
132 {
133 json_t *projects, *root;
134 char *data;
135
136 /* First, fetch all projects. */
137 if ((projects = db_project_list())) {
138 fill_projects(projects);
139
140 root = json_pack("{so}", "projects", projects);
141 printf("===\n%s\n===\n", json_dumps(root, JSON_INDENT(4)));
142 data = theme_page_index(scid.theme, root);
143 pageutil_render(req, KHTTP_200, KMIME_TEXT_HTML, data);
144 json_decref(projects);
136 } else 145 } else
137 render(array); 146 pageutil_status(req, KHTTP_500);
138 #endif
139 khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_TEXT_HTML]);
140 khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]);
141 khttp_body(r);
142 khttp_printf(r, "%s", theme_render_index(scid.theme, "{}"));
143 khttp_free(r);
144 } 147 }
145 148
146 void 149 void
147 page_index(struct kreq *r) 150 page_index(struct kreq *r)
148 { 151 {
151 switch (r->method) { 154 switch (r->method) {
152 case KMETHOD_GET: 155 case KMETHOD_GET:
153 get(r); 156 get(r);
154 break; 157 break;
155 default: 158 default:
156 page(r, KHTTP_400, KMIME_TEXT_HTML, "pages/400.html", NULL); 159 pageutil_status(r, KHTTP_400);
157 break; 160 break;
158 } 161 }
159 } 162 }