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;
+	}
+}