application/davcontroller.c

changeset 20
db263186edf3
parent 19
813c97c5b6d3
child 21
3060a5a1d5fd
--- a/application/davcontroller.c	Tue Feb 06 19:01:52 2024 +0100
+++ b/application/davcontroller.c	Wed Feb 07 17:10:01 2024 +0100
@@ -255,10 +255,18 @@
     size_t uploaded_files;
     size_t uploaded_directories;
 
+    DavBool upload_file;
+    size_t current_file_size;
+    size_t current_file_upload;
+
+    char *current_file_name;
+
     UiObject *dialog;
     UiDouble *progress;
-    UiString *file_label;
-    UiString *speed_label;
+    UiString *label_top_left;
+    UiString *label_top_right;
+    UiString *label_bottom_left;
+    UiString *label_bottom_right;
 } DavFileUpload;
 
 typedef struct DUFile {
@@ -274,6 +282,76 @@
     return ((double)upload->uploaded_bytes / (double)upload->total_bytes) * 100;
 }
 
+static void update_upload_labels(DavFileUpload *upload) {
+    char *sz_total = util_size_str(FALSE, upload->total_bytes);
+    char *sz_uploaded = util_size_str2(FALSE, upload->uploaded_bytes, upload->total_bytes, 2);
+    char *sz_uploaded_end = strchr(sz_uploaded, ' ');
+    if (sz_uploaded_end) {
+        *sz_uploaded_end = 0;
+    }
+
+    cxmutstr label1 = cx_asprintf(
+        "%s/%s   %zu/%zu files",
+        sz_uploaded,
+        sz_total,
+        upload->uploaded_files+upload->uploaded_directories,
+        upload->total_files+upload->total_directories);
+    ui_set(upload->label_top_left, label1.ptr);
+
+    free(sz_total);
+    free(label1.ptr);
+
+
+    cxmutstr file_label = cx_asprintf("%s (%.0f%%)", upload->current_file_name, ((float)upload->current_file_upload/(float)upload->current_file_size)*100);
+    ui_set(upload->label_top_right, file_label.ptr);
+
+    free(file_label.ptr);
+}
+
+static int uithr_update_upload_labels(void *data) {
+    update_upload_labels(data);
+    return 0;
+}
+
+static void upload_dav_progress(DavResource *res, int64_t total, int64_t now, void *data) {
+    DavFileUpload *upload = data;
+    if (upload->upload_file) {
+        if (now > upload->current_file_size) {
+            // current_file_size is not accurate (either the file was changed after the last stat
+            // or we have some extra bytes because of encryption
+            // adjust current_file_size and the total upload size
+            int64_t extra = now - upload->current_file_size;
+            upload->current_file_size += extra;
+            upload->total_bytes += extra;
+        }
+
+        int64_t new_progress = now - upload->current_file_upload;
+        upload->uploaded_bytes += new_progress;
+        upload->current_file_upload = now;
+
+        ui_call_mainthread(uithr_update_upload_labels, upload);
+    }
+}
+
+
+typedef struct FileNameUpdate {
+    DavFileUpload *upload;
+    char *name;
+} FileNameUpdate;
+
+static int uithr_update_file_label(FileNameUpdate *update) {
+    // replace upload->current_filename with update->name
+    if (update->upload->current_file_name) {
+        free(update->upload->current_file_name);
+    }
+    update->upload->current_file_name = update->name;
+
+    ui_set(update->upload->label_top_right, update->name);
+
+    free(update);
+    return 0;
+}
+
 static int qthr_file_upload(void *data) {
     DUFile *f = data;
     DavFileUpload *upload = f->upload;
@@ -285,7 +363,17 @@
         return 0;
     }
 
+    upload->upload_file = TRUE;
+    upload->current_file_size = f->bytes;
+    upload->current_file_upload = 0;
+
     DavResource *res = dav_resource_new(sn, f->upload_path);
+
+    FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate));
+    ui_update->upload = upload;
+    ui_update->name = strdup(res->name);
+    ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update);
+
     dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)fseek);
     if (dav_store(res)) {
         f->error = sn->error;
@@ -294,6 +382,8 @@
 
     fclose(in);
 
+    upload->upload_file = FALSE;
+
     return 0;
 }
 
@@ -302,11 +392,13 @@
     DavFileUpload *upload = file->upload;
 
     upload->uploaded_files++;
-    upload->uploaded_bytes += file->bytes;
+    //upload->uploaded_bytes += file->bytes;
 
     double progress = upload_progress(upload);
     ui_set(upload->progress, upload_progress(upload));
 
+    update_upload_labels(upload);
+
     free(file->path);
     free(file->upload_path);
 }
@@ -319,6 +411,11 @@
     DavResource *res = dav_resource_new(sn, f->upload_path);
     res->iscollection = TRUE;
 
+    FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate));
+    ui_update->upload = upload;
+    ui_update->name = strdup(res->name);
+    ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update);
+
     if (dav_create(res)) {
         f->error = sn->error;
     }
@@ -334,6 +431,8 @@
 
     upload->uploaded_directories++;
 
+    update_upload_labels(upload);
+
     free(file->path);
     free(file->upload_path);
 }
@@ -372,7 +471,7 @@
         cxListRemove(stack, 0);
 
         SYS_STAT s;
-        if (!stat(f->path, &s)) {
+        if (!sys_stat(f->path, &s)) {
             if (S_ISDIR(s.st_mode)) {
                 f->isdirectory = TRUE;
                 upload->total_directories++;
@@ -421,6 +520,8 @@
 
 static void uithr_upload_scan_finished(UiEvent *event, void *data) {
     DavFileUpload *upload = data;
+
+    update_upload_labels(upload);
 }
 
 
@@ -437,6 +538,8 @@
     DavFileUpload *upload = malloc(sizeof(DavFileUpload));
     memset(upload, 0, sizeof(DavFileUpload));
 
+    dav_session_set_progresscallback(upload_session, NULL, upload_dav_progress, upload);
+
     upload->ui = ui;
     upload->browser = browser;
     upload->sn = upload_session;
@@ -445,21 +548,34 @@
     upload->queue = ui_threadpool_create(1);
 
     // create upload progress window
-    UiObject *dialog = ui_simple_window("Upload", upload);
+    cxmutstr wtitle = cx_asprintf("Upload to: %s", ui_get(browser->path));
+    UiObject *dialog = ui_simple_window(wtitle.ptr, upload);
+    free(wtitle.ptr);
     upload->dialog = dialog;
-    ui_window_size(dialog, 450, 120);
+    ui_window_size(dialog, 550, 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);
+    upload->label_top_left = ui_string_new(dialog->ctx, NULL);
+    upload->label_top_right = ui_string_new(dialog->ctx, NULL);
+    upload->label_bottom_left = ui_string_new(dialog->ctx, NULL);
+    upload->label_bottom_right = 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_grid(dialog, .margin = 10, .spacing = 10, .fill = TRUE) {
+        ui_llabel(dialog, .value = upload->label_top_left, .hexpand = TRUE);
+        ui_rlabel(dialog, .value = upload->label_top_right);
+        ui_newline(dialog);
+
+        ui_progressbar(dialog, .value = upload->progress, .colspan = 2, .hexpand = TRUE);
+        ui_newline(dialog);
+
+        ui_llabel(dialog, .value = upload->label_bottom_left);
+        ui_rlabel(dialog, .value = upload->label_bottom_right);
+        ui_newline(dialog);
     }
 
-    ui_set(upload->file_label, "");
-    ui_set(upload->speed_label, "");
+    ui_set(upload->label_top_left, "");
+    ui_set(upload->label_top_right, "");
+    ui_set(upload->label_bottom_left, "");
+    ui_set(upload->label_bottom_right, "");
     ui_set(upload->progress, 0);
 
     ui_show(dialog);

mercurial