Compare commits
4 Commits
cb2895c498
...
a4ec4966d2
Author | SHA1 | Date | |
---|---|---|---|
|
a4ec4966d2 | ||
|
8ee6fd8602 | ||
|
2e1d7d5564 | ||
|
46cc8b7989 |
15
.air.toml
Normal file
15
.air.toml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# .air.toml
|
||||||
|
root = "."
|
||||||
|
tmp_dir = "tmp"
|
||||||
|
|
||||||
|
[build]
|
||||||
|
bin = "/tmp/new_tab"
|
||||||
|
cmd = "go build -o /tmp/new_tab main.go"
|
||||||
|
include = ["*.go", "*.html", "*.css"]
|
||||||
|
exclude = ["tmp", "vendor"]
|
||||||
|
|
||||||
|
[color]
|
||||||
|
main = "yellow"
|
||||||
|
watcher = "cyan"
|
||||||
|
build = "green"
|
||||||
|
log = "white"
|
@ -1,3 +1,12 @@
|
|||||||
# trans new tab page
|
# trans new tab page
|
||||||
|
|
||||||
https://diyhrt.market/api/
|
https://diyhrt.market/api/
|
||||||
|
|
||||||
|
## development
|
||||||
|
|
||||||
|
1. Install [air](https://github.com/air-verse/air)
|
||||||
|
2. Run air
|
||||||
|
|
||||||
|
```sh
|
||||||
|
air
|
||||||
|
```
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>{{ .PageTitle }}</title>
|
<title>{{ .PageTitle }}</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="assets/style.css">
|
||||||
<link rel="stylesheet" type="text/css" href="assets/style.css" />
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<form class="search-grid" action="{{ .SearchFormAction }}">
|
<form class="search-grid" action="{{ .SearchFormAction }}">
|
||||||
@ -14,13 +13,15 @@
|
|||||||
<h2 class="phrases"></h2>
|
<h2 class="phrases"></h2>
|
||||||
<img als="girl_juice" src="assets/girl_juice.png" />
|
<img als="girl_juice" src="assets/girl_juice.png" />
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input name="{{ .SearchInputName }}" type="text" class="grid-item" class="search" placeholder="{{ .SearchPlaceholder }}" />
|
||||||
name="{{ .SearchInputName }}"
|
|
||||||
type="text"
|
<div class="store-cards">
|
||||||
class="grid-item"
|
{{range $Store := .Stores }}
|
||||||
class="search"
|
<a target="_blank" href="{{ $Store.Url }}" class="card">
|
||||||
placeholder="{{ .SearchPlaceholder }}"
|
<h3>{{ $Store.Name }}</h3>
|
||||||
/>
|
</a>
|
||||||
|
{{- end }}
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
9
go.mod
9
go.mod
@ -2,15 +2,16 @@ module gitea.elara.ws/Hazel/transfem-startpage
|
|||||||
|
|
||||||
go 1.24.2
|
go 1.24.2
|
||||||
|
|
||||||
|
require github.com/labstack/echo/v4 v4.13.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/labstack/echo/v4 v4.13.4 // indirect
|
|
||||||
github.com/labstack/gommon v0.4.2 // indirect
|
github.com/labstack/gommon v0.4.2 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
golang.org/x/crypto v0.38.0 // indirect
|
golang.org/x/crypto v0.39.0 // indirect
|
||||||
golang.org/x/net v0.40.0 // indirect
|
golang.org/x/net v0.41.0 // indirect
|
||||||
golang.org/x/sys v0.33.0 // indirect
|
golang.org/x/sys v0.33.0 // indirect
|
||||||
golang.org/x/text v0.25.0 // indirect
|
golang.org/x/text v0.26.0 // indirect
|
||||||
)
|
)
|
||||||
|
20
go.sum
20
go.sum
@ -1,3 +1,5 @@
|
|||||||
|
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/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA=
|
github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA=
|
||||||
github.com/labstack/echo/v4 v4.13.4/go.mod h1:g63b33BZ5vZzcIUF8AtRH40DrTlXnx4UMC8rBdndmjQ=
|
github.com/labstack/echo/v4 v4.13.4/go.mod h1:g63b33BZ5vZzcIUF8AtRH40DrTlXnx4UMC8rBdndmjQ=
|
||||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||||
@ -6,16 +8,22 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
|
|||||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
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/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 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/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||||
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
||||||
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
||||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
||||||
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.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
@ -2,8 +2,7 @@ package diyhrt
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"errors"
|
||||||
"io"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
@ -14,7 +13,7 @@ const endpoint = "https://diyhrt.market/api/listings"
|
|||||||
func GetListings() ([]Listing, error) {
|
func GetListings() ([]Listing, error) {
|
||||||
apiKey := os.Getenv("API_KEY")
|
apiKey := os.Getenv("API_KEY")
|
||||||
if apiKey == "" {
|
if apiKey == "" {
|
||||||
return nil, fmt.Errorf("API_KEY environment variable not set")
|
return nil, errors.New("API_KEY environment variable not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create HTTP client
|
// Create HTTP client
|
||||||
@ -23,26 +22,25 @@ func GetListings() ([]Listing, error) {
|
|||||||
// Create request
|
// Create request
|
||||||
req, err := http.NewRequest("GET", endpoint+"?api_token="+apiKey, nil)
|
req, err := http.NewRequest("GET", endpoint+"?api_token="+apiKey, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("creating request failed: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send request
|
// Send request
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("request failed: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
// Check status code
|
// Check status code
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
body, _ := io.ReadAll(resp.Body)
|
return nil, errors.New("unexpected status code")
|
||||||
return nil, fmt.Errorf("unexpected status code %d: %s", resp.StatusCode, string(body))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode response
|
// Decode response
|
||||||
var listings []Listing
|
var listings []Listing
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&listings); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&listings); err != nil {
|
||||||
return nil, fmt.Errorf("decoding failed: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return listings, nil
|
return listings, nil
|
||||||
|
42
internal/diyhrt/filter.go
Normal file
42
internal/diyhrt/filter.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package diyhrt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StoreFilter struct{
|
||||||
|
Limit int
|
||||||
|
|
||||||
|
IncludeIds []int
|
||||||
|
ExcludeIds []int
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (f StoreFilter) Filter (stores []Store) []Store {
|
||||||
|
result := make([]Store, 0)
|
||||||
|
|
||||||
|
for _, s := range stores {
|
||||||
|
if f.Limit > 0 && len(result) >= f.Limit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(f.IncludeIds) > 0 {
|
||||||
|
if slices.Contains(f.IncludeIds, s.Id) {
|
||||||
|
result = append(result, s)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if slices.Contains(f.ExcludeIds, s.Id) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
result = append(result, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(len(result))
|
||||||
|
return result
|
||||||
|
}
|
@ -1,8 +1,6 @@
|
|||||||
package rendering
|
package rendering
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"gitea.elara.ws/Hazel/transfem-startpage/internal/diyhrt"
|
"gitea.elara.ws/Hazel/transfem-startpage/internal/diyhrt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,6 +13,8 @@ type RenderingConfig struct {
|
|||||||
SearchFormAction string
|
SearchFormAction string
|
||||||
SearchInputName string
|
SearchInputName string
|
||||||
|
|
||||||
|
StoreFilter diyhrt.StoreFilter
|
||||||
|
|
||||||
Listings []diyhrt.Listing
|
Listings []diyhrt.Listing
|
||||||
Stores []diyhrt.Store
|
Stores []diyhrt.Store
|
||||||
}
|
}
|
||||||
@ -36,6 +36,10 @@ func DefaultRenderingConfig() RenderingConfig {
|
|||||||
SearchPlaceholder: "Search on DuckDuckGo",
|
SearchPlaceholder: "Search on DuckDuckGo",
|
||||||
SearchFormAction: "https://duckduckgo.com/",
|
SearchFormAction: "https://duckduckgo.com/",
|
||||||
SearchInputName: "q",
|
SearchInputName: "q",
|
||||||
|
|
||||||
|
StoreFilter: diyhrt.StoreFilter{
|
||||||
|
Limit: 4,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +48,6 @@ func (rc *RenderingConfig) LoadDiyHrt(listings []diyhrt.Listing) {
|
|||||||
stores := make([]diyhrt.Store, 0)
|
stores := make([]diyhrt.Store, 0)
|
||||||
|
|
||||||
for _, listing := range listings {
|
for _, listing := range listings {
|
||||||
fmt.Println(listing)
|
|
||||||
if _, ok := existingStores[listing.Store.Id]; ok {
|
if _, ok := existingStores[listing.Store.Id]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -53,5 +56,5 @@ func (rc *RenderingConfig) LoadDiyHrt(listings []diyhrt.Listing) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc.Listings = listings
|
rc.Listings = listings
|
||||||
rc.Stores = stores
|
rc.Stores = rc.StoreFilter.Filter(stores)
|
||||||
}
|
}
|
||||||
|
1
main.go
1
main.go
@ -45,7 +45,6 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
fmt.Println(CurrentRenderingConfig.Stores)
|
|
||||||
|
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
e.Static("/assets", "frontend/assets")
|
e.Static("/assets", "frontend/assets")
|
||||||
|
1
tmp/build-errors.log
Normal file
1
tmp/build-errors.log
Normal file
@ -0,0 +1 @@
|
|||||||
|
exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1
|
Loading…
x
Reference in New Issue
Block a user