232 browser->navstack_enabled = false; |
234 browser->navstack_enabled = false; |
233 davbrowser_query_url(ui, browser, nav_url); |
235 davbrowser_query_url(ui, browser, nav_url); |
234 browser->navstack_enabled = true; |
236 browser->navstack_enabled = true; |
235 } |
237 } |
236 } |
238 } |
|
239 |
|
240 |
|
241 // ------------------------------------- File Upload ------------------------------------- |
|
242 |
|
243 typedef struct DavFileUpload { |
|
244 UiObject *ui; |
|
245 DavBrowser *browser; |
|
246 DavSession *sn; |
|
247 UiFileList files; |
|
248 char *base_path; |
|
249 |
|
250 UiObject *dialog; |
|
251 UiDouble *progress; |
|
252 UiString *file_label; |
|
253 UiString *speed_label; |
|
254 } DavFileUpload; |
|
255 |
|
256 typedef struct DUFile { |
|
257 char *path; |
|
258 char *upload_path; |
|
259 } DUFile; |
|
260 |
|
261 static int jobthr_file_upload(void *data) { |
|
262 DavFileUpload *upload = data; |
|
263 |
|
264 CxList *stack = cxLinkedListCreateSimple(sizeof(DUFile)); |
|
265 for (int i = 0; i < upload->files.nfiles; i++) { |
|
266 DUFile f; |
|
267 f.path = upload->files.files[i]; |
|
268 f.upload_path = util_path_file_name(f.path); |
|
269 cxListInsert(stack, 0, &f); |
|
270 } |
|
271 |
|
272 while (stack->size > 0) { |
|
273 DUFile *f = cxListAt(stack, 0); |
|
274 |
|
275 char *path = util_concat_path(upload->base_path, f->upload_path); |
|
276 DavResource *res = dav_resource_new(upload->sn, path); |
|
277 |
|
278 SYS_STAT s; |
|
279 if (!stat(f->path, &s)) { |
|
280 if (S_ISDIR(s.st_mode)) { |
|
281 res->iscollection = 1; |
|
282 dav_create(res); |
|
283 |
|
284 SYS_DIR dir = sys_opendir(f->path); |
|
285 if (dir) { |
|
286 SysDirEnt *entry; |
|
287 int nument = 0; |
|
288 while((entry = sys_readdir(dir)) != NULL) { |
|
289 if(!strcmp(entry->name, ".") || !strcmp(entry->name, "..")) { |
|
290 continue; |
|
291 } |
|
292 |
|
293 cxmutstr newpath = util_concat_sys_path(cx_str(f->path), cx_str(entry->name)); |
|
294 char *new_upload_path = util_concat_path(f->upload_path, entry->name); |
|
295 |
|
296 DUFile child; |
|
297 child.path = newpath.ptr; |
|
298 child.upload_path = new_upload_path; |
|
299 cxListAdd(stack, &child); |
|
300 } |
|
301 |
|
302 sys_closedir(dir); |
|
303 } |
|
304 } else if (S_ISREG(s.st_mode)) { |
|
305 FILE *in = sys_fopen(f->path, "rb"); |
|
306 if (in) { |
|
307 dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)fseek); |
|
308 //dav_set_content_length(res, s.st_size); |
|
309 int err = dav_store(res); |
|
310 if (err) { |
|
311 // TODO: error |
|
312 |
|
313 } |
|
314 fclose(in); |
|
315 } |
|
316 } |
|
317 } // TODO: else error msg |
|
318 |
|
319 dav_resource_free(res); |
|
320 free(path); |
|
321 |
|
322 cxListRemove(stack, 0); |
|
323 } |
|
324 |
|
325 return 0; |
|
326 } |
|
327 |
|
328 static void uithr_file_upload_finished(UiEvent *event, void *data) { |
|
329 DavFileUpload *upload = data; |
|
330 } |
|
331 |
|
332 |
|
333 void davbrowser_upload_files(UiObject *ui, DavBrowser *browser, UiFileList files) { |
|
334 if (!browser->sn) { |
|
335 return; // TODO: error msg |
|
336 } |
|
337 |
|
338 // we need a clone of the current session, because the upload |
|
339 // is done in a separate thread |
|
340 DavSession *upload_session = dav_session_clone(browser->sn); |
|
341 |
|
342 // create upload obj, that contains all relevant data for the upload |
|
343 DavFileUpload *upload = malloc(sizeof(DavFileUpload)); |
|
344 upload->ui = ui; |
|
345 upload->browser = browser; |
|
346 upload->sn = upload_session; |
|
347 upload->files = files; |
|
348 upload->base_path = strdup(browser->current->path); |
|
349 |
|
350 // create upload progress window |
|
351 UiObject *dialog = ui_simple_window("Upload", upload); |
|
352 upload->dialog = dialog; |
|
353 ui_window_size(dialog, 450, 120); |
|
354 upload->progress = ui_double_new(dialog->ctx, NULL); |
|
355 upload->file_label = ui_string_new(dialog->ctx, NULL); |
|
356 upload->speed_label = ui_string_new(dialog->ctx, NULL); |
|
357 |
|
358 ui_vbox(dialog, .margin = 10, .spacing = 10) { |
|
359 ui_llabel(dialog, .value = upload->file_label); |
|
360 ui_progressbar(dialog, .value = upload->progress); |
|
361 ui_llabel(dialog, .value = upload->speed_label); |
|
362 } |
|
363 |
|
364 ui_set(upload->file_label, ""); |
|
365 ui_set(upload->speed_label, ""); |
|
366 ui_set(upload->progress, 0); |
|
367 |
|
368 //ui_show(dialog); |
|
369 |
|
370 // start upload and stat threads |
|
371 ui_job(ui, jobthr_file_upload, upload, uithr_file_upload_finished, upload); |
|
372 } |