diff options
Diffstat (limited to 'clients/screens_attachments.c')
| -rw-r--r-- | clients/screens_attachments.c | 163 |
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); + } +} |
