Mercurial > sci
diff page-api-jobs.c @ 2:5fa3d2f479b2
sci: initial upload support
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 10 Jun 2021 10:39:21 +0200 |
parents | |
children | 215c0c3b3609 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/page-api-jobs.c Thu Jun 10 10:39:21 2021 +0200 @@ -0,0 +1,129 @@ +#include <sys/types.h> +#include <assert.h> +#include <stdarg.h> +#include <stdint.h> +#include <string.h> + +#include <kcgi.h> +#include <jansson.h> + +#include "config.h" +#include "job.h" +#include "log.h" +#include "page.h" +#include "req.h" +#include "util.h" + +static void +list(struct kreq *r, const struct job_result *jobs, size_t jobsz) +{ + json_t *array, *obj; + + array = json_array(); + + for (size_t i = 0; i < jobsz; ++i) { + obj = json_object(); + json_object_set(obj, "id", json_integer(jobs[i].job.id)); + json_object_set(obj, "tag", json_string(jobs[i].job.tag)); + json_object_set(obj, "project", json_string(jobs[i].job.project.name)); + json_array_append(array, obj); + } + + khttp_puts(r, json_dumps(array, JSON_COMPACT)); +} + +static void +get(struct kreq *r) +{ + struct req req; + struct job_result jobs[SCI_JOB_LIST_MAX]; + size_t jobsz = UTIL_SIZE(jobs); + const char *worker = util_basename(r->path); + + if ((req = req_job_list(jobs, &jobsz, worker)).status) + page(r, NULL, KHTTP_500, KMIME_APP_JSON, NULL); + else { + khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_APP_JSON]); + khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); + khttp_body(r); + list(r, jobs, jobsz); + khttp_free(r); + } +} + +static int +parse(struct job_result *res, const char *json) +{ + json_t *doc, *code, *id, *retcode; + json_error_t err; + + if (!(doc = json_loads(json, 0, &err))) + return log_warn("api/post: invalid JSON input: %s", err.text), -1; + if (!json_is_object(doc) || + !json_is_string((code = json_object_get(doc, "code"))) || + !json_is_integer((id = json_object_get(doc, "id"))) || + !json_is_integer((retcode = json_object_get(doc, "retcode")))) { + log_warn("api/post: invalid JSON input"); + json_decref(doc); + return -1; + } + + res->job.id = json_integer_value(id); + res->retcode = json_integer_value(retcode); + res->console = util_strdup(json_string_value(code)); + json_decref(doc); + + return 0; +} + +static int +save(struct job_result *res) +{ + struct req req; + + if ((req = req_job_save(res)).status) { + log_warn("api/post: save error: %s", strerror(req.status)); + return -1; + } + + return 0; +} + +static void +post(struct kreq *r) +{ + struct job_result res = {0}; + const char *worker = util_basename(r->path); + + strlcpy(res.worker.name, worker, sizeof (res.worker.name)); + log_info("data=%s", r->fields[0].key); + + if (r->fieldsz < 1 || parse(&res, r->fields[0].key) || save(&res) < 0) + page(r, NULL, KHTTP_500, KMIME_APP_JSON, NULL); + else { + khttp_head(r, kresps[KRESP_CONTENT_TYPE], "%s", kmimetypes[KMIME_APP_JSON]); + khttp_head(r, kresps[KRESP_STATUS], "%s", khttps[KHTTP_200]); + khttp_body(r); + khttp_free(r); + } + + free(res.console); +} + +void +page_api_v1_jobs(struct kreq *r) +{ + assert(r); + + switch (r->method) { + case KMETHOD_GET: + get(r); + break; + case KMETHOD_POST: + post(r); + break; + default: + page(r, NULL, KHTTP_400, KMIME_APP_JSON, NULL); + break; + } +}