15 Commits

Author SHA1 Message Date
video-prize-ranch
0f1fbc2401 Update air git repo (#186)
Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/186
Co-authored-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
Co-committed-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
2024-07-03 13:02:39 +00:00
video-prize-ranch
4afb7cefe7 Add support for new gallery link format (#185)
Fixes #183

Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/185
Co-authored-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
Co-committed-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
2024-07-03 12:56:13 +00:00
video-prize-ranch
20715f53af Fix "Internal Server Error" (#182)
Fixes #181

Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/182
Co-authored-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
Co-committed-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
2024-06-21 02:14:31 +00:00
video-prize-ranch
ac9582df0a Update dependencies (#180)
Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/180
Co-authored-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
Co-committed-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
2024-06-21 00:16:32 +00:00
video-prize-ranch
0ce85ed2bd Update go modules (#174)
Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/174
Co-authored-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
Co-committed-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
2024-02-07 01:16:59 +00:00
orangix
09a76779c9 check page length before return in nextInTag (#173)
fixes #172

Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/173
Co-authored-by: orangix <uleo8b8g@anonaddy.me>
Co-committed-by: orangix <uleo8b8g@anonaddy.me>
2024-02-07 01:13:29 +00:00
video-prize-ranch
337796b9be Update Justfile (#170)
Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/170
Co-authored-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
Co-committed-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
2024-02-05 22:57:33 +00:00
orangix
927ea20fad next button for tagged posts (#169)
No previous button because that would be annoying to implement serverside with pagination etc.

Closes #115

Fixed conflict with #154, #155, #156

Co-authored-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/169
Reviewed-by: video-prize-ranch <video-prize-ranch@noreply.codeberg.org>
Co-authored-by: orangix <orangix@noreply.codeberg.org>
Co-committed-by: orangix <orangix@noreply.codeberg.org>
2024-02-05 22:47:04 +00:00
orangix
7433265991 Merge pull request 'Errors in image format' (#168) from feature/image-errors into main
Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/168
Reviewed-by: orangix <orangix@noreply.codeberg.org>
2024-02-05 21:28:29 +00:00
video-prize-ranch
fb82afc7dd Only show image errors on image direct links 2024-02-05 16:26:54 -05:00
video-prize-ranch
1579e59dca Errors in image format (closes #165) 2024-02-04 21:24:55 -05:00
video-prize-ranch
6d528c7d0a Add start_url to manifest (#161)
Fixes #160

Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/161
Reviewed-by: orangix <orangix@noreply.codeberg.org>
Co-authored-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
Co-committed-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
2024-01-17 22:11:22 +00:00
video-prize-ranch
9a6173a662 Update dependencies (#162)
Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/162
Reviewed-by: orangix <orangix@noreply.codeberg.org>
Co-authored-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
Co-committed-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
2024-01-17 22:11:01 +00:00
video-prize-ranch
c366f95f6b Replace io/ioutil with io (#159)
io/ioutil is deprecated

Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/159
2023-12-11 03:50:36 +00:00
video-prize-ranch
f5e1669a61 Handle error on app.Listen (closes #157) (#158)
Reviewed-on: https://codeberg.org/rimgo/rimgo/pulls/158
Reviewed-by: orangix <orangix@noreply.codeberg.org>
Co-authored-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
Co-committed-by: video-prize-ranch <cb.8a3w5@simplelogin.co>
2023-12-11 03:49:58 +00:00
17 changed files with 258 additions and 181 deletions

View File

@@ -4,4 +4,9 @@ build:
dev: dev:
tailwindcss -i static/tailwind.css -o static/app.css -m -w & tailwindcss -i static/tailwind.css -o static/app.css -m -w &
go run github.com/cosmtrek/air@latest -c .air.toml go run github.com/air-verse/air@latest -c .air.toml
tag-vpr:
podman pull codeberg.org/rimgo/rimgo:latest
podman image tag codeberg.org/rimgo/rimgo:latest codeberg.org/video-prize-ranch/rimgo:latest
podman push codeberg.org/video-prize-ranch/rimgo:latest

View File

@@ -1,10 +1,10 @@
package api package api
import ( import (
"io/ioutil" "io"
"net/http" "net/http"
"net/url"
"strings" "strings"
"sync"
"github.com/patrickmn/go-cache" "github.com/patrickmn/go-cache"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
@@ -21,6 +21,9 @@ type Tag struct {
} }
func (client *Client) FetchTag(tag string, sort string, page string) (Tag, error) { func (client *Client) FetchTag(tag string, sort string, page string) (Tag, error) {
// Dots are automatically removed on Imgur, so more cache hits
tag = strings.ReplaceAll(tag, ".", "")
cacheData, found := client.Cache.Get(tag + sort + page + "-tag") cacheData, found := client.Cache.Get(tag + sort + page + "-tag")
if found { if found {
return cacheData.(Tag), nil return cacheData.(Tag), nil
@@ -57,25 +60,25 @@ func (client *Client) FetchTag(tag string, sort string, page string) (Tag, error
return Tag{}, err return Tag{}, err
} }
body, err := ioutil.ReadAll(res.Body) body, err := io.ReadAll(res.Body)
if err != nil { if err != nil {
return Tag{}, err return Tag{}, err
} }
data := gjson.Parse(string(body)) data := gjson.Parse(string(body))
wg := sync.WaitGroup{}
posts := make([]Submission, 0) posts := make([]Submission, 0)
data.Get("posts").ForEach( data.Get("posts").ForEach(
func(key, value gjson.Result) bool { func(key, value gjson.Result) bool {
wg.Add(1) url, _ := url.Parse(strings.ReplaceAll(value.Get("url").String(), "https://imgur.com", ""))
q := url.Query()
q.Add("tag", tag+"."+sort+"."+page+"."+key.String())
url.RawQuery = q.Encode()
go func() {
defer wg.Done()
posts = append(posts, Submission{ posts = append(posts, Submission{
Id: value.Get("id").String(), Id: value.Get("id").String(),
Title: value.Get("title").String(), Title: value.Get("title").String(),
Link: strings.ReplaceAll(value.Get("url").String(), "https://imgur.com", ""), Link: url.String(),
Cover: Media{ Cover: Media{
Id: value.Get("cover_id").String(), Id: value.Get("cover_id").String(),
Type: value.Get("cover.type").String(), Type: value.Get("cover.type").String(),
@@ -88,14 +91,11 @@ func (client *Client) FetchTag(tag string, sort string, page string) (Tag, error
Views: value.Get("view_count").Int(), Views: value.Get("view_count").Int(),
IsAlbum: value.Get("is_album").Bool(), IsAlbum: value.Get("is_album").Bool(),
}) })
}()
return true return true
}, },
) )
wg.Wait()
tagData := Tag{ tagData := Tag{
Tag: tag, Tag: tag,
Display: data.Get("display").String(), Display: data.Get("display").String(),
@@ -105,6 +105,6 @@ func (client *Client) FetchTag(tag string, sort string, page string) (Tag, error
Background: "/" + data.Get("background_id").String() + ".webp", Background: "/" + data.Get("background_id").String() + ".webp",
} }
client.Cache.Set(tag + sort + page + "-tag", tagData, cache.DefaultExpiration) client.Cache.Set(tag+sort+page+"-tag", tagData, 4*cache.DefaultExpiration)
return tagData, nil return tagData, nil
} }

29
go.mod
View File

@@ -5,39 +5,40 @@ go 1.21
toolchain go1.21.4 toolchain go1.21.4
require ( require (
github.com/PuerkitoBio/goquery v1.8.1 github.com/PuerkitoBio/goquery v1.9.2
github.com/aymerick/raymond v2.0.2+incompatible
github.com/dustin/go-humanize v1.0.1 github.com/dustin/go-humanize v1.0.1
github.com/gofiber/fiber/v2 v2.51.0 github.com/gofiber/fiber/v2 v2.52.4
github.com/gofiber/template/handlebars/v2 v2.1.6 github.com/gofiber/template/handlebars/v2 v2.1.9
github.com/joho/godotenv v1.5.1 github.com/joho/godotenv v1.5.1
github.com/mailgun/raymond/v2 v2.0.48
github.com/microcosm-cc/bluemonday v1.0.26 github.com/microcosm-cc/bluemonday v1.0.26
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/tidwall/gjson v1.17.0 github.com/tidwall/gjson v1.17.1
gitlab.com/golang-commonmark/linkify v0.0.0-20200225224916-64bca66f6ad3 gitlab.com/golang-commonmark/linkify v0.0.0-20200225224916-64bca66f6ad3
) )
require ( require (
github.com/andybalholm/brotli v1.0.6 // indirect github.com/andybalholm/brotli v1.1.0 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/aymerick/douceur v0.2.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect
github.com/gofiber/template v1.8.2 // indirect github.com/gofiber/template v1.8.3 // indirect
github.com/gofiber/utils v1.1.0 // indirect github.com/gofiber/utils v1.1.0 // indirect
github.com/google/uuid v1.4.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/css v1.0.1 // indirect github.com/gorilla/css v1.0.1 // indirect
github.com/klauspost/compress v1.17.3 // indirect github.com/klauspost/compress v1.17.9 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/philhofer/fwd v1.1.2 // indirect github.com/philhofer/fwd v1.1.2 // indirect
github.com/rivo/uniseg v0.4.4 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect
github.com/tinylib/msgp v1.1.9 // indirect github.com/tinylib/msgp v1.1.9 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.51.0 // indirect github.com/valyala/fasthttp v1.55.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect
golang.org/x/net v0.18.0 // indirect golang.org/x/net v0.26.0 // indirect
golang.org/x/sys v0.14.0 // indirect golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.14.0 // indirect golang.org/x/text v0.16.0 // indirect
) )

80
go.sum
View File

@@ -1,32 +1,34 @@
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE=
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk=
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss= github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= 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/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/gofiber/fiber/v2 v2.51.0 h1:JNACcZy5e2tGApWB2QrRpenTWn0fq0hkFm6k0C86gKQ= github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM=
github.com/gofiber/fiber/v2 v2.51.0/go.mod h1:xaQRZQJGqnKOQnbQw+ltvku3/h8QxvNi8o6JiJ7Ll0U= github.com/gofiber/fiber/v2 v2.52.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
github.com/gofiber/template v1.8.2 h1:PIv9s/7Uq6m+Fm2MDNd20pAFFKt5wWs7ZBd8iV9pWwk= github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
github.com/gofiber/template v1.8.2/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8= github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
github.com/gofiber/template/handlebars/v2 v2.1.6 h1:+z9S2/L3RZueHpRtjxyMGpNHKIMUYkvyVEGHQrau+Po= github.com/gofiber/template/handlebars/v2 v2.1.9 h1:NXzwrqBtXyy1JlgwIPAU5KoyorEZ1PLnTyS51W2nPwM=
github.com/gofiber/template/handlebars/v2 v2.1.6/go.mod h1:Kes9qTj4iD73xj1bq94HjJHNqhUhuyWpLvs9fyH5aMs= github.com/gofiber/template/handlebars/v2 v2.1.9/go.mod h1:yi2z68McoNaCB5G7NCP5duB8py0zfpiJPqcl6mfWYrE=
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM= github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0= github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw=
github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@@ -40,11 +42,21 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw= github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0= github.com/philhofer/fwd v1.1.2/go.mod h1:qkPdfjR2SIEbspLqpe1tO4n5yICnr2DY7mqEx2tUTP0=
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/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
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/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
@@ -54,8 +66,8 @@ github.com/tinylib/msgp v1.1.9 h1:SHf3yoO2sGA0veCJeCBYLHuttAVFHGm2RHgNodW7wQU=
github.com/tinylib/msgp v1.1.9/go.mod h1:BCXGB54lDD8qUEPmiG0cQQUANC4IUQyB2ItS2UDlO/k= github.com/tinylib/msgp v1.1.9/go.mod h1:BCXGB54lDD8qUEPmiG0cQQUANC4IUQyB2ItS2UDlO/k=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 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/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8=
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
@@ -67,44 +79,46 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
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-20201119102817-f84b799fce68/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

25
main.go
View File

@@ -11,7 +11,7 @@ import (
"codeberg.org/rimgo/rimgo/static" "codeberg.org/rimgo/rimgo/static"
"codeberg.org/rimgo/rimgo/utils" "codeberg.org/rimgo/rimgo/utils"
"codeberg.org/rimgo/rimgo/views" "codeberg.org/rimgo/rimgo/views"
"github.com/aymerick/raymond" "github.com/mailgun/raymond/v2"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cache" "github.com/gofiber/fiber/v2/middleware/cache"
"github.com/gofiber/fiber/v2/middleware/filesystem" "github.com/gofiber/fiber/v2/middleware/filesystem"
@@ -52,14 +52,7 @@ func main() {
code = e.Code code = e.Code
} }
err = ctx.Status(code).Render("errors/error", fiber.Map{ return utils.RenderError(ctx, code)
"err": err,
})
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
}
return nil
}, },
}) })
@@ -77,14 +70,23 @@ func main() {
app.Get("/errors/429", func(c *fiber.Ctx) error { app.Get("/errors/429", func(c *fiber.Ctx) error {
return c.Render("errors/429", nil) return c.Render("errors/429", nil)
}) })
app.Get("/errors/429/img", func(c *fiber.Ctx) error {
return c.Redirect("/static/img/error-429.png")
})
app.Get("/errors/404", func(c *fiber.Ctx) error { app.Get("/errors/404", func(c *fiber.Ctx) error {
return c.Render("errors/404", nil) return c.Render("errors/404", nil)
}) })
app.Get("/errors/404/img", func(c *fiber.Ctx) error {
return c.Redirect("/static/img/error-404.png")
})
app.Get("/errors/error", func(c *fiber.Ctx) error { app.Get("/errors/error", func(c *fiber.Ctx) error {
return c.Render("errors/error", fiber.Map{ return c.Render("errors/error", fiber.Map{
"err": "Test error", "err": "Test error",
}) })
}) })
app.Get("/errors/error/img", func(c *fiber.Ctx) error {
return c.Redirect("/static/img/error-generic.png")
})
} else { } else {
app.Use("/static", filesystem.New(filesystem.Config{ app.Use("/static", filesystem.New(filesystem.Config{
MaxAge: 2592000, MaxAge: 2592000,
@@ -135,5 +137,8 @@ func main() {
app.Get("/:postID", pages.HandlePost) app.Get("/:postID", pages.HandlePost)
app.Get("/:postID/embed", pages.HandleEmbed) app.Get("/:postID/embed", pages.HandleEmbed)
app.Listen(utils.Config.Addr + ":" + utils.Config.Port) err := app.Listen(utils.Config.Addr + ":" + utils.Config.Port)
if err != nil {
fmt.Println(err)
}
} }

View File

@@ -23,10 +23,10 @@ func HandleEmbed(c *fiber.Ctx) error {
post, err = ApiClient.FetchMedia(c.Params("postID")) post, err = ApiClient.FetchMedia(c.Params("postID"))
} }
if err != nil && err.Error() == "ratelimited by imgur" { if err != nil && err.Error() == "ratelimited by imgur" {
return c.Status(429).Render("errors/429", nil) return utils.RenderError(c, 429)
} }
if err != nil && post.Id == "" && strings.Contains(err.Error(), "404") { if err != nil && post.Id == "" && strings.Contains(err.Error(), "404") {
return c.Status(404).Render("errors/404", nil) return utils.RenderError(c, 404)
} }
if err != nil { if err != nil {
return err return err

View File

@@ -11,6 +11,7 @@ import (
func HandleMedia(c *fiber.Ctx) error { func HandleMedia(c *fiber.Ctx) error {
c.Set("Cache-Control", "public,max-age=31557600") c.Set("Cache-Control", "public,max-age=31557600")
c.Set("Content-Security-Policy", "default-src 'none'; style-src 'self'; img-src 'self'")
if strings.HasPrefix(c.Path(), "/stack") { if strings.HasPrefix(c.Path(), "/stack") {
return handleMedia(c, "https://i.stack.imgur.com/"+strings.ReplaceAll(c.Params("baseName"), "stack/", "")+"."+c.Params("extension")) return handleMedia(c, "https://i.stack.imgur.com/"+strings.ReplaceAll(c.Params("baseName"), "stack/", "")+"."+c.Params("extension"))
} else { } else {
@@ -20,13 +21,15 @@ func HandleMedia(c *fiber.Ctx) error {
func HandleUserCover(c *fiber.Ctx) error { func HandleUserCover(c *fiber.Ctx) error {
c.Set("Cache-Control", "public,max-age=604800") c.Set("Cache-Control", "public,max-age=604800")
c.Set("Content-Security-Policy", "default-src 'none'")
return handleMedia(c, "https://imgur.com/user/"+c.Params("userID")+"/cover?maxwidth=2560") return handleMedia(c, "https://imgur.com/user/"+c.Params("userID")+"/cover?maxwidth=2560")
}; }
func HandleUserAvatar(c *fiber.Ctx) error { func HandleUserAvatar(c *fiber.Ctx) error {
c.Set("Cache-Control", "public,max-age=604800") c.Set("Cache-Control", "public,max-age=604800")
c.Set("Content-Security-Policy", "default-src 'none'")
return handleMedia(c, "https://imgur.com/user/"+c.Params("userID")+"/avatar") return handleMedia(c, "https://imgur.com/user/"+c.Params("userID")+"/avatar")
}; }
func handleMedia(c *fiber.Ctx, url string) error { func handleMedia(c *fiber.Ctx, url string) error {
utils.SetHeaders(c) utils.SetHeaders(c)
@@ -57,19 +60,14 @@ func handleMedia(c *fiber.Ctx, url string) error {
return err return err
} }
c.Status(res.StatusCode) if res.StatusCode == 404 || strings.Contains(res.Request.URL.String(), "error/404") {
if res.StatusCode == 404 { return utils.RenderError(c, 404)
return c.Render("errors/404", fiber.Map{
"path": c.Path(),
})
} else if res.StatusCode == 429 { } else if res.StatusCode == 429 {
return c.Render("errors/429", fiber.Map{ return utils.RenderError(c, 429)
"path": c.Path(),
})
} }
c.Set("Accept-Ranges", "bytes") c.Set("Accept-Ranges", "bytes")
c.Set("Content-Type", res.Header.Get("Content-Type")); c.Set("Content-Type", res.Header.Get("Content-Type"))
c.Set("Content-Length", res.Header.Get("Content-Length")) c.Set("Content-Length", res.Header.Get("Content-Length"))
if res.Header.Get("Content-Range") != "" { if res.Header.Get("Content-Range") != "" {
c.Set("Content-Range", res.Header.Get("Content-Range")) c.Set("Content-Range", res.Header.Get("Content-Range"))

View File

@@ -3,6 +3,7 @@ package pages
import ( import (
"crypto/rand" "crypto/rand"
"fmt" "fmt"
"strconv"
"strings" "strings"
"codeberg.org/rimgo/rimgo/api" "codeberg.org/rimgo/rimgo/api"
@@ -10,28 +11,53 @@ import (
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
// Cursed function
func nextInTag(client *api.Client, tagname, sort, page, I string) string {
i, err := strconv.Atoi(I)
if err != nil || i < 0 {
return ""
}
tag, err := client.FetchTag(tagname, sort, page)
if err != nil {
return ""
}
if i >= len(tag.Posts)-1 {
pageNumber, _ := strconv.Atoi(page)
tagn, err := client.FetchTag(tagname, sort, strconv.Itoa(pageNumber+1))
// Check length - Imgur will not return an error if there are no more posts and you request the next page
if err != nil || len(tagn.Posts) < 1 {
return ""
}
return tagn.Posts[0].Link
}
return tag.Posts[i+1].Link
}
func HandlePost(c *fiber.Ctx) error { func HandlePost(c *fiber.Ctx) error {
utils.SetHeaders(c) utils.SetHeaders(c)
c.Set("X-Frame-Options", "DENY") c.Set("X-Frame-Options", "DENY")
postId := c.Params("postID")
if strings.Contains(postId, "-") {
postId = postId[len(postId)-7:]
}
post, err := api.Album{}, error(nil) post, err := api.Album{}, error(nil)
switch { switch {
case strings.HasPrefix(c.Path(), "/a"): case strings.HasPrefix(c.Path(), "/a"):
post, err = ApiClient.FetchAlbum(c.Params("postID")) post, err = ApiClient.FetchAlbum(postId)
case strings.HasPrefix(c.Path(), "/gallery"): case strings.HasPrefix(c.Path(), "/gallery"):
post, err = ApiClient.FetchPosts(c.Params("postID")) post, err = ApiClient.FetchPosts(postId)
case strings.HasPrefix(c.Path(), "/t"): case strings.HasPrefix(c.Path(), "/t"):
post, err = ApiClient.FetchPosts(c.Params("postID")) post, err = ApiClient.FetchPosts(postId)
default: default:
post, err = ApiClient.FetchMedia(c.Params("postID")) post, err = ApiClient.FetchMedia(postId)
} }
if err != nil && err.Error() == "ratelimited by imgur" { if err != nil && err.Error() == "ratelimited by imgur" {
return c.Status(429).Render("errors/429", fiber.Map{ return utils.RenderError(c, 429)
"path": c.Path(),
})
} }
if err != nil && post.Id == "" && strings.Contains(err.Error(), "404") { if err != nil && post.Id == "" && strings.Contains(err.Error(), "404") {
return c.Status(404).Render("errors/404", nil) return utils.RenderError(c, 404)
} }
if err != nil { if err != nil {
return err return err
@@ -40,7 +66,7 @@ func HandlePost(c *fiber.Ctx) error {
comments := []api.Comment{} comments := []api.Comment{}
if post.SharedWithCommunity { if post.SharedWithCommunity {
c.Set("Cache-Control", "public,max-age=604800") c.Set("Cache-Control", "public,max-age=604800")
comments, err = ApiClient.FetchComments(c.Params("postID")) comments, err = ApiClient.FetchComments(postId)
if err != nil { if err != nil {
return err return err
} }
@@ -58,8 +84,16 @@ func HandlePost(c *fiber.Ctx) error {
} }
c.Set("Content-Security-Policy", csp) c.Set("Content-Security-Policy", csp)
var next string
tagParam := strings.Split(c.Query("tag"), ".")
if len(tagParam) == 4 {
tag, sort, page, index := tagParam[0], tagParam[1], tagParam[2], tagParam[3]
next = nextInTag(ApiClient, tag, sort, page, index)
}
return c.Render("post", fiber.Map{ return c.Render("post", fiber.Map{
"post": post, "post": post,
"next": next,
"comments": comments, "comments": comments,
"nonce": nonce, "nonce": nonce,
}) })

View File

@@ -9,6 +9,7 @@ import (
func HandlePrivacy(c *fiber.Ctx) error { func HandlePrivacy(c *fiber.Ctx) error {
utils.SetHeaders(c) utils.SetHeaders(c)
c.Set("X-Frame-Options", "DENY") c.Set("X-Frame-Options", "DENY")
c.Set("Content-Security-Policy", "default-src 'none'; form-action 'self'; style-src 'self'; img-src 'self'; manifest-src 'self'; block-all-mixed-content")
return c.Render("privacy", fiber.Map{ return c.Render("privacy", fiber.Map{
"config": utils.Config, "config": utils.Config,

View File

@@ -25,15 +25,13 @@ func HandleTag(c *fiber.Ctx) error {
tag, err := ApiClient.FetchTag(c.Params("tag"), c.Query("sort"), page) tag, err := ApiClient.FetchTag(c.Params("tag"), c.Query("sort"), page)
if err != nil && err.Error() == "ratelimited by imgur" { if err != nil && err.Error() == "ratelimited by imgur" {
return c.Status(429).Render("errors/429", fiber.Map{ return utils.RenderError(c, 429)
"path": c.Path(),
})
} }
if err != nil { if err != nil {
return err return err
} }
if tag.Display == "" { if tag.Display == "" {
return c.Status(404).Render("errors/404", nil) return utils.RenderError(c, 404)
} }
return c.Render("tag", fiber.Map{ return c.Render("tag", fiber.Map{

View File

@@ -25,23 +25,19 @@ func HandleUser(c *fiber.Ctx) error {
user, err := ApiClient.FetchUser(c.Params("userID")) user, err := ApiClient.FetchUser(c.Params("userID"))
if err != nil && err.Error() == "ratelimited by imgur" { if err != nil && err.Error() == "ratelimited by imgur" {
return c.Status(429).Render("errors/429", fiber.Map{ return utils.RenderError(c, 429)
"path": c.Path(),
})
} }
if err != nil { if err != nil {
return err return err
} }
if user.Username == "" { if user.Username == "" {
return c.Status(404).Render("errors/404", nil) return utils.RenderError(c, 404)
} }
submissions, err := ApiClient.FetchSubmissions(c.Params("userID"), "newest", page) submissions, err := ApiClient.FetchSubmissions(c.Params("userID"), "newest", page)
if err != nil && err.Error() == "ratelimited by imgur" { if err != nil && err.Error() == "ratelimited by imgur" {
c.Status(429) c.Status(429)
return c.Render("errors/429", fiber.Map{ return utils.RenderError(c, 429)
"path": c.Path(),
})
} }
if err != nil { if err != nil {
return err return err
@@ -64,23 +60,19 @@ func HandleUserComments(c *fiber.Ctx) error {
user, err := ApiClient.FetchUser(c.Params("userID")) user, err := ApiClient.FetchUser(c.Params("userID"))
if err != nil && err.Error() == "ratelimited by imgur" { if err != nil && err.Error() == "ratelimited by imgur" {
return c.Status(429).Render("errors/429", fiber.Map{ return utils.RenderError(c, 429)
"path": c.Path(),
})
} }
if err != nil { if err != nil {
return err return err
} }
if user.Username == "" { if user.Username == "" {
return c.Status(404).Render("errors/404", nil) return utils.RenderError(c, 404)
} }
comments, err := ApiClient.FetchUserComments(c.Params("userID")) comments, err := ApiClient.FetchUserComments(c.Params("userID"))
if err != nil && err.Error() == "ratelimited by imgur" { if err != nil && err.Error() == "ratelimited by imgur" {
c.Status(429) c.Status(429)
return c.Render("errors/429", fiber.Map{ return utils.RenderError(c, 429)
"path": c.Path(),
})
} }
if err != nil { if err != nil {
return err return err
@@ -110,23 +102,18 @@ func HandleUserFavorites(c *fiber.Ctx) error {
user, err := ApiClient.FetchUser(c.Params("userID")) user, err := ApiClient.FetchUser(c.Params("userID"))
if err != nil && err.Error() == "ratelimited by imgur" { if err != nil && err.Error() == "ratelimited by imgur" {
return c.Status(429).Render("errors/429", fiber.Map{ return utils.RenderError(c, 429)
"path": c.Path(),
})
} }
if err != nil { if err != nil {
return err return err
} }
if user.Username == "" { if user.Username == "" {
return c.Status(404).Render("errors/404", nil) return utils.RenderError(c, 404)
} }
favorites, err := ApiClient.FetchUserFavorites(c.Params("userID"), "newest", page) favorites, err := ApiClient.FetchUserFavorites(c.Params("userID"), "newest", page)
if err != nil && err.Error() == "ratelimited by imgur" { if err != nil && err.Error() == "ratelimited by imgur" {
c.Status(429) return utils.RenderError(c, 429)
return c.Render("errors/429", fiber.Map{
"path": c.Path(),
})
} }
if err != nil { if err != nil {
return err return err

View File

@@ -1,6 +1,7 @@
{ {
"name": "rimgo", "name": "rimgo",
"short_name": "rimgo", "short_name": "rimgo",
"start_url": "/",
"icons": [ "icons": [
{ {
"src": "/static/favicon/android-chrome-192x192.png", "src": "/static/favicon/android-chrome-192x192.png",

BIN
static/img/error-404.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
static/img/error-429.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

25
utils/error.go Normal file
View File

@@ -0,0 +1,25 @@
package utils
import (
"strconv"
"strings"
"codeberg.org/rimgo/rimgo/static"
"github.com/gofiber/fiber/v2"
)
func RenderError(c *fiber.Ctx, code int) error {
if !strings.Contains(c.Get("Accept"), "html") && c.Params("extension") != "" {
codeStr := "generic"
if code != 0 {
codeStr = strconv.Itoa(code)
}
img, _ := static.GetFiles().ReadFile("img/error-" + codeStr + ".png")
c.Set("Content-Type", "image/png")
return c.Status(code).Send(img)
} else {
return c.Status(code).Render("errors/" + strconv.Itoa(code), fiber.Map{
"path": c.Path(),
})
}
}

View File

@@ -25,7 +25,8 @@
</header> </header>
<main> <main>
<div class="flex flex-col gap-2 md:flex-row md:gap-4 md:items-center my-4"> <div class="flex flex-col sm:flex-row my-4 w-full justify-between">
<div class="flex flex-col gap-2 md:flex-row md:gap-4 md:items-center">
{{#if post.User.Username}} {{#if post.User.Username}}
<a href="/user/{{post.User.Username}}" class="flex gap-2 items-center"> <a href="/user/{{post.User.Username}}" class="flex gap-2 items-center">
<img src="{{post.User.Avatar}}" class="rounded-full" width="36" height="36" /> <img src="{{post.User.Avatar}}" class="rounded-full" width="36" height="36" />
@@ -51,6 +52,12 @@
{{/if}} {{/if}}
</div> </div>
</div> </div>
{{#noteq next ""}}
<a href="{{next}}" class="self-end">
<button class="p-2 rounded-lg bg-slate-600">Next &gt;</button>
</a>
{{/noteq}}
</div>
<div class="flex flex-center flex-col break-words"> <div class="flex flex-center flex-col break-words">
{{#each post.Media}} {{#each post.Media}}
@@ -101,7 +108,8 @@
{{#if comments}} {{#if comments}}
<div> <div>
<input id="comments__expandBtn" type="checkbox" checked> <input id="comments__expandBtn" type="checkbox" checked>
<label class="comments__expandBtn__label my-2 py-4 border-solid border-t-2 border-slate-400" for="comments__expandBtn"> <label class="comments__expandBtn__label my-2 py-4 border-solid border-t-2 border-slate-400"
for="comments__expandBtn">
<h3 class="text-xl font-bold">Comments ({{post.Comments}})</h3> <h3 class="text-xl font-bold">Comments ({{post.Comments}})</h3>
<span class="text-xl font-bold"></span> <span class="text-xl font-bold"></span>
</label> </label>