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 + } + } }