685 size_t total_directories; |
685 size_t total_directories; |
686 size_t downloaded_bytes; |
686 size_t downloaded_bytes; |
687 size_t downloaded_files; |
687 size_t downloaded_files; |
688 size_t downloaded_directories; |
688 size_t downloaded_directories; |
689 |
689 |
|
690 size_t current_file_size; |
|
691 size_t current_file_downloaded; |
|
692 |
690 UiObject *dialog; |
693 UiObject *dialog; |
691 UiDouble *progress; |
694 UiDouble *progress; |
692 UiString *label_top_left; |
695 UiString *label_top_left; |
693 UiString *label_top_right; |
696 UiString *label_top_right; |
694 UiString *label_bottom_left; |
697 UiString *label_bottom_left; |
696 } DavFileDownload; |
699 } DavFileDownload; |
697 |
700 |
698 |
701 |
699 static int uithr_download_update_progress(void *data) { |
702 static int uithr_download_update_progress(void *data) { |
700 DavFileDownload *download = data; |
703 DavFileDownload *download = data; |
701 |
|
702 char *sz_total = util_size_str(FALSE, download->total_bytes); |
704 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); |
705 char *sz_downloaded = util_size_str2(FALSE, download->downloaded_bytes, download->total_bytes, 2); |
704 char *sz_downloaded_end = strchr(sz_downloaded, ' '); |
706 char *sz_downloaded_end = strchr(sz_downloaded, ' '); |
705 if (sz_downloaded_end) { |
707 if (sz_downloaded_end) { |
706 *sz_downloaded_end = 0; |
708 *sz_downloaded_end = 0; |
707 } |
709 } |
708 |
710 |
709 double progress = (double)download->downloaded_bytes / (double)download->total_bytes; |
711 if (download->total_bytes > 0) { |
710 ui_set(download->progress, progress); |
712 double progress = (double)download->downloaded_bytes / (double)download->total_bytes; |
|
713 ui_set(download->progress, progress*100); |
|
714 } |
|
715 |
711 |
716 |
712 cxmutstr label1; |
717 cxmutstr label1; |
713 if (download->total_files + download->total_directories > 1) { |
718 if (download->total_files + download->total_directories > 1) { |
714 label1 = cx_asprintf( |
719 label1 = cx_asprintf( |
715 "%s/%s %zu/%zu files", |
720 "%s/%s %zu/%zu files", |
727 |
732 |
728 free(sz_total); |
733 free(sz_total); |
729 free(label1.ptr); |
734 free(label1.ptr); |
730 |
735 |
731 |
736 |
732 return 0; |
737 return 1; |
733 } |
738 } |
734 |
739 |
735 // dav download file |
740 // dav download file |
736 typedef struct DDFile { |
741 typedef struct DDFile { |
737 DavFileDownload *download; |
742 DavFileDownload *download; |
|
743 size_t size; |
738 char *path; |
744 char *path; |
739 char *to; |
745 char *to; |
|
746 FILE *fd; |
740 } DDFile; |
747 } DDFile; |
|
748 |
|
749 static size_t ddfile_write(const void *buf, size_t size, size_t count, void *stream) { |
|
750 DDFile *file = stream; |
|
751 |
|
752 size_t w = fwrite(buf, size, count, file->fd); |
|
753 file->download->current_file_downloaded += w; |
|
754 |
|
755 file->download->downloaded_bytes += w; |
|
756 |
|
757 if (file->download->current_file_downloaded > file->download->current_file_size) { |
|
758 size_t diff = file->download->current_file_downloaded - file->download->current_file_size; |
|
759 file->download->current_file_size = file->download->current_file_downloaded; |
|
760 file->download->total_bytes += diff; |
|
761 } |
|
762 |
|
763 ui_call_mainthread(uithr_download_update_progress, file->download); |
|
764 |
|
765 return w; |
|
766 } |
741 |
767 |
742 static int qthr_download_resource(void *data) { |
768 static int qthr_download_resource(void *data) { |
743 DDFile *file = data; |
769 DDFile *file = data; |
|
770 |
|
771 file->download->current_file_downloaded = 0; |
|
772 file->download->current_file_size = file->size; |
744 |
773 |
745 FILE *f = fopen(file->to, "wb"); |
774 FILE *f = fopen(file->to, "wb"); |
746 if (!f) { |
775 if (!f) { |
747 return 0; |
776 return 0; |
748 } |
777 } |
|
778 file->fd = f; |
749 |
779 |
750 DavResource *res = dav_resource_new(file->download->download_sn, file->path); |
780 DavResource *res = dav_resource_new(file->download->download_sn, file->path); |
751 dav_get_content(res, f, (dav_write_func)fwrite); |
781 dav_get_content(res, file, (dav_write_func)ddfile_write); |
752 |
782 |
753 file->download->downloaded_bytes += res->contentlength; |
783 file->download->downloaded_bytes += ftell(f); |
754 file->download->downloaded_files++; |
784 file->download->downloaded_files++; |
|
785 |
|
786 ui_call_mainthread(uithr_download_update_progress, file->download); |
755 |
787 |
756 dav_resource_free(res); |
788 dav_resource_free(res); |
757 |
789 |
758 fclose(f); |
790 fclose(f); |
759 |
791 |
760 free(file->path); |
792 free(file->path); |
761 free(file->to); |
793 free(file->to); |
762 free(file); |
794 free(file); |
|
795 |
|
796 return 0; |
763 } |
797 } |
764 |
798 |
765 |
799 |
766 typedef struct DlStackElm { |
800 typedef struct DlStackElm { |
767 DavResource *resource; |
801 DavResource *resource; |
803 if (dav_load(res)) { |
837 if (dav_load(res)) { |
804 // TODO: handle error |
838 // TODO: handle error |
805 continue; |
839 continue; |
806 } |
840 } |
807 |
841 |
808 download->total_directories++; |
|
809 |
|
810 // update ui |
842 // update ui |
811 //ui_call_mainthread(uithr_download_update_progress, download); |
843 ui_call_mainthread(uithr_download_update_progress, download); |
812 |
844 |
813 char *path = util_concat_path(download->local_path, sub_path); |
845 char *path = util_concat_path(download->local_path, sub_path); |
814 int err = sys_mkdir(path); |
846 int err = sys_mkdir(path); |
815 free(path); |
847 free(path); |
816 if (err) { |
848 if (err) { |
830 } else { |
862 } else { |
831 // add the file to the download queue |
863 // add the file to the download queue |
832 DDFile *file = malloc(sizeof(DDFile)); |
864 DDFile *file = malloc(sizeof(DDFile)); |
833 file->download = download; |
865 file->download = download; |
834 file->path = strdup(res->path); |
866 file->path = strdup(res->path); |
|
867 file->size = res->contentlength; |
835 if (download->isdirectory) { |
868 if (download->isdirectory) { |
836 file->to = util_concat_path(download->local_path, sub_path); |
869 file->to = util_concat_path(download->local_path, sub_path); |
837 } else { |
870 } else { |
838 file->to = strdup(download->local_path); |
871 file->to = strdup(download->local_path); |
839 } |
872 } |
841 // stats |
874 // stats |
842 download->total_files++; |
875 download->total_files++; |
843 download->total_bytes += res->contentlength; |
876 download->total_bytes += res->contentlength; |
844 |
877 |
845 // update ui |
878 // update ui |
846 //ui_call_mainthread(uithr_download_update_progress, download); |
879 ui_call_mainthread(uithr_download_update_progress, download); |
847 |
880 |
848 ui_threadpool_job(download->queue, download->ui, qthr_download_resource, file, NULL, NULL); |
881 ui_threadpool_job(download->queue, download->ui, qthr_download_resource, file, NULL, NULL); |
849 } |
882 } |
850 } |
883 } |
851 |
884 |
852 cxListDestroy(stack); |
885 cxListDestroy(stack); |
|
886 |
|
887 return 0; |
853 } |
888 } |
854 |
889 |
855 static void uithr_download_scan_finished(UiEvent *event, void *data) { |
890 static void uithr_download_scan_finished(UiEvent *event, void *data) { |
|
891 DavFileDownload *download = data; |
856 |
892 |
857 } |
893 } |
858 |
894 |
859 static void download_window_closed(UiEvent *event, void *data) { |
895 static void download_window_closed(UiEvent *event, void *data) { |
860 |
896 |