diff -r 905ac52c910f -r 726b24766437 application/davcontroller.c --- /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 + +#include + +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); +}