From 71e3b6e02919e4205688b7bbe89b4649d7cee2e8 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 9 Sep 2023 15:19:11 +0200 Subject: [PATCH] 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 --- annotations.go | 104 +++++++++++++++++++++++++++++++++++++++++++++++ main.go | 1 + static/script.js | 15 ++++++- 3 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 annotations.go diff --git a/annotations.go b/annotations.go new file mode 100644 index 0000000..374d473 --- /dev/null +++ b/annotations.go @@ -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 +} diff --git a/main.go b/main.go index 0161943..d819a0a 100644 --- a/main.go +++ b/main.go @@ -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) { diff --git a/static/script.js b/static/script.js index 1a45d35..fec2af0 100644 --- a/static/script.js +++ b/static/script.js @@ -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 + } + } }