static gboolean datasource_osm_my_traces_process ( VikTrwLayer *vtl, const gchar *cmd, const gchar *extra, BabelStatusFunc status_cb, acq_dialog_widgets_t *adw, DownloadMapOptions *options_unused ) { //datasource_osm_my_traces_t *data = (datasource_osm_my_traces_t *)adw->user_data; gboolean result; gchar *user_pass = osm_get_login(); DownloadMapOptions options = { FALSE, FALSE, NULL, 2, NULL, user_pass }; // Allow a couple of redirects xml_data *xd = g_malloc ( sizeof (xml_data) ); //xd->xpath = g_string_new ( "" ); xd->c_cdata = g_string_new ( "" ); xd->current_tag = tt_unknown; xd->current_gpx_meta_data = new_gpx_meta_data_t(); xd->list_of_gpx_meta_data = NULL; gchar *tmpname = a_download_uri_to_tmp_file ( DS_OSM_TRACES_GPX_FILES, &options ); result = read_gpx_files_metadata_xml ( tmpname, xd ); // Test already downloaded metadata file: eg: //result = read_gpx_files_metadata_xml ( "/tmp/viking-download.GI47PW", xd ); if ( tmpname ) { g_remove ( tmpname ); g_free ( tmpname ); } if ( ! result ) return FALSE; if ( g_list_length ( xd->list_of_gpx_meta_data ) == 0 ) { if (!vik_datasource_osm_my_traces_interface.is_thread) none_found ( GTK_WINDOW(adw->vw) ); return FALSE; } xd->list_of_gpx_meta_data = g_list_reverse ( xd->list_of_gpx_meta_data ); set_in_current_view_property ( vtl, adw->user_data, xd->list_of_gpx_meta_data ); if (vik_datasource_osm_my_traces_interface.is_thread) gdk_threads_enter(); GList *selected = select_from_list ( GTK_WINDOW(adw->vw), xd->list_of_gpx_meta_data, "Select GPS Traces", "Select the GPS traces you want to add." ); if (vik_datasource_osm_my_traces_interface.is_thread) gdk_threads_leave(); // If passed in on an existing layer - we will create everything into that. // thus with many differing gpx's - this will combine all waypoints into this single layer! // Hence the preference is to create multiple layers // and so this creation of the layers must be managed here gboolean create_new_layer = ( !vtl ); // Only update the screen on the last layer acquired VikTrwLayer *vtl_last = vtl; gboolean got_something = FALSE; GList *selected_iterator = selected; while ( selected_iterator ) { VikTrwLayer *vtlX = vtl; if ( create_new_layer ) { // Have data but no layer - so create one vtlX = VIK_TRW_LAYER ( vik_layer_create ( VIK_LAYER_TRW, vik_window_viewport(adw->vw), NULL, FALSE ) ); if ( ((gpx_meta_data_t*)selected_iterator->data)->name ) vik_layer_rename ( VIK_LAYER ( vtlX ), ((gpx_meta_data_t*)selected_iterator->data)->name ); else vik_layer_rename ( VIK_LAYER ( vtlX ), _("My OSM Traces") ); vik_aggregate_layer_add_layer ( vik_layers_panel_get_top_layer (adw->vlp), VIK_LAYER(vtlX) ); } result = FALSE; gint gpx_id = ((gpx_meta_data_t*)selected_iterator->data)->id; if ( gpx_id ) { gchar *url = g_strdup_printf ( DS_OSM_TRACES_GPX_URL_FMT, gpx_id ); result = a_babel_convert_from_url ( vtlX, url, "gpx", status_cb, adw, &options ); // TODO investigate using a progress bar: // http://developer.gnome.org/gtk/2.24/GtkProgressBar.html got_something = got_something || result; // TODO feedback to UI to inform which traces failed if ( !result ) g_warning ( _("Unable to get trace: %s"), url ); } if ( result ) { // Move to area of the track vik_trw_layer_auto_set_view ( vtlX, vik_window_viewport(adw->vw) ); vik_layer_post_read ( VIK_LAYER(vtlX), vik_window_viewport(adw->vw), TRUE ); vtl_last = vtlX; } else if ( create_new_layer ) { // Layer not needed as no data has been acquired g_object_unref ( vtlX ); } selected_iterator = g_list_next ( selected_iterator ); } // Free memory if ( xd->current_gpx_meta_data ) free_gpx_meta_data ( xd->current_gpx_meta_data, NULL ); g_free ( xd->current_gpx_meta_data ); free_gpx_meta_data_list ( xd->list_of_gpx_meta_data ); free_gpx_meta_data_list ( selected ); g_free ( xd ); g_free ( user_pass ); // Would prefer to keep the update in acquire.c, // however since we may create the layer - need to do the update here if ( got_something ) vik_layer_emit_update ( VIK_LAYER(vtl_last) ); // ATM The user is only informed if all getting *all* of the traces failed if ( selected ) result = got_something; else // Process was cancelled but need to return that it proceeded as expected result = TRUE; return result; }
/* * Upload a file * returns a basic status: * < 0 : curl error * == 0 : OK * > 0 : HTTP error * 1001 : URL signing error */ static gint osm_traces_upload_file(const char *user, const char *password, const char *file, const char *filename, const char *description, const char *tags, const OsmTraceVis_t *vistype) { CURL *curl; CURLcode res; char curl_error_buffer[CURL_ERROR_SIZE]; struct curl_slist *headers = NULL; struct curl_httppost *post=NULL; struct curl_httppost *last=NULL; gchar *trace_url = NULL; if ( !a_settings_get_string ( VIK_SETTINGS_OSM_TRACE_URL, &trace_url ) ) trace_url = g_strdup ( OSM_GPX_UPLOAD_URL ); gchar *user_pass = osm_get_login(); #ifdef HAVE_OAUTH_H char *base_url = osm_oauth_sign_url ( trace_url, "POST" ); if ( !base_url ) { g_free ( trace_url ); return 1001; } #else char *base_url = trace_url; #endif gint result = 0; // Default to it worked! g_debug("%s: %s %s %s %s %s %s %s", __FUNCTION__, base_url, user, password, file, filename, description, tags); /* Init CURL */ curl = curl_easy_init(); /* Filling the form */ curl_formadd(&post, &last, CURLFORM_COPYNAME, "description", CURLFORM_COPYCONTENTS, description, CURLFORM_END); curl_formadd(&post, &last, CURLFORM_COPYNAME, "tags", CURLFORM_COPYCONTENTS, tags, CURLFORM_END); curl_formadd(&post, &last, CURLFORM_COPYNAME, "visibility", CURLFORM_COPYCONTENTS, vistype->apistr, CURLFORM_END); curl_formadd(&post, &last, CURLFORM_COPYNAME, "file", CURLFORM_FILE, file, CURLFORM_FILENAME, filename, CURLFORM_CONTENTTYPE, "text/xml", CURLFORM_END); /* Prepare request */ /* As explained in http://wiki.openstreetmap.org/index.php/User:LA2 */ /* Expect: header seems to produce incompatibilites between curl and httpd */ headers = curl_slist_append(headers, "Expect: "); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPPOST, post); curl_easy_setopt(curl, CURLOPT_URL, base_url); #ifndef HAVE_OAUTH_H curl_easy_setopt(curl, CURLOPT_USERPWD, user_pass); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); #else if ( osm_use_basic_auth() ) { curl_easy_setopt(curl, CURLOPT_USERPWD, user_pass); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); } #endif curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_error_buffer); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 3L); if (vik_verbose) curl_easy_setopt ( curl, CURLOPT_VERBOSE, 1 ); /* Execute request */ res = curl_easy_perform(curl); if (res == CURLE_OK) { long code; res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); if (res == CURLE_OK) { g_debug("received valid curl response: %ld", code); if (code != 200) { g_warning(_("failed to upload data: HTTP response is %ld"), code); result = code; } } else { g_critical(_("curl_easy_getinfo failed: %d"), res); result = -1; } } else { g_warning(_("curl request failed: %s"), curl_error_buffer); result = -2; } /* Memory */ g_free(base_url); g_free(user_pass); user_pass = NULL; g_free(base_url); curl_formfree(post); curl_easy_cleanup(curl); return result; }