Browse Source

Rework and test the geo title feature

master
Jan-Lukas Else 3 months ago
parent
commit
63a069cec8
  1. 2
      app.go
  2. 56
      geo.go
  3. 60
      geo_test.go

2
app.go

@ -41,6 +41,8 @@ type goBlog struct {
db *database
// Errors
errorCheckMediaTypes []ct.MediaType
// Geo
photonMutex sync.Mutex
// Hooks
pPostHooks []postHookFunc
pUpdateHooks []postHookFunc

56
geo.go

@ -1,9 +1,9 @@
package main
import (
"bytes"
"context"
"embed"
"encoding/json"
"fmt"
"strings"
@ -11,47 +11,57 @@ import (
"github.com/carlmjohnson/requests"
geojson "github.com/paulmach/go.geojson"
"github.com/thoas/go-funk"
"go.goblog.app/app/pkgs/bufferpool"
)
func (a *goBlog) geoTitle(g *gogeouri.Geo, lang string) string {
if name, ok := g.Parameters["name"]; ok && len(name) > 0 && name[0] != "" {
return name[0]
}
ba, err := a.photonReverse(g.Latitude, g.Longitude, lang)
if err != nil {
return ""
}
fc, err := geojson.UnmarshalFeatureCollection(ba)
fc, err := a.photonReverse(g.Latitude, g.Longitude, lang)
if err != nil || len(fc.Features) < 1 {
return ""
}
f := fc.Features[0]
name := f.PropertyMustString("name", "")
city := f.PropertyMustString("city", "")
state := f.PropertyMustString("state", "")
country := f.PropertyMustString("country", "")
return strings.Join(funk.FilterString([]string{name, city, state, country}, func(s string) bool { return s != "" }), ", ")
return strings.Join(funk.FilterString([]string{
f.PropertyMustString("name", ""), f.PropertyMustString("city", ""), f.PropertyMustString("state", ""), f.PropertyMustString("country", ""),
}, func(s string) bool { return s != "" }), ", ")
}
func (a *goBlog) photonReverse(lat, lon float64, lang string) ([]byte, error) {
func (a *goBlog) photonReverse(lat, lon float64, lang string) (*geojson.FeatureCollection, error) {
// Only allow one concurrent request
a.photonMutex.Lock()
defer a.photonMutex.Unlock()
// Create feature collection
fc := geojson.NewFeatureCollection()
// Check cache
cacheKey := fmt.Sprintf("photon-%v-%v-%v", lat, lon, lang)
cache, _ := a.db.retrievePersistentCache(cacheKey)
if cache != nil {
return cache, nil
if cache, _ := a.db.retrievePersistentCache(cacheKey); cache != nil {
// Cache hit, unmarshal and return
if err := json.Unmarshal(cache, fc); err != nil {
return nil, err
}
return fc, nil
}
var buf bytes.Buffer
rb := requests.URL("https://photon.komoot.io/reverse").Client(a.httpClient).UserAgent(appUserAgent).ToBytesBuffer(&buf)
// No cache, fetch from Photon
buf := bufferpool.Get()
defer bufferpool.Put(buf)
// Create request
rb := requests.URL("https://photon.komoot.io/reverse").Client(a.httpClient).UserAgent(appUserAgent).ToBytesBuffer(buf)
// Set parameters
rb.Param("lat", fmt.Sprintf("%v", lat)).Param("lon", fmt.Sprintf("%v", lon))
if lang == "de" || lang == "fr" || lang == "it" {
rb.Param("lang", lang)
} else {
rb.Param("lang", "en")
}
rb.Param("lang", funk.ShortIf(lang == "de" || lang == "fr" || lang == "it", lang, "en").(string)) // Photon only supports en, de, fr, it
// Do request
if err := rb.Fetch(context.Background()); err != nil {
return nil, err
}
// Cache response
_ = a.db.cachePersistently(cacheKey, buf.Bytes())
return buf.Bytes(), nil
// Unmarshal response
if err := json.NewDecoder(buf).Decode(fc); err != nil {
return nil, err
}
return fc, nil
}
func geoOSMLink(g *gogeouri.Geo) string {

60
geo_test.go

@ -0,0 +1,60 @@
package main
import (
"net/http"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_geo(t *testing.T) {
fc := newFakeHttpClient()
app := &goBlog{
httpClient: fc.Client,
cfg: createDefaultTestConfig(t),
}
_ = app.initConfig()
_ = app.initDatabase(false)
defer app.db.close()
app.initComponents(false)
p := &post{
Blog: "en",
Parameters: map[string][]string{
"location": {"geo:52.51627,13.37737"},
},
}
gu := app.geoURI(p)
require.NotNil(t, gu)
assert.Equal(t, 52.51627, gu.Latitude)
assert.Equal(t, 13.37737, gu.Longitude)
osmLink := geoOSMLink(gu)
assert.Equal(t, "https://www.openstreetmap.org/?mlat=52.51627&mlon=13.37737", osmLink)
// Test original Photon request
fc.setFakeResponse(http.StatusOK, `{"features":[{"geometry":{"coordinates":[13.3774202,52.5162623],"type":"Point"},"type":"Feature","properties":{"osm_id":38345682,"osm_type":"W","extent":[13.3772052,52.5162623,13.3774202,52.5162476],"country":"Deutschland","osm_key":"highway","city":"Berlin","countrycode":"DE","district":"Mitte","osm_value":"service","postcode":"10117","name":"Platz des 18. März","type":"street"}}],"type":"FeatureCollection"}`)
gt := app.geoTitle(gu, "de")
require.NotNil(t, fc.req)
assert.Equal(t, "https://photon.komoot.io/reverse?lang=de&lat=52.51627&lon=13.37737", fc.req.URL.String())
assert.Equal(t, "Platz des 18. März, Berlin, Deutschland", gt)
// Test cache
fc.setFakeResponse(http.StatusOK, "")
gt = app.geoTitle(gu, "de")
assert.Nil(t, fc.req)
assert.Equal(t, "Platz des 18. März, Berlin, Deutschland", gt)
}
Loading…
Cancel
Save