コード例 #1
0
void osm_upload(appdata_t *appdata, osm_t *osm, project_t *project) {

  printf("starting upload\n");

  /* upload config and confirmation dialog */

  /* count nodes */
  osm_dirty_t dirty;
  memset(&dirty, 0, sizeof(dirty));

  const node_t *node = osm->node;
  while(node) {
    object_counter(OSM_BASE(node), &dirty.nodes);
    node = node->next;
  }
  printf("nodes:     new %2d, dirty %2d, deleted %2d\n",
	 dirty.nodes.added, dirty.nodes.dirty, dirty.nodes.deleted);

  /* count ways */
  const way_t *way = osm->way;
  while(way) {
    object_counter(OSM_BASE(way), &dirty.ways);
    way = way->next;
  }
  printf("ways:      new %2d, dirty %2d, deleted %2d\n",
	 dirty.ways.added, dirty.ways.dirty, dirty.ways.deleted);

  /* count relations */
  const relation_t *relation = osm->relation;
  while(relation) {
    object_counter(OSM_BASE(relation), &dirty.relations);
    relation = relation->next;
  }
  printf("relations: new %2d, dirty %2d, deleted %2d\n",
	 dirty.relations.added, dirty.relations.dirty, dirty.relations.deleted);


  GtkWidget *dialog =
    misc_dialog_new(MISC_DIALOG_MEDIUM, _("Upload to OSM"),
		    GTK_WINDOW(appdata->window),
		    GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
		    GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
		    NULL);

  GtkWidget *table = gtk_table_new(4, 5, TRUE);

  table_attach_label_c(table, _("Total"),          1, 2, 0, 1);
  table_attach_label_c(table, _("New"),            2, 3, 0, 1);
  table_attach_label_c(table, _("Modified"),       3, 4, 0, 1);
  table_attach_label_c(table, _("Deleted"),        4, 5, 0, 1);

  int row = 1;
  table_attach_label_l(table, _("Nodes:"),         0, 1, row, row + 1);
  table_insert_count(table, &dirty.nodes, row++);

  table_attach_label_l(table, _("Ways:"),          0, 1, row, row + 1);
  table_insert_count(table, &dirty.ways, row++);

  table_attach_label_l(table, _("Relations:"),     0, 1, row, row + 1);
  table_insert_count(table, &dirty.relations, row++);

  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, FALSE, 0);

  /* ------------------------------------------------------ */

  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
		     gtk_hseparator_new(), FALSE, FALSE, 0);

  /* ------- add username and password entries ------------ */

  table = gtk_table_new(2, 2, FALSE);
  table_attach_label_l(table, _("Username:"******"Password:"******"Please add a comment"), -1);

  /* disable ok button until user edited the comment */
  gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog),
				    GTK_RESPONSE_ACCEPT, FALSE);

  g_signal_connect(G_OBJECT(buffer), "changed",
		   G_CALLBACK(callback_buffer_modified), dialog);

#ifndef FREMANTLE
  GtkWidget *view = gtk_text_view_new_with_buffer(buffer);
#else
  GtkWidget *view = hildon_text_view_new();
  hildon_text_view_set_buffer(HILDON_TEXT_VIEW(view), buffer);
#endif

  gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD);
  gtk_text_view_set_editable(GTK_TEXT_VIEW(view), TRUE);
  gtk_text_view_set_left_margin(GTK_TEXT_VIEW(view), 2 );
  gtk_text_view_set_right_margin(GTK_TEXT_VIEW(view), 2 );

  g_object_set_data(G_OBJECT(view), "first_click", GINT_TO_POINTER(TRUE));
  g_signal_connect(G_OBJECT(view), "focus-in-event",
		   G_CALLBACK(cb_focus_in), buffer);


  gtk_container_add(GTK_CONTAINER(scrolled_win), view);

  gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(dialog)->vbox),
  			      scrolled_win);
  gtk_widget_show_all(dialog);

  if(GTK_RESPONSE_ACCEPT != gtk_dialog_run(GTK_DIALOG(dialog))) {
    printf("upload cancelled\n");
    gtk_widget_destroy(dialog);
    return;
  }

  printf("clicked ok\n");

  /* retrieve username and password */
  g_free(appdata->settings->username);
  appdata->settings->username =
    g_strdup(gtk_entry_get_text(GTK_ENTRY(uentry)));

  g_free(appdata->settings->password);
  appdata->settings->password =
    g_strdup(gtk_entry_get_text(GTK_ENTRY(pentry)));

  /* osm upload itself also has a gui */
  osm_upload_context_t *context = g_new0(osm_upload_context_t, 1);
  context->appdata = appdata;
  context->osm = osm;
  context->project = project;

  /* add proxy settings if required */
  if(appdata->settings)
    context->proxy = appdata->settings->proxy;

  /* fetch comment from dialog */
  GtkTextIter start, end;
  gtk_text_buffer_get_start_iter(buffer, &start);
  gtk_text_buffer_get_end_iter(buffer, &end);
  char *text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
  context->comment = g_strdup(text);

  gtk_widget_destroy(dialog);
  project_save(GTK_WIDGET(appdata->window), project);

  context->dialog =
    misc_dialog_new(MISC_DIALOG_LARGE,_("Uploading"),
	  GTK_WINDOW(appdata->window),
	  GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);

  gtk_dialog_set_response_sensitive(GTK_DIALOG(context->dialog),
				    GTK_RESPONSE_CLOSE, FALSE);

  /* ------- main ui element is this text view --------------- */

  GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
  				 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

  context->log.buffer = gtk_text_buffer_new(NULL);

  context->log.view = gtk_text_view_new_with_buffer(context->log.buffer);
  gtk_text_view_set_editable(GTK_TEXT_VIEW(context->log.view), FALSE);
  gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(context->log.view), FALSE);
  gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(context->log.view), GTK_WRAP_WORD);

  gtk_container_add(GTK_CONTAINER(scrolled_window), context->log.view);
  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),
				      GTK_SHADOW_IN);

  gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context->dialog)->vbox),
			       scrolled_window);
  gtk_widget_show_all(context->dialog);

  /* server url should not end with a slash */
  if(project->rserver && project->rserver[strlen(project->rserver)-1] == '/') {
    printf("removing trailing slash\n");
    project->rserver[strlen(project->rserver)-1] = 0;
  }

  appendf(&context->log, NULL, _("Log generated by %s v%s using API 0.6\n"),
	  PACKAGE, VERSION);
  appendf(&context->log, NULL, _("User comment: %s\n"), context->comment);

   /* check if server name contains string "0.5" and adjust it */
  if(project->rserver && strstr(project->rserver, "0.5") != NULL) {
    strstr(project->rserver, "0.5")[2] = '6';

    appendf(&context->log, NULL, _("Adjusting server name to v0.6\n"));
  }

  appendf(&context->log, NULL, _("Uploading to %s\n"), project->server);

  /* create a new changeset */
  gchar *cred;
  if(osm_create_changeset(context, &cred)) {
    /* check for dirty entries */
    appendf(&context->log, NULL, _("Uploading nodes:\n"));
    osm_upload_nodes(context, cred);
    appendf(&context->log, NULL, _("Uploading ways:\n"));
    osm_upload_ways(context, cred);
    appendf(&context->log, NULL, _("Uploading relations:\n"));
    osm_upload_relations(context, cred);
    appendf(&context->log, NULL, _("Deleting relations:\n"));
    osm_delete_relations(context, cred);
    appendf(&context->log, NULL, _("Deleting ways:\n"));
    osm_delete_ways(context, cred);
    appendf(&context->log, NULL, _("Deleting nodes:\n"));
    osm_delete_nodes(context, cred);

    /* close changeset */
    osm_close_changeset(context, cred);
  }

  appendf(&context->log, NULL, _("Upload done.\n"));

  gboolean reload_map = FALSE;
  if(project->data_dirty) {
    appendf(&context->log, NULL, _("Server data has been modified.\n"));
    appendf(&context->log, NULL, _("Downloading updated osm data ...\n"));

    if(osm_download(context->dialog, appdata->settings, project)) {
      appendf(&context->log, NULL, _("Download successful!\n"));
      appendf(&context->log, NULL, _("The map will be reloaded.\n"));
      project->data_dirty = FALSE;
      reload_map = TRUE;
    } else
      appendf(&context->log, NULL, _("Download failed!\n"));

    project_save(context->dialog, project);

    if(reload_map) {
      /* this kind of rather brute force reload is useful as the moment */
      /* after the upload is a nice moment to bring everything in sync again. */
      /* we basically restart the entire map with fresh data from the server */
      /* and the diff will hopefully be empty (if the upload was successful) */

      appendf(&context->log, NULL, _("Reloading map ...\n"));

      if(!diff_is_clean(appdata->osm, FALSE)) {
	appendf(&context->log, COLOR_ERR, _("*** DIFF IS NOT CLEAN ***\n"));
	appendf(&context->log, COLOR_ERR, _("Something went wrong during upload,\n"));
	appendf(&context->log, COLOR_ERR, _("proceed with care!\n"));
      }

      /* redraw the entire map by destroying all map items and redrawing them */
      appendf(&context->log, NULL, _("Cleaning up ...\n"));
      diff_save(appdata->project, appdata->osm);
      map_clear(appdata, MAP_LAYER_OBJECTS_ONLY);
      osm_free(appdata->osm);

      appendf(&context->log, NULL, _("Loading OSM ...\n"));
      appdata->osm = osm_parse(appdata->project->path, appdata->project->osm, &appdata->icon);
      appendf(&context->log, NULL, _("Applying diff ...\n"));
      diff_restore(appdata, appdata->project, appdata->osm);
      appendf(&context->log, NULL, _("Painting ...\n"));
      map_paint(appdata);
      appendf(&context->log, NULL, _("Done!\n"));
    }
  }

  /* tell the user that he can stop waiting ... */
  appendf(&context->log, NULL, _("Process finished.\n"));

  gtk_dialog_set_response_sensitive(GTK_DIALOG(context->dialog),
				    GTK_RESPONSE_CLOSE, TRUE);

  gtk_dialog_run(GTK_DIALOG(context->dialog));
  gtk_widget_destroy(context->dialog);

  g_free(context->comment);
  g_free(context);
}
コード例 #2
0
ファイル: diff_restore.cpp プロジェクト: AMDmi3/osm2go
int main(int argc, char **argv)
{
  int result = 0;

  if(argc != 4)
    return EINVAL;

  xmlInitParser();

  const std::string osm_path = argv[1];
  assert_cmpnum(osm_path[osm_path.size() - 1], '/');

  map_state_t dummystate;
  project_t project(dummystate, argv[2], osm_path);
  project.osmFile = argv[2] + std::string(".osm");

  bool b = project.parse_osm();
  if(!b) {
    std::cerr << "cannot open " << argv[1] << argv[2] << ": " << strerror(errno) << std::endl;
    return 1;
  }
  osm_t::ref osm = project.osm;
  assert(osm);

  assert_cmpnum(osm->uploadPolicy, osm_t::Upload_Blocked);
  assert(osm->sanity_check().isEmpty());

  const relation_t * const r255 = osm->relation_by_id(296255);
  assert(r255 != nullptr);
  assert_cmpnum(r255->flags, 0);
  assert_cmpnum(r255->members.size(), 165);
  assert_cmpnum(r255->tags.asMap().size(), 8);
  const node_t * const n72 = osm->node_by_id(638499572);
  assert_cmpnum(n72->tags.asMap().size(), 4);
  const object_t r255m572(const_cast<node_t *>(n72));
  std::vector<member_t>::const_iterator r255it = r255->find_member_object(r255m572);
  assert(r255it != r255->members.end());
  assert(r255it->role != nullptr);
  assert_cmpstr(r255it->role, "stop");
  const relation_t * const r66316 = osm->relation_by_id(66316);
  assert(r66316 != nullptr);
  object_t rmember(object_t::RELATION_ID, 296255);
  assert(!rmember.is_real());
  const std::vector<member_t>::const_iterator r66316it = r66316->find_member_object(rmember);
  assert(r66316it != r66316->members.end());
  // the child relation exists, so it should be stored as real ref
  assert(r66316it->object.is_real());

  assert_cmpnum(10, osm->nodes.size());
  assert_cmpnum(3, osm->ways.size());
  assert_cmpnum(4, osm->relations.size());

  assert(osm->is_clean(true));

  assert(project.diff_file_present());
  unsigned int flags = project.diff_restore();
  assert_cmpnum(flags, DIFF_RESTORED | DIFF_HAS_HIDDEN);

  verify_diff(osm);

  xmlString rel_str(r255->generate_xml("42"));
  printf("%s\n", rel_str.get());

  rel_str.reset(n72->generate_xml("42"));
  printf("%s\n", rel_str.get());

  char tmpdir[] = "/tmp/osm2go-diff_restore-XXXXXX";

  if(mkdtemp(tmpdir) == nullptr) {
    std::cerr << "cannot create temporary directory" << std::endl;
    result = 1;
  } else {
    // create an empty directoy
    std::string bpath = tmpdir + std::string("/") + argv[2];
    const std::string osmpath = bpath + '/' + argv[2] + ".osm";
    mkdir(bpath.c_str(), 0755);
    bpath.erase(bpath.rfind('/') + 1);
    // and create a new project from that
    std::unique_ptr<project_t> sproject(new project_t(dummystate, argv[2], bpath));
    // CAUTION: osm is shared between the projects now
    sproject->osm.reset(osm.get());

    // the directory is empty, there can't be any diff
    flags = sproject->diff_restore();
    assert_cmpnum(flags, DIFF_NONE_PRESENT);
    // should not do anything bad
    diff_restore(sproject, nullptr);

    sproject->diff_save();
    bpath += argv[2];
    std::string bdiff = bpath;
    std::string no_diff = bpath;
    bpath += '/';
    bpath += argv[2];
    bpath += '.';
    bpath += "diff";

    bdiff += "/backup.diff";
    assert(sproject->diff_file_present());
    assert_cmpnum(rename(bpath.c_str(), bdiff.c_str()), 0);
    // having backup.diff should still count as being present
    assert(sproject->diff_file_present());
    no_diff += "/no.diff";
    assert_cmpnum(rename(bdiff.c_str(), no_diff.c_str()), 0);
    assert(!sproject->diff_file_present());

    // saving without OSM data should just do nothing
    sproject->osm.release();
    // CAUTION: end of sharing
    sproject->diff_save();
    assert(!sproject->diff_file_present());

    // put the OSM data into this directory
    const std::string origosmpath = project.path + project.osmFile;
    symlink(origosmpath.c_str(), osmpath.c_str());
    sproject->osmFile = project.osmFile;
    bool pvalid = sproject->parse_osm();
    assert(pvalid);
    assert(sproject->osm);

    // now create a diff file dummy
    fdguard fd(open(bpath.c_str(), O_CREAT | O_WRONLY, 0600));
    assert(fd.valid());
    {
      fdguard none(-1);
      none.swap(fd);
    }
    assert(sproject->diff_file_present());
    sproject->diff_save();
    assert(!sproject->diff_file_present());

    assert_cmpnum(rename(no_diff.c_str(), bdiff.c_str()), 0);
    flags = sproject->diff_restore();
    assert_cmpnum(flags, DIFF_RESTORED | DIFF_HAS_HIDDEN);

    verify_diff(osm);

    unlink(osmpath.c_str());
    unlink(bdiff.c_str());
    bpath.erase(bpath.rfind('/'));
    rmdir(bpath.c_str());
    bpath.erase(bpath.rfind('/'));
    rmdir(bpath.c_str());
  }

  test_osmChange(osm, argv[3]);

  xmlCleanupParser();

  return result;
}