forked from MapComplete/MapComplete
		
	Fix changeset reuse for automaton
This commit is contained in:
		
							parent
							
								
									90fc0e0840
								
							
						
					
					
						commit
						0ae78f19f3
					
				
					 4 changed files with 50 additions and 49 deletions
				
			
		|  | @ -105,7 +105,9 @@ export default class OsmFeatureSource { | ||||||
|                 // We only keep what is needed
 |                 // We only keep what is needed
 | ||||||
| 
 | 
 | ||||||
|                 geojson.features = geojson.features.filter(feature => this.allowedTags.matchesProperties(feature.properties)) |                 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); |                 const index = Tiles.tile_index(z, x, y); | ||||||
|                 new PerLayerFeatureSourceSplitter(this.filteredLayers, |                 new PerLayerFeatureSourceSplitter(this.filteredLayers, | ||||||
|  |  | ||||||
|  | @ -107,7 +107,7 @@ export class Changes { | ||||||
|      * Uploads all the pending changes in one go. |      * Uploads all the pending changes in one go. | ||||||
|      * Triggered by the 'PendingChangeUploader'-actor in Actors |      * Triggered by the 'PendingChangeUploader'-actor in Actors | ||||||
|      */ |      */ | ||||||
|     public async flushChanges(flushreason: string = undefined) : Promise<void>{ |     public async flushChanges(flushreason: string = undefined, openChangeset: UIEventSource<number>) : Promise<void>{ | ||||||
|         if (this.pendingChanges.data.length === 0) { |         if (this.pendingChanges.data.length === 0) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  | @ -115,12 +115,14 @@ export class Changes { | ||||||
|             console.log("Is already uploading... Abort") |             console.log("Is already uploading... Abort") | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |          | ||||||
|         console.log("Uploading changes due to: ", flushreason) |         console.log("Uploading changes due to: ", flushreason) | ||||||
|         this.isUploading.setData(true) |         this.isUploading.setData(true) | ||||||
|         try { |         try { | ||||||
|             const csNumber = await this.flushChangesAsync() |             const csNumber = await this.flushChangesAsync(openChangeset) | ||||||
|             this.isUploading.setData(false) |             this.isUploading.setData(false) | ||||||
|             console.log("Changes flushed!"); |             console.log("Changes flushed. Your changeset is "+csNumber); | ||||||
|         } catch (e) { |         } catch (e) { | ||||||
|             this.isUploading.setData(false) |             this.isUploading.setData(false) | ||||||
|             console.error("Flushing changes failed due to", e); |             console.error("Flushing changes failed due to", e); | ||||||
|  | @ -207,10 +209,8 @@ export class Changes { | ||||||
|     /** |     /** | ||||||
|      * UPload the selected changes to OSM. |      * UPload the selected changes to OSM. | ||||||
|      * Returns 'true' if successfull and if they can be removed |      * Returns 'true' if successfull and if they can be removed | ||||||
|      * @param pending |  | ||||||
|      * @private |  | ||||||
|      */ |      */ | ||||||
|     private async flushSelectChanges(pending: ChangeDescription[]): Promise<boolean> { |     private async flushSelectChanges(pending: ChangeDescription[], openChangeset: UIEventSource<number>): Promise<boolean> { | ||||||
|         const self = this; |         const self = this; | ||||||
|         const neededIds = Changes.GetNeededIds(pending) |         const neededIds = Changes.GetNeededIds(pending) | ||||||
| 
 | 
 | ||||||
|  | @ -304,14 +304,15 @@ export class Changes { | ||||||
| 
 | 
 | ||||||
|         await this.state.osmConnection.changesetHandler.UploadChangeset( |         await this.state.osmConnection.changesetHandler.UploadChangeset( | ||||||
|             (csId) => Changes.createChangesetFor("" + csId, changes), |             (csId) => Changes.createChangesetFor("" + csId, changes), | ||||||
|             metatags |             metatags, | ||||||
|  |             openChangeset | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         console.log("Upload successfull!") |         console.log("Upload successfull!") | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private async flushChangesAsync(): Promise<void> { |     private async flushChangesAsync(openChangeset: UIEventSource<number>): Promise<void> { | ||||||
|         const self = this; |         const self = this; | ||||||
|         try { |         try { | ||||||
|             // At last, we build the changeset and upload
 |             // At last, we build the changeset and upload
 | ||||||
|  | @ -326,10 +327,23 @@ export class Changes { | ||||||
|                 pendingPerTheme.get(theme).push(changeDescription) |                 pendingPerTheme.get(theme).push(changeDescription) | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             const successes = await Promise.all(Array.from(pendingPerTheme, ([_, value]) => value) |             const successes = await Promise.all(Array.from(pendingPerTheme,  | ||||||
|                 .map(async pendingChanges => { |                async ([theme, pendingChanges]) => { | ||||||
|                     try { |                     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) { |                     } catch (e) { | ||||||
|                         console.error("Could not upload some changes:", e) |                         console.error("Could not upload some changes:", e) | ||||||
|                         return false |                         return false | ||||||
|  |  | ||||||
|  | @ -15,7 +15,6 @@ export interface ChangesetTag { | ||||||
| 
 | 
 | ||||||
| export class ChangesetHandler { | export class ChangesetHandler { | ||||||
| 
 | 
 | ||||||
|     public readonly currentChangeset: UIEventSource<number>; |  | ||||||
|     private readonly allElements: ElementStorage; |     private readonly allElements: ElementStorage; | ||||||
|     private osmConnection: OsmConnection; |     private osmConnection: OsmConnection; | ||||||
|     private readonly changes: Changes; |     private readonly changes: Changes; | ||||||
|  | @ -24,7 +23,8 @@ export class ChangesetHandler { | ||||||
|     private readonly auth: any; |     private readonly auth: any; | ||||||
|     private readonly backend: string; |     private readonly backend: string; | ||||||
| 
 | 
 | ||||||
|     constructor(layoutName: string, dryRun: boolean, |     constructor(layoutName: string, | ||||||
|  |                 dryRun: boolean, | ||||||
|                 osmConnection: OsmConnection, |                 osmConnection: OsmConnection, | ||||||
|                 allElements: ElementStorage, |                 allElements: ElementStorage, | ||||||
|                 changes: Changes, |                 changes: Changes, | ||||||
|  | @ -36,19 +36,11 @@ export class ChangesetHandler { | ||||||
|         this.userDetails = osmConnection.userDetails; |         this.userDetails = osmConnection.userDetails; | ||||||
|         this.backend = osmConnection._oauth_config.url |         this.backend = osmConnection._oauth_config.url | ||||||
|         this.auth = auth; |         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) { |         if (dryRun) { | ||||||
|             console.log("DRYRUN ENABLED"); |             console.log("DRYRUN ENABLED"); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | @ -63,7 +55,8 @@ export class ChangesetHandler { | ||||||
|      */ |      */ | ||||||
|     public async UploadChangeset( |     public async UploadChangeset( | ||||||
|         generateChangeXML: (csid: number) => string, |         generateChangeXML: (csid: number) => string, | ||||||
|         extraMetaTags: ChangesetTag[]): Promise<void> { |         extraMetaTags: ChangesetTag[], | ||||||
|  |         openChangeset: UIEventSource<number>): Promise<void> { | ||||||
| 
 | 
 | ||||||
|         if (!extraMetaTags.some(tag => tag.key === "comment") || !extraMetaTags.some(tag => tag.key === "theme")) { |         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`" |             throw "The meta tags should at least contain a `comment` and a `theme`" | ||||||
|  | @ -81,30 +74,30 @@ export class ChangesetHandler { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (this.currentChangeset.data === undefined) { |         if (openChangeset.data === undefined) { | ||||||
|             // We have to open a new changeset
 |             // We have to open a new changeset
 | ||||||
|             try { |             try { | ||||||
|                 const csId = await this.OpenChangeset(extraMetaTags) |                 const csId = await this.OpenChangeset(extraMetaTags) | ||||||
|                 this.currentChangeset.setData(csId); |                 openChangeset.setData(csId); | ||||||
|                 const changeset = generateChangeXML(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) |                 await this.AddChange(csId, changeset) | ||||||
|             } catch (e) { |             } catch (e) { | ||||||
|                 console.error("Could not open/upload changeset due to ", e) |                 console.error("Could not open/upload changeset due to ", e) | ||||||
|                 this.currentChangeset.setData(undefined) |                 openChangeset.setData(undefined) | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             // There still exists an open changeset (or at least we hope so)
 |             // There still exists an open changeset (or at least we hope so)
 | ||||||
|             // Let's check!
 |             // Let's check!
 | ||||||
|             const csId = this.currentChangeset.data; |             const csId = openChangeset.data; | ||||||
|             try { |             try { | ||||||
| 
 |  | ||||||
|                 const oldChangesetMeta = await this.GetChangesetMeta(csId) |                 const oldChangesetMeta = await this.GetChangesetMeta(csId) | ||||||
|                 if (!oldChangesetMeta.open) { |                 if (!oldChangesetMeta.open) { | ||||||
|                     // Mark the CS as closed...
 |                     // 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  
 |                     // ... 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; |                     return; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  | @ -146,7 +139,7 @@ export class ChangesetHandler { | ||||||
| 
 | 
 | ||||||
|             } catch (e) { |             } catch (e) { | ||||||
|                 console.warn("Could not upload, changeset is probably closed: ", 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<void> { |     private async CloseChangeset(changesetId: number = undefined): Promise<void> { | ||||||
|         const self = this |         const self = this | ||||||
|         return new Promise<void>(function (resolve, reject) { |         return new Promise<void>(function (resolve, reject) { | ||||||
|             if (changesetId === undefined) { |  | ||||||
|                 changesetId = self.currentChangeset.data; |  | ||||||
|             } |  | ||||||
|             if (changesetId === undefined) { |             if (changesetId === undefined) { | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             console.log("closing changeset", changesetId); |             console.log("closing changeset", changesetId); | ||||||
|             self.currentChangeset.setData(undefined); |  | ||||||
|             self.auth.xhr({ |             self.auth.xhr({ | ||||||
|                 method: 'PUT', |                 method: 'PUT', | ||||||
|                 path: '/api/0.6/changeset/' + changesetId + '/close', |                 path: '/api/0.6/changeset/' + changesetId + '/close', | ||||||
|  |  | ||||||
|  | @ -30,6 +30,7 @@ import DynamicGeoJsonTileSource from "../Logic/FeatureSource/TiledFeatureSource/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class AutomationPanel extends Combine{ | class AutomationPanel extends Combine{ | ||||||
|  |     private static readonly openChangeset = new UIEventSource<number>(undefined); | ||||||
| 
 | 
 | ||||||
|     constructor(layoutToUse: LayoutConfig, indices: number[], extraCommentText: UIEventSource<string>, tagRenderingToAutomate: { layer: LayerConfig, tagRendering: TagRenderingConfig }) { |     constructor(layoutToUse: LayoutConfig, indices: number[], extraCommentText: UIEventSource<string>, tagRenderingToAutomate: { layer: LayerConfig, tagRendering: TagRenderingConfig }) { | ||||||
|         const layerId = tagRenderingToAutomate.layer.id |         const layerId = tagRenderingToAutomate.layer.id | ||||||
|  | @ -39,8 +40,9 @@ class AutomationPanel extends Combine{ | ||||||
|         if (indices === undefined) { |         if (indices === undefined) { | ||||||
|            throw ("No tiles loaded - can not automate") |            throw ("No tiles loaded - can not automate") | ||||||
|         } |         } | ||||||
|         const openChangeset = new UIEventSource<string>(undefined); |         const openChangeset = AutomationPanel.openChangeset; | ||||||
|         openChangeset.addCallbackAndRun(cs => console.log("Sync current open changeset to:", cs)) |        | ||||||
|  |         openChangeset.addCallbackAndRun(cs => console.trace("Sync current open changeset to:", cs)) | ||||||
| 
 | 
 | ||||||
|         const nextTileToHandle = tileState.map(handledTiles => { |         const nextTileToHandle = tileState.map(handledTiles => { | ||||||
|             for (const index of indices) { |             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<string>,  |     private static TileHandler(layoutToUse: LayoutConfig, tileIndex: number, targetLayer: string, targetAction: TagRenderingConfig, extraCommentText: UIEventSource<string>,  | ||||||
|                                openChangeset: UIEventSource<string>, |                                openChangeset: UIEventSource<number>, | ||||||
|                                whenDone: ((result: string, logMessage?: string) => void)): BaseUIElement { |                                whenDone: ((result: string, logMessage?: string) => void)): BaseUIElement { | ||||||
| 
 | 
 | ||||||
|         const state = new MapState(layoutToUse, {attemptLogin: false}) |         const state = new MapState(layoutToUse, {attemptLogin: false}) | ||||||
|  | @ -203,13 +205,7 @@ class AutomationPanel extends Combine{ | ||||||
|                     whenDone("no-action","Inspected "+inspected+" elements: "+log.join("; ")) |                     whenDone("no-action","Inspected "+inspected+" elements: "+log.join("; ")) | ||||||
|                 }else{ |                 }else{ | ||||||
|                     state.osmConnection.AttemptLogin() |                     state.osmConnection.AttemptLogin() | ||||||
|                     const openCS = state.osmConnection.GetPreference("current-open-changeset-"+layoutToUse.id) |                     state.changes.flushChanges("handled tile automatically, time to flush!", openChangeset) | ||||||
|                     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!") |  | ||||||
|                     whenDone("fixed", "Updated " + handled+" elements, inspected "+inspected+": "+log.join("; ")) |                     whenDone("fixed", "Updated " + handled+" elements, inspected "+inspected+": "+log.join("; ")) | ||||||
|                 } |                 } | ||||||
|                 return true; |                 return true; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue