application/davcontroller.c

changeset 19
813c97c5b6d3
parent 18
af411868ab9b
child 20
db263186edf3
equal deleted inserted replaced
18:af411868ab9b 19:813c97c5b6d3
244 UiObject *ui; 244 UiObject *ui;
245 DavBrowser *browser; 245 DavBrowser *browser;
246 DavSession *sn; 246 DavSession *sn;
247 UiFileList files; 247 UiFileList files;
248 char *base_path; 248 char *base_path;
249 UiThreadpool *queue;
250
251 size_t total_bytes;
252 size_t total_files;
253 size_t total_directories;
254 size_t uploaded_bytes;
255 size_t uploaded_files;
256 size_t uploaded_directories;
249 257
250 UiObject *dialog; 258 UiObject *dialog;
251 UiDouble *progress; 259 UiDouble *progress;
252 UiString *file_label; 260 UiString *file_label;
253 UiString *speed_label; 261 UiString *speed_label;
254 } DavFileUpload; 262 } DavFileUpload;
255 263
256 typedef struct DUFile { 264 typedef struct DUFile {
257 char *path; 265 char *path;
258 char *upload_path; 266 char *upload_path;
267 size_t bytes;
268 DavBool isdirectory;
269 DavFileUpload *upload;
270 DavError error;
259 } DUFile; 271 } DUFile;
260 272
261 static int jobthr_file_upload(void *data) { 273 static double upload_progress(DavFileUpload *upload) {
274 return ((double)upload->uploaded_bytes / (double)upload->total_bytes) * 100;
275 }
276
277 static int qthr_file_upload(void *data) {
278 DUFile *f = data;
279 DavFileUpload *upload = f->upload;
280 DavSession *sn = upload->sn;
281
282 FILE *in = sys_fopen(f->path, "rb");
283 if (!in) {
284 // TODO: error msg
285 return 0;
286 }
287
288 DavResource *res = dav_resource_new(sn, f->upload_path);
289 dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)fseek);
290 if (dav_store(res)) {
291 f->error = sn->error;
292 }
293 dav_resource_free(res);
294
295 fclose(in);
296
297 return 0;
298 }
299
300 static void uithr_file_uploaded(UiEvent *event, void *data) {
301 DUFile *file = data;
302 DavFileUpload *upload = file->upload;
303
304 upload->uploaded_files++;
305 upload->uploaded_bytes += file->bytes;
306
307 double progress = upload_progress(upload);
308 ui_set(upload->progress, upload_progress(upload));
309
310 free(file->path);
311 free(file->upload_path);
312 }
313
314 static int qthr_dir_upload(void *data) {
315 DUFile *f = data;
316 DavFileUpload *upload = f->upload;
317 DavSession *sn = upload->sn;
318
319 DavResource *res = dav_resource_new(sn, f->upload_path);
320 res->iscollection = TRUE;
321
322 if (dav_create(res)) {
323 f->error = sn->error;
324 }
325
326 dav_resource_free(res);
327
328 return 0;
329 }
330
331 static void uithr_dir_uploaded(UiEvent *event, void *data) {
332 DUFile *file = data;
333 DavFileUpload *upload = file->upload;
334
335 upload->uploaded_directories++;
336
337 free(file->path);
338 free(file->upload_path);
339 }
340
341 static int qthr_upload_finished(void *data) {
342 return 0;
343 }
344
345 static void uithr_upload_finished(UiEvent *event, void *data) {
262 DavFileUpload *upload = data; 346 DavFileUpload *upload = data;
263 347 ui_threadpool_destroy(upload->queue);
264 CxList *stack = cxLinkedListCreateSimple(sizeof(DUFile)); 348
349 free(upload->base_path);
350 dav_session_destroy(upload->sn);
351 }
352
353 static int jobthr_upload_scan(void *data) {
354 DavFileUpload *upload = data;
355
356 CxList *stack = cxLinkedListCreateSimple(CX_STORE_POINTERS);
265 for (int i = 0; i < upload->files.nfiles; i++) { 357 for (int i = 0; i < upload->files.nfiles; i++) {
266 DUFile f; 358 DUFile *f = malloc(sizeof(DUFile));
267 f.path = upload->files.files[i]; 359 f->path = strdup(upload->files.files[i]);
268 f.upload_path = util_path_file_name(f.path); 360 f->upload_path = util_concat_path(upload->base_path, util_path_file_name(f->path));
269 cxListInsert(stack, 0, &f); 361 f->isdirectory = FALSE;
362 f->bytes = 0;
363 f->upload = upload;
364 f->error = 0;
365 cxListInsert(stack, 0, f);
270 } 366 }
271 367
272 while (stack->size > 0) { 368 while (stack->size > 0) {
273 DUFile *f = cxListAt(stack, 0); 369 DUFile *f = cxListAt(stack, 0);
274 370
275 char *path = util_concat_path(upload->base_path, f->upload_path); 371 char *path = util_concat_path(upload->base_path, f->upload_path);
276 DavResource *res = dav_resource_new(upload->sn, path); 372 cxListRemove(stack, 0);
277 373
278 SYS_STAT s; 374 SYS_STAT s;
279 if (!stat(f->path, &s)) { 375 if (!stat(f->path, &s)) {
280 if (S_ISDIR(s.st_mode)) { 376 if (S_ISDIR(s.st_mode)) {
281 res->iscollection = 1; 377 f->isdirectory = TRUE;
282 dav_create(res); 378 upload->total_directories++;
379 ui_threadpool_job(upload->queue, upload->ui, qthr_dir_upload, f, uithr_dir_uploaded, f);
283 380
284 SYS_DIR dir = sys_opendir(f->path); 381 SYS_DIR dir = sys_opendir(f->path);
285 if (dir) { 382 if (dir) {
286 SysDirEnt *entry; 383 SysDirEnt *entry;
287 int nument = 0; 384 int nument = 0;
288 while((entry = sys_readdir(dir)) != NULL) { 385 while((entry = sys_readdir(dir)) != NULL) {
289 if(!strcmp(entry->name, ".") || !strcmp(entry->name, "..")) { 386 if(!strcmp(entry->name, ".") || !strcmp(entry->name, "..")) {
290 continue; 387 continue;
291 } 388 }
292 389
293 cxmutstr newpath = util_concat_sys_path(cx_str(f->path), cx_str(entry->name)); 390 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); 391 char *new_upload_path = util_concat_path(f->upload_path, entry->name);
295 392
296 DUFile child; 393 DUFile *child = malloc(sizeof(DUFile));
297 child.path = newpath.ptr; 394 child->path = newpath.ptr;
298 child.upload_path = new_upload_path; 395 child->upload_path = new_upload_path;
299 cxListAdd(stack, &child); 396 child->isdirectory = FALSE;
397 child->bytes = 0;
398 child->upload = upload;
399 child->error = 0;
400 cxListAdd(stack, child);
300 } 401 }
301 402
302 sys_closedir(dir); 403 sys_closedir(dir);
303 } 404 }
304 } else if (S_ISREG(s.st_mode)) { 405 } else if (S_ISREG(s.st_mode)) {
305 FILE *in = sys_fopen(f->path, "rb"); 406 f->isdirectory = FALSE;
306 if (in) { 407 f->bytes = s.st_size;
307 dav_set_content(res, in, (dav_read_func)fread, (dav_seek_func)fseek); 408 upload->total_files++;
308 //dav_set_content_length(res, s.st_size); 409 upload->total_bytes += s.st_size;
309 int err = dav_store(res); 410 ui_threadpool_job(upload->queue, upload->ui, qthr_file_upload, f, uithr_file_uploaded, f);
310 if (err) {
311 // TODO: error
312
313 }
314 fclose(in);
315 }
316 } 411 }
317 } // TODO: else error msg 412 }
318 413 } // TODO: else error msg
319 dav_resource_free(res); 414
320 free(path); 415 ui_threadpool_job(upload->queue, upload->ui, qthr_upload_finished, upload, uithr_upload_finished, upload);
321 416
322 cxListRemove(stack, 0); 417 ui_filelist_free(upload->files);
323 }
324 418
325 return 0; 419 return 0;
326 } 420 }
327 421
328 static void uithr_file_upload_finished(UiEvent *event, void *data) { 422 static void uithr_upload_scan_finished(UiEvent *event, void *data) {
329 DavFileUpload *upload = data; 423 DavFileUpload *upload = data;
330 } 424 }
331 425
332 426
333 void davbrowser_upload_files(UiObject *ui, DavBrowser *browser, UiFileList files) { 427 void davbrowser_upload_files(UiObject *ui, DavBrowser *browser, UiFileList files) {
339 // is done in a separate thread 433 // is done in a separate thread
340 DavSession *upload_session = dav_session_clone(browser->sn); 434 DavSession *upload_session = dav_session_clone(browser->sn);
341 435
342 // create upload obj, that contains all relevant data for the upload 436 // create upload obj, that contains all relevant data for the upload
343 DavFileUpload *upload = malloc(sizeof(DavFileUpload)); 437 DavFileUpload *upload = malloc(sizeof(DavFileUpload));
438 memset(upload, 0, sizeof(DavFileUpload));
439
344 upload->ui = ui; 440 upload->ui = ui;
345 upload->browser = browser; 441 upload->browser = browser;
346 upload->sn = upload_session; 442 upload->sn = upload_session;
347 upload->files = files; 443 upload->files = files;
348 upload->base_path = strdup(browser->current->path); 444 upload->base_path = strdup(browser->current->path);
445 upload->queue = ui_threadpool_create(1);
349 446
350 // create upload progress window 447 // create upload progress window
351 UiObject *dialog = ui_simple_window("Upload", upload); 448 UiObject *dialog = ui_simple_window("Upload", upload);
352 upload->dialog = dialog; 449 upload->dialog = dialog;
353 ui_window_size(dialog, 450, 120); 450 ui_window_size(dialog, 450, 120);
363 460
364 ui_set(upload->file_label, ""); 461 ui_set(upload->file_label, "");
365 ui_set(upload->speed_label, ""); 462 ui_set(upload->speed_label, "");
366 ui_set(upload->progress, 0); 463 ui_set(upload->progress, 0);
367 464
368 //ui_show(dialog); 465 ui_show(dialog);
369 466
370 // start upload and stat threads 467 // start upload and stat threads
371 ui_job(ui, jobthr_file_upload, upload, uithr_file_upload_finished, upload); 468 ui_job(ui, jobthr_upload_scan, upload, uithr_upload_scan_finished, upload);
372 } 469 }

mercurial