application/davcontroller.c

changeset 18
af411868ab9b
parent 17
7cfd36aa005b
child 19
813c97c5b6d3
--- a/application/davcontroller.c	Wed Jan 31 12:55:11 2024 +0100
+++ b/application/davcontroller.c	Tue Feb 06 14:17:22 2024 +0100
@@ -33,6 +33,8 @@
 
 #include "config.h"
 
+#include "system.h"
+
 #include <libidav/config.h>
 #include <libidav/utils.h>
 
@@ -234,3 +236,137 @@
         browser->navstack_enabled = true;
     }
 }
+
+
+// ------------------------------------- File Upload -------------------------------------
+
+typedef struct DavFileUpload {
+    UiObject *ui;
+    DavBrowser *browser;
+    DavSession *sn;
+    UiFileList files;
+    char *base_path;
+
+    UiObject *dialog;
+    UiDouble *progress;
+    UiString *file_label;
+    UiString *speed_label;
+} DavFileUpload;
+
+typedef struct DUFile {
+    char *path;
+    char *upload_path;
+} DUFile;
+
+static int jobthr_file_upload(void *data) {
+    DavFileUpload *upload = data;
+
+    CxList *stack = cxLinkedListCreateSimple(sizeof(DUFile));
+    for (int i = 0; i < upload->files.nfiles; i++) {
+        DUFile f;
+        f.path = upload->files.files[i];
+        f.upload_path = util_path_file_name(f.path);
+        cxListInsert(stack, 0, &f);
+    }
+
+    while (stack->size > 0) {
+        DUFile *f = cxListAt(stack, 0);
+
+        char *path = util_concat_path(upload->base_path, f->upload_path);
+        DavResource *res = dav_resource_new(upload->sn, path);
+
+        SYS_STAT s;
+        if (!stat(f->path, &s)) {
+            if (S_ISDIR(s.st_mode)) {
+                res->iscollection = 1;
+                dav_create(res);
+
+                SYS_DIR dir = sys_opendir(f->path);
+                if (dir) {
+                    SysDirEnt *entry;
+                    int nument = 0;
+                    while((entry = sys_readdir(dir)) != NULL) {
+                        if(!strcmp(entry->name, ".") || !strcmp(entry->name, "..")) {
+                            continue;
+                        }
+                        
+                        cxmutstr newpath = util_concat_sys_path(cx_str(f->path), cx_str(entry->name));
+                        char *new_upload_path = util_concat_path(f->upload_path, entry->name);
+
+                        DUFile child;
+                        child.path = newpath.ptr;
+                        child.upload_path = new_upload_path;
+                        cxListAdd(stack, &child);
+                    }
+
+                    sys_closedir(dir);
+                }
+            } else if (S_ISREG(s.st_mode)) {
+                FILE *in = sys_fopen(f->path, "rb");
+                if (in) {
+                    dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)fseek);
+                    //dav_set_content_length(res, s.st_size);
+                    int err = dav_store(res);
+                    if (err) {
+                        // TODO: error
+
+                    }
+                    fclose(in);
+                }
+            }
+        } // TODO: else error msg
+
+        dav_resource_free(res);
+        free(path);
+
+        cxListRemove(stack, 0);
+    }
+
+    return 0;
+}
+
+static void uithr_file_upload_finished(UiEvent *event, void *data) {
+    DavFileUpload *upload = data;
+}
+
+
+void davbrowser_upload_files(UiObject *ui, DavBrowser *browser, UiFileList files) {
+    if (!browser->sn) {
+        return; // TODO: error msg
+    }
+
+    // we need a clone of the current session, because the upload
+    // is done in a separate thread
+    DavSession *upload_session = dav_session_clone(browser->sn);
+
+    // create upload obj, that contains all relevant data for the upload
+    DavFileUpload *upload = malloc(sizeof(DavFileUpload));
+    upload->ui = ui;
+    upload->browser = browser;
+    upload->sn = upload_session;
+    upload->files = files;
+    upload->base_path = strdup(browser->current->path);
+
+    // create upload progress window
+    UiObject *dialog = ui_simple_window("Upload", upload);
+    upload->dialog = dialog;
+    ui_window_size(dialog, 450, 120);
+    upload->progress = ui_double_new(dialog->ctx, NULL);
+    upload->file_label = ui_string_new(dialog->ctx, NULL);
+    upload->speed_label = ui_string_new(dialog->ctx, NULL);
+
+    ui_vbox(dialog, .margin = 10, .spacing = 10) {
+        ui_llabel(dialog, .value = upload->file_label);
+        ui_progressbar(dialog, .value = upload->progress);
+        ui_llabel(dialog, .value = upload->speed_label);
+    }
+
+    ui_set(upload->file_label, "");
+    ui_set(upload->speed_label, "");
+    ui_set(upload->progress, 0);
+
+    //ui_show(dialog);
+
+    // start upload and stat threads
+    ui_job(ui, jobthr_file_upload, upload, uithr_file_upload_finished, upload);
+}

mercurial