application/davcontroller.c

changeset 29
3fc287f06305
parent 28
1ecc1183f046
child 30
762afc7adc63
--- a/application/davcontroller.c	Sun Feb 11 15:59:56 2024 +0100
+++ b/application/davcontroller.c	Mon Feb 12 17:32:02 2024 +0100
@@ -666,6 +666,143 @@
 }
 
 
+// ------------------------------------- File Download -------------------------------------
+
+typedef struct DavFileDownload {
+    UiObject *ui;
+    DavBrowser *browser;
+
+    DavSession *sn;
+    DavResource *reslist;
+    char *local_path;
+    DavBool isdirectory;
+
+    UiThreadpool *queue;
+
+    size_t total_bytes;
+    size_t total_files;
+    size_t total_directories;
+    size_t downloaded_bytes;
+    size_t downloaded_files;
+    size_t downloaded_directories;
+
+    UiObject *dialog;
+    UiDouble *progress;
+    UiString *label_top_left;
+    UiString *label_top_right;
+    UiString *label_bottom_left;
+    UiString *label_bottom_right;
+} DavFileDownload;
+
+// dav download file
+typedef struct DDFile {
+    DavFileDownload *download;
+    DavResource *res;
+    char *to;
+} DDFile;
+
+static int qthr_download_resource(void *data) {
+    DDFile *file = data;
+
+    FILE *f = fopen(file->to, "wb");
+    if (!f) {
+        return 0;
+    }
+
+    dav_get_content(file->res, f, (dav_write_func)fwrite);
+
+    fclose(f);
+}
+
+static int jobthr_download_scan(void *data) {
+    DavFileDownload *download = data;
+    DavBrowser *browser = download->browser;
+
+    // check if the specified local location is a directory
+    SYS_STAT s;
+    if (!sys_stat(download->local_path, &s)) {
+        if (S_ISDIR(s.st_mode)) {
+            download->isdirectory = TRUE;
+        }
+    }
+
+    // add selected files to the download queue
+    DavResource *res = download->reslist;
+    while (res) {
+        DDFile *file = malloc(sizeof(DDFile));
+        file->download = download;
+        file->res = res;
+        if (download->isdirectory) {
+            file->to = util_concat_path(download->local_path, res->name);
+        } else {
+            file->to = strdup(download->local_path);
+        }
+
+        ui_threadpool_job(download->queue, download->ui, qthr_download_resource, file, NULL, NULL);
+
+        res = res->next;
+    }
+}
+
+static void uithr_download_scan_finished(UiEvent *event, void *data) {
+
+}
+
+static void download_window_closed(UiEvent *event, void *data) {
+
+}
+
+
+void davbrowser_download(UiObject *ui, DavBrowser *browser, DavResource *reslist, const char *local_path) {
+    DavFileDownload *download = malloc(sizeof(DavFileDownload));
+    memset(download, 0, sizeof(DavFileDownload));
+
+    download->browser = browser;
+    download->sn = reslist->session;
+    download->reslist = reslist;
+    download->local_path = strdup(local_path);
+
+    download->queue = ui_threadpool_create(1);
+
+    // create download progress window
+    cxmutstr wtitle = cx_asprintf("Download to: %s", local_path);
+    UiObject *dialog = ui_simple_window(wtitle.ptr, download);
+    ui_context_closefunc(dialog->ctx, download_window_closed, NULL);
+    free(wtitle.ptr);
+    download->dialog = dialog;
+    ui_window_size(dialog, 550, 120);
+    download->progress = ui_double_new(dialog->ctx, NULL);
+    download->label_top_left = ui_string_new(dialog->ctx, NULL);
+    download->label_top_right = ui_string_new(dialog->ctx, NULL);
+    download->label_bottom_left = ui_string_new(dialog->ctx, NULL);
+    download->label_bottom_right = ui_string_new(dialog->ctx, NULL);
+
+    ui_grid(dialog, .margin = 10, .spacing = 10, .fill = TRUE) {
+        ui_llabel(dialog, .value = download->label_top_left, .hexpand = TRUE);
+        ui_rlabel(dialog, .value = download->label_top_right);
+        ui_newline(dialog);
+
+        ui_progressbar(dialog, .value = download->progress, .colspan = 2, .hexpand = TRUE);
+        ui_newline(dialog);
+
+        ui_llabel(dialog, .value = download->label_bottom_left);
+        ui_rlabel(dialog, .value = download->label_bottom_right);
+        ui_newline(dialog);
+    }
+
+    ui_set(download->label_top_left, "");
+    ui_set(download->label_top_right, "");
+    ui_set(download->label_bottom_left, "");
+    ui_set(download->label_bottom_right, "");
+    ui_set(download->progress, 0);
+
+    ui_show(dialog);
+
+    // start upload and stat threads
+    ui_job(ui, jobthr_download_scan, download, uithr_download_scan_finished, download);
+}
+
+
 // ------------------------------------- Path Operation (DELETE, MKCOL) -------------------------------------
 
 enum DavPathOpType {
@@ -812,8 +949,6 @@
     return 0;
 }
 
-
-
 void davbrowser_delete(UiObject *ui, DavBrowser *browser, UiListSelection selection) {
     DavPathOp *op = malloc(sizeof(DavPathOp));
     op->ui = ui;

mercurial