application/davcontroller.c

changeset 8
726b24766437
child 10
f8dfc5705516
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/application/davcontroller.c	Mon Jan 29 18:50:04 2024 +0100
@@ -0,0 +1,147 @@
+/*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+*
+* Copyright 2024 Olaf Wintermann. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+*   1. Redistributions of source code must retain the above copyright
+*      notice, this list of conditions and the following disclaimer.
+*
+*   2. Redistributions in binary form must reproduce the above copyright
+*      notice, this list of conditions and the following disclaimer in the
+*      documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "davcontroller.h"
+#include "window.h"
+
+#include <cx/printf.h>
+
+#include <libidav/utils.h>
+
+DavBrowser* davbrowser_create(UiObject *toplevel) {
+    DavBrowser *doc = ui_document_new(sizeof(DavBrowser));
+    UiContext *ctx = ui_document_context(doc);
+    doc->ctx = ctx;
+
+    doc->dav_queue = ui_threadpool_create(1);
+
+    doc->path = ui_string_new(ctx, "path");
+    doc->resources = ui_list_new(ctx, "reslist");
+
+    return doc;
+}
+
+
+void davbrowser_set_collection(UiObject *ui, DavBrowser *browser, DavResource *collection) {
+    ui_list_clear(browser->resources);
+
+    for (DavResource *res = collection->children; res; res = res->next) {
+        ui_list_append(browser->resources, res);
+    }
+
+    browser->resources->update(browser->resources, 0);
+}
+
+// ------------------------------ davbrowser_connect2repo ------------------------------
+
+static int connect2repo(void *data) {
+    DavBrowser *browser = data;
+    DavCfgRepository *repo = browser->repository;
+
+    // TODO: cleanup current session
+    DavSession *sn = dav_session_new(application_dav_context(), repo->url.value.ptr);
+    if (repo->user.value.ptr && repo->password.value.ptr) {
+        cxmutstr decodedpw = dav_repository_get_decodedpassword(repo);
+        dav_session_set_auth(sn, repo->user.value.ptr, decodedpw.ptr);
+        free(decodedpw.ptr);
+    }
+    browser->sn = sn;
+
+    return 0;
+}
+
+static void repo_connected(UiEvent *event, void *data) {
+    DavBrowser *browser = event->document;
+    ui_set(browser->path, browser->repository->name.value.ptr);
+
+    davbrowser_query_path(event->obj, browser, "/");
+}
+
+void davbrowser_connect2repo(UiObject *ui, DavBrowser *browser, DavCfgRepository *repo) {
+    browser->repository = repo;
+    ui_threadpool_job(browser->dav_queue, ui, connect2repo, browser, repo_connected, NULL);
+}
+
+
+// ------------------------------ davbrowser_query_path ------------------------------
+
+typedef struct DavBrowserQueryPath {
+    DavBrowser *browser;
+    char *path;
+    DavResource *result;
+} DavBrowserQueryPath;
+
+static int browser_query_path(void *data) {
+    DavBrowserQueryPath *query = data;
+    DavSession *sn = query->browser->sn;
+
+    DavResource *res = dav_query(sn, "select `idav:crypto-name`,`idav:crypto-key`,D:lockdiscovery from %s with depth = 1 order by iscollection desc, name", query->path);
+    query->result = res;
+
+    return 0;
+}
+
+static void browser_query_finished(UiEvent *event, void *data) {
+    DavBrowserQueryPath *query = data;
+    DavBrowser *browser = event->document;
+
+    if (query->result) {
+        davbrowser_set_collection(event->obj, browser, query->result);
+    } else {
+        // TODO: error
+    }
+
+    free(query->path);
+    free(query);
+
+    window_progress(event->window, 0);
+}
+
+void davbrowser_query_path(UiObject *ui, DavBrowser *browser, const char *path) {
+    // for comparison, we need the current base_url/repo_name + path
+    size_t len = path ? strlen(path) : 0;
+    if (len == 1 && *path == '/') {
+        path = "";
+    }
+    char *full_path = util_concat_path(browser->repository->name.value.ptr, path);
+    // compare new path with current path
+    // in theory we could always set path, but maybe this is faster
+    char *current_path = ui_get(browser->path);
+    if (strcmp(full_path, current_path)) {
+        ui_set(browser->path, full_path);
+    }
+    free(full_path);
+
+    DavBrowserQueryPath *query = malloc(sizeof(DavBrowserQueryPath));
+    query->browser = browser;
+    query->path = strdup(path);
+    query->result = NULL;
+    ui_threadpool_job(browser->dav_queue, ui, browser_query_path, query, browser_query_finished, query);
+
+    window_progress(ui->window, 1);
+}

mercurial