Clean up + add webserver
This commit is contained in:
parent
2eed16376f
commit
67e2e4d306
7 changed files with 216 additions and 68 deletions
File diff suppressed because one or more lines are too long
21
go.mod
21
go.mod
|
|
@ -3,8 +3,25 @@ module git.readonly.ch/bouzoure/gpx-downloader
|
|||
go 1.25.7
|
||||
|
||||
require (
|
||||
github.com/golang-io/requests v0.0.0-20260112012319-11ff3d588020 // indirect
|
||||
github.com/tkrajina/gpxgo v1.4.0 // indirect
|
||||
github.com/gofiber/fiber/v2 v2.52.11
|
||||
github.com/gofiber/helmet/v2 v2.2.26
|
||||
github.com/golang-io/requests v0.0.0-20260112012319-11ff3d588020
|
||||
github.com/tkrajina/gpxgo v1.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.2.0 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.6.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/klauspost/compress v1.18.4 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.19 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.69.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/net v0.50.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
)
|
||||
|
|
|
|||
29
go.sum
29
go.sum
|
|
@ -1,16 +1,45 @@
|
|||
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
|
||||
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
||||
github.com/clipperhouse/uax29/v2 v2.6.0 h1:z0cDbUV+aPASdFb2/ndFnS9ts/WNXgTNNGFoKXuhpos=
|
||||
github.com/clipperhouse/uax29/v2 v2.6.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gofiber/fiber/v2 v2.52.11 h1:5f4yzKLcBcF8ha1GQTWB+mpblWz3Vz6nSAbTL31HkWs=
|
||||
github.com/gofiber/fiber/v2 v2.52.11/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||
github.com/gofiber/helmet/v2 v2.2.26 h1:KreQVUpCIGppPQ6Yt8qQMaIR4fVXMnvBdsda0dJSsO8=
|
||||
github.com/gofiber/helmet/v2 v2.2.26/go.mod h1:XE0DF4cgf0M5xIt7qyAK5zOi8jJblhxfSDv9DAmEEQo=
|
||||
github.com/golang-io/requests v0.0.0-20260112012319-11ff3d588020 h1:NsY7l0CzD6sL4YDmi2ug1XJ2syK6HYtE4Vu38+S59Kc=
|
||||
github.com/golang-io/requests v0.0.0-20260112012319-11ff3d588020/go.mod h1:axo3gO6bWOpJNUipkqkmAH7WwdeLg5phLVI3N1dFBnM=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
|
||||
github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
|
||||
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tkrajina/gpxgo v1.4.0 h1:cSD5uSwy3VZuNFieTEZLyRnuIwhonQEkGPkPGW4XNag=
|
||||
github.com/tkrajina/gpxgo v1.4.0/go.mod h1:BXSMfUAvKiEhMEXAFM2NvNsbjsSvp394mOvdcNjettg=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.69.0 h1:fNLLESD2SooWeh2cidsuFtOcrEi4uB4m1mPrkJMZyVI=
|
||||
github.com/valyala/fasthttp v1.69.0/go.mod h1:4wA4PfAraPlAsJ5jMSqCE2ug5tqUPwKXxVj8oNECGcw=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
|
|
|
|||
82
main.go
82
main.go
|
|
@ -1,75 +1,29 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"log"
|
||||
|
||||
"github.com/golang-io/requests"
|
||||
"github.com/tkrajina/gpxgo/gpx"
|
||||
"git.readonly.ch/bouzoure/gpx-downloader/routes"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/helmet/v2"
|
||||
)
|
||||
|
||||
type SuisseMobileGeometry struct {
|
||||
Segments [][][]float64 `json:"coordinates"`
|
||||
}
|
||||
|
||||
type SuisseMobileProperties struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type SuisseMobileResponse struct {
|
||||
Properties SuisseMobileProperties `json:"properties"`
|
||||
Geometry SuisseMobileGeometry `json:"geometry"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
sess := requests.New(requests.URL("https://schweizmobil.ch"))
|
||||
resp, _ := sess.DoRequest(context.Background(),
|
||||
requests.Path("/api/6/tracks/1856337628"),
|
||||
)
|
||||
// Create fiber config
|
||||
appConfig := fiber.Config{}
|
||||
|
||||
var response SuisseMobileResponse
|
||||
err := json.Unmarshal(resp.Content.Bytes(), &response)
|
||||
// Init fiber webapp with config
|
||||
app := fiber.New(appConfig)
|
||||
|
||||
// Apply middlewares
|
||||
app.Use(helmet.New())
|
||||
|
||||
// Routes
|
||||
app.Get("/", routes.Index)
|
||||
app.Post("/fetch", routes.Fetch)
|
||||
|
||||
err := app.Listen("127.0.0.1:3000")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var gpxFile gpx.GPX
|
||||
var gpxTrack gpx.GPXTrack
|
||||
|
||||
gpxFile.Name = response.Properties.Name
|
||||
|
||||
for _, segments := range response.Geometry.Segments {
|
||||
var gpxTrackSegment gpx.GPXTrackSegment
|
||||
|
||||
for _, point := range segments {
|
||||
fmt.Println(point)
|
||||
var gpxPoint gpx.GPXPoint
|
||||
|
||||
gpxPoint.Longitude = point[0]
|
||||
gpxPoint.Latitude = point[1]
|
||||
gpxPoint.Elevation = *gpx.NewNullableFloat64(point[2])
|
||||
|
||||
gpxTrackSegment.AppendPoint(&gpxPoint)
|
||||
}
|
||||
|
||||
gpxTrack.AppendSegment(&gpxTrackSegment)
|
||||
}
|
||||
|
||||
gpxFile.AppendTrack(&gpxTrack)
|
||||
xml, err := gpxFile.ToXml(gpx.ToXmlParams{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
file, err := os.Create("1856337628.gpx")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
_, err = file.Write(xml)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
84
providers/suisse_mobile.go
Normal file
84
providers/suisse_mobile.go
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
package providers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/golang-io/requests"
|
||||
"github.com/tkrajina/gpxgo/gpx"
|
||||
)
|
||||
|
||||
func SuisseMobileCheckURL(url string) int {
|
||||
var id int
|
||||
|
||||
re := regexp.MustCompile(`https?://(?:www\.)?schweizmobil\.ch/[^/]+/tour/(\d+)`)
|
||||
matches := re.FindStringSubmatch(url)
|
||||
|
||||
if len(matches) > 1 {
|
||||
id, _ = strconv.Atoi(matches[1])
|
||||
}
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
type SuisseMobileGeometry struct {
|
||||
Segments [][][]float64 `json:"coordinates"`
|
||||
}
|
||||
|
||||
type SuisseMobileProperties struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type SuisseMobileResponse struct {
|
||||
Properties SuisseMobileProperties `json:"properties"`
|
||||
Geometry SuisseMobileGeometry `json:"geometry"`
|
||||
}
|
||||
|
||||
func SuisseMobileFetch(id int) (gpx.GPX, error) {
|
||||
var gpxFile gpx.GPX
|
||||
var gpxTrack gpx.GPXTrack
|
||||
|
||||
sess := requests.New(
|
||||
requests.URL("https://schweizmobil.ch"),
|
||||
)
|
||||
resp, err := sess.DoRequest(
|
||||
context.Background(),
|
||||
requests.Path(fmt.Sprintf(
|
||||
"/api/6/tracks/%d", id,
|
||||
)),
|
||||
)
|
||||
if err != nil {
|
||||
return gpxFile, err
|
||||
}
|
||||
|
||||
var response SuisseMobileResponse
|
||||
err = json.Unmarshal(resp.Content.Bytes(), &response)
|
||||
if err != nil {
|
||||
return gpxFile, err
|
||||
}
|
||||
|
||||
gpxFile.Name = response.Properties.Name
|
||||
|
||||
for _, segments := range response.Geometry.Segments {
|
||||
var gpxTrackSegment gpx.GPXTrackSegment
|
||||
|
||||
for _, point := range segments {
|
||||
var gpxPoint gpx.GPXPoint
|
||||
|
||||
gpxPoint.Longitude = point[0]
|
||||
gpxPoint.Latitude = point[1]
|
||||
gpxPoint.Elevation = *gpx.NewNullableFloat64(point[2])
|
||||
|
||||
gpxTrackSegment.AppendPoint(&gpxPoint)
|
||||
}
|
||||
|
||||
gpxTrack.AppendSegment(&gpxTrackSegment)
|
||||
}
|
||||
|
||||
gpxFile.AppendTrack(&gpxTrack)
|
||||
|
||||
return gpxFile, nil
|
||||
}
|
||||
53
routes/fetch.go
Normal file
53
routes/fetch.go
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
package routes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.readonly.ch/bouzoure/gpx-downloader/providers"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/tkrajina/gpxgo/gpx"
|
||||
)
|
||||
|
||||
func Fetch(c *fiber.Ctx) error {
|
||||
sourceUrl := c.FormValue("url")
|
||||
if len(sourceUrl) <= 0 {
|
||||
c.SendStatus(422)
|
||||
return c.SendString("Error: URL is empty")
|
||||
}
|
||||
|
||||
var gpxFile gpx.GPX
|
||||
var err error
|
||||
var filename string
|
||||
|
||||
// Check if link is Suisse Mobile
|
||||
suisseMobileId := providers.SuisseMobileCheckURL(sourceUrl)
|
||||
if suisseMobileId > 0 {
|
||||
filename = fmt.Sprintf(
|
||||
"suisse_mobile_%d",
|
||||
suisseMobileId,
|
||||
)
|
||||
|
||||
gpxFile, err = providers.SuisseMobileFetch(suisseMobileId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(filename) <= 0 {
|
||||
c.SendStatus(422)
|
||||
return c.SendString("Error: URL is not supported")
|
||||
}
|
||||
|
||||
xml, err := gpxFile.ToXml(gpx.ToXmlParams{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Set("Content-Type", "octet-stream")
|
||||
c.Set("Content-Disposition", fmt.Sprintf(
|
||||
"attechment,filename=%s.gpx",
|
||||
filename,
|
||||
))
|
||||
|
||||
return c.Send(xml)
|
||||
}
|
||||
13
routes/index.go
Normal file
13
routes/index.go
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
package routes
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
|
||||
func Index(c *fiber.Ctx) error {
|
||||
c.Set("Content-Type", "text/html")
|
||||
return c.SendString(`
|
||||
<form method="post" action="/fetch">
|
||||
<input name="url" required />
|
||||
<button type="submit">Fetch</button>
|
||||
</form>
|
||||
`)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue