plakateapp

Check-in [7d0c6ad749]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Wir haben jetzt eine Straßensuche!
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | master | trunk
Files: files | file ages | folders
SHA3-256: 7d0c6ad749073c1a99b31731b76714caacffda6f3f987a9159ee393ad906d400
User & Date: git@tuxproject.de 2019-08-12 19:17:57
Context
2019-08-12
19:27
Redundanz war versehentlich wieder da. check-in: 8907e4df67 user: git@tuxproject.de tags: master, trunk
19:17
Wir haben jetzt eine Straßensuche! check-in: 7d0c6ad749 user: git@tuxproject.de tags: master, trunk
19:16
Adding - at least - SOME design... check-in: d9f9eccc70 user: git@tuxproject.de tags: master, trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/plakateapp.go.

1
2
3
4

5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

22
23























24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40




41
42
43
44
45

46
47
48
49
50
51
52
53
54

55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87




























88
89
90
91
92
93

94
95
96
97
98
99
100
101
102









103

104
105
106
107
108
109
110
111

112



113






114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package main

import (
    "encoding/json"

    "fmt"
    "html/template"

    "log"
    "net/http"
    "strconv"

    // Bibliotheken aus GitHub:
    _ "github.com/mattn/go-sqlite3"
    "github.com/jmoiron/sqlx"
    "github.com/gorilla/mux"
)

type Plakat struct {
    // Mapping DB <-> Go-Datentypen:
    ID          int     `db:"id"`
    Latitude    float32 `db:"lat"`
    Longitude   float32 `db:"lon"`

}
























func CheckError(err error) {
    // Bei Fehlern schreiend im Kreis rennen:
    if err != nil {
        panic(err)
    }
}

func FetchPlakate() []Plakat {
    // Liste von Plakaten aus der DB in ein Plakat-Array schieben:
    db, err := sqlx.Open("sqlite3", "./plakate.db")
    CheckError(err)
    defer db.Close()
    
    // Liste erzeugen:
    plakate := []Plakat{}
    db.Select(&plakate, "SELECT * FROM plakate")
    




    return plakate
}

func DeletePlakat(id string) {
    // Datenbank aufrufen:

    db, err := sqlx.Open("sqlite3", "./plakate.db")
    CheckError(err)
    defer db.Close()
    
    // Löschen, falls möglich:
    stmt, err := db.Prepare("delete from plakate where id = ?")
    _, err = stmt.Exec(strconv.Atoi(id))
    CheckError(err)
}

    

// ----------------------------------------
   
func HomeHandler(w http.ResponseWriter, r *http.Request) {
    // Startseite aufrufen:
    tmpl := template.Must(template.ParseFiles("templates/index.htm"))
    tmpl.Execute(w, "")
}

func ManagePlakateHandler(w http.ResponseWriter, r *http.Request) {
    // Datenbank aufrufen:
    plakate := FetchPlakate()
    
    // delete.htm mit Plakate-struct aufrufen:
    tmpl := template.Must(template.ParseFiles("templates/delete.htm"))
    tmpl.Execute(w, plakate)
}

func ListPlakateHandler(w http.ResponseWriter, r *http.Request) {
    // Datenbank aufrufen:
    plakate := FetchPlakate()
    
    // JSON-Objekt ausgeben:
    jsonobj, err := json.Marshal(plakate)
    CheckError(err)
    fmt.Fprintf(w, "%s", string(jsonobj))
}

func NeuesPlakatHandler(w http.ResponseWriter, r *http.Request) {
    // Plakat mit "lat" und "lon" erzeugen:
    lat := r.FormValue("lat")
    lon := r.FormValue("lon")
    




























    // Datenbank aufrufen:
    db, err := sqlx.Open("sqlite3", "./plakate.db")
    CheckError(err)
    defer db.Close()
    
    stmt, err := db.Prepare("insert into plakate (lat, lon) values (?, ?)")

    _, err = stmt.Exec(lat, lon)
    CheckError(err)
    
    fmt.Fprintf(w, "Plakat erfolgreich eingetragen!")
}

func DelHandler(w http.ResponseWriter, r *http.Request) {
    // Plakat mit URL-Parameter "id" löschen:
    vars := mux.Vars(r)









    DeletePlakat(vars["id"])

    
    // Falls kein Fehler aufgetreten ist, umleiten auf /manageplakate:
    http.Redirect(w, r, "/manageplakate", http.StatusMovedPermanently)
}

func DelPostHandler(w http.ResponseWriter, r *http.Request) {
    // Plakat mit POST-Parameter "id" löschen:
    data := r.FormValue("id")

    DeletePlakat(data)



    






    // Falls kein Fehler aufgetreten ist, umleiten auf /manageplakate:
    http.Redirect(w, r, "/manageplakate", http.StatusMovedPermanently)
}

func main() {
    // Routing:
    r := mux.NewRouter()
    r.HandleFunc("/", HomeHandler)
    r.HandleFunc("/manageplakate", ManagePlakateHandler)
    r.HandleFunc("/listplakate", ListPlakateHandler).Methods("POST")
    r.HandleFunc("/neuesplakat", NeuesPlakatHandler).Methods("POST")
    r.HandleFunc("/del/{id:[0-9]+}", DelHandler)
    r.HandleFunc("/delpost", DelPostHandler).Methods("POST")
    
    // script.js auch aus /templates ausliefern:
    r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./templates"))))
    http.Handle("/", r)

    // Server starten:
    log.Fatal(http.ListenAndServe(":6090", nil))
}




>


>


<












>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<





|
|
|

|
|
|
|
<
|
>
>
>
>
|


<
<
>



|
|
|
|
<
|
>
|
>

|









|








|










|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|
|
>
|

|




|

>
>
>
>
>
>
>
>
>
|
>
|





<

>
|
>
>
>
|
>
>
>
>
>
>













|







1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61
62

63
64
65
66
67
68
69
70


71
72
73
74
75
76
77
78

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
package main

import (
    "encoding/json"
    "encoding/xml"
    "fmt"
    "html/template"
    "io/ioutil"
    "log"
    "net/http"


    // Bibliotheken aus GitHub:
    _ "github.com/mattn/go-sqlite3"
    "github.com/jmoiron/sqlx"
    "github.com/gorilla/mux"
)

type Plakat struct {
    // Mapping DB <-> Go-Datentypen:
    ID          int     `db:"id"`
    Latitude    float32 `db:"lat"`
    Longitude   float32 `db:"lon"`
    Location    string  `db:"location"`
}

// Reverse-Geocoding via Nominatim:

type ReverseGeoCode struct {
    XMLName     xml.Name    `xml:"reversegeocode"`
    AdressParts AdressParts `xml:"addressparts"`
}

type AdressParts struct {
    XMLName      xml.Name   `xml:"addressparts"`
    HouseNumber  string     `xml:"house_number"`
    Road         string     `xml:"road"`
    Suburb       string     `xml:"suburb"`
    District     string     `xml:"city_district"`
    City         string     `xml:"city"`
    State        string     `xml:"state"`
    Postcode     string     `xml:"postcode"`
    Country      string     `xml:"country"`
    CountryCode  string     `xml:"country_code"`
}


// ----------------------------------------

func CheckError(err error) {

    if err != nil {
        panic(err)
    }
}

func GetXML(url string) ([]byte, error) {
    // XML herunterladen:
    resp, err := http.Get(url)
    CheckError(err)
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        return []byte{}, fmt.Errorf("Statusfehler: %v", resp.StatusCode)

    }

    data, err := ioutil.ReadAll(resp.Body)
    CheckError(err)

    return data, nil
}



func FetchPlakate() []Plakat {
    db, err := sqlx.Open("sqlite3", "./plakate.db")
    CheckError(err)
    defer db.Close()

    // Liste erzeugen:
    plakate := []Plakat{}
    db.Select(&plakate, "SELECT * FROM plakate")


    return plakate
}

// ----------------------------------------

func HomeHandler(w http.ResponseWriter, r *http.Request) {
    // Startseite aufrufen:
    tmpl := template.Must(template.ParseFiles("templates/index.htm"))
    tmpl.Execute(w, "")
}

func ManagePlakateHandler(w http.ResponseWriter, r *http.Request) {
    // Datenbank aufrufen:
    plakate := FetchPlakate()

    // delete.htm mit Plakate-struct aufrufen:
    tmpl := template.Must(template.ParseFiles("templates/delete.htm"))
    tmpl.Execute(w, plakate)
}

func ListPlakateHandler(w http.ResponseWriter, r *http.Request) {
    // Datenbank aufrufen:
    plakate := FetchPlakate()

    // JSON-Objekt ausgeben:
    jsonobj, err := json.Marshal(plakate)
    CheckError(err)
    fmt.Fprintf(w, "%s", string(jsonobj))
}

func NeuesPlakatHandler(w http.ResponseWriter, r *http.Request) {
    // Plakat mit "lat" und "lon" erzeugen:
    lat := r.FormValue("lat")
    lon := r.FormValue("lon")

    // Geocoding:
    url := fmt.Sprintf("https://nominatim.openstreetmap.org/reverse?lat=%s&lon=%s", lat, lon)
    xmlBytes, err := GetXML(url)
    CheckError(err)

    var xmlFile ReverseGeoCode
    xml.Unmarshal(xmlBytes, &xmlFile)

    adressData := xmlFile.AdressParts

    p1 := ""
    p2 := ""
    p3 := ""

    if adressData.Road != "" {
        p1 = fmt.Sprintf("%s %s, ", adressData.Road, adressData.HouseNumber)
    }

    if adressData.District != "" {
        p2 = fmt.Sprintf("%s, ", adressData.District)
    }

    if adressData.Postcode != "" {
        p3 = fmt.Sprintf("%s %s", adressData.Postcode, adressData.City)
    }

    location := fmt.Sprintf("%s%s%s", p1, p2, p3)

    // Datenbank aufrufen:
    db, err := sqlx.Open("sqlite3", "./plakate.db")
    CheckError(err)
    defer db.Close()

    stmt, err := db.Prepare("insert into plakate (lat, lon, location) values (?, ?, ?)")
    CheckError(err)
    _, err = stmt.Exec(lat, lon, location)
    CheckError(err)

    fmt.Fprintf(w, "Plakat erfolgreich eingetragen!")
}

func DelHandler(w http.ResponseWriter, r *http.Request) {
    // Plakat mit vars["id"] löschen:
    vars := mux.Vars(r)

    // Datenbank aufrufen:
    db, err := sqlx.Open("sqlite3", "./plakate.db")
    CheckError(err)
    defer db.Close()

    // Löschen, falls möglich:
    stmt, err := db.Prepare("delete from plakate where id = ?")
    CheckError(err)
    _, err = stmt.Exec(vars["id"])
    CheckError(err)

    // Falls kein Fehler aufgetreten ist, umleiten auf /manageplakate:
    http.Redirect(w, r, "/manageplakate", http.StatusMovedPermanently)
}

func DelPostHandler(w http.ResponseWriter, r *http.Request) {

    data := r.FormValue("id")

    // Datenbank aufrufen:
    db, err := sqlx.Open("sqlite3", "./plakate.db")
    CheckError(err)
    defer db.Close()

    // Löschen, falls möglich:
    stmt, err := db.Prepare("delete from plakate where id = ?")
    CheckError(err)
    _, err = stmt.Exec(data)
    CheckError(err)

    // Falls kein Fehler aufgetreten ist, umleiten auf /manageplakate:
    http.Redirect(w, r, "/manageplakate", http.StatusMovedPermanently)
}

func main() {
    // Routing:
    r := mux.NewRouter()
    r.HandleFunc("/", HomeHandler)
    r.HandleFunc("/manageplakate", ManagePlakateHandler)
    r.HandleFunc("/listplakate", ListPlakateHandler).Methods("POST")
    r.HandleFunc("/neuesplakat", NeuesPlakatHandler).Methods("POST")
    r.HandleFunc("/del/{id:[0-9]+}", DelHandler)
    r.HandleFunc("/delpost", DelPostHandler).Methods("POST")

    // script.js auch aus /templates ausliefern:
    r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./templates"))))
    http.Handle("/", r)

    // Server starten:
    log.Fatal(http.ListenAndServe(":6090", nil))
}