From 0ae78f19f38766c7ad6770d543a9ff2a2f5a9c10 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 17 Dec 2021 19:28:05 +0100 Subject: [PATCH] Fix changeset reuse for automaton --- .../TiledFeatureSource/OsmFeatureSource.ts | 4 +- Logic/Osm/Changes.ts | 36 +++++++++++----- Logic/Osm/ChangesetHandler.ts | 41 +++++++------------ UI/AutomatonGui.ts | 18 ++++---- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts b/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts index faae720889..3c31ff63e7 100644 --- a/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/OsmFeatureSource.ts @@ -105,7 +105,9 @@ export default class OsmFeatureSource { // We only keep what is needed geojson.features = geojson.features.filter(feature => this.allowedTags.matchesProperties(feature.properties)) - geojson.features.forEach(f => f.properties["_backend"] = this._backend) + geojson.features.forEach(f => { + f.properties["_backend"] = this._backend + }) const index = Tiles.tile_index(z, x, y); new PerLayerFeatureSourceSplitter(this.filteredLayers, diff --git a/Logic/Osm/Changes.ts b/Logic/Osm/Changes.ts index 71a193c1d3..1ef1396033 100644 --- a/Logic/Osm/Changes.ts +++ b/Logic/Osm/Changes.ts @@ -107,7 +107,7 @@ export class Changes { * Uploads all the pending changes in one go. * Triggered by the 'PendingChangeUploader'-actor in Actors */ - public async flushChanges(flushreason: string = undefined) : Promise{ + public async flushChanges(flushreason: string = undefined, openChangeset: UIEventSource) : Promise{ if (this.pendingChanges.data.length === 0) { return; } @@ -115,12 +115,14 @@ export class Changes { console.log("Is already uploading... Abort") return; } + + console.log("Uploading changes due to: ", flushreason) this.isUploading.setData(true) try { - const csNumber = await this.flushChangesAsync() + const csNumber = await this.flushChangesAsync(openChangeset) this.isUploading.setData(false) - console.log("Changes flushed!"); + console.log("Changes flushed. Your changeset is "+csNumber); } catch (e) { this.isUploading.setData(false) console.error("Flushing changes failed due to", e); @@ -207,10 +209,8 @@ export class Changes { /** * UPload the selected changes to OSM. * Returns 'true' if successfull and if they can be removed - * @param pending - * @private */ - private async flushSelectChanges(pending: ChangeDescription[]): Promise { + private async flushSelectChanges(pending: ChangeDescription[], openChangeset: UIEventSource): Promise { const self = this; const neededIds = Changes.GetNeededIds(pending) @@ -304,14 +304,15 @@ export class Changes { await this.state.osmConnection.changesetHandler.UploadChangeset( (csId) => Changes.createChangesetFor("" + csId, changes), - metatags + metatags, + openChangeset ) console.log("Upload successfull!") return true; } - private async flushChangesAsync(): Promise { + private async flushChangesAsync(openChangeset: UIEventSource): Promise { const self = this; try { // At last, we build the changeset and upload @@ -326,10 +327,23 @@ export class Changes { pendingPerTheme.get(theme).push(changeDescription) } - const successes = await Promise.all(Array.from(pendingPerTheme, ([_, value]) => value) - .map(async pendingChanges => { + const successes = await Promise.all(Array.from(pendingPerTheme, + async ([theme, pendingChanges]) => { try { - return await self.flushSelectChanges(pendingChanges); + if(openChangeset === undefined){ + openChangeset = this.state.osmConnection.GetPreference("current-open-changeset-" + theme).map( + str => { + const n = Number(str); + if (isNaN(n)) { + return undefined + } + return n + }, [], n => "" + n + ); + console.log("Using current-open-changeset-"+theme+" from the preferences, got "+openChangeset.data) + } + + return await self.flushSelectChanges(pendingChanges, openChangeset); } catch (e) { console.error("Could not upload some changes:", e) return false diff --git a/Logic/Osm/ChangesetHandler.ts b/Logic/Osm/ChangesetHandler.ts index 50e899f383..6f758f9858 100644 --- a/Logic/Osm/ChangesetHandler.ts +++ b/Logic/Osm/ChangesetHandler.ts @@ -15,7 +15,6 @@ export interface ChangesetTag { export class ChangesetHandler { - public readonly currentChangeset: UIEventSource; private readonly allElements: ElementStorage; private osmConnection: OsmConnection; private readonly changes: Changes; @@ -24,7 +23,8 @@ export class ChangesetHandler { private readonly auth: any; private readonly backend: string; - constructor(layoutName: string, dryRun: boolean, + constructor(layoutName: string, + dryRun: boolean, osmConnection: OsmConnection, allElements: ElementStorage, changes: Changes, @@ -36,19 +36,11 @@ export class ChangesetHandler { this.userDetails = osmConnection.userDetails; this.backend = osmConnection._oauth_config.url this.auth = auth; - this.currentChangeset = osmConnection.GetPreference("current-open-changeset-" + layoutName).map( - str => { - const n = Number(str); - if (isNaN(n)) { - return undefined - } - return n - }, [], n => "" + n - ); if (dryRun) { console.log("DRYRUN ENABLED"); } + } /** @@ -63,12 +55,13 @@ export class ChangesetHandler { */ public async UploadChangeset( generateChangeXML: (csid: number) => string, - extraMetaTags: ChangesetTag[]): Promise { + extraMetaTags: ChangesetTag[], + openChangeset: UIEventSource): Promise { if (!extraMetaTags.some(tag => tag.key === "comment") || !extraMetaTags.some(tag => tag.key === "theme")) { throw "The meta tags should at least contain a `comment` and a `theme`" } - + if (this.userDetails.data.csCount == 0) { // The user became a contributor! this.userDetails.data.csCount = 1; @@ -81,30 +74,30 @@ export class ChangesetHandler { return; } - if (this.currentChangeset.data === undefined) { + if (openChangeset.data === undefined) { // We have to open a new changeset try { const csId = await this.OpenChangeset(extraMetaTags) - this.currentChangeset.setData(csId); + openChangeset.setData(csId); const changeset = generateChangeXML(csId); - console.log("Current changeset is:", changeset); + console.trace("Opened a new changeset (openChangeset.data is undefined):", changeset); await this.AddChange(csId, changeset) } catch (e) { console.error("Could not open/upload changeset due to ", e) - this.currentChangeset.setData(undefined) + openChangeset.setData(undefined) } } else { // There still exists an open changeset (or at least we hope so) // Let's check! - const csId = this.currentChangeset.data; + const csId = openChangeset.data; try { - const oldChangesetMeta = await this.GetChangesetMeta(csId) if (!oldChangesetMeta.open) { // Mark the CS as closed... - this.currentChangeset.setData(undefined); + console.log("Could not fetch the metadata from the already open changeset") + openChangeset.setData(undefined); // ... and try again. As the cs is closed, no recursive loop can exist - await this.UploadChangeset(generateChangeXML, extraMetaTags) + await this.UploadChangeset(generateChangeXML, extraMetaTags, openChangeset) return; } @@ -146,7 +139,7 @@ export class ChangesetHandler { } catch (e) { console.warn("Could not upload, changeset is probably closed: ", e); - this.currentChangeset.setData(undefined); + openChangeset.setData(undefined); } } } @@ -209,14 +202,10 @@ export class ChangesetHandler { private async CloseChangeset(changesetId: number = undefined): Promise { const self = this return new Promise(function (resolve, reject) { - if (changesetId === undefined) { - changesetId = self.currentChangeset.data; - } if (changesetId === undefined) { return; } console.log("closing changeset", changesetId); - self.currentChangeset.setData(undefined); self.auth.xhr({ method: 'PUT', path: '/api/0.6/changeset/' + changesetId + '/close', diff --git a/UI/AutomatonGui.ts b/UI/AutomatonGui.ts index 6c3a4d3a80..036d64e957 100644 --- a/UI/AutomatonGui.ts +++ b/UI/AutomatonGui.ts @@ -30,7 +30,8 @@ import DynamicGeoJsonTileSource from "../Logic/FeatureSource/TiledFeatureSource/ class AutomationPanel extends Combine{ - + private static readonly openChangeset = new UIEventSource(undefined); + constructor(layoutToUse: LayoutConfig, indices: number[], extraCommentText: UIEventSource, tagRenderingToAutomate: { layer: LayerConfig, tagRendering: TagRenderingConfig }) { const layerId = tagRenderingToAutomate.layer.id const trId = tagRenderingToAutomate.tagRendering.id @@ -39,8 +40,9 @@ class AutomationPanel extends Combine{ if (indices === undefined) { throw ("No tiles loaded - can not automate") } - const openChangeset = new UIEventSource(undefined); - openChangeset.addCallbackAndRun(cs => console.log("Sync current open changeset to:", cs)) + const openChangeset = AutomationPanel.openChangeset; + + openChangeset.addCallbackAndRun(cs => console.trace("Sync current open changeset to:", cs)) const nextTileToHandle = tileState.map(handledTiles => { for (const index of indices) { @@ -115,7 +117,7 @@ class AutomationPanel extends Combine{ } private static TileHandler(layoutToUse: LayoutConfig, tileIndex: number, targetLayer: string, targetAction: TagRenderingConfig, extraCommentText: UIEventSource, - openChangeset: UIEventSource, + openChangeset: UIEventSource, whenDone: ((result: string, logMessage?: string) => void)): BaseUIElement { const state = new MapState(layoutToUse, {attemptLogin: false}) @@ -203,13 +205,7 @@ class AutomationPanel extends Combine{ whenDone("no-action","Inspected "+inspected+" elements: "+log.join("; ")) }else{ state.osmConnection.AttemptLogin() - const openCS = state.osmConnection.GetPreference("current-open-changeset-"+layoutToUse.id) - openCS.addCallbackAndRun(cs => { - console.log("Current open Changeset is now: ", cs) - openChangeset.setData(cs) - }) - openCS.setData(openChangeset.data) - state.changes.flushChanges("handled tile automatically, time to flush!") + state.changes.flushChanges("handled tile automatically, time to flush!", openChangeset) whenDone("fixed", "Updated " + handled+" elements, inspected "+inspected+": "+log.join("; ")) } return true;