application/davcontroller.c

changeset 30
762afc7adc63
parent 29
3fc287f06305
child 31
bf810176ddb8
equal deleted inserted replaced
29:3fc287f06305 30:762afc7adc63
671 typedef struct DavFileDownload { 671 typedef struct DavFileDownload {
672 UiObject *ui; 672 UiObject *ui;
673 DavBrowser *browser; 673 DavBrowser *browser;
674 674
675 DavSession *sn; 675 DavSession *sn;
676 DavSession *download_sn;
676 DavResource *reslist; 677 DavResource *reslist;
677 char *local_path; 678 char *local_path;
678 DavBool isdirectory; 679 DavBool isdirectory;
679 680
680 UiThreadpool *queue; 681 UiThreadpool *queue;
692 UiString *label_top_right; 693 UiString *label_top_right;
693 UiString *label_bottom_left; 694 UiString *label_bottom_left;
694 UiString *label_bottom_right; 695 UiString *label_bottom_right;
695 } DavFileDownload; 696 } DavFileDownload;
696 697
698
699 static int uithr_download_update_progress(void *data) {
700 DavFileDownload *download = data;
701
702 char *sz_total = util_size_str(FALSE, download->total_bytes);
703 char *sz_downloaded = util_size_str2(FALSE, download->downloaded_bytes, download->total_bytes, 2);
704 char *sz_downloaded_end = strchr(sz_downloaded, ' ');
705 if (sz_downloaded_end) {
706 *sz_downloaded_end = 0;
707 }
708
709 double progress = (double)download->downloaded_bytes / (double)download->total_bytes;
710 ui_set(download->progress, progress);
711
712 cxmutstr label1;
713 if (download->total_files + download->total_directories > 1) {
714 label1 = cx_asprintf(
715 "%s/%s %zu/%zu files",
716 sz_downloaded,
717 sz_total,
718 download->downloaded_files+download->downloaded_directories,
719 download->total_files+download->total_directories);
720 } else {
721 label1 = cx_asprintf(
722 "%s/%s",
723 sz_downloaded,
724 sz_total);
725 }
726 ui_set(download->label_top_left, label1.ptr);
727
728 free(sz_total);
729 free(label1.ptr);
730
731
732 return 0;
733 }
734
697 // dav download file 735 // dav download file
698 typedef struct DDFile { 736 typedef struct DDFile {
699 DavFileDownload *download; 737 DavFileDownload *download;
700 DavResource *res; 738 char *path;
701 char *to; 739 char *to;
702 } DDFile; 740 } DDFile;
703 741
704 static int qthr_download_resource(void *data) { 742 static int qthr_download_resource(void *data) {
705 DDFile *file = data; 743 DDFile *file = data;
707 FILE *f = fopen(file->to, "wb"); 745 FILE *f = fopen(file->to, "wb");
708 if (!f) { 746 if (!f) {
709 return 0; 747 return 0;
710 } 748 }
711 749
712 dav_get_content(file->res, f, (dav_write_func)fwrite); 750 DavResource *res = dav_resource_new(file->download->download_sn, file->path);
751 dav_get_content(res, f, (dav_write_func)fwrite);
752
753 file->download->downloaded_bytes += res->contentlength;
754 file->download->downloaded_files++;
755
756 dav_resource_free(res);
713 757
714 fclose(f); 758 fclose(f);
715 } 759
760 free(file->path);
761 free(file->to);
762 free(file);
763 }
764
765
766 typedef struct DlStackElm {
767 DavResource *resource;
768 char *sub_path;
769 } DlStackElm;
716 770
717 static int jobthr_download_scan(void *data) { 771 static int jobthr_download_scan(void *data) {
718 DavFileDownload *download = data; 772 DavFileDownload *download = data;
719 DavBrowser *browser = download->browser; 773 DavBrowser *browser = download->browser;
720 774
724 if (S_ISDIR(s.st_mode)) { 778 if (S_ISDIR(s.st_mode)) {
725 download->isdirectory = TRUE; 779 download->isdirectory = TRUE;
726 } 780 }
727 } 781 }
728 782
783 CxList *stack = cxLinkedListCreateSimple(sizeof(DlStackElm));
784
729 // add selected files to the download queue 785 // add selected files to the download queue
730 DavResource *res = download->reslist; 786 DavResource *res = download->reslist;
731 while (res) { 787 while (res) {
732 DDFile *file = malloc(sizeof(DDFile)); 788 DlStackElm elm;
733 file->download = download; 789 elm.resource = res;
734 file->res = res; 790 elm.sub_path = strdup(res->name);
735 if (download->isdirectory) { 791 cxListAdd(stack, &elm);
736 file->to = util_concat_path(download->local_path, res->name); 792
793 res = res->next;
794 }
795
796 while (stack->size > 0) {
797 DlStackElm *elm = cxListAt(stack, 0);
798 DavResource *res = elm->resource;
799 char *sub_path = elm->sub_path;
800 cxListRemove(stack, 0);
801
802 if (res->iscollection) {
803 if (dav_load(res)) {
804 // TODO: handle error
805 continue;
806 }
807
808 download->total_directories++;
809
810 // update ui
811 //ui_call_mainthread(uithr_download_update_progress, download);
812
813 char *path = util_concat_path(download->local_path, sub_path);
814 int err = sys_mkdir(path);
815 free(path);
816 if (err) {
817 // TODO: handle error
818 }
819
820 DavResource *child = res->children;
821 while (child) {
822 char *child_path = util_concat_path(sub_path, child->name);
823 DlStackElm childelm;
824 childelm.resource = child;
825 childelm.sub_path = child_path;
826 cxListAdd(stack, &childelm);
827
828 child = child->next;
829 }
737 } else { 830 } else {
738 file->to = strdup(download->local_path); 831 // add the file to the download queue
739 } 832 DDFile *file = malloc(sizeof(DDFile));
740 833 file->download = download;
741 ui_threadpool_job(download->queue, download->ui, qthr_download_resource, file, NULL, NULL); 834 file->path = strdup(res->path);
742 835 if (download->isdirectory) {
743 res = res->next; 836 file->to = util_concat_path(download->local_path, sub_path);
744 } 837 } else {
838 file->to = strdup(download->local_path);
839 }
840
841 // stats
842 download->total_files++;
843 download->total_bytes += res->contentlength;
844
845 // update ui
846 //ui_call_mainthread(uithr_download_update_progress, download);
847
848 ui_threadpool_job(download->queue, download->ui, qthr_download_resource, file, NULL, NULL);
849 }
850 }
851
852 cxListDestroy(stack);
745 } 853 }
746 854
747 static void uithr_download_scan_finished(UiEvent *event, void *data) { 855 static void uithr_download_scan_finished(UiEvent *event, void *data) {
748 856
749 } 857 }
755 863
756 void davbrowser_download(UiObject *ui, DavBrowser *browser, DavResource *reslist, const char *local_path) { 864 void davbrowser_download(UiObject *ui, DavBrowser *browser, DavResource *reslist, const char *local_path) {
757 DavFileDownload *download = malloc(sizeof(DavFileDownload)); 865 DavFileDownload *download = malloc(sizeof(DavFileDownload));
758 memset(download, 0, sizeof(DavFileDownload)); 866 memset(download, 0, sizeof(DavFileDownload));
759 867
868 download->ui = ui;
760 download->browser = browser; 869 download->browser = browser;
761 download->sn = reslist->session; 870 download->sn = reslist->session;
871 download->download_sn = dav_session_clone(download->sn);
762 download->reslist = reslist; 872 download->reslist = reslist;
763 download->local_path = strdup(local_path); 873 download->local_path = strdup(local_path);
764 874
765 download->queue = ui_threadpool_create(1); 875 download->queue = ui_threadpool_create(1);
766 876

mercurial