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 (
|
require (
|
||||||
|
github.com/allegro/bigcache/v3 v3.0.2 // indirect
|
||||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 // 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 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
|
||||||
github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
|
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 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
||||||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
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) {
|
func lyricsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
id := mux.Vars(r)["id"]
|
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)
|
url := fmt.Sprintf("https://genius.com/%s-lyrics", id)
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -78,4 +83,5 @@ func lyricsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Execute(w, s)
|
t.Execute(w, s)
|
||||||
|
setCache(id, s)
|
||||||
}
|
}
|
||||||
|
|
23
main.go
23
main.go
|
@ -2,32 +2,27 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/allegro/bigcache/v3"
|
||||||
"github.com/gorilla/mux"
|
"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() {
|
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 := mux.NewRouter()
|
||||||
|
|
||||||
|
r.Use(securityHeaders)
|
||||||
|
|
||||||
r.HandleFunc("/{id}-lyrics", lyricsHandler)
|
r.HandleFunc("/{id}-lyrics", lyricsHandler)
|
||||||
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
|
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)
|
item.addEventListener("click", getAnnotation)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,6 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
#lyrics {
|
#lyrics {
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
padding: 1rem 0;
|
|
||||||
color: #171717;
|
color: #171717;
|
||||||
line-height: 2.5rem;
|
line-height: 2.5rem;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +54,10 @@ body {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#lyrics a:hover {
|
||||||
|
background-color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
#nav {
|
#nav {
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -76,24 +76,30 @@ a {
|
||||||
#metadata {
|
#metadata {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
padding: 1rem;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#metadata h1 {
|
#metadata h1 {
|
||||||
font-size: 2.2rem;
|
font-size: 2rem;
|
||||||
color: #171717;
|
color: #171717;
|
||||||
}
|
}
|
||||||
|
|
||||||
#metadata h2 {
|
#metadata h2 {
|
||||||
font-size: 1.5rem;
|
font-size: 1.4rem;
|
||||||
color: #1E1E1E;
|
color: #1E1E1E;
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
#metadata > img {
|
#metadata > img {
|
||||||
width: 20rem;
|
width: 20rem;
|
||||||
border-radius: 3px;
|
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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 id="nav">DUMB</h1>
|
<h1 id="nav">DUMB</h1>
|
||||||
|
<div id="container">
|
||||||
<div id="metadata">
|
<div id="metadata">
|
||||||
<img src="{{.Image}}"/>
|
<img src="{{.Image}}"/>
|
||||||
<h2>{{.Artist}}</h2>
|
<h2>{{.Artist}}</h2>
|
||||||
<h1>{{.Title}}</h1>
|
<h1>{{.Title}}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="lyrics">{{.Lyrics}}</div>
|
<div id="lyrics">{{.Lyrics}}</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user