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