664 // start upload and stat threads |
664 // start upload and stat threads |
665 ui_job(ui, jobthr_upload_scan, upload, uithr_upload_scan_finished, upload); |
665 ui_job(ui, jobthr_upload_scan, upload, uithr_upload_scan_finished, upload); |
666 } |
666 } |
667 |
667 |
668 |
668 |
|
669 // ------------------------------------- File Download ------------------------------------- |
|
670 |
|
671 typedef struct DavFileDownload { |
|
672 UiObject *ui; |
|
673 DavBrowser *browser; |
|
674 |
|
675 DavSession *sn; |
|
676 DavResource *reslist; |
|
677 char *local_path; |
|
678 DavBool isdirectory; |
|
679 |
|
680 UiThreadpool *queue; |
|
681 |
|
682 size_t total_bytes; |
|
683 size_t total_files; |
|
684 size_t total_directories; |
|
685 size_t downloaded_bytes; |
|
686 size_t downloaded_files; |
|
687 size_t downloaded_directories; |
|
688 |
|
689 UiObject *dialog; |
|
690 UiDouble *progress; |
|
691 UiString *label_top_left; |
|
692 UiString *label_top_right; |
|
693 UiString *label_bottom_left; |
|
694 UiString *label_bottom_right; |
|
695 } DavFileDownload; |
|
696 |
|
697 // dav download file |
|
698 typedef struct DDFile { |
|
699 DavFileDownload *download; |
|
700 DavResource *res; |
|
701 char *to; |
|
702 } DDFile; |
|
703 |
|
704 static int qthr_download_resource(void *data) { |
|
705 DDFile *file = data; |
|
706 |
|
707 FILE *f = fopen(file->to, "wb"); |
|
708 if (!f) { |
|
709 return 0; |
|
710 } |
|
711 |
|
712 dav_get_content(file->res, f, (dav_write_func)fwrite); |
|
713 |
|
714 fclose(f); |
|
715 } |
|
716 |
|
717 static int jobthr_download_scan(void *data) { |
|
718 DavFileDownload *download = data; |
|
719 DavBrowser *browser = download->browser; |
|
720 |
|
721 // check if the specified local location is a directory |
|
722 SYS_STAT s; |
|
723 if (!sys_stat(download->local_path, &s)) { |
|
724 if (S_ISDIR(s.st_mode)) { |
|
725 download->isdirectory = TRUE; |
|
726 } |
|
727 } |
|
728 |
|
729 // add selected files to the download queue |
|
730 DavResource *res = download->reslist; |
|
731 while (res) { |
|
732 DDFile *file = malloc(sizeof(DDFile)); |
|
733 file->download = download; |
|
734 file->res = res; |
|
735 if (download->isdirectory) { |
|
736 file->to = util_concat_path(download->local_path, res->name); |
|
737 } else { |
|
738 file->to = strdup(download->local_path); |
|
739 } |
|
740 |
|
741 ui_threadpool_job(download->queue, download->ui, qthr_download_resource, file, NULL, NULL); |
|
742 |
|
743 res = res->next; |
|
744 } |
|
745 } |
|
746 |
|
747 static void uithr_download_scan_finished(UiEvent *event, void *data) { |
|
748 |
|
749 } |
|
750 |
|
751 static void download_window_closed(UiEvent *event, void *data) { |
|
752 |
|
753 } |
|
754 |
|
755 |
|
756 void davbrowser_download(UiObject *ui, DavBrowser *browser, DavResource *reslist, const char *local_path) { |
|
757 DavFileDownload *download = malloc(sizeof(DavFileDownload)); |
|
758 memset(download, 0, sizeof(DavFileDownload)); |
|
759 |
|
760 download->browser = browser; |
|
761 download->sn = reslist->session; |
|
762 download->reslist = reslist; |
|
763 download->local_path = strdup(local_path); |
|
764 |
|
765 download->queue = ui_threadpool_create(1); |
|
766 |
|
767 // create download progress window |
|
768 cxmutstr wtitle = cx_asprintf("Download to: %s", local_path); |
|
769 UiObject *dialog = ui_simple_window(wtitle.ptr, download); |
|
770 ui_context_closefunc(dialog->ctx, download_window_closed, NULL); |
|
771 free(wtitle.ptr); |
|
772 download->dialog = dialog; |
|
773 ui_window_size(dialog, 550, 120); |
|
774 download->progress = ui_double_new(dialog->ctx, NULL); |
|
775 download->label_top_left = ui_string_new(dialog->ctx, NULL); |
|
776 download->label_top_right = ui_string_new(dialog->ctx, NULL); |
|
777 download->label_bottom_left = ui_string_new(dialog->ctx, NULL); |
|
778 download->label_bottom_right = ui_string_new(dialog->ctx, NULL); |
|
779 |
|
780 ui_grid(dialog, .margin = 10, .spacing = 10, .fill = TRUE) { |
|
781 ui_llabel(dialog, .value = download->label_top_left, .hexpand = TRUE); |
|
782 ui_rlabel(dialog, .value = download->label_top_right); |
|
783 ui_newline(dialog); |
|
784 |
|
785 ui_progressbar(dialog, .value = download->progress, .colspan = 2, .hexpand = TRUE); |
|
786 ui_newline(dialog); |
|
787 |
|
788 ui_llabel(dialog, .value = download->label_bottom_left); |
|
789 ui_rlabel(dialog, .value = download->label_bottom_right); |
|
790 ui_newline(dialog); |
|
791 } |
|
792 |
|
793 ui_set(download->label_top_left, ""); |
|
794 ui_set(download->label_top_right, ""); |
|
795 ui_set(download->label_bottom_left, ""); |
|
796 ui_set(download->label_bottom_right, ""); |
|
797 ui_set(download->progress, 0); |
|
798 |
|
799 ui_show(dialog); |
|
800 |
|
801 // start upload and stat threads |
|
802 ui_job(ui, jobthr_download_scan, download, uithr_download_scan_finished, download); |
|
803 } |
|
804 |
|
805 |
669 // ------------------------------------- Path Operation (DELETE, MKCOL) ------------------------------------- |
806 // ------------------------------------- Path Operation (DELETE, MKCOL) ------------------------------------- |
670 |
807 |
671 enum DavPathOpType { |
808 enum DavPathOpType { |
672 DAV_PATH_OP_DELETE = 0, |
809 DAV_PATH_OP_DELETE = 0, |
673 DAV_PATH_OP_MKCOL |
810 DAV_PATH_OP_MKCOL |