Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Commit

Permalink
Add get all ratings functionality to GET ratings endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
cpacia committed Nov 20, 2017
1 parent 0b500d5 commit fa8507f
Show file tree
Hide file tree
Showing 3 changed files with 237 additions and 53 deletions.
166 changes: 154 additions & 12 deletions api/jsonapi.go
Expand Up @@ -3157,38 +3157,180 @@ func (i *jsonAPIHandler) GETRatings(w http.ResponseWriter, r *http.Request) {
urlPath, slug := path.Split(r.URL.Path)
_, peerId := path.Split(urlPath[:len(urlPath)-1])

if peerId == "ratings" {
peerId = slug
slug = ""
}

var indexBytes []byte
if peerId != i.node.IpfsNode.Identity.Pretty() {
indexBytes, _ = ipfs.ResolveThenCat(i.node.Context, ipnspath.FromString(path.Join(peerId, "ratings.json")))

} else {
indexBytes, _ = ioutil.ReadFile(path.Join(i.node.RepoPath, "root", "ratings.json"))
}
var rating *core.SavedRating
if indexBytes == nil {
rating = new(core.SavedRating)
rating.Slug = slug
rating := new(core.SavedRating)
rating.Ratings = []string{}
} else {
var ratingList []core.SavedRating
err := json.Unmarshal(indexBytes, &ratingList)
ret, err := json.MarshalIndent(rating, "", " ")
if err != nil {
ErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
SanitizedResponse(w, string(ret))
return
}

var ratingList []core.SavedRating
err := json.Unmarshal(indexBytes, &ratingList)
if err != nil {
ErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

if slug != "" {
rating := new(core.SavedRating)
for _, r := range ratingList {
if r.Slug == slug {
rating = &r
break
}
}
ret, err := json.MarshalIndent(rating, "", " ")
if err != nil {
ErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
SanitizedResponse(w, string(ret))
} else {

total := float32(0)
count := 0
var ratingHashes []string
for _, r := range ratingList {
total += r.Average * float32(r.Count)
count += r.Count
ratingHashes = append(ratingHashes, r.Ratings...)
}
query := r.URL.Query().Get("async")
async, _ := strconv.ParseBool(query)
if !async {
rl := new(pb.RatingList)
rl.Count = uint32(count)
rl.Average = total / float32(count)
var wg sync.WaitGroup
var l sync.Mutex
for _, id := range ratingHashes {
wg.Add(1)
go func(rid string) {
ratingBytes, err := ipfs.Cat(i.node.Context, rid)
if err != nil {
return
}
rating := new(pb.Rating)
err = jsonpb.UnmarshalString(string(ratingBytes), rating)
if err != nil {
return
}
valid, err := core.ValidateRating(rating)
if !valid || err != nil {
return
}
l.Lock()
rl.Ratings = append(rl.Ratings, rating)
l.Unlock()
wg.Done()
}(id)
}
wg.Wait()
m := jsonpb.Marshaler{
EnumsAsInts: false,
EmitDefaults: true,
Indent: " ",
OrigName: false,
}
respJson, err := m.MarshalToString(rl)
if err != nil {
return
}
SanitizedResponseM(w, string(respJson), new(pb.RatingList))
} else {
idBytes := make([]byte, 16)
rand.Read(idBytes)
id := base58.Encode(idBytes)

type resp struct {
Count int `json:"count"`
Average float32 `json:"average"`
Id string `json:"id"`
}
response := resp{
Count: count,
Average: total / float32(count),
Id: id,
}
respJson, _ := json.MarshalIndent(response, "", " ")
w.WriteHeader(http.StatusAccepted)
SanitizedResponse(w, string(respJson))
for _, r := range ratingHashes {
go func(rid string) {
type ratingError struct {
ID string `json:"id"`
RatingID string `json:"ratingId"`
Error string `json:"error"`
}
respondWithError := func(errorMsg string) {
e := ratingError{id, rid, "Not found"}
ret, err := json.MarshalIndent(e, "", " ")
if err != nil {
return
}
i.node.Broadcast <- ret
return
}
ratingBytes, err := ipfs.Cat(i.node.Context, rid)
if err != nil {
respondWithError("Not Found")
return
}

rating := new(pb.Rating)
err = jsonpb.UnmarshalString(string(ratingBytes), rating)
if err != nil {
respondWithError("Invalid rating")
return
}
valid, err := core.ValidateRating(rating)
if !valid || err != nil {
respondWithError(err.Error())
return
}
resp := new(pb.RatingWithID)
resp.Id = id
resp.RatingId = rid
resp.Rating = rating
m := jsonpb.Marshaler{
EnumsAsInts: false,
EmitDefaults: true,
Indent: " ",
OrigName: false,
}
out, err := m.MarshalToString(resp)
if err != nil {
respondWithError("Error marshalling rating")
return
}
b, err := SanitizeProtobuf(out, new(pb.RatingWithID))
if err != nil {
respondWithError("Error marshalling rating")
return
}
i.node.Broadcast <- b
}(r)
}
}
}
ret, err := json.MarshalIndent(rating, "", " ")
if err != nil {
ErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
SanitizedResponse(w, string(ret))

}

func (i *jsonAPIHandler) GETRating(w http.ResponseWriter, r *http.Request) {
Expand Down
118 changes: 77 additions & 41 deletions pb/api.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions pb/protos/api.proto
Expand Up @@ -65,4 +65,10 @@ message RatingWithID {
string id = 1;
string ratingId = 2;
Rating rating = 3;
}

message RatingList {
uint32 count = 1;
float average = 2;
repeated Rating ratings = 3;
}

0 comments on commit fa8507f

Please sign in to comment.