aboutsummaryrefslogtreecommitdiff
path: root/clients/screens_attachments.c
diff options
context:
space:
mode:
Diffstat (limited to 'clients/screens_attachments.c')
-rw-r--r--clients/screens_attachments.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/clients/screens_attachments.c b/clients/screens_attachments.c
new file mode 100644
index 0000000..3eeb9e9
--- /dev/null
+++ b/clients/screens_attachments.c
@@ -0,0 +1,163 @@
+#include <dirent.h>
+#include <errno.h>
+#include <locale.h>
+#include <math.h>
+#include <ncursesw/ncurses.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "client.h"
+#include "tui.h"
+#include "formula.h"
+#include "util.h"
+#include "version.h"
+#include "yyjson.h"
+#include "ui.h"
+
+static void inbox_upload(struct app *a)
+{
+ char *path = file_browser(a, a->attachment_dir);
+ if (!path)
+ return;
+ struct stat sb;
+ if (stat(path, &sb) == 0 && (long)sb.st_size > a->max_attachment_bytes) {
+ tui_message("Bilaga", "Filen är %.1f MB, max %ld MB.",
+ (double)sb.st_size / (1024 * 1024),
+ a->max_attachment_bytes / (1024 * 1024));
+ free(path);
+ return;
+ }
+ char *b64 = read_file_b64(path);
+ if (!b64) {
+ tui_message("Fel", "Kunde inte läsa %s", path);
+ free(path);
+ return;
+ }
+ const char *base = strrchr(path, '/');
+ base = base ? base + 1 : path;
+ yyjson_mut_doc *d = yyjson_mut_doc_new(NULL);
+ yyjson_mut_val *o = yyjson_mut_obj(d);
+ yyjson_mut_doc_set_root(d, o);
+ yyjson_mut_obj_add_strcpy(d, o, "filename", base);
+ yyjson_mut_obj_add_strcpy(d, o, "content_base64", b64);
+ char *args = yyjson_mut_write(d, 0, NULL);
+ yyjson_mut_doc_free(d);
+ free(b64);
+ size_t reqlen = strlen(args) + 256;
+ char *raw = xmalloc(reqlen);
+ snprintf(raw, reqlen,
+ "{\"v\":1,\"id\":\"tui\",\"cmd\":\"attachment.put\","
+ "\"session\":\"%s\",\"org\":%lld,\"args\":%s}",
+ a->session, (long long)a->org, args);
+ free(args);
+ char *r = NULL;
+ if (client_send_line(&a->conn, raw) == 0)
+ r = client_read_line(&a->conn);
+ free(raw);
+ if (r && client_ok(r))
+ tui_message("Underlag", "Sparat.");
+ else
+ show_error("Kunde inte spara", r);
+ free(r);
+ free(path);
+}
+
+struct inboxctx {
+ struct app *a;
+ int64_t *ids;
+ size_t n;
+ int cursor;
+};
+
+static int inbox_key(void *ud, int ch)
+{
+ struct inboxctx *ctx = ud;
+ struct app *a = ctx->a;
+ int64_t sel_id = (ctx->cursor >= 0 && (size_t)ctx->cursor < ctx->n)
+ ? ctx->ids[ctx->cursor]
+ : 0;
+ if (ch == 'k' && sel_id) {
+ int64_t vid = pick_voucher(a);
+ if (vid) {
+ char kargs[64];
+ snprintf(kargs, sizeof kargs, "{\"id\":%lld,\"voucher_id\":%lld}",
+ (long long)sel_id, (long long)vid);
+ char *r = client_rpc(&a->conn, "attachment.link", a->session,
+ a->org, kargs);
+ if (r && client_ok(r))
+ tui_message("Underlag", "Kopplat till verifikatet.");
+ else
+ show_error("Kunde inte koppla", r);
+ free(r);
+ }
+ return TUI_HOOK_REFRESH;
+ }
+ if (ch == 'a' || ch == 'A') {
+ inbox_upload(a);
+ return TUI_HOOK_REFRESH;
+ }
+ return TUI_HOOK_NONE;
+}
+
+void inbox_screen(struct app *a)
+{
+ int cursor = 0;
+ for (;;) {
+ if (g_quit)
+ return;
+ char *resp = client_rpc(&a->conn, "attachment.list", a->session, a->org,
+ "{\"unlinked\":true,\"limit\":200}");
+ if (!resp || !client_ok(resp)) {
+ show_error("Underlag", resp);
+ free(resp);
+ return;
+ }
+ size_t n = jarr_size(resp, "result.items");
+ char **items = xcalloc(n ? n : 1, sizeof(char *));
+ int64_t *ids = xcalloc(n ? n : 1, sizeof(int64_t));
+ for (size_t i = 0; i < n; i++) {
+ char path[64], line[512];
+ snprintf(path, sizeof path, "result.items.%zu.id", i);
+ ids[i] = jint_val(resp, path, 0);
+ snprintf(path, sizeof path, "result.items.%zu.filename", i);
+ char *fn = jstr_dup(resp, path);
+ snprintf(path, sizeof path, "result.items.%zu.size_bytes", i);
+ int64_t size = jint_val(resp, path, 0);
+ char fnbuf[256];
+ snprintf(fnbuf, sizeof fnbuf, "%s", fn ? fn : "");
+ tui_pad_field(fnbuf, sizeof fnbuf, 40);
+ snprintf(line, sizeof line, "%s %8lld byte", fnbuf,
+ (long long)size);
+ items[i] = xstrdup(line);
+ free(fn);
+ }
+ struct inboxctx ctx = { a, ids, n, cursor };
+ int sel = tui_select_list_hook("Underlag (inkorg)", items, (int)n,
+ cursor, 1, &cursor, 1, NULL, 0,
+ inbox_key, &ctx);
+ int64_t sel_id =
+ (sel >= 0 && (size_t)sel < n) ? ids[sel] : 0;
+ for (size_t i = 0; i < n; i++)
+ free(items[i]);
+ free(items);
+ free(ids);
+ free(resp);
+ if (sel == -1)
+ return;
+ if (sel == -2)
+ continue;
+ if (sel == -4) {
+ inbox_upload(a);
+ continue;
+ }
+ if (sel_id)
+ attachment_download(a, sel_id);
+ }
+}