Skip to content

Commit

Permalink
osm toilet - re-use changeset
Browse files Browse the repository at this point in the history
  • Loading branch information
baditaflorin committed Jun 19, 2024
1 parent 587d1f2 commit 0b27e54
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 40 deletions.
20 changes: 11 additions & 9 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions osm-toilet-map/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
codexgigantus -debug -dir ./osm-toilet-map/ -ignore-file package-lock.json,codexgigantus,frontend.txt,LICENSE -ignore-dir static,cmd,pkg,.idea,.git,node_modules,__previewjs__ -ignore-ext sum,txt,svg,png,ico,md -output-file osm-toilet_GO_chagpt_v131.txt -save


codexgigantus -debug -dir ./osm-toilet-map/ -ignore-file package-lock.json,codexgigantus,frontend.txt,LICENSE -ignore-dir static,cmd,pkg,.idea,.git,node_modules,__previewjs__ -ignore-ext sum,txt,svg,png,ico,md -output-file osm-toilet_GO_chagpt_v131.txt -save
1 change: 1 addition & 0 deletions osm-toilet-map/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Config struct {
ChangesetComment string
CreatedBy string
Port string
ChangesetID string // New field to store the current changeset ID
}

func LoadConfig() *Config {
Expand Down
20 changes: 14 additions & 6 deletions osm-toilet-map/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func HandleFetchNode(cfg *config.Config) http.HandlerFunc {

func HandleUpdateNode(cfg *config.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Get the node ID from the URL
nodeIDStr := r.URL.Path[len("/updateNode/"):]
log.Printf("Received request to update node with ID: %s", nodeIDStr)
nodeID, err := strconv.ParseInt(nodeIDStr, 10, 64)
Expand All @@ -51,7 +50,6 @@ func HandleUpdateNode(cfg *config.Config) http.HandlerFunc {
return
}

// Parse the incoming JSON payload
var updatedTags map[string]string
if err := json.NewDecoder(r.Body).Decode(&updatedTags); err != nil {
log.Printf("Error parsing request body: %v", err)
Expand All @@ -61,7 +59,6 @@ func HandleUpdateNode(cfg *config.Config) http.HandlerFunc {

log.Printf("Updating node %d with tags: %v", nodeID, updatedTags)

// Retrieve the OAuth token from the session
session, _ := oauth.Store.Get(r, "session-name")
token, ok := session.Values["oauth-token"].(*oauth2.Token)
if !ok {
Expand All @@ -70,8 +67,15 @@ func HandleUpdateNode(cfg *config.Config) http.HandlerFunc {
return
}

// Update the node details using the OSM package
err = osm.UpdateNodeDetails(cfg, token, nodeID, updatedTags)
// Use the CreateChangesetIfNeeded function
changesetID, err := oauth.CreateChangesetIfNeeded(cfg, token)
if err != nil {
log.Printf("Error creating changeset: %v", err)
http.Error(w, "Failed to create changeset: "+err.Error(), http.StatusInternalServerError)
return
}

err = osm.UpdateNodeDetails(cfg, token, nodeID, updatedTags, changesetID)
if err != nil {
log.Printf("Error updating node details: %v", err)
http.Error(w, "Failed to update node details: "+err.Error(), http.StatusInternalServerError)
Expand Down Expand Up @@ -158,7 +162,11 @@ func HandleAddNode(cfg *config.Config) http.HandlerFunc {
log.Printf("Retrieved OAuth token from session: %v", token)

// Create the map node using the OAuth token
oauth.CreateMapNode(cfg, token, node.Lat, node.Lon, node.Tags)
err := oauth.CreateMapNode(cfg, token, node.Lat, node.Lon, node.Tags)
if err != nil {
http.Error(w, "Failed to create node: "+err.Error(), http.StatusInternalServerError)
return
}

fmt.Fprintf(w, "Node created successfully")
}
Expand Down
114 changes: 102 additions & 12 deletions osm-toilet-map/oauth/oauth.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// oauth/oauth.go
package oauth

import (
Expand All @@ -7,6 +6,7 @@ import (
"io/ioutil"
"log"
"net/http"
"strings"
"toilet_map/config"
"toilet_map/utils"

Expand All @@ -17,6 +17,7 @@ import (
var (
Oauth2Config *oauth2.Config
Store = sessions.NewCookieStore([]byte("super-secret-key"))
ChangesetID int // Global variable to store the current changeset ID
)

func Init(cfg *config.Config) {
Expand All @@ -37,6 +38,98 @@ func Init(cfg *config.Config) {
TokenURL: cfg.TokenURL,
},
}

ChangesetID = 0 // Initialize changeset ID
}

func CreateChangesetIfNeeded(cfg *config.Config, token *oauth2.Token) (int, error) {
if ChangesetID != 0 {
// Check if the changeset is still open
log.Printf("Checking if existing changeset %d is still open", ChangesetID)
isOpen, err := IsChangesetOpen(token, ChangesetID)
if err != nil {
log.Printf("Error checking if changeset %d is open: %v", ChangesetID, err)
return 0, err
}
if isOpen {
log.Printf("Reusing open changeset %d", ChangesetID)
return ChangesetID, nil
}
// If not open, close it
log.Printf("Closing changeset %d because it is no longer open", ChangesetID)
err = CloseChangeset(token, ChangesetID)
if err != nil {
log.Printf("Error closing changeset %d: %v", ChangesetID, err)
return 0, err
}
}

// Create a new changeset
client := Oauth2Config.Client(oauth2.NoContext, token)
req, err := createChangesetRequest(cfg, token)
if err != nil {
log.Printf("Failed to create changeset request: %v", err)
return 0, err
}
req.Header.Set("Authorization", "Bearer "+token.AccessToken)

log.Println("Sending changeset creation request")
resp, err := client.Do(req)
if err != nil {
log.Printf("Error creating changeset: %v", err)
return 0, err
}
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Printf("Error reading changeset response body: %v", err)
return 0, err
}

log.Printf("Changeset creation response body: %s", string(body))

var changesetID int
fmt.Sscanf(string(body), "%d", &changesetID)
log.Printf("Created changeset with ID: %d", changesetID)

ChangesetID = changesetID // Update the global changeset ID
return changesetID, nil
}

func IsChangesetOpen(token *oauth2.Token, changesetID int) (bool, error) {
client := Oauth2Config.Client(oauth2.NoContext, token)
url := fmt.Sprintf("https://api.openstreetmap.org/api/0.6/changeset/%d", changesetID)
req, err := utils.CreateRequest("GET", url, "application/json", nil)
if err != nil {
log.Printf("Failed to create request to check if changeset %d is open: %v", changesetID, err)
return false, fmt.Errorf("failed to create request: %v", err)
}
req.Header.Set("Authorization", "Bearer "+token.AccessToken)

log.Printf("Checking if changeset %d is open", changesetID)
resp, err := client.Do(req)
if err != nil {
log.Printf("Failed to fetch changeset status for changeset %d: %v", changesetID, err)
return false, fmt.Errorf("failed to fetch changeset status: %v", err)
}
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Printf("Failed to read response body for changeset %d: %v", changesetID, err)
return false, fmt.Errorf("failed to read response body: %v", err)
}

log.Printf("Response body for changeset %d: %s", changesetID, string(body))

// Check if the response body contains `open="true"`
if strings.Contains(string(body), `open="true"`) {
log.Printf("Changeset %d is open", changesetID)
return true, nil
}
log.Printf("Changeset %d is closed", changesetID)
return false, nil
}

func createChangesetRequest(cfg *config.Config, token *oauth2.Token) (*http.Request, error) {
Expand Down Expand Up @@ -108,7 +201,7 @@ func CloseChangeset(token *oauth2.Token, changesetID int) error {
req.Header.Set("Authorization", "Bearer "+token.AccessToken)

log.Printf("Sending close changeset request for changeset ID: %d", changesetID)
_, err = utils.DoRequest(client, req)
_, err = client.Do(req)
if err != nil {
log.Printf("Error closing changeset: %v", err)
} else {
Expand All @@ -117,27 +210,24 @@ func CloseChangeset(token *oauth2.Token, changesetID int) error {
return err
}

func CreateMapNode(cfg *config.Config, token *oauth2.Token, lat, lon float64, tags map[string]string) {
changesetID, err := CreateChangeset(cfg, token)
func CreateMapNode(cfg *config.Config, token *oauth2.Token, lat, lon float64, tags map[string]string) error {
changesetID, err := CreateChangesetIfNeeded(cfg, token)
if err != nil {
log.Fatalf("Failed to create changeset: %v", err)
return fmt.Errorf("failed to create changeset: %v", err)
}

client := Oauth2Config.Client(oauth2.NoContext, token)
req, err := createNodeRequest(changesetID, lat, lon, tags)
if err != nil {
log.Fatalf("Failed to create request: %v", err)
return fmt.Errorf("failed to create request: %v", err)
}
req.Header.Set("Authorization", "Bearer "+token.AccessToken)

_, err = utils.DoRequest(client, req)
if err != nil {
log.Fatalf("Failed to create node: %v", err)
return fmt.Errorf("failed to create node: %v", err)
}

fmt.Printf("Node created successfully\n")

if err := CloseChangeset(token, changesetID); err != nil {
log.Fatalf("Failed to close changeset: %v", err)
}
log.Printf("Node created successfully\n")
return nil
}
16 changes: 3 additions & 13 deletions osm-toilet-map/osm/osm.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"strings"

"toilet_map/config"
"toilet_map/oauth"
"toilet_map/utils"
)

Expand Down Expand Up @@ -87,20 +86,14 @@ func FetchNodeDetails(cfg *config.Config, nodeID int64) (*Node, error) {
return &data.Elements[0], nil
}

func UpdateNodeDetails(cfg *config.Config, token *oauth2.Token, nodeID int64, updatedTags map[string]string) error {
func UpdateNodeDetails(cfg *config.Config, token *oauth2.Token, nodeID int64, updatedTags map[string]string, changesetID int) error {
client := oauth2.NewClient(oauth2.NoContext, oauth2.StaticTokenSource(token))

// Fetch the current node details to get lat, lon, and version
node, err := FetchNodeDetails(cfg, nodeID)
if err != nil {
return fmt.Errorf("failed to fetch node details: %v", err)
}

changesetID, err := oauth.CreateChangeset(cfg, token)
if err != nil {
return fmt.Errorf("failed to create changeset: %v", err)
}

var tagsXML string
for key, value := range updatedTags {
tagsXML += fmt.Sprintf(`<tag k="%s" v="%s"/>`, key, value)
Expand All @@ -121,14 +114,11 @@ func UpdateNodeDetails(cfg *config.Config, token *oauth2.Token, nodeID int64, up
}
req.Header.Set("Authorization", "Bearer "+token.AccessToken)

_, err = utils.DoRequest(client, req)
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("failed to update node: %v", err)
}

if err := oauth.CloseChangeset(token, changesetID); err != nil {
return fmt.Errorf("failed to close changeset: %v", err)
}
defer resp.Body.Close()

log.Printf("Node %d updated successfully\n", nodeID)
return nil
Expand Down

0 comments on commit 0b27e54

Please sign in to comment.