5db1d04692d39b4048dd848e43bff65c86e829c9
[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 # Group all api handlers in one router
27 class APIFeedbackRouter
28 super APIRouter
29
30 init do
31 use("/stars/:id", new APIStars(config))
32 end
33 end
34
35 # Stars attributed to mentities
36 class APIStars
37 super APIHandler
38
39 redef fun get(req, res) do
40 var mentity = mentity_from_uri(req, res)
41 if mentity == null then
42 res.error 404
43 return
44 end
45
46 res.json mentity_ratings(mentity)
47 end
48
49 redef fun post(req, res) do
50 var mentity = mentity_from_uri(req, res)
51 if mentity == null then
52 res.error 404
53 return
54 end
55 var obj = req.body.parse_json
56 if not obj isa JsonObject then
57 res.error 400
58 return
59 end
60 var rating = obj["rating"]
61 if not rating isa Int then
62 res.error 400
63 return
64 end
65
66 var val = new MEntityRating(mentity.full_name, rating, get_time)
67 config.stars.insert(val.json)
68
69 res.json mentity_ratings(mentity)
70 end
71
72 # Get the ratings of a `mentity`
73 fun mentity_ratings(mentity: MEntity): MEntityRatings do
74 var ratings = new MEntityRatings(mentity)
75
76 var req = new JsonObject
77 req["mentity"] = mentity.full_name
78 var rs = config.stars.find_all(req)
79 for r in rs do ratings.ratings.add new MEntityRating.from_json(r)
80 return ratings
81 end
82 end
83
84 # Ratings representation for a mentity
85 class MEntityRatings
86 super Jsonable
87
88 # MEntity rated
89 var mentity: MEntity
90
91 # List of ratings
92 var ratings = new Array[MEntityRating]
93
94 # Mean of all ratings or 0
95 fun mean: Float do
96 if ratings.is_empty then return 0.0
97 var sum = 0.0
98 for r in ratings do sum += r.rating.to_f
99 var res = sum / ratings.length.to_f
100 return res
101 end
102
103 # Json representation of `self`
104 fun json: JsonObject do
105 var obj = new JsonObject
106 obj["mentity"] = mentity.full_name
107 obj["ratings"] = new JsonArray.from(ratings)
108 obj["mean"] = mean
109 return obj
110 end
111
112 redef fun to_json do return json.to_json
113 end
114
115 # Rating value of a MEntity
116 class MEntityRating
117 super Jsonable
118
119 # MEntity this rating is about
120 var mentity: String
121
122 # Rating value (between 1 and 5)
123 var rating: Int
124
125 # Timestamp of this rating
126 var timestamp: Int
127
128 # Init this rating value from a JsonObject
129 init from_json(obj: JsonObject) do
130 init(obj["mentity"].as(String), obj["rating"].as(Int), obj["timestamp"].as(Int))
131 end
132
133 # Translate this rating value to a JsonObject
134 fun json: JsonObject do
135 var obj = new JsonObject
136 obj["mentity"] = mentity
137 obj["rating"] = rating
138 obj["timestamp"] = timestamp
139 return obj
140 end
141
142 redef fun to_json do return json.to_json
143 end