e2bfa9a01465da29f2e5b9c74e896d27a9524190
[nit.git] / src / web / api_feedback.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Feedback related features
16 module api_feedback
17
18 import web_base
19
20 redef class NitwebConfig
21
22 # MongoDB collection used to store stars.
23 var stars: MongoCollection is lazy do return db.collection("stars")
24 end
25
26 redef class APIRouter
27 redef init do
28 super
29 use("/feedback/stars/:id", new APIStars(config))
30 end
31 end
32
33 # Stars attributed to mentities
34 class APIStars
35 super APIHandler
36
37 redef fun get(req, res) do
38 var mentity = mentity_from_uri(req, res)
39 if mentity == null then return
40 res.json mentity_ratings(mentity)
41 end
42
43 redef fun post(req, res) do
44 var mentity = mentity_from_uri(req, res)
45 if mentity == null then return
46 var obj = req.body.parse_json
47 if not obj isa JsonObject then
48 res.api_error(400, "Expected a JSON object")
49 return
50 end
51 var rating = obj["rating"]
52 if not rating isa Int then
53 res.api_error(400, "Expected a key `rating`")
54 return
55 end
56
57 var val = new MEntityRating(mentity.full_name, rating, get_time)
58 config.stars.insert(val.json)
59
60 res.json mentity_ratings(mentity)
61 end
62
63 # Get the ratings of a `mentity`
64 fun mentity_ratings(mentity: MEntity): MEntityRatings do
65 var ratings = new MEntityRatings(mentity)
66
67 var req = new JsonObject
68 req["mentity"] = mentity.full_name
69 var rs = config.stars.find_all(req)
70 for r in rs do ratings.ratings.add new MEntityRating.from_json(r)
71 return ratings
72 end
73 end
74
75 # Ratings representation for a mentity
76 class MEntityRatings
77 super Jsonable
78
79 # MEntity rated
80 var mentity: MEntity
81
82 # List of ratings
83 var ratings = new Array[MEntityRating]
84
85 # Mean of all ratings or 0
86 fun mean: Float do
87 if ratings.is_empty then return 0.0
88 var sum = 0.0
89 for r in ratings do sum += r.rating.to_f
90 var res = sum / ratings.length.to_f
91 return res
92 end
93
94 # Json representation of `self`
95 fun json: JsonObject do
96 var obj = new JsonObject
97 obj["mentity"] = mentity.full_name
98 obj["ratings"] = new JsonArray.from(ratings)
99 obj["mean"] = mean
100 return obj
101 end
102
103 redef fun to_json do return json.to_json
104 end
105
106 # Rating value of a MEntity
107 class MEntityRating
108 super Jsonable
109
110 # MEntity this rating is about
111 var mentity: String
112
113 # Rating value (between 1 and 5)
114 var rating: Int
115
116 # Timestamp of this rating
117 var timestamp: Int
118
119 # Init this rating value from a JsonObject
120 init from_json(obj: JsonObject) do
121 init(obj["mentity"].as(String), obj["rating"].as(Int), obj["timestamp"].as(Int))
122 end
123
124 # Translate this rating value to a JsonObject
125 fun json: JsonObject do
126 var obj = new JsonObject
127 obj["mentity"] = mentity
128 obj["rating"] = rating
129 obj["timestamp"] = timestamp
130 return obj
131 end
132
133 redef fun to_json do return json.to_json
134 end