add caching and change the layout a bit
This commit is contained in:
parent
7b2c43cc16
commit
e7aa7403c7
1
go.mod
1
go.mod
|
@ -8,6 +8,7 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/allegro/bigcache/v3 v3.0.2 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 // indirect
|
||||
)
|
||||
|
|
2
go.sum
2
go.sum
|
@ -1,5 +1,7 @@
|
|||
github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
|
||||
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
|
||||
github.com/allegro/bigcache/v3 v3.0.2 h1:AKZCw+5eAaVyNTBmI2fgyPVJhHkdWder3O9IrprcQfI=
|
||||
github.com/allegro/bigcache/v3 v3.0.2/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I=
|
||||
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
||||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
|
|
|
@ -49,6 +49,11 @@ func (s *song) parse(doc *goquery.Document) {
|
|||
func lyricsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
id := mux.Vars(r)["id"]
|
||||
|
||||
if data, err := getCache(id); err == nil {
|
||||
render(w, data)
|
||||
return
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("https://genius.com/%s-lyrics", id)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
|
@ -78,4 +83,5 @@ func lyricsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
t.Execute(w, s)
|
||||
setCache(id, s)
|
||||
}
|
||||
|
|
23
main.go
23
main.go
|
@ -2,32 +2,27 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/allegro/bigcache/v3"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func fatal(err any) {
|
||||
log.Fatalf("[ERR] %s\n", err)
|
||||
}
|
||||
|
||||
func info(s string) {
|
||||
log.Printf("[INFO] %s\n", s)
|
||||
}
|
||||
|
||||
func write(w http.ResponseWriter, status int, data []byte) {
|
||||
w.WriteHeader(status)
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
func main() {
|
||||
c, err := bigcache.NewBigCache(bigcache.DefaultConfig(time.Hour * 2))
|
||||
if err != nil {
|
||||
fatal("can't initialize caching")
|
||||
}
|
||||
cache = c
|
||||
|
||||
r := mux.NewRouter()
|
||||
|
||||
r.Use(securityHeaders)
|
||||
|
||||
r.HandleFunc("/{id}-lyrics", lyricsHandler)
|
||||
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
document.querySelectorAll("#lyrics > a").forEach(item => {
|
||||
document.querySelectorAll("#lyrics a").forEach(item => {
|
||||
item.addEventListener("click", getAnnotation)
|
||||
})
|
||||
|
||||
|
|
|
@ -45,10 +45,6 @@ body {
|
|||
}
|
||||
|
||||
#lyrics {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding: 1rem 0;
|
||||
color: #171717;
|
||||
line-height: 2.5rem;
|
||||
}
|
||||
|
@ -58,6 +54,10 @@ body {
|
|||
color: inherit;
|
||||
}
|
||||
|
||||
#lyrics a:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
#nav {
|
||||
font-size: 2.5rem;
|
||||
text-align: center;
|
||||
|
@ -76,24 +76,30 @@ a {
|
|||
#metadata {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#metadata h1 {
|
||||
font-size: 2.2rem;
|
||||
font-size: 2rem;
|
||||
color: #171717;
|
||||
}
|
||||
|
||||
#metadata h2 {
|
||||
font-size: 1.5rem;
|
||||
font-size: 1.4rem;
|
||||
color: #1E1E1E;
|
||||
text-transform: uppercase;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
#metadata > img {
|
||||
width: 20rem;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 1px #ddd;
|
||||
}
|
||||
|
||||
#container {
|
||||
display: flex;
|
||||
padding: 2rem;
|
||||
gap: 5rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
|
73
utils.go
Normal file
73
utils.go
Normal file
|
@ -0,0 +1,73 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"path"
|
||||
"text/template"
|
||||
|
||||
"github.com/allegro/bigcache/v3"
|
||||
)
|
||||
|
||||
var cache *bigcache.BigCache
|
||||
|
||||
func setCache(key string, entry any) error {
|
||||
data, err := json.Marshal(&entry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cache.Set(key, data)
|
||||
}
|
||||
|
||||
func getCache(key string) (any, error) {
|
||||
data, err := cache.Get(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var decoded any
|
||||
|
||||
if err = json.Unmarshal(data, &decoded); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return decoded, nil
|
||||
}
|
||||
|
||||
func fatal(err any) {
|
||||
log.Fatalf("[ERR] %s\n", err)
|
||||
}
|
||||
|
||||
func info(s string) {
|
||||
log.Printf("[INFO] %s\n", s)
|
||||
}
|
||||
|
||||
func write(w http.ResponseWriter, status int, data []byte) {
|
||||
w.WriteHeader(status)
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
func securityHeaders(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
csp := "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' images.genius.com; object-src 'none'"
|
||||
w.Header().Add("content-security-policy", csp)
|
||||
w.Header().Add("referrer-policy", "no-referrer")
|
||||
w.Header().Add("x-content-type-options", "nosniff")
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func render(w http.ResponseWriter, data any) {
|
||||
t, err := template.ParseFiles(path.Join("views/lyrics.tmpl"))
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if err = t.Execute(w, data); err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
|
@ -8,11 +8,13 @@
|
|||
</head>
|
||||
<body>
|
||||
<h1 id="nav">DUMB</h1>
|
||||
<div id="metadata">
|
||||
<img src="{{.Image}}"/>
|
||||
<h2>{{.Artist}}</h2>
|
||||
<h1>{{.Title}}</h1>
|
||||
<div id="container">
|
||||
<div id="metadata">
|
||||
<img src="{{.Image}}"/>
|
||||
<h2>{{.Artist}}</h2>
|
||||
<h1>{{.Title}}</h1>
|
||||
</div>
|
||||
<div id="lyrics">{{.Lyrics}}</div>
|
||||
</div>
|
||||
<div id="lyrics">{{.Lyrics}}</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in New Issue
Block a user