application/davcontroller.c

changeset 20
db263186edf3
parent 19
813c97c5b6d3
child 21
3060a5a1d5fd
equal deleted inserted replaced
19:813c97c5b6d3 20:db263186edf3
253 size_t total_directories; 253 size_t total_directories;
254 size_t uploaded_bytes; 254 size_t uploaded_bytes;
255 size_t uploaded_files; 255 size_t uploaded_files;
256 size_t uploaded_directories; 256 size_t uploaded_directories;
257 257
258 DavBool upload_file;
259 size_t current_file_size;
260 size_t current_file_upload;
261
262 char *current_file_name;
263
258 UiObject *dialog; 264 UiObject *dialog;
259 UiDouble *progress; 265 UiDouble *progress;
260 UiString *file_label; 266 UiString *label_top_left;
261 UiString *speed_label; 267 UiString *label_top_right;
268 UiString *label_bottom_left;
269 UiString *label_bottom_right;
262 } DavFileUpload; 270 } DavFileUpload;
263 271
264 typedef struct DUFile { 272 typedef struct DUFile {
265 char *path; 273 char *path;
266 char *upload_path; 274 char *upload_path;
272 280
273 static double upload_progress(DavFileUpload *upload) { 281 static double upload_progress(DavFileUpload *upload) {
274 return ((double)upload->uploaded_bytes / (double)upload->total_bytes) * 100; 282 return ((double)upload->uploaded_bytes / (double)upload->total_bytes) * 100;
275 } 283 }
276 284
285 static void update_upload_labels(DavFileUpload *upload) {
286 char *sz_total = util_size_str(FALSE, upload->total_bytes);
287 char *sz_uploaded = util_size_str2(FALSE, upload->uploaded_bytes, upload->total_bytes, 2);
288 char *sz_uploaded_end = strchr(sz_uploaded, ' ');
289 if (sz_uploaded_end) {
290 *sz_uploaded_end = 0;
291 }
292
293 cxmutstr label1 = cx_asprintf(
294 "%s/%s %zu/%zu files",
295 sz_uploaded,
296 sz_total,
297 upload->uploaded_files+upload->uploaded_directories,
298 upload->total_files+upload->total_directories);
299 ui_set(upload->label_top_left, label1.ptr);
300
301 free(sz_total);
302 free(label1.ptr);
303
304
305 cxmutstr file_label = cx_asprintf("%s (%.0f%%)", upload->current_file_name, ((float)upload->current_file_upload/(float)upload->current_file_size)*100);
306 ui_set(upload->label_top_right, file_label.ptr);
307
308 free(file_label.ptr);
309 }
310
311 static int uithr_update_upload_labels(void *data) {
312 update_upload_labels(data);
313 return 0;
314 }
315
316 static void upload_dav_progress(DavResource *res, int64_t total, int64_t now, void *data) {
317 DavFileUpload *upload = data;
318 if (upload->upload_file) {
319 if (now > upload->current_file_size) {
320 // current_file_size is not accurate (either the file was changed after the last stat
321 // or we have some extra bytes because of encryption
322 // adjust current_file_size and the total upload size
323 int64_t extra = now - upload->current_file_size;
324 upload->current_file_size += extra;
325 upload->total_bytes += extra;
326 }
327
328 int64_t new_progress = now - upload->current_file_upload;
329 upload->uploaded_bytes += new_progress;
330 upload->current_file_upload = now;
331
332 ui_call_mainthread(uithr_update_upload_labels, upload);
333 }
334 }
335
336
337 typedef struct FileNameUpdate {
338 DavFileUpload *upload;
339 char *name;
340 } FileNameUpdate;
341
342 static int uithr_update_file_label(FileNameUpdate *update) {
343 // replace upload->current_filename with update->name
344 if (update->upload->current_file_name) {
345 free(update->upload->current_file_name);
346 }
347 update->upload->current_file_name = update->name;
348
349 ui_set(update->upload->label_top_right, update->name);
350
351 free(update);
352 return 0;
353 }
354
277 static int qthr_file_upload(void *data) { 355 static int qthr_file_upload(void *data) {
278 DUFile *f = data; 356 DUFile *f = data;
279 DavFileUpload *upload = f->upload; 357 DavFileUpload *upload = f->upload;
280 DavSession *sn = upload->sn; 358 DavSession *sn = upload->sn;
281 359
283 if (!in) { 361 if (!in) {
284 // TODO: error msg 362 // TODO: error msg
285 return 0; 363 return 0;
286 } 364 }
287 365
366 upload->upload_file = TRUE;
367 upload->current_file_size = f->bytes;
368 upload->current_file_upload = 0;
369
288 DavResource *res = dav_resource_new(sn, f->upload_path); 370 DavResource *res = dav_resource_new(sn, f->upload_path);
371
372 FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate));
373 ui_update->upload = upload;
374 ui_update->name = strdup(res->name);
375 ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update);
376
289 dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)fseek); 377 dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)fseek);
290 if (dav_store(res)) { 378 if (dav_store(res)) {
291 f->error = sn->error; 379 f->error = sn->error;
292 } 380 }
293 dav_resource_free(res); 381 dav_resource_free(res);
294 382
295 fclose(in); 383 fclose(in);
296 384
385 upload->upload_file = FALSE;
386
297 return 0; 387 return 0;
298 } 388 }
299 389
300 static void uithr_file_uploaded(UiEvent *event, void *data) { 390 static void uithr_file_uploaded(UiEvent *event, void *data) {
301 DUFile *file = data; 391 DUFile *file = data;
302 DavFileUpload *upload = file->upload; 392 DavFileUpload *upload = file->upload;
303 393
304 upload->uploaded_files++; 394 upload->uploaded_files++;
305 upload->uploaded_bytes += file->bytes; 395 //upload->uploaded_bytes += file->bytes;
306 396
307 double progress = upload_progress(upload); 397 double progress = upload_progress(upload);
308 ui_set(upload->progress, upload_progress(upload)); 398 ui_set(upload->progress, upload_progress(upload));
399
400 update_upload_labels(upload);
309 401
310 free(file->path); 402 free(file->path);
311 free(file->upload_path); 403 free(file->upload_path);
312 } 404 }
313 405
317 DavSession *sn = upload->sn; 409 DavSession *sn = upload->sn;
318 410
319 DavResource *res = dav_resource_new(sn, f->upload_path); 411 DavResource *res = dav_resource_new(sn, f->upload_path);
320 res->iscollection = TRUE; 412 res->iscollection = TRUE;
321 413
414 FileNameUpdate *ui_update = malloc(sizeof(FileNameUpdate));
415 ui_update->upload = upload;
416 ui_update->name = strdup(res->name);
417 ui_call_mainthread((ui_threadfunc)uithr_update_file_label, ui_update);
418
322 if (dav_create(res)) { 419 if (dav_create(res)) {
323 f->error = sn->error; 420 f->error = sn->error;
324 } 421 }
325 422
326 dav_resource_free(res); 423 dav_resource_free(res);
331 static void uithr_dir_uploaded(UiEvent *event, void *data) { 428 static void uithr_dir_uploaded(UiEvent *event, void *data) {
332 DUFile *file = data; 429 DUFile *file = data;
333 DavFileUpload *upload = file->upload; 430 DavFileUpload *upload = file->upload;
334 431
335 upload->uploaded_directories++; 432 upload->uploaded_directories++;
433
434 update_upload_labels(upload);
336 435
337 free(file->path); 436 free(file->path);
338 free(file->upload_path); 437 free(file->upload_path);
339 } 438 }
340 439
370 469
371 char *path = util_concat_path(upload->base_path, f->upload_path); 470 char *path = util_concat_path(upload->base_path, f->upload_path);
372 cxListRemove(stack, 0); 471 cxListRemove(stack, 0);
373 472
374 SYS_STAT s; 473 SYS_STAT s;
375 if (!stat(f->path, &s)) { 474 if (!sys_stat(f->path, &s)) {
376 if (S_ISDIR(s.st_mode)) { 475 if (S_ISDIR(s.st_mode)) {
377 f->isdirectory = TRUE; 476 f->isdirectory = TRUE;
378 upload->total_directories++; 477 upload->total_directories++;
379 ui_threadpool_job(upload->queue, upload->ui, qthr_dir_upload, f, uithr_dir_uploaded, f); 478 ui_threadpool_job(upload->queue, upload->ui, qthr_dir_upload, f, uithr_dir_uploaded, f);
380 479
419 return 0; 518 return 0;
420 } 519 }
421 520
422 static void uithr_upload_scan_finished(UiEvent *event, void *data) { 521 static void uithr_upload_scan_finished(UiEvent *event, void *data) {
423 DavFileUpload *upload = data; 522 DavFileUpload *upload = data;
523
524 update_upload_labels(upload);
424 } 525 }
425 526
426 527
427 void davbrowser_upload_files(UiObject *ui, DavBrowser *browser, UiFileList files) { 528 void davbrowser_upload_files(UiObject *ui, DavBrowser *browser, UiFileList files) {
428 if (!browser->sn) { 529 if (!browser->sn) {
434 DavSession *upload_session = dav_session_clone(browser->sn); 535 DavSession *upload_session = dav_session_clone(browser->sn);
435 536
436 // create upload obj, that contains all relevant data for the upload 537 // create upload obj, that contains all relevant data for the upload
437 DavFileUpload *upload = malloc(sizeof(DavFileUpload)); 538 DavFileUpload *upload = malloc(sizeof(DavFileUpload));
438 memset(upload, 0, sizeof(DavFileUpload)); 539 memset(upload, 0, sizeof(DavFileUpload));
540
541 dav_session_set_progresscallback(upload_session, NULL, upload_dav_progress, upload);
439 542
440 upload->ui = ui; 543 upload->ui = ui;
441 upload->browser = browser; 544 upload->browser = browser;
442 upload->sn = upload_session; 545 upload->sn = upload_session;
443 upload->files = files; 546 upload->files = files;
444 upload->base_path = strdup(browser->current->path); 547 upload->base_path = strdup(browser->current->path);
445 upload->queue = ui_threadpool_create(1); 548 upload->queue = ui_threadpool_create(1);
446 549
447 // create upload progress window 550 // create upload progress window
448 UiObject *dialog = ui_simple_window("Upload", upload); 551 cxmutstr wtitle = cx_asprintf("Upload to: %s", ui_get(browser->path));
552 UiObject *dialog = ui_simple_window(wtitle.ptr, upload);
553 free(wtitle.ptr);
449 upload->dialog = dialog; 554 upload->dialog = dialog;
450 ui_window_size(dialog, 450, 120); 555 ui_window_size(dialog, 550, 120);
451 upload->progress = ui_double_new(dialog->ctx, NULL); 556 upload->progress = ui_double_new(dialog->ctx, NULL);
452 upload->file_label = ui_string_new(dialog->ctx, NULL); 557 upload->label_top_left = ui_string_new(dialog->ctx, NULL);
453 upload->speed_label = ui_string_new(dialog->ctx, NULL); 558 upload->label_top_right = ui_string_new(dialog->ctx, NULL);
454 559 upload->label_bottom_left = ui_string_new(dialog->ctx, NULL);
455 ui_vbox(dialog, .margin = 10, .spacing = 10) { 560 upload->label_bottom_right = ui_string_new(dialog->ctx, NULL);
456 ui_llabel(dialog, .value = upload->file_label); 561
457 ui_progressbar(dialog, .value = upload->progress); 562 ui_grid(dialog, .margin = 10, .spacing = 10, .fill = TRUE) {
458 ui_llabel(dialog, .value = upload->speed_label); 563 ui_llabel(dialog, .value = upload->label_top_left, .hexpand = TRUE);
459 } 564 ui_rlabel(dialog, .value = upload->label_top_right);
460 565 ui_newline(dialog);
461 ui_set(upload->file_label, ""); 566
462 ui_set(upload->speed_label, ""); 567 ui_progressbar(dialog, .value = upload->progress, .colspan = 2, .hexpand = TRUE);
568 ui_newline(dialog);
569
570 ui_llabel(dialog, .value = upload->label_bottom_left);
571 ui_rlabel(dialog, .value = upload->label_bottom_right);
572 ui_newline(dialog);
573 }
574
575 ui_set(upload->label_top_left, "");
576 ui_set(upload->label_top_right, "");
577 ui_set(upload->label_bottom_left, "");
578 ui_set(upload->label_bottom_right, "");
463 ui_set(upload->progress, 0); 579 ui_set(upload->progress, 0);
464 580
465 ui_show(dialog); 581 ui_show(dialog);
466 582
467 // start upload and stat threads 583 // start upload and stat threads

mercurial