Add progress callback

This commit is contained in:
Olivier Goffart 2012-12-04 17:21:53 +01:00
parent f2f1672ba6
commit f18f58ace0
4 changed files with 77 additions and 2 deletions

View file

@ -52,7 +52,7 @@
#include "csync_log.h"
#if 1 || defined(NDEBUG)
#define DEBUG_WEBDAV(...) { printf(__VA_ARGS__); printf("\n"); }
#define DEBUG_WEBDAV(...)
#else // FIXME: can't use CSYNC_LOG here because there is no ctx
#define DEBUG_WEBDAV(...) CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, __VA_ARGS__)
#endif
@ -153,6 +153,8 @@ int _connected = 0; /* flag to indicate if a connection exists
csync_vio_file_stat_t _fs;
csync_auth_callback _authcb;
csync_progress_callback _progresscb;
#define PUT_BUFFER_SIZE 1024*5
@ -559,6 +561,17 @@ static void request_created_hook(ne_request *req, void *userdata,
}
static void ne_notify_status_cb (void *userdata, ne_session_status status,
const ne_session_status_info *info)
{
struct transfer_context *tc = (struct transfer_context*) userdata;
// printf("ne_notify_status %i %s %ld %ld\n", status, tc->clean_uri, info->sr.progress, info->sr.total);
if (_progresscb && (status == ne_status_sending || status == ne_status_recving))
_progresscb(tc->clean_uri, CSYNC_NOTIFY_PROGRESS, info->sr.progress, info->sr.total, dav_session.userdata);
}
/*
* Connect to a DAV server
* This function sets the flag _connected if the connection is established
@ -1527,11 +1540,15 @@ static int owncloud_sendfile(csync_vio_method_handle_t *src, csync_vio_method_ha
/* Attach the request to the file descriptor */
ne_set_request_body_fd(request, fd, 0, sb.st_size );
if (_progresscb) {
ne_set_notifier(dav_session.ctx, ne_notify_status_cb, write_ctx);
_progresscb(write_ctx->clean_uri, CSYNC_NOTIFY_START_UPLOAD, 0 , 0, dav_session.userdata);
}
/* Start the request. */
rc = ne_request_dispatch( write_ctx->req );
if( rc != NE_OK ) {
set_errno_from_neon_errcode( rc );
return rc;
} else {
status = ne_get_status( request );
if( status->klass != 2 ) {
@ -1542,6 +1559,11 @@ static int owncloud_sendfile(csync_vio_method_handle_t *src, csync_vio_method_ha
DEBUG_WEBDAV("http request all cool, result code %d", status->code);
}
}
if (_progresscb) {
ne_set_notifier(dav_session.ctx, 0, 0);
_progresscb(write_ctx->clean_uri, rc != NE_OK ? CSYNC_NOTFY_ERROR : CSYNC_NOTIFY_FINISHED,
0, 0, dav_session.userdata);
}
} else {
DEBUG_WEBDAV("Could not stat file descriptor");
}
@ -1552,6 +1574,10 @@ static int owncloud_sendfile(csync_vio_method_handle_t *src, csync_vio_method_ha
/* GET a file to the file descriptor */
/* actually do the request */
write_ctx->fd = fd;
if (_progresscb) {
ne_set_notifier(dav_session.ctx, ne_notify_status_cb, write_ctx);
_progresscb(write_ctx->clean_uri, CSYNC_NOTIFY_START_UPLOAD, 0 , 0, dav_session.userdata);
}
rc = ne_request_dispatch(write_ctx->req );
/* possible return codes are:
* NE_OK, NE_AUTH, NE_CONNECT, NE_TIMEOUT, NE_ERROR (from ne_request.h)
@ -1572,6 +1598,11 @@ static int owncloud_sendfile(csync_vio_method_handle_t *src, csync_vio_method_ha
if( write_ctx->decompress ) {
ne_decompress_destroy( write_ctx->decompress );
}
if (_progresscb) {
ne_set_notifier(dav_session.ctx, 0, 0);
_progresscb(write_ctx->clean_uri, (rc != NE_OK) ? CSYNC_NOTFY_ERROR : CSYNC_NOTIFY_FINISHED,
0,0, dav_session.userdata);
}
} else {
DEBUG_WEBDAV("Unknown method!");
}
@ -1915,6 +1946,10 @@ int owncloud_set_property(const char *key, void *data) {
dav_session.proxy_port = *(int*)(data);
return 0;
}
if (c_streq(key, "progress_callback")) {
_progresscb = *(csync_progress_callback*)(data);
return 0;
}
return -1;
}

View file

@ -322,6 +322,9 @@ retry_vio_init:
}
}
if (ctx->callbacks.progresscb)
csync_set_module_property(ctx, "progress_callback", &ctx->callbacks.progresscb);
if (c_rbtree_create(&ctx->local.tree, _key_cmp, _data_cmp) < 0) {
ctx->error_code = CSYNC_ERR_TREE;
rc = -1;
@ -1011,4 +1014,23 @@ int csync_set_module_property(CSYNC* ctx, const char* key, void* value)
return csync_vio_set_property(ctx, key, value);
}
int csync_set_progress_callback(CSYNC* ctx, csync_progress_callback cb)
{
if (ctx == NULL || cb == NULL) {
ctx->error_code = CSYNC_ERR_PARAM;
return -1;
}
ctx->error_code = CSYNC_ERR_NONE;
ctx->callbacks.progresscb = cb;
if (ctx->status & CSYNC_STATUS_INIT) {
fprintf(stderr, "This function must be called before initialization.");
ctx->error_code = CSYNC_ERR_UNSPEC;
return -1;
}
return 0;
}
/* vim: set ts=8 sw=2 et cindent: */

View file

@ -487,6 +487,23 @@ bool csync_file_known( char *statedb_file, const char* url );
*/
int csync_set_module_property(CSYNC *ctx, const char *key, void *value);
enum csync_notify_type_e { CSYNC_NOTIFY_START_DOWNLOAD, CSYNC_NOTIFY_START_UPLOAD, CSYNC_NOTIFY_PROGRESS,
CSYNC_NOTIFY_FINISHED, CSYNC_NOTFY_ERROR };
typedef void (*csync_progress_callback) (const char *remote_url, enum csync_notify_type_e kind,
long long o1, long long o2, void *userdata);
/**
* @brief Set a progress callback
*
* @param ctx The csync context.
*
* @param cb The callback
*/
int csync_set_progress_callback(CSYNC *ctx, csync_progress_callback cb);
#ifdef __cplusplus
}
#endif

View file

@ -82,6 +82,7 @@ struct csync_s {
struct {
csync_auth_callback auth_function;
csync_log_callback log_function;
csync_progress_callback progresscb;
void *userdata;
} callbacks;
c_strlist_t *excludes;