Templates + build
This commit is contained in:
parent
67e2e4d306
commit
7e821296a6
13 changed files with 202 additions and 15 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
__debug_bin*
|
||||
templates/*_templ.go
|
||||
bin/
|
||||
14
.vscode/launch.json
vendored
Normal file
14
.vscode/launch.json
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"preLaunchTask": "just: prebuild",
|
||||
"name": "Launch Package",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceRoot}",
|
||||
"console": "integratedTerminal",
|
||||
}
|
||||
]
|
||||
}
|
||||
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"editor.tabSize": 2,
|
||||
"editor.detectIndentation": false,
|
||||
"editor.insertSpaces": false,
|
||||
}
|
||||
9
.vscode/tasks.json
vendored
Normal file
9
.vscode/tasks.json
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [{
|
||||
"label": "just: prebuild",
|
||||
"command": "just",
|
||||
"args": ["prebuild"],
|
||||
"type": "shell"
|
||||
}]
|
||||
}
|
||||
12
go.mod
12
go.mod
|
|
@ -10,18 +10,30 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect
|
||||
github.com/a-h/templ v0.3.977 // indirect
|
||||
github.com/andybalholm/brotli v1.2.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cli/browser v1.3.0 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.6.0 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.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/natefinch/atomic v1.0.1 // 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/mod v0.32.0 // indirect
|
||||
golang.org/x/net v0.50.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
golang.org/x/tools v0.41.0 // indirect
|
||||
)
|
||||
|
||||
tool github.com/a-h/templ/cmd/templ
|
||||
|
|
|
|||
20
go.sum
20
go.sum
|
|
@ -1,8 +1,20 @@
|
|||
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ69NYAb5jbGNfHanvm1+iYlo=
|
||||
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ=
|
||||
github.com/a-h/templ v0.3.977 h1:kiKAPXTZE2Iaf8JbtM21r54A8bCNsncrfnokZZSrSDg=
|
||||
github.com/a-h/templ v0.3.977/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo=
|
||||
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
|
||||
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=
|
||||
github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=
|
||||
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/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
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=
|
||||
|
|
@ -19,6 +31,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
|||
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/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=
|
||||
github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=
|
||||
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=
|
||||
|
|
@ -32,9 +46,13 @@ github.com/valyala/fasthttp v1.69.0 h1:fNLLESD2SooWeh2cidsuFtOcrEi4uB4m1mPrkJMZy
|
|||
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/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
|
||||
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
|
||||
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/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
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=
|
||||
|
|
@ -45,5 +63,7 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
|
||||
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
11
helpers/templates.go
Normal file
11
helpers/templates.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package helpers
|
||||
|
||||
import (
|
||||
"github.com/a-h/templ"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func TemplRender(c *fiber.Ctx, component templ.Component) error {
|
||||
c.Set("Content-Type", "text/html")
|
||||
return component.Render(c.UserContext(), c.Response().BodyWriter())
|
||||
}
|
||||
22
justfile
Normal file
22
justfile
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
go := require("go")
|
||||
templ := require("templ")
|
||||
air := require("air")
|
||||
|
||||
templ:
|
||||
templ generate
|
||||
|
||||
prebuild: templ
|
||||
|
||||
run: prebuild
|
||||
go run main.go
|
||||
|
||||
build: prebuild
|
||||
go build -o bin/gpx-downloader main.go
|
||||
|
||||
watch:
|
||||
CI=1 CLICOLOR_FORCE=1 air \
|
||||
--build.cmd "just build" \
|
||||
--build.bin "./bin/gpx-downloader" \
|
||||
-build.include_ext "go,templ" \
|
||||
--build.exclude_dir "data" \
|
||||
--build.exclude_regex "_templ.go"
|
||||
|
|
@ -14,7 +14,7 @@ import (
|
|||
func SuisseMobileCheckURL(url string) int {
|
||||
var id int
|
||||
|
||||
re := regexp.MustCompile(`https?://(?:www\.)?schweizmobil\.ch/[^/]+/tour/(\d+)`)
|
||||
re := regexp.MustCompile(`schweizmobil\.ch/[^/]+/tour/(\d+)`)
|
||||
matches := re.FindStringSubmatch(url)
|
||||
|
||||
if len(matches) > 1 {
|
||||
|
|
|
|||
|
|
@ -3,16 +3,25 @@ package routes
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"git.readonly.ch/bouzoure/gpx-downloader/helpers"
|
||||
"git.readonly.ch/bouzoure/gpx-downloader/providers"
|
||||
"git.readonly.ch/bouzoure/gpx-downloader/templates"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/log"
|
||||
"github.com/tkrajina/gpxgo/gpx"
|
||||
)
|
||||
|
||||
func Fetch(c *fiber.Ctx) error {
|
||||
// In case of error
|
||||
baseParams := templates.BaseTemplateParams{
|
||||
Title: "Error - GPX downloader",
|
||||
}
|
||||
var indexParams templates.IndexParams
|
||||
|
||||
sourceUrl := c.FormValue("url")
|
||||
if len(sourceUrl) <= 0 {
|
||||
c.SendStatus(422)
|
||||
return c.SendString("Error: URL is empty")
|
||||
indexParams.Error = "Error: URL is empty"
|
||||
return helpers.TemplRender(c, templates.Index(baseParams, indexParams))
|
||||
}
|
||||
|
||||
var gpxFile gpx.GPX
|
||||
|
|
@ -29,18 +38,22 @@ func Fetch(c *fiber.Ctx) error {
|
|||
|
||||
gpxFile, err = providers.SuisseMobileFetch(suisseMobileId)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Error(err)
|
||||
indexParams.Error = "An error occured"
|
||||
return helpers.TemplRender(c, templates.Index(baseParams, indexParams))
|
||||
}
|
||||
}
|
||||
|
||||
if len(filename) <= 0 {
|
||||
c.SendStatus(422)
|
||||
return c.SendString("Error: URL is not supported")
|
||||
indexParams.Error = "Error: URL is not supported"
|
||||
return helpers.TemplRender(c, templates.Index(baseParams, indexParams))
|
||||
}
|
||||
|
||||
xml, err := gpxFile.ToXml(gpx.ToXmlParams{})
|
||||
if err != nil {
|
||||
return err
|
||||
log.Error(err)
|
||||
indexParams.Error = "An error occured"
|
||||
return helpers.TemplRender(c, templates.Index(baseParams, indexParams))
|
||||
}
|
||||
|
||||
c.Set("Content-Type", "octet-stream")
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
package routes
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
import (
|
||||
"git.readonly.ch/bouzoure/gpx-downloader/helpers"
|
||||
"git.readonly.ch/bouzoure/gpx-downloader/templates"
|
||||
"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>
|
||||
`)
|
||||
baseParams := templates.BaseTemplateParams{
|
||||
Title: "GPX downloader",
|
||||
}
|
||||
var indexParams templates.IndexParams
|
||||
|
||||
return helpers.TemplRender(c, templates.Index(baseParams, indexParams))
|
||||
}
|
||||
|
|
|
|||
49
templates/base.templ
Normal file
49
templates/base.templ
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
package templates
|
||||
|
||||
type BaseTemplateParams struct {
|
||||
Title string
|
||||
}
|
||||
|
||||
templ BaseTemplate(params BaseTemplateParams) {
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{ params.Title }</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
#main {
|
||||
margin: 30px auto;
|
||||
text-align: center;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
#main h1 {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
input[name="url"] {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
margin: 30px;
|
||||
padding: 10px;
|
||||
background-color: #aa0000;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{ children... }
|
||||
</body>
|
||||
</html>
|
||||
}
|
||||
26
templates/index.templ
Normal file
26
templates/index.templ
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package templates
|
||||
|
||||
type IndexParams struct {
|
||||
Error string
|
||||
}
|
||||
|
||||
templ Index(baseParams BaseTemplateParams, indexParams IndexParams) {
|
||||
@BaseTemplate(baseParams) {
|
||||
<div id="main">
|
||||
<h1>GPX downloader</h1>
|
||||
|
||||
if len(indexParams.Error) <= 0 {
|
||||
<form method="post" action="/fetch">
|
||||
<input name="url" required />
|
||||
<button type="submit">Fetch</button>
|
||||
</form>
|
||||
} else {
|
||||
<div class="error-message">
|
||||
{ indexParams.Error }
|
||||
</div>
|
||||
|
||||
<a href="/">Retour</a>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue