comparison page-api-jobs.c @ 3:215c0c3b3609

misc: use JSON everywhere (scictl/sciwebd)
author David Demelier <markand@malikania.fr>
date Mon, 14 Jun 2021 22:08:24 +0200
parents 5fa3d2f479b2
children eb76429ce112
comparison
equal deleted inserted replaced
2:5fa3d2f479b2 3:215c0c3b3609
6 6
7 #include <kcgi.h> 7 #include <kcgi.h>
8 #include <jansson.h> 8 #include <jansson.h>
9 9
10 #include "config.h" 10 #include "config.h"
11 #include "job.h"
12 #include "log.h" 11 #include "log.h"
12 #include "page-api-jobs.h"
13 #include "page.h" 13 #include "page.h"
14 #include "req.h" 14 #include "req.h"
15 #include "types.h"
15 #include "util.h" 16 #include "util.h"
16 17
17 static void 18 static void
18 list(struct kreq *r, const struct job_result *jobs, size_t jobsz) 19 list(struct kreq *r, const struct job *jobs, size_t jobsz)
19 { 20 {
20 json_t *array, *obj; 21 json_t *doc;
22 char *dump;
21 23
22 array = json_array(); 24 doc = job_to(jobs, jobsz);
25 dump = json_dumps(doc, JSON_COMPACT);
23 26
24 for (size_t i = 0; i < jobsz; ++i) { 27 khttp_puts(r, dump);
25 obj = json_object(); 28 free(dump);
26 json_object_set(obj, "id", json_integer(jobs[i].job.id)); 29 json_decref(doc);
27 json_object_set(obj, "tag", json_string(jobs[i].job.tag)); 30 }
28 json_object_set(obj, "project", json_string(jobs[i].job.project.name));
29 json_array_append(array, obj);
30 }
31 31
32 khttp_puts(r, json_dumps(array, JSON_COMPACT)); 32 static int
33 save(const char *json)
34 {
35 struct req req = {0};
36 struct jobresult res = {0};
37 int ret = -1;
38
39 json_t *doc;
40 json_error_t err;
41
42 if (!(doc = json_loads(json, 0, &err)))
43 log_warn("api/post: invalid JSON input: %s", err.text);
44 else if (jobresult_from(&res, 1, doc) < 0)
45 log_warn("api/post: failed to decode parameters");
46 else if ((req = req_jobresult_add(&res)).status)
47 log_warn("api/post: save error: %s", strerror(req.status));
48 else
49 ret = 0;
50
51 json_decref(doc);
52 req_finish(&req);
53
54 return ret;
33 } 55 }
34 56
35 static void 57 static void
36 get(struct kreq *r) 58 get(struct kreq *r)
37 { 59 {
38 struct req req; 60 struct req req;
39 struct job_result jobs[SCI_JOB_LIST_MAX]; 61 struct job jobs[SCI_JOB_LIST_MAX];
40 size_t jobsz = UTIL_SIZE(jobs); 62 size_t jobsz = UTIL_SIZE(jobs);
41 const char *worker = util_basename(r->path); 63 const char *worker = util_basename(r->path);
42 64
43 if ((req = req_job_list(jobs, &jobsz, worker)).status) 65 if ((req = req_job_todo(jobs, &jobsz, worker)).status)
44 page(r, NULL, KHTTP_500, KMIME_APP_JSON, NULL); 66 page(r, NULL, KHTTP_500, KMIME_APP_JSON, NULL);
45 else { 67 else {
46 khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_APP_JSON]); 68 khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_APP_JSON]);
47 khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); 69 khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]);
48 khttp_body(r); 70 khttp_body(r);
49 list(r, jobs, jobsz); 71 list(r, jobs, jobsz);
72 req_finish(&req);
50 khttp_free(r); 73 khttp_free(r);
51 } 74 }
52 }
53
54 static int
55 parse(struct job_result *res, const char *json)
56 {
57 json_t *doc, *code, *id, *retcode;
58 json_error_t err;
59
60 if (!(doc = json_loads(json, 0, &err)))
61 return log_warn("api/post: invalid JSON input: %s", err.text), -1;
62 if (!json_is_object(doc) ||
63 !json_is_string((code = json_object_get(doc, "code"))) ||
64 !json_is_integer((id = json_object_get(doc, "id"))) ||
65 !json_is_integer((retcode = json_object_get(doc, "retcode")))) {
66 log_warn("api/post: invalid JSON input");
67 json_decref(doc);
68 return -1;
69 }
70
71 res->job.id = json_integer_value(id);
72 res->retcode = json_integer_value(retcode);
73 res->console = util_strdup(json_string_value(code));
74 json_decref(doc);
75
76 return 0;
77 }
78
79 static int
80 save(struct job_result *res)
81 {
82 struct req req;
83
84 if ((req = req_job_save(res)).status) {
85 log_warn("api/post: save error: %s", strerror(req.status));
86 return -1;
87 }
88
89 return 0;
90 } 75 }
91 76
92 static void 77 static void
93 post(struct kreq *r) 78 post(struct kreq *r)
94 { 79 {
95 struct job_result res = {0}; 80 if (r->fieldsz < 1)
96 const char *worker = util_basename(r->path); 81 page(r, NULL, KHTTP_400, KMIME_APP_JSON, NULL);
97 82 else if (save(r->fields[0].key) < 0)
98 strlcpy(res.worker.name, worker, sizeof (res.worker.name));
99 log_info("data=%s", r->fields[0].key);
100
101 if (r->fieldsz < 1 || parse(&res, r->fields[0].key) || save(&res) < 0)
102 page(r, NULL, KHTTP_500, KMIME_APP_JSON, NULL); 83 page(r, NULL, KHTTP_500, KMIME_APP_JSON, NULL);
103 else { 84 else {
104 khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_APP_JSON]); 85 khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_APP_JSON]);
105 khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); 86 khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]);
106 khttp_body(r); 87 khttp_body(r);
107 khttp_free(r); 88 khttp_free(r);
108 } 89 }
109
110 free(res.console);
111 } 90 }
112 91
113 void 92 void
114 page_api_v1_jobs(struct kreq *r) 93 page_api_v1_jobs(struct kreq *r)
115 { 94 {