diff -r 7cfd36aa005b -r af411868ab9b application/davcontroller.c --- 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 #include @@ -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); +}