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