Merge pull request #40 from qvalentin/feature/annotations
annotations support
This commit is contained in:
commit
98aa8db9ee
127
annotations.go
Normal file
127
annotations.go
Normal file
@ -0,0 +1,127 @@
|
||||
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"]
|
||||
|
||||
if data, err := getCache(id); err == nil {
|
||||
|
||||
response, err := json.Marshal(data)
|
||||
|
||||
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
|
||||
}
|
||||
w.Header().Set("content-type", "application/json")
|
||||
_, err = w.Write(response)
|
||||
if err != nil {
|
||||
logger.Errorln("Error sending response: ", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
setCache(id, body)
|
||||
_, 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
|
||||
}
|
1
main.go
1
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.HandleFunc("/albums/{artist}/{albumName}", albumHandler)
|
||||
|
@ -14,6 +14,24 @@ 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")
|
||||
const presentAnnotation = document.getElementById(uri)
|
||||
if (presentAnnotation) {
|
||||
presentAnnotation.remove()
|
||||
return
|
||||
}
|
||||
|
||||
xhr = new XMLHttpRequest()
|
||||
xhr.open("GET", uri + "/annotations")
|
||||
xhr.send()
|
||||
xhr.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
const parsedReponse = JSON.parse(this.responseText)
|
||||
const annotationDiv = document.createElement('div');
|
||||
annotationDiv.innerHTML = parsedReponse.html
|
||||
annotationDiv.id = uri
|
||||
annotationDiv.className = "annotation"
|
||||
e.target.parentElement.insertAdjacentElement('afterend', annotationDiv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,8 +56,7 @@ body {
|
||||
cursor: initial;
|
||||
}
|
||||
|
||||
/*** NOT YET IMPLEMENTED
|
||||
#lyrics a {
|
||||
#lyrics a, .annotation {
|
||||
background-color: #ddd;
|
||||
color: inherit;
|
||||
}
|
||||
@ -65,7 +64,6 @@ body {
|
||||
#lyrics a:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
***/
|
||||
|
||||
nav {
|
||||
background-color: #ffcd38;
|
||||
@ -166,6 +164,19 @@ a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.annotation {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.annotation img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.annotation ul {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
@ -337,6 +348,16 @@ footer a:hover {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
#lyrics a, .annotation {
|
||||
background-color: #272d44;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
|
||||
#lyrics a:hover {
|
||||
background-color: #32384f;
|
||||
}
|
||||
|
||||
#metadata h1 {
|
||||
color: #ddd;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user