diff options
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | config.example.scfg | 4 | ||||
| -rw-r--r-- | go.mod | 43 | ||||
| -rw-r--r-- | go.sum | 140 | ||||
| -rw-r--r-- | pkg/config/config.go | 38 | ||||
| -rw-r--r-- | pkg/config/config_test.go | 32 | ||||
| -rw-r--r-- | pkg/handler/git/handler.go | 2 | ||||
| -rw-r--r-- | pkg/handler/router.go | 15 | ||||
| -rw-r--r-- | pkg/handler/static/handler.go | 59 | ||||
| -rw-r--r-- | templates/base.qtpl | 22 | ||||
| -rw-r--r-- | templates/base.qtpl.go | 125 |
11 files changed, 308 insertions, 175 deletions
@@ -62,9 +62,6 @@ mail@gabrielgio.me ### TODO - dark theme that does not require js -- dark theme support for systax highlight configuration - - we should be able to generate css from both theme and provide as an - endpoint. ### Ideas diff --git a/config.example.scfg b/config.example.scfg index 5e47548..e726c19 100644 --- a/config.example.scfg +++ b/config.example.scfg @@ -3,9 +3,9 @@ listen-addr unix://var/run/cerrado.sock root-readme /srv/git/README.md -syntax-highlight monokailight +syntax-highlight monokailight monokai -# full hostname address plus protocol. +# full hostname address plus protocol. # This is going to be used to display full link (e.g.: clone link) hostname https://domain.tld @@ -1,39 +1,42 @@ module git.gabrielgio.me/cerrado -go 1.22.2 +go 1.24.0 + +toolchain go1.24.9 require ( git.sr.ht/~emersion/go-scfg v0.0.0-20250102010123-2f3fb2d5d50e - github.com/alecthomas/chroma/v2 v2.15.0 - github.com/andybalholm/brotli v1.1.1 - github.com/go-git/go-git/v5 v5.13.2 - github.com/gomarkdown/markdown v0.0.0-20250207164621-7a1f277a159e - github.com/google/go-cmp v0.6.0 - github.com/klauspost/compress v1.17.11 + github.com/alecthomas/chroma/v2 v2.20.0 + github.com/andybalholm/brotli v1.2.0 + github.com/go-git/go-git/v5 v5.16.3 + github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a + github.com/google/go-cmp v0.7.0 + github.com/klauspost/compress v1.18.1 github.com/valyala/quicktemplate v1.8.0 - golang.org/x/crypto v0.33.0 - golang.org/x/sync v0.11.0 + golang.org/x/crypto v0.43.0 + golang.org/x/sync v0.17.0 ) require ( - dario.cat/mergo v1.0.1 // indirect + dario.cat/mergo v1.0.2 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/ProtonMail/go-crypto v1.1.5 // indirect - github.com/cloudflare/circl v1.6.0 // indirect - github.com/cyphar/filepath-securejoin v0.4.1 // indirect - github.com/dlclark/regexp2 v1.11.4 // indirect + github.com/ProtonMail/go-crypto v1.3.0 // indirect + github.com/cloudflare/circl v1.6.1 // indirect + github.com/cyphar/filepath-securejoin v0.5.0 // indirect + github.com/dlclark/regexp2 v1.11.5 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/pjbgf/sha1cd v0.3.2 // indirect - github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect - github.com/skeema/knownhosts v1.3.1 // indirect + github.com/kevinburke/ssh_config v1.4.0 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/pjbgf/sha1cd v0.5.0 // indirect + github.com/sergi/go-diff v1.4.0 // indirect + github.com/skeema/knownhosts v1.3.2 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sys v0.30.0 // indirect + golang.org/x/net v0.46.0 // indirect + golang.org/x/sys v0.37.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect ) @@ -1,80 +1,63 @@ -dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= -dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -git.sr.ht/~emersion/go-scfg v0.0.0-20240128091534-2ae16e782082 h1:9Udx5fm4vRtmgDIBjy2ef5QioHbzpw5oHabbhpAUyEw= -git.sr.ht/~emersion/go-scfg v0.0.0-20240128091534-2ae16e782082/go.mod h1:ybgvEJTIx5XbaspSviB3KNa6OdPmAZqDoSud7z8fFlw= +dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= +dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= git.sr.ht/~emersion/go-scfg v0.0.0-20250102010123-2f3fb2d5d50e h1:dKdXdn8yhldnz8ynz/HNmLPk40tvTwDBsTdQcHddesg= git.sr.ht/~emersion/go-scfg v0.0.0-20250102010123-2f3fb2d5d50e/go.mod h1:7eWdbNLaP10M+QMSmmHYmYd8q86NHZy12Cq9TiZ9LC8= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= -github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= -github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4= -github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= -github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE= -github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= +github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= -github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E= -github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4EbYP4i6n68SG4I= -github.com/alecthomas/chroma/v2 v2.15.0 h1:LxXTQHFoYrstG2nnV9y2X5O94sOBzf0CIUpSTbpxvMc= -github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio= -github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= -github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= -github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= -github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= +github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= +github.com/alecthomas/chroma/v2 v2.20.0 h1:sfIHpxPyR07/Oylvmcai3X/exDlE8+FA820NTz+9sGw= +github.com/alecthomas/chroma/v2 v2.20.0/go.mod h1:e7tViK0xh/Nf4BYHl00ycY6rV7b8iXBksI9E359yNmA= +github.com/alecthomas/repr v0.5.1 h1:E3G4t2QbHTSNpPKBgMTln5KLkZHLOcU7r37J4pXBuIg= +github.com/alecthomas/repr v0.5.1/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= +github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= -github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= -github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk= -github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= -github.com/cyphar/filepath-securejoin v0.3.5 h1:L81NHjquoQmcPgXcttUS9qTSR/+bXry6pbSINQGpjj4= -github.com/cyphar/filepath-securejoin v0.3.5/go.mod h1:edhVd3c6OXKjUmSrVa/tGJRS9joFTxlslFCAyaxigkE= -github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= -github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= +github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= +github.com/cyphar/filepath-securejoin v0.5.0 h1:hIAhkRBMQ8nIeuVwcAoymp7MY4oherZdAxD+m0u9zaw= +github.com/cyphar/filepath-securejoin v0.5.0/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo= -github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= -github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM= +github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= +github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= +github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= -github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= +github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= -github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= -github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= -github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0= -github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A= +github.com/go-git/go-git/v5 v5.16.3 h1:Z8BtvxZ09bYm/yYNgPKCzgWtaRqDTgIKRgIRHBfU6Z8= +github.com/go-git/go-git/v5 v5.16.3/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= -github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62 h1:pbAFUZisjG4s6sxvRJvf2N7vhpCvx2Oxb3PmS6pDO1g= -github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= -github.com/gomarkdown/markdown v0.0.0-20250207164621-7a1f277a159e h1:ESHlT0RVZphh4JGBz49I5R6nTdC8Qyc08vU25GQHzzQ= -github.com/gomarkdown/markdown v0.0.0-20250207164621-7a1f277a159e/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a h1:l7A0loSszR5zHd/qK53ZIHMO8b3bBSmENnQ6eKnUT0A= +github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/kevinburke/ssh_config v1.4.0 h1:6xxtP5bZ2E4NF5tuQulISpTO2z8XbtH8cg1PWkxoFkQ= +github.com/kevinburke/ssh_config v1.4.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= +github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= +github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -84,29 +67,24 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= -github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= -github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= -github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= -github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= +github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0= +github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= -github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= +github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= -github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= -github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= -github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= +github.com/skeema/knownhosts v1.3.2 h1:EDL9mgf4NzwMXCTfaxSD/o/a5fxDw/xL9nkU28JjdBg= +github.com/skeema/knownhosts v1.3.2/go.mod h1:bEg3iQAuw+jyiw+484wwFJoKSLwcfd7fqRy+N0QTiow= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 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/quicktemplate v1.8.0 h1:zU0tjbIqTRgKQzFY1L42zq0qR3eh4WoQQdIdqCysW5k= @@ -116,39 +94,29 @@ github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= +golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= +golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= +golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/config/config.go b/pkg/config/config.go index c00586b..ff969ec 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -39,6 +39,11 @@ type ( Public bool } + SyntaxHighlight struct { + Dark string + Light string + } + // configuration represents file configuration. // fields needs to be exported to cmp to work configuration struct { @@ -50,7 +55,7 @@ type ( Repositories []*GitRepositoryConfiguration RootReadme string Scans []*scan - SyntaxHighlight string + SyntaxHighlight SyntaxHighlight Hostname string } @@ -75,7 +80,7 @@ type ( removeSuffix bool repositories []*GitRepositoryConfiguration rootReadme string - syntaxHighlight string + syntaxHighlight SyntaxHighlight hostname string } ) @@ -129,7 +134,11 @@ func (c *ConfigurationRepository) GetOrderBy() OrderBy { } func (c *ConfigurationRepository) GetSyntaxHighlight() string { - return c.syntaxHighlight + return c.syntaxHighlight.Light +} + +func (c *ConfigurationRepository) GetSyntaxHighlightDark() string { + return c.syntaxHighlight.Dark } func (c *ConfigurationRepository) GetListenAddr() string { @@ -371,9 +380,26 @@ func setAESKey(block scfg.Block, listenAddr *string) error { return setString(scanDir, listenAddr) } -func setSyntaxHighlight(block scfg.Block, listenAddr *string) error { - scanDir := block.Get("syntax-highlight") - return setString(scanDir, listenAddr) +func setSyntaxHighlight(block scfg.Block, sh *SyntaxHighlight) error { + shDir := block.Get("syntax-highlight") + if shDir == nil { + return nil + } + + themes := shDir.Params + if len(themes) > 2 || len(themes) == 0 { + return errors.New("syntax-highlight must contains at most two params and at least one, light then dark theme name") + } + + sh.Light = themes[0] + if len(themes) > 1 { + sh.Dark = themes[1] + } else { + // if dark is not set use light + sh.Dark = sh.Light + } + + return nil } func setOrderby(block scfg.Block, orderBy *string) error { diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 31cf1c0..50744b5 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -48,6 +48,21 @@ scan "/srv/git" { }, }, { + name: "themes", + config: ` +syntax-highlight light dark`, + expectedConfig: &configuration{ + Scans: defaultScans(), + ListenAddr: defaultAddr(), + Hostname: defaultHostname(), + Repositories: []*GitRepositoryConfiguration{}, + SyntaxHighlight: SyntaxHighlight{ + Light: "light", + Dark: "dark", + }, + }, + }, + { name: "minimal repository", config: `repository /srv/git/cerrado.git`, expectedConfig: &configuration{ @@ -139,13 +154,16 @@ repository /srv/git/cerrado.git { Path: "/srv/git", }, }, - ListenAddr: "unix://var/run/cerrado/cerrado.sock", - Passphrase: "$2a$14$VnB/ZcB1DUDkMnosRA6Y7.dj8h5eroslDxTeXlLwfQX/x86mh6WAq", - AESKey: "8XHptZxSWCGs1m7QzztX5zNQ7D9NiQevVX0DaUTNMbDpRwFzoJiB0U7K6O/kqIt01jJVgzBUfiR8ES46ZLLb4w==", - SyntaxHighlight: "monokailight", - OrderBy: "lastcommit-desc", - RemoveSuffix: true, - Hostname: "https://domain.tld", + ListenAddr: "unix://var/run/cerrado/cerrado.sock", + Passphrase: "$2a$14$VnB/ZcB1DUDkMnosRA6Y7.dj8h5eroslDxTeXlLwfQX/x86mh6WAq", + AESKey: "8XHptZxSWCGs1m7QzztX5zNQ7D9NiQevVX0DaUTNMbDpRwFzoJiB0U7K6O/kqIt01jJVgzBUfiR8ES46ZLLb4w==", + SyntaxHighlight: SyntaxHighlight{ + Light: "monokailight", + Dark: "monokailight", + }, + OrderBy: "lastcommit-desc", + RemoveSuffix: true, + Hostname: "https://domain.tld", Repositories: []*GitRepositoryConfiguration{ { Name: "linux.git", diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go index ffa5dfd..d046d19 100644 --- a/pkg/handler/git/handler.go +++ b/pkg/handler/git/handler.go @@ -349,6 +349,7 @@ func (g *GitHandler) Blob(w http.ResponseWriter, r *ext.Request) error { formatter := html.New( html.WithLineNumbers(true), html.WithLinkableLineNumbers(true, "L"), + html.WithClasses(true), ) iterator, err := lexer.Tokenise(nil, string(file)) @@ -440,6 +441,7 @@ func (g *GitHandler) Commit(w http.ResponseWriter, r *ext.Request) error { formatter := html.New( html.WithLineNumbers(true), html.WithLinkableLineNumbers(true, "L"), + html.WithClasses(true), ) iterator, err := lexer.Tokenise(nil, diff) diff --git a/pkg/handler/router.go b/pkg/handler/router.go index fea8827..1fbc4e3 100644 --- a/pkg/handler/router.go +++ b/pkg/handler/router.go @@ -1,6 +1,7 @@ package handler import ( + "fmt" "net/http" serverconfig "git.gabrielgio.me/cerrado/pkg/config" @@ -10,6 +11,7 @@ import ( "git.gabrielgio.me/cerrado/pkg/handler/git" "git.gabrielgio.me/cerrado/pkg/handler/static" "git.gabrielgio.me/cerrado/pkg/service" + "git.gabrielgio.me/cerrado/templates" ) // Mount handler gets the requires service and repository to build the handlers @@ -31,6 +33,14 @@ func MountHandler( return nil, err } + cssStaticHandler, err := static.ServeStaticCSSHandler( + configRepo.GetSyntaxHighlight(), + configRepo.GetSyntaxHighlightDark(), + ) + if err != nil { + return nil, err + } + mux := ext.NewRouter() mux.AddMiddleware(ext.Compress) mux.AddMiddleware(ext.Log) @@ -45,6 +55,11 @@ func MountHandler( } mux.HandleFunc("/static/{file}", staticHandler) + // add slug and session so css file can be cached forever. + // Slug follow commit id, which is update every new version + // Session is update every time server restarts, this allows the css to be + // cached forever but refresh if the admin updates the server configuration. + mux.HandleFunc(fmt.Sprintf("/static/theme.%s%s.css", templates.Session, templates.Slug), cssStaticHandler) mux.HandleFunc("/{name}/about/{$}", gitHandler.About) mux.HandleFunc("/{name}", gitHandler.Multiplex) mux.HandleFunc("/{name}/{rest...}", gitHandler.Multiplex) diff --git a/pkg/handler/static/handler.go b/pkg/handler/static/handler.go index cdb2ae6..6cc884e 100644 --- a/pkg/handler/static/handler.go +++ b/pkg/handler/static/handler.go @@ -1,6 +1,9 @@ package static import ( + "bytes" + "fmt" + "io" "io/fs" "mime" "net/http" @@ -8,6 +11,9 @@ import ( "git.gabrielgio.me/cerrado/pkg/ext" "git.gabrielgio.me/cerrado/static" + "github.com/alecthomas/chroma/v2" + "github.com/alecthomas/chroma/v2/formatters/html" + "github.com/alecthomas/chroma/v2/styles" ) func ServeStaticHandler() (ext.ErrorRequestHandler, error) { @@ -28,3 +34,56 @@ func ServeStaticHandler() (ext.ErrorRequestHandler, error) { return nil }, nil } + +func ServeStaticCSSHandler(lightTheme, darkTheme string) (ext.ErrorRequestHandler, error) { + var ( + lightStyle = styles.Get(lightTheme) + darkStyle = styles.Get(darkTheme) + formatter = html.New( + html.WithCSSComments(false), + ) + ) + + return func(w http.ResponseWriter, r *ext.Request) error { + ext.SetMIME(w, "text/css") + w.Header().Add("Cache-Control", "max-age=31536000") + + // use buffer so this function can fail before writing to http.ResponseWriter + var buffer bytes.Buffer + + var style *chroma.Style + style = darkStyle + buffer.Write([]byte("[data-bs-theme=\"dark\"] {\n")) + err := formatter.WriteCSS(&ws{&buffer}, style) + if err != nil { + return err + } + buffer.Write([]byte("}\n")) + + style = lightStyle + buffer.Write([]byte("[data-bs-theme=\"light\"] {\n")) + err = formatter.WriteCSS(&ws{&buffer}, style) + if err != nil { + return err + } + buffer.Write([]byte("}")) + + _, err = io.Copy(w, &buffer) + if err != nil { + return err + } + + return nil + }, nil +} + +type ws struct { + inner io.Writer +} + +// This is very cursed, and rely on the fact that it writes every css rule at time. +// it adds & to the begging so it can be nested by the ServeStaticCSSHandler. +// This will allow the follow bootstrap data-bs-theme. +func (w *ws) Write(p []byte) (n int, err error) { + return fmt.Fprintf(w.inner, "& %s", string(p)) +} diff --git a/templates/base.qtpl b/templates/base.qtpl index b3df94a..6ff3d53 100644 --- a/templates/base.qtpl +++ b/templates/base.qtpl @@ -1,11 +1,28 @@ This is a base page template. All the other template pages implement this interface. {% import "context" %} +{% import "crypto/rand" %} +{% import "encoding/hex" %} {% import "strconv" %} {% import "time" %} -{% code +{% code + var Slug = "" + var Session = "" + + func init() { + Session = hex.EncodeToString(generateSmallTimeID()) +} + +func generateSmallTimeID() []byte { + b := make([]byte, 4) + _, err := rand.Read(b) + if err != nil { + panic(err) + } + return b +} %} {% interface @@ -58,8 +75,9 @@ Page prints a page implementing Page interface. <head> <meta charset="utf-8"> <link rel="icon" href="data:,"> - <title>{%= p.Title(ctx) %}</title> + <title>{%= p.Title(ctx) %}</title> <link rel="stylesheet" href="/static/main{%s Slug %}.css"> + <link rel="stylesheet" href="/static/theme.{%s Session %}{%s Slug %}.css"> <html data-bs-theme="dark"> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> <meta name="viewport" content="width=device-width, initial-scale=1" /> diff --git a/templates/base.qtpl.go b/templates/base.qtpl.go index dce4cbc..db8afec 100644 --- a/templates/base.qtpl.go +++ b/templates/base.qtpl.go @@ -11,57 +11,77 @@ package templates import "context" //line templates/base.qtpl:4 -import "strconv" +import "crypto/rand" //line templates/base.qtpl:5 -import "time" +import "encoding/hex" + +//line templates/base.qtpl:6 +import "strconv" //line templates/base.qtpl:7 +import "time" + +//line templates/base.qtpl:9 import ( qtio422016 "io" qt422016 "github.com/valyala/quicktemplate" ) -//line templates/base.qtpl:7 +//line templates/base.qtpl:9 var ( _ = qtio422016.Copy _ = qt422016.AcquireByteBuffer ) -//line templates/base.qtpl:8 +//line templates/base.qtpl:11 var Slug = "" +var Session = "" + +func init() { + Session = hex.EncodeToString(generateSmallTimeID()) +} + +func generateSmallTimeID() []byte { + b := make([]byte, 4) + _, err := rand.Read(b) + if err != nil { + panic(err) + } + return b +} -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 type Page interface { -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 Title(ctx context.Context) string -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 StreamTitle(qw422016 *qt422016.Writer, ctx context.Context) -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 WriteTitle(qq422016 qtio422016.Writer, ctx context.Context) -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 Content(ctx context.Context) string -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 StreamContent(qw422016 *qt422016.Writer, ctx context.Context) -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 WriteContent(qq422016 qtio422016.Writer, ctx context.Context) -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 Script(ctx context.Context) string -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 StreamScript(qw422016 *qt422016.Writer, ctx context.Context) -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 WriteScript(qq422016 qtio422016.Writer, ctx context.Context) -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 Navbar(ctx context.Context) string -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 StreamNavbar(qw422016 *qt422016.Writer, ctx context.Context) -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 WriteNavbar(qq422016 qtio422016.Writer, ctx context.Context) -//line templates/base.qtpl:12 +//line templates/base.qtpl:29 } -//line templates/base.qtpl:21 +//line templates/base.qtpl:38 func FromUInttoString(u *uint) string { if u != nil { return strconv.FormatUint(uint64(*u), 10) @@ -69,23 +89,23 @@ func FromUInttoString(u *uint) string { return "" } -//line templates/base.qtpl:31 +//line templates/base.qtpl:48 func TimeFormat(t time.Time) string { return t.Format("02.01.2006") } -//line templates/base.qtpl:36 +//line templates/base.qtpl:53 func Ignore[T any](v T, _ error) T { return v } -//line templates/base.qtpl:42 +//line templates/base.qtpl:59 func IsAuthenticationDisabled(ctx context.Context) bool { t, ok := ctx.Value("disableAuthentication").(bool) return ok && t } -//line templates/base.qtpl:48 +//line templates/base.qtpl:65 func IsLoggedIn(ctx context.Context) bool { t, ok := ctx.Value("logged").(bool) return ok && t @@ -93,9 +113,9 @@ func IsLoggedIn(ctx context.Context) bool { // Page prints a page implementing Page interface. -//line templates/base.qtpl:55 +//line templates/base.qtpl:72 func StreamPageTemplate(qw422016 *qt422016.Writer, p Page, ctx context.Context) { -//line templates/base.qtpl:55 +//line templates/base.qtpl:72 qw422016.N().S(` <!DOCTYPE html> <html lang="en" data-bs-theme="light"> @@ -103,14 +123,21 @@ func StreamPageTemplate(qw422016 *qt422016.Writer, p Page, ctx context.Context) <meta charset="utf-8"> <link rel="icon" href="data:,"> <title>`) -//line templates/base.qtpl:61 +//line templates/base.qtpl:78 p.StreamTitle(qw422016, ctx) -//line templates/base.qtpl:61 - qw422016.N().S(`</title> +//line templates/base.qtpl:78 + qw422016.N().S(`</title> <link rel="stylesheet" href="/static/main`) -//line templates/base.qtpl:62 +//line templates/base.qtpl:79 qw422016.E().S(Slug) -//line templates/base.qtpl:62 +//line templates/base.qtpl:79 + qw422016.N().S(`.css"> + <link rel="stylesheet" href="/static/theme.`) +//line templates/base.qtpl:80 + qw422016.E().S(Session) +//line templates/base.qtpl:80 + qw422016.E().S(Slug) +//line templates/base.qtpl:80 qw422016.N().S(`.css"> <html data-bs-theme="dark"> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> @@ -118,53 +145,53 @@ func StreamPageTemplate(qw422016 *qt422016.Writer, p Page, ctx context.Context) </head> <body> `) -//line templates/base.qtpl:68 +//line templates/base.qtpl:86 p.StreamNavbar(qw422016, ctx) -//line templates/base.qtpl:68 +//line templates/base.qtpl:86 qw422016.N().S(` <div class="container"> `) -//line templates/base.qtpl:70 +//line templates/base.qtpl:88 p.StreamContent(qw422016, ctx) -//line templates/base.qtpl:70 +//line templates/base.qtpl:88 qw422016.N().S(` </div> </body> `) -//line templates/base.qtpl:73 +//line templates/base.qtpl:91 p.StreamScript(qw422016, ctx) -//line templates/base.qtpl:73 +//line templates/base.qtpl:91 qw422016.N().S(` <script> function a(){const e=window.matchMedia("(prefers-color-scheme: dark)").matches;document.documentElement.setAttribute("data-bs-theme",e?"dark":"light")}a(),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",a); </script> </html> `) -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 } -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 func WritePageTemplate(qq422016 qtio422016.Writer, p Page, ctx context.Context) { -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 qw422016 := qt422016.AcquireWriter(qq422016) -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 StreamPageTemplate(qw422016, p, ctx) -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 qt422016.ReleaseWriter(qw422016) -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 } -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 func PageTemplate(p Page, ctx context.Context) string { -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 qb422016 := qt422016.AcquireByteBuffer() -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 WritePageTemplate(qb422016, p, ctx) -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 qs422016 := string(qb422016.B) -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 qt422016.ReleaseByteBuffer(qb422016) -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 return qs422016 -//line templates/base.qtpl:78 +//line templates/base.qtpl:96 } |
