Mercurial > sci
comparison scid/page-index.c @ 26:7e10cace67a3
scid: add basic mustache support
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 02 Aug 2022 13:24:13 +0200 |
parents | 600204c31bf0 |
children | dae2de19ca5d |
comparison
equal
deleted
inserted
replaced
25:c40f98360ac9 | 26:7e10cace67a3 |
---|---|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 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 | 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 */ | 17 */ |
18 | 18 |
19 #include <sys/types.h> | 19 #include <errno.h> |
20 #include <assert.h> | 20 #include <string.h> |
21 #include <stdarg.h> | |
22 #include <stdint.h> | |
23 | 21 |
24 #include <kcgi.h> | 22 #include "log.h" |
25 | 23 #include "config.h" |
26 #include "database.h" | 24 #include "db.h" |
27 #include "fragment-paste.h" | |
28 #include "page-index.h" | |
29 #include "page.h" | 25 #include "page.h" |
30 #include "paste.h" | 26 #include "types.h" |
31 #include "util.h" | 27 #include "util.h" |
32 | 28 |
33 struct template { | 29 /* |
34 struct kreq *req; | 30 * Document we create for templatize. |
35 const struct paste *pastes; | 31 * |
36 size_t pastesz; | 32 * { |
37 }; | 33 * "projects: [ |
34 * { | |
35 * "name": "project name", | |
36 * "description": "project short description", | |
37 * "url": "project URL or homepage", | |
38 * "jobs": [ | |
39 * { | |
40 * "job": job-id, | |
41 * "tag": "job tag / revision", | |
42 * "success": true, // on success (absent otherwise) | |
43 * "failed: true // on failure (absent otherwise) | |
44 * } | |
45 * ] | |
46 * } | |
47 * ] | |
48 * } | |
49 */ | |
38 | 50 |
39 static const char *keywords[] = { | 51 static json_t * |
40 "pastes" | 52 make_job(const struct job *job) |
41 }; | 53 { |
54 struct jobresult res[SCI_WORKER_MAX]; | |
55 ssize_t resz; | |
56 json_t *doc = NULL; | |
42 | 57 |
43 static int | 58 doc = json_pack("{sI ss}", |
44 template(size_t keyword, void *arg) | 59 "id", (json_int_t)job->id, |
60 "tag", job->tag | |
61 ); | |
62 | |
63 /* Find every job result associated to see if there are failures. */ | |
64 resz = db_jobresult_list_by_job_group(res, UTIL_SIZE(res), job->id); | |
65 | |
66 for (ssize_t i = 0; i < resz; ++i) | |
67 if (res[i].exitcode) | |
68 json_object_set_new(doc, "failed", json_true()); | |
69 | |
70 if (!json_object_get(doc, "failed")) | |
71 json_object_set_new(doc, "success", json_true()); | |
72 | |
73 return doc; | |
74 } | |
75 | |
76 static json_t * | |
77 make_jobs(const char *project) | |
45 { | 78 { |
46 struct template *tp = arg; | 79 struct job jobs[10]; |
80 ssize_t jobsz; | |
81 json_t *array = NULL, *obj; | |
47 | 82 |
48 switch (keyword) { | 83 if ((jobsz = db_job_list(jobs, UTIL_SIZE(jobs), project)) >= 0) { |
49 case 0: | 84 if (!(array = json_array())) |
50 for (size_t i = 0; i < tp->pastesz; ++i) | 85 return NULL; |
51 fragment_paste(tp->req, &tp->pastes[i]); | 86 for (ssize_t i = 0; i < jobsz; ++i) |
52 break; | 87 if ((obj = make_job(&jobs[i]))) |
53 default: | 88 json_array_append(array, obj); |
54 break; | |
55 } | 89 } |
56 | 90 |
57 return 1; | 91 return array; |
92 } | |
93 | |
94 static json_t * | |
95 make_project(const struct project *project) | |
96 { | |
97 return json_pack("{ss ss ss so*}", | |
98 "name", project->name, | |
99 "description", project->desc, | |
100 "url", project->url, | |
101 "jobs", make_jobs(project->name) | |
102 ); | |
58 } | 103 } |
59 | 104 |
60 static void | 105 static void |
61 get(struct kreq *r) | 106 get(struct kreq *r) |
62 { | 107 { |
63 struct paste pastes[10] = {0}; | 108 (void)r; |
64 size_t pastesz = NELEM(pastes); | 109 struct project projects[SCI_PROJECT_MAX] = {0}; |
110 ssize_t projectsz = 0; | |
111 json_t *array; | |
65 | 112 |
66 if (!database_recents(pastes, &pastesz)) | 113 /* 'projects' array. */ |
67 page(r, NULL, KHTTP_500, "pages/500.html"); | 114 if (!(array = json_array())) |
68 else | 115 log_die("page-index: %s", strerror(ENOMEM)); |
69 page_index_render(r, pastes, pastesz); | |
70 | 116 |
71 for (size_t i = 0; i < pastesz; ++i) | 117 projectsz = db_project_list(projects, UTIL_SIZE(projects)); |
72 paste_finish(&pastes[i]); | |
73 } | |
74 | 118 |
75 void | 119 for (ssize_t i = 0; i < projectsz; ++i) |
76 page_index_render(struct kreq *r, const struct paste *pastes, size_t pastesz) | 120 json_array_append(array, make_project(&projects[i])); |
77 { | |
78 struct template data = { | |
79 .req = r, | |
80 .pastes = pastes, | |
81 .pastesz = pastesz | |
82 }; | |
83 | 121 |
84 struct ktemplate kt = { | 122 page(r, KHTTP_200, KMIME_TEXT_HTML, "pages/index.html", json_pack("{so}", |
85 .key = keywords, | 123 "projects", array |
86 .keysz = NELEM(keywords), | 124 )); |
87 .arg = &data, | |
88 .cb = template | |
89 }; | |
90 | |
91 page(r, &kt, KHTTP_200, "pages/index.html"); | |
92 } | 125 } |
93 | 126 |
94 void | 127 void |
95 page_index(struct kreq *r) | 128 page_index(struct kreq *r) |
96 { | 129 { |
97 switch (r->method) { | 130 switch (r->method) { |
98 case KMETHOD_GET: | 131 case KMETHOD_GET: |
99 get(r); | 132 get(r); |
100 break; | 133 break; |
101 default: | 134 default: |
102 page(r, NULL, KHTTP_400, "400.html"); | 135 page(r, KHTTP_400, KMIME_TEXT_HTML, "pages/400.html", NULL); |
103 break; | 136 break; |
104 } | 137 } |
105 } | 138 } |