Add api for annotations

this only returns the first available annotation for now
annotation content is returned in html format, so it can easily be
inserted in the frontend

displaying the annotation in the frontend is still a TODO
This commit is contained in:
qvalentin 2023-09-09 15:19:11 +02:00
parent ab19250c66
commit 71e3b6e029
3 changed files with 118 additions and 2 deletions

104
annotations.go Normal file
View File

@ -0,0 +1,104 @@
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"regexp"
"strings"
"github.com/gorilla/mux"
)
type annotationsResponse struct {
Response struct {
Referent struct {
Annotations []struct {
Body struct {
Html string `json:"html"`
} `json:"body"`
} `json:"annotations"`
} `json:"referent"`
} `json:"response"`
}
func annotationsHandler(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"]
url := fmt.Sprintf("https://genius.com/api/referents/%s?text_format=html", id)
resp, err := sendRequest(url)
if err != nil {
logger.Errorln(err)
w.WriteHeader(http.StatusInternalServerError)
render("error", w, map[string]string{
"Status": "500",
"Error": "cannot reach genius servers",
})
return
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusNotFound {
w.WriteHeader(http.StatusNotFound)
render("error", w, map[string]string{
"Status": "404",
"Error": "page not found",
})
return
}
buf := new(bytes.Buffer)
_, err = buf.ReadFrom(resp.Body)
if err != nil {
logger.Errorln("Error paring genius api response", err)
w.WriteHeader(http.StatusInternalServerError)
render("error", w, map[string]string{
"Status": "500",
"Error": "Parsing error",
})
return
}
var data annotationsResponse
err = json.Unmarshal(buf.Bytes(), &data)
if err != nil {
logger.Errorf("could not unmarshal json: %s\n", err)
w.WriteHeader(http.StatusInternalServerError)
render("error", w, map[string]string{
"Status": "500",
"Error": "Could not parse genius api response",
})
return
}
w.Header().Set("content-type", "application/json")
body := data.Response.Referent.Annotations[0].Body
body.Html = cleanBody(body.Html)
response, err := json.Marshal(body)
if err != nil {
logger.Errorf("could not marshal json: %s\n", err)
w.WriteHeader(http.StatusInternalServerError)
render("error", w, map[string]string{
"Status": "500",
"Error": "Could not parse genius api response",
})
return
}
_, err = w.Write(response)
if err != nil {
logger.Errorln("Error sending response: ", err)
}
}
func cleanBody(body string) string {
var withCleanedImageLinks = strings.Replace(body, "https://images.rapgenius.com/", "/images/", -1)
var re = regexp.MustCompile(`https?:\/\/[a-z]*.?genius.com`)
var withCleanedLinks = re.ReplaceAllString(withCleanedImageLinks, "")
return withCleanedLinks
}

View File

@ -29,6 +29,7 @@ func main() {
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { render("home", w, nil) })
r.HandleFunc("/search", searchHandler).Methods("GET")
r.HandleFunc("/{id}-lyrics", lyricsHandler)
r.HandleFunc("/{id}/{artist-song}/{verse}/annotations", annotationsHandler)
r.HandleFunc("/images/{filename}.{ext}", proxyHandler)
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
r.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

View File

@ -14,6 +14,17 @@ document.querySelectorAll("#lyrics a").forEach(item => {
function getAnnotation(e) {
e.preventDefault()
//const uri = e.target.parentElement.getAttribute("href")
console.log("Annotations are not yet implemented!")
const uri = e.target.parentElement.getAttribute("href")
console.log("Annotations are not yet implemented!", uri)
xhr = new XMLHttpRequest()
xhr.open("GET", uri + "/annotations")
xhr.send()
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
json = JSON.parse(this.responseText)
alert(json.html)
// TODO: display annotations properly
}
}
}