diff --git a/geoMap.go b/geoMap.go index c415b65..96935ff 100644 --- a/geoMap.go +++ b/geoMap.go @@ -56,10 +56,12 @@ func (a *goBlog) serveGeoMapTracks(w http.ResponseWriter, r *http.Request) { blog, _ := a.getBlog(r) allPostsWithTracks, err := a.getPosts(&postsRequestConfig{ - blog: blog, - status: statusPublished, - parameters: []string{gpxParameter}, - withOnlyParameters: []string{gpxParameter}, + blog: blog, + status: statusPublished, + parameters: []string{gpxParameter}, + withOnlyParameters: []string{gpxParameter}, + excludeParameter: showRouteParam, + excludeParameterValue: "false", // Don't show hidden route tracks }) if err != nil { 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 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{ Paths: t.Paths, Points: t.Points, diff --git a/geoTrack.go b/geoTrack.go index 1f16262..a3ccaab 100644 --- a/geoTrack.go +++ b/geoTrack.go @@ -12,13 +12,20 @@ import ( ) const gpxParameter = "gpx" +const showRouteParam = "showroute" -func (p *post) HasTrack() bool { +func (p *post) hasTrack() bool { return p.firstParameter(gpxParameter) != "" } +func (p *post) showTrackRoute() bool { + if param := p.firstParameter(showRouteParam); param == "false" { + return false + } + return true +} + type trackResult struct { - HasPoints bool Paths [][]*trackPoint PathsJSON string Points []*trackPoint @@ -30,7 +37,11 @@ type trackResult struct { 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) if gpxString == "" { 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) 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{ - HasPoints: len(parseResult.paths) > 0 && len(parseResult.paths[0]) > 0, - Paths: parseResult.paths, - PathsJSON: string(pathsJSON), - Points: parseResult.points, - PointsJSON: string(pointsJSON), - Name: parseResult.gpxData.Name, - MapAttribution: a.getMapAttribution(), - MinZoom: a.getMinZoom(), - MaxZoom: a.getMaxZoom(), + Name: parseResult.gpxData.Name, + } + + if withMapFeatures { + // Add Paths + pathsJSON, err := json.Marshal(parseResult.paths) + if err != nil { + return nil, err + } + 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 { diff --git a/geoTrack_test.go b/geoTrack_test.go index 7b60752..d74dc90 100644 --- a/geoTrack_test.go +++ b/geoTrack_test.go @@ -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) - assert.True(t, resEn.HasPoints) assert.NotEmpty(t, resEn.Paths) assert.Empty(t, resEn.Points) assert.Equal(t, "2.70", resEn.Kilometers) @@ -55,10 +54,9 @@ func Test_geoTrack(t *testing.T) { p.Blog = "de" - resDe, err := app.getTrack(p) + resDe, err := app.getTrack(p, true) require.NoError(t, err) - assert.True(t, resDe.HasPoints) assert.NotEmpty(t, resDe.Paths) assert.Empty(t, resDe.Points) 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) - assert.True(t, resEn.HasPoints) assert.NotEmpty(t, resEn.Paths) assert.NotEmpty(t, resEn.Points) assert.Equal(t, "0.08", resEn.Kilometers) 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) 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) - assert.True(t, resEn.HasPoints) assert.NotEmpty(t, resEn.Paths) assert.Empty(t, resEn.Points) assert.Equal(t, "", resEn.Kilometers) diff --git a/go.mod b/go.mod index c9af13b..a218a27 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/jlelse/feeds v1.2.1-0.20210704161900-189f94254ad4 github.com/justinas/alice v1.2.0 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/lopezator/migrator v0.3.1 github.com/mattn/go-sqlite3 v1.14.14 @@ -49,7 +49,7 @@ require ( github.com/spf13/cast v1.5.0 github.com/spf13/viper v1.12.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 github.com/tkrajina/gpxgo v1.2.2-0.20220217201249-321f19554eec github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 diff --git a/go.sum b/go.sum index ad17816..94cc5ae 100644 --- a/go.sum +++ b/go.sum @@ -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/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.15.7 h1:7cgTQxJCU/vy+oP/E3B9RGbQTgbiVzIJWIKOLoAsPok= -github.com/klauspost/compress v1.15.7/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/compress v1.15.8 h1:JahtItbkWjf2jzm/T+qgMxkP9EMHsqEUA6vCMGmXvhA= +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/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk= 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/tcnksm/go-httpstat v0.2.0 h1:rP7T5e5U2HfmOBmZzGgGZjBQ5/GluWUylujl0tJ04I0= 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.11.12/go.mod h1:8mvf+KglD7XurfvvFZDUYvVURy6bA/r0oTvmakXMnyg= +github.com/tdewolff/minify/v2 v2.12.0 h1:ZyvMKeciyR3vzJrK/oHyBcSmpttQ/V+ah7qOqTZclaU= +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/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho= github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= diff --git a/postsDb.go b/postsDb.go index ef17967..7fb30ea 100644 --- a/postsDb.go +++ b/postsDb.go @@ -344,6 +344,8 @@ type postsRequestConfig struct { parameters []string // Ignores parameterValue parameter string // Ignores parameters 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 publishedBefore time.Time randomOrder bool @@ -415,6 +417,15 @@ func buildPostsQuery(c *postsRequestConfig, selection string) (query string, arg } 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 { 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)) diff --git a/uiComponents.go b/uiComponents.go index 01ddabe..4277eac 100644 --- a/uiComponents.go +++ b/uiComponents.go @@ -67,7 +67,7 @@ func (a *goBlog) renderSummary(hb *htmlBuilder, bc *configBlog, p *post, typ sum // Contains photos prefix.WriteString("🖼️") } - if p.HasTrack() { + if p.hasTrack() { // Has GPX track prefix.WriteString("🗺️") } @@ -432,11 +432,11 @@ func (*goBlog) renderPostTitle(hb *htmlBuilder, p *post) { } func (a *goBlog) renderPostGPX(hb *htmlBuilder, p *post, b *configBlog) { - if p == nil || !p.HasTrack() { + if p == nil || !p.hasTrack() { return } - track, err := a.getTrack(p) - if err != nil || track == nil || !track.HasPoints { + track, err := a.getTrack(p, p.showTrackRoute()) + if err != nil || track == nil { return } // Track stats @@ -459,17 +459,19 @@ func (a *goBlog) renderPostGPX(hb *htmlBuilder, p *post, b *configBlog) { hb.writeEscaped(track.Hours) } hb.writeElementClose("p") - // Map - hb.writeElementOpen( - "div", "id", "map", "class", "p", - "data-paths", track.PathsJSON, - "data-points", track.PointsJSON, - "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("script") + // Map (only show if it has features) + if track.hasMapFeatures() { + hb.writeElementOpen( + "div", "id", "map", "class", "p", + "data-paths", track.PathsJSON, + "data-points", track.PointsJSON, + "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("script") + } } func (a *goBlog) renderPostReactions(hb *htmlBuilder, p *post) {