| 580 | } |
| 581 | |
| 582 | void Editor::UploadChanges(string const & oauthToken, ChangesetTags tags, FinishUploadCallback callback) |
| 583 | { |
| 584 | if (m_notes->NotUploadedNotesCount()) |
| 585 | m_notes->Upload(OsmOAuth::ServerAuth(oauthToken)); |
| 586 | |
| 587 | if (!HaveMapEditsToUpload(*m_features.Get())) |
| 588 | { |
| 589 | LOG(LDEBUG, ("There are no local edits to upload.")); |
| 590 | return; |
| 591 | } |
| 592 | |
| 593 | std::unique_lock<std::mutex> uploadingEditsLock(m_uploadingEditsMutex, std::defer_lock); |
| 594 | if (!uploadingEditsLock.try_lock()) |
| 595 | { |
| 596 | // Do not run more than one uploading task at a time. |
| 597 | LOG(LDEBUG, ("OSM edits upload is already running")); |
| 598 | return; |
| 599 | } |
| 600 | |
| 601 | int uploadedFeaturesCount = 0, errorsCount = 0; |
| 602 | ChangesetWrapper changeset(oauthToken, std::move(tags)); |
| 603 | auto const features = m_features.Get(); |
| 604 | |
| 605 | for (auto const & id : *features) |
| 606 | { |
| 607 | if (!id.first.IsAlive()) |
| 608 | continue; |
| 609 | |
| 610 | for (auto const & index : id.second) |
| 611 | { |
| 612 | FeatureTypeInfo const & fti = index.second; |
| 613 | // Do not process already uploaded features or those failed permanently. |
| 614 | if (!NeedsUpload(fti.m_uploadStatus)) |
| 615 | continue; |
| 616 | |
| 617 | // TODO(a): Use UploadInfo as part of FeatureTypeInfo. |
| 618 | UploadInfo uploadInfo = {fti.m_uploadAttemptTimestamp, fti.m_uploadStatus, fti.m_uploadError}; |
| 619 | |
| 620 | LOG(LINFO, ("Uploading edits of feature ID:", fti.m_object.GetID(), |
| 621 | "name:", fti.m_object.GetDefaultName(), "latlon:", fti.m_object.GetLatLon())); |
| 622 | LOG(LDEBUG, ("Content of editJournal:\n", fti.m_object.GetJournal().JournalToString())); |
| 623 | |
| 624 | try |
| 625 | { |
| 626 | switch (fti.m_status) |
| 627 | { |
| 628 | case FeatureStatus::Untouched: CHECK(false, ("It's impossible.")); continue; |
| 629 | case FeatureStatus::Obsolete: continue; // Obsolete features will be deleted by OSMers. |
| 630 | case FeatureStatus::Created: // fallthrough |
| 631 | case FeatureStatus::Modified: |
| 632 | { |
| 633 | std::list<JournalEntry> const & journal = fti.m_object.GetJournal().GetJournal(); |
| 634 | |
| 635 | switch (fti.m_object.GetEditingLifecycle()) |
| 636 | { |
| 637 | case EditingLifecycle::CREATED: |
| 638 | { |
| 639 | // Generate XMLFeature for new object |
no test coverage detected