Option to hide gpx route with frontmatter "showroute: false"

This commit is contained in:
Jan-Lukas Else 2022-07-13 16:02:08 +02:00
parent b14070ce04
commit 22fce13246
7 changed files with 100 additions and 56 deletions

View File

@ -56,10 +56,12 @@ func (a *goBlog) serveGeoMapTracks(w http.ResponseWriter, r *http.Request) {
blog, _ := a.getBlog(r) blog, _ := a.getBlog(r)
allPostsWithTracks, err := a.getPosts(&postsRequestConfig{ allPostsWithTracks, err := a.getPosts(&postsRequestConfig{
blog: blog, blog: blog,
status: statusPublished, status: statusPublished,
parameters: []string{gpxParameter}, parameters: []string{gpxParameter},
withOnlyParameters: []string{gpxParameter}, withOnlyParameters: []string{gpxParameter},
excludeParameter: showRouteParam,
excludeParameterValue: "false", // Don't show hidden route tracks
}) })
if err != nil { if err != nil {
a.serveError(w, r, err.Error(), http.StatusInternalServerError) a.serveError(w, r, err.Error(), http.StatusInternalServerError)
@ -74,7 +76,7 @@ func (a *goBlog) serveGeoMapTracks(w http.ResponseWriter, r *http.Request) {
var tracks []*templateTrack var tracks []*templateTrack
for _, p := range allPostsWithTracks { for _, p := range allPostsWithTracks {
if t, err := a.getTrack(p); err == nil && t != nil { if t, err := a.getTrack(p, true); err == nil && t != nil {
tracks = append(tracks, &templateTrack{ tracks = append(tracks, &templateTrack{
Paths: t.Paths, Paths: t.Paths,
Points: t.Points, Points: t.Points,

View File

@ -12,13 +12,20 @@ import (
) )
const gpxParameter = "gpx" const gpxParameter = "gpx"
const showRouteParam = "showroute"
func (p *post) HasTrack() bool { func (p *post) hasTrack() bool {
return p.firstParameter(gpxParameter) != "" return p.firstParameter(gpxParameter) != ""
} }
func (p *post) showTrackRoute() bool {
if param := p.firstParameter(showRouteParam); param == "false" {
return false
}
return true
}
type trackResult struct { type trackResult struct {
HasPoints bool
Paths [][]*trackPoint Paths [][]*trackPoint
PathsJSON string PathsJSON string
Points []*trackPoint Points []*trackPoint
@ -30,7 +37,11 @@ type trackResult struct {
MinZoom, MaxZoom int MinZoom, MaxZoom int
} }
func (a *goBlog) getTrack(p *post) (result *trackResult, err error) { func (t *trackResult) hasMapFeatures() bool {
return t.Points != nil || t.Paths != nil
}
func (a *goBlog) getTrack(p *post, withMapFeatures bool) (result *trackResult, err error) {
gpxString := p.firstParameter(gpxParameter) gpxString := p.firstParameter(gpxParameter)
if gpxString == "" { if gpxString == "" {
return nil, errors.New("no gpx parameter in post") return nil, errors.New("no gpx parameter in post")
@ -47,26 +58,29 @@ func (a *goBlog) getTrack(p *post) (result *trackResult, err error) {
l, _ := language.Parse(a.cfg.Blogs[p.Blog].Lang) l, _ := language.Parse(a.cfg.Blogs[p.Blog].Lang)
lp := message.NewPrinter(l) lp := message.NewPrinter(l)
pathsJSON, err := json.Marshal(parseResult.paths)
if err != nil {
return nil, err
}
pointsJSON, err := json.Marshal(parseResult.points)
if err != nil {
return nil, err
}
result = &trackResult{ result = &trackResult{
HasPoints: len(parseResult.paths) > 0 && len(parseResult.paths[0]) > 0, Name: parseResult.gpxData.Name,
Paths: parseResult.paths, }
PathsJSON: string(pathsJSON),
Points: parseResult.points, if withMapFeatures {
PointsJSON: string(pointsJSON), // Add Paths
Name: parseResult.gpxData.Name, pathsJSON, err := json.Marshal(parseResult.paths)
MapAttribution: a.getMapAttribution(), if err != nil {
MinZoom: a.getMinZoom(), return nil, err
MaxZoom: a.getMaxZoom(), }
result.Paths = parseResult.paths
result.PathsJSON = string(pathsJSON)
// Add Points
pointsJSON, err := json.Marshal(parseResult.points)
if err != nil {
return nil, err
}
result.Points = parseResult.points
result.PointsJSON = string(pointsJSON)
// Map settings
result.MapAttribution = a.getMapAttribution()
result.MinZoom = a.getMinZoom()
result.MaxZoom = a.getMaxZoom()
} }
if parseResult.md != nil { if parseResult.md != nil {

View File

@ -44,10 +44,9 @@ func Test_geoTrack(t *testing.T) {
}, },
} }
resEn, err := app.getTrack(p) resEn, err := app.getTrack(p, true)
require.NoError(t, err) require.NoError(t, err)
assert.True(t, resEn.HasPoints)
assert.NotEmpty(t, resEn.Paths) assert.NotEmpty(t, resEn.Paths)
assert.Empty(t, resEn.Points) assert.Empty(t, resEn.Points)
assert.Equal(t, "2.70", resEn.Kilometers) assert.Equal(t, "2.70", resEn.Kilometers)
@ -55,10 +54,9 @@ func Test_geoTrack(t *testing.T) {
p.Blog = "de" p.Blog = "de"
resDe, err := app.getTrack(p) resDe, err := app.getTrack(p, true)
require.NoError(t, err) require.NoError(t, err)
assert.True(t, resDe.HasPoints)
assert.NotEmpty(t, resDe.Paths) assert.NotEmpty(t, resDe.Paths)
assert.Empty(t, resDe.Points) assert.Empty(t, resDe.Points)
assert.Equal(t, "2,70", resDe.Kilometers) assert.Equal(t, "2,70", resDe.Kilometers)
@ -77,15 +75,33 @@ func Test_geoTrack(t *testing.T) {
}, },
} }
resEn, err = app.getTrack(p) resEn, err = app.getTrack(p, true)
require.NoError(t, err) require.NoError(t, err)
assert.True(t, resEn.HasPoints)
assert.NotEmpty(t, resEn.Paths) assert.NotEmpty(t, resEn.Paths)
assert.NotEmpty(t, resEn.Points) assert.NotEmpty(t, resEn.Points)
assert.Equal(t, "0.08", resEn.Kilometers) assert.Equal(t, "0.08", resEn.Kilometers)
assert.Equal(t, "0:01:29", resEn.Hours) assert.Equal(t, "0:01:29", resEn.Hours)
// Test "privacy" feature to hide track
p = &post{
Blog: "en",
Parameters: map[string][]string{
"gpx": {string(gpxBytes)},
"showroute": {"false"},
},
}
resEn, err = app.getTrack(p, p.showTrackRoute())
require.NoError(t, err)
assert.False(t, p.showTrackRoute())
assert.Empty(t, resEn.Paths)
assert.Empty(t, resEn.Points)
assert.Equal(t, "0.08", resEn.Kilometers)
assert.Equal(t, "0:01:29", resEn.Hours)
// Third file (just with route) // Third file (just with route)
gpxBytes, _ = os.ReadFile("testdata/test3.gpx") gpxBytes, _ = os.ReadFile("testdata/test3.gpx")
@ -99,10 +115,9 @@ func Test_geoTrack(t *testing.T) {
}, },
} }
resEn, err = app.getTrack(p) resEn, err = app.getTrack(p, true)
require.NoError(t, err) require.NoError(t, err)
assert.True(t, resEn.HasPoints)
assert.NotEmpty(t, resEn.Paths) assert.NotEmpty(t, resEn.Paths)
assert.Empty(t, resEn.Points) assert.Empty(t, resEn.Points)
assert.Equal(t, "", resEn.Kilometers) assert.Equal(t, "", resEn.Kilometers)

4
go.mod
View File

@ -33,7 +33,7 @@ require (
github.com/jlelse/feeds v1.2.1-0.20210704161900-189f94254ad4 github.com/jlelse/feeds v1.2.1-0.20210704161900-189f94254ad4
github.com/justinas/alice v1.2.0 github.com/justinas/alice v1.2.0
github.com/kaorimatz/go-opml v0.0.0-20210201121027-bc8e2852d7f9 github.com/kaorimatz/go-opml v0.0.0-20210201121027-bc8e2852d7f9
github.com/klauspost/compress v1.15.7 github.com/klauspost/compress v1.15.8
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/lopezator/migrator v0.3.1 github.com/lopezator/migrator v0.3.1
github.com/mattn/go-sqlite3 v1.14.14 github.com/mattn/go-sqlite3 v1.14.14
@ -49,7 +49,7 @@ require (
github.com/spf13/cast v1.5.0 github.com/spf13/cast v1.5.0
github.com/spf13/viper v1.12.0 github.com/spf13/viper v1.12.0
github.com/stretchr/testify v1.8.0 github.com/stretchr/testify v1.8.0
github.com/tdewolff/minify/v2 v2.11.12 github.com/tdewolff/minify/v2 v2.12.0
// master // master
github.com/tkrajina/gpxgo v1.2.2-0.20220217201249-321f19554eec github.com/tkrajina/gpxgo v1.2.2-0.20220217201249-321f19554eec
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80

8
go.sum
View File

@ -329,8 +329,8 @@ github.com/kaorimatz/go-opml v0.0.0-20210201121027-bc8e2852d7f9 h1:+9REu9CK9D1AQ
github.com/kaorimatz/go-opml v0.0.0-20210201121027-bc8e2852d7f9/go.mod h1:OvY5ZBrAC9kOvM2PZs9Lw0BH+5K7tjrT6T7SFhn27OA= github.com/kaorimatz/go-opml v0.0.0-20210201121027-bc8e2852d7f9/go.mod h1:OvY5ZBrAC9kOvM2PZs9Lw0BH+5K7tjrT6T7SFhn27OA=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.15.7 h1:7cgTQxJCU/vy+oP/E3B9RGbQTgbiVzIJWIKOLoAsPok= github.com/klauspost/compress v1.15.8 h1:JahtItbkWjf2jzm/T+qgMxkP9EMHsqEUA6vCMGmXvhA=
github.com/klauspost/compress v1.15.7/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/klauspost/compress v1.15.8/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ= github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ=
github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk= github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
@ -469,8 +469,8 @@ github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85 h1:zrsUcqrG2uQ
github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0= github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0=
github.com/tcnksm/go-httpstat v0.2.0 h1:rP7T5e5U2HfmOBmZzGgGZjBQ5/GluWUylujl0tJ04I0= github.com/tcnksm/go-httpstat v0.2.0 h1:rP7T5e5U2HfmOBmZzGgGZjBQ5/GluWUylujl0tJ04I0=
github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8= github.com/tcnksm/go-httpstat v0.2.0/go.mod h1:s3JVJFtQxtBEBC9dwcdTTXS9xFnM3SXAZwPG41aurT8=
github.com/tdewolff/minify/v2 v2.11.12 h1:LwC0+ayfFkLwIwpeun2T35FeUaO3f6XS2bus/QWAnC0= github.com/tdewolff/minify/v2 v2.12.0 h1:ZyvMKeciyR3vzJrK/oHyBcSmpttQ/V+ah7qOqTZclaU=
github.com/tdewolff/minify/v2 v2.11.12/go.mod h1:8mvf+KglD7XurfvvFZDUYvVURy6bA/r0oTvmakXMnyg= github.com/tdewolff/minify/v2 v2.12.0/go.mod h1:8mvf+KglD7XurfvvFZDUYvVURy6bA/r0oTvmakXMnyg=
github.com/tdewolff/parse/v2 v2.6.1 h1:RIfy1erADkO90ynJWvty8VIkqqKYRzf2iLp8ObG174I= github.com/tdewolff/parse/v2 v2.6.1 h1:RIfy1erADkO90ynJWvty8VIkqqKYRzf2iLp8ObG174I=
github.com/tdewolff/parse/v2 v2.6.1/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho= github.com/tdewolff/parse/v2 v2.6.1/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=

View File

@ -344,6 +344,8 @@ type postsRequestConfig struct {
parameters []string // Ignores parameterValue parameters []string // Ignores parameterValue
parameter string // Ignores parameters parameter string // Ignores parameters
parameterValue string parameterValue string
excludeParameter string // exclude posts that have a certain parameter (with non-empty value)
excludeParameterValue string // ... with exactly this value
publishedYear, publishedMonth, publishedDay int publishedYear, publishedMonth, publishedDay int
publishedBefore time.Time publishedBefore time.Time
randomOrder bool randomOrder bool
@ -415,6 +417,15 @@ func buildPostsQuery(c *postsRequestConfig, selection string) (query string, arg
} }
queryBuilder.WriteString(") and length(coalesce(value, '')) > 0)") queryBuilder.WriteString(") and length(coalesce(value, '')) > 0)")
} }
if c.excludeParameter != "" {
if c.excludeParameterValue != "" {
queryBuilder.WriteString(" and path not in (select path from post_parameters where parameter = @param and value = @paramval)")
args = append(args, sql.Named("param", c.excludeParameter), sql.Named("paramval", c.excludeParameterValue))
} else {
queryBuilder.WriteString(" and path not in (select path from post_parameters where parameter = @param and length(coalesce(value, '')) > 0)")
args = append(args, sql.Named("param", c.excludeParameter))
}
}
if c.taxonomy != nil && len(c.taxonomyValue) > 0 { if c.taxonomy != nil && len(c.taxonomyValue) > 0 {
queryBuilder.WriteString(" and path in (select path from post_parameters where parameter = @taxname and lowerx(value) = lowerx(@taxval))") queryBuilder.WriteString(" and path in (select path from post_parameters where parameter = @taxname and lowerx(value) = lowerx(@taxval))")
args = append(args, sql.Named("taxname", c.taxonomy.Name), sql.Named("taxval", c.taxonomyValue)) args = append(args, sql.Named("taxname", c.taxonomy.Name), sql.Named("taxval", c.taxonomyValue))

View File

@ -67,7 +67,7 @@ func (a *goBlog) renderSummary(hb *htmlBuilder, bc *configBlog, p *post, typ sum
// Contains photos // Contains photos
prefix.WriteString("🖼️") prefix.WriteString("🖼️")
} }
if p.HasTrack() { if p.hasTrack() {
// Has GPX track // Has GPX track
prefix.WriteString("🗺️") prefix.WriteString("🗺️")
} }
@ -432,11 +432,11 @@ func (*goBlog) renderPostTitle(hb *htmlBuilder, p *post) {
} }
func (a *goBlog) renderPostGPX(hb *htmlBuilder, p *post, b *configBlog) { func (a *goBlog) renderPostGPX(hb *htmlBuilder, p *post, b *configBlog) {
if p == nil || !p.HasTrack() { if p == nil || !p.hasTrack() {
return return
} }
track, err := a.getTrack(p) track, err := a.getTrack(p, p.showTrackRoute())
if err != nil || track == nil || !track.HasPoints { if err != nil || track == nil {
return return
} }
// Track stats // Track stats
@ -459,17 +459,19 @@ func (a *goBlog) renderPostGPX(hb *htmlBuilder, p *post, b *configBlog) {
hb.writeEscaped(track.Hours) hb.writeEscaped(track.Hours)
} }
hb.writeElementClose("p") hb.writeElementClose("p")
// Map // Map (only show if it has features)
hb.writeElementOpen( if track.hasMapFeatures() {
"div", "id", "map", "class", "p", hb.writeElementOpen(
"data-paths", track.PathsJSON, "div", "id", "map", "class", "p",
"data-points", track.PointsJSON, "data-paths", track.PathsJSON,
"data-minzoom", track.MinZoom, "data-maxzoom", track.MaxZoom, "data-points", track.PointsJSON,
"data-attribution", track.MapAttribution, "data-minzoom", track.MinZoom, "data-maxzoom", track.MaxZoom,
) "data-attribution", track.MapAttribution,
hb.writeElementClose("div") )
hb.writeElementOpen("script", "defer", "", "src", a.assetFileName("js/geomap.js")) hb.writeElementClose("div")
hb.writeElementClose("script") hb.writeElementOpen("script", "defer", "", "src", a.assetFileName("js/geomap.js"))
hb.writeElementClose("script")
}
} }
func (a *goBlog) renderPostReactions(hb *htmlBuilder, p *post) { func (a *goBlog) renderPostReactions(hb *htmlBuilder, p *post) {