contrib/opportunity: prevent null receiver error
[nit.git] / contrib / opportunity / src / opportunity_controller.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 # Actions for Opportunity web application
16 module opportunity_controller
17
18 import nitcorn
19 import sha1
20 import templates
21 import opportunity_model
22
23 # Any kind of opportunity `Action` (serves a request)
24 abstract class OpportunityAction
25 super Action
26
27 # Path to db
28 var db_path = "opportunity"
29
30 # Returns a bad request with an error code 400
31 #
32 # TODO: Add a specific body to the bad request page.
33 fun bad_req: HttpResponse do
34 var rsp = new HttpResponse(400)
35 rsp.body = (new OpportunityHomePage).write_to_string
36 return rsp
37 end
38 end
39
40 # Welcome page for Opportunity
41 class OpportunityWelcome
42 super OpportunityAction
43
44 redef fun answer(request, url) do
45 print "Received request for {url}"
46 var get = request.get_args
47 var rq = url.split("/")
48 if rq.has("meetup_create") then
49 var ansset = new HashSet[String]
50 var ans_tmp = "answer_"
51 var cnt = 1
52 loop
53 var anss = request.string_arg(ans_tmp + cnt.to_s)
54 cnt += 1
55 if anss == null then break
56 if ansset.has(anss) then continue
57 ansset.add anss
58 end
59
60 var mname = request.string_arg("meetup_name")
61 var mdate = request.string_arg("meetup_date")
62 var mplace = request.string_arg("meetup_place")
63 var mmodestr = request.string_arg("meetup_mode")
64 var mmode = 0
65 if mdate == null then mdate = ""
66 if mplace == null then mplace = ""
67 if mmodestr != null then
68 mmode = 1
69 end
70 if mname == null then
71 mname = ""
72 var rsp = new HttpResponse(200)
73 var meetpage = new MeetupCreationPage
74 var meet = new Meetup(mname, mdate, mplace, mmode)
75 meetpage.ans = ansset
76 meetpage.meet = meet
77 meetpage.error = "'Meetup name' is a mandatory fields."
78 rsp.body = meetpage.write_to_string
79 return rsp
80
81 end
82 var db = new OpportunityDB.open(db_path)
83 var meet = new Meetup(mname, mdate, mplace, mmode)
84 if ansset.is_empty then
85 db.close
86 var rsp = new HttpResponse(200)
87 var meetpage = new MeetupCreationPage
88 meetpage.meet = meet
89 meetpage.error = "You need to input at least one answer."
90 rsp.body = meetpage.write_to_string
91 return rsp
92 end
93 if not meet.commit(db) then
94 db.close
95 var rsp = new HttpResponse(200)
96 var meetpage = new MeetupCreationPage
97 meetpage.meet = meet
98 meetpage.ans = ansset
99 meetpage.error = """<p>Could not create Meetup.</p>
100 <p>Hmm, that's embarassing, the database indicates that your meetup already exists.</p>
101 <p>If this is not a duplicated submission, please contact the mainainers of the website, you might have found a bug !</p>"""
102 rsp.body = meetpage.write_to_string
103 return rsp
104 end
105 for v in ansset do
106 var ans = new Answer(v)
107 ans.meetup = meet
108 ans.commit(db)
109 end
110 db.close
111 var rsp = new HttpResponse(200)
112 rsp.body = (new MeetupConfirmation(meet)).write_to_string
113 return rsp
114 end
115 if rq.has("new_meetup") then
116 var rsp = new HttpResponse(200)
117 var page = new MeetupCreationPage
118 rsp.body = page.write_to_string
119 return rsp
120 end
121 if get.has_key("meetup_id") then
122 var rsp = new HttpResponse(200)
123 rsp.body = (new OpportunityMeetupPage.from_id(get["meetup_id"])).write_to_string
124 return rsp
125 end
126 var rsp = new HttpResponse(200)
127 rsp.body = (new OpportunityHomePage).write_to_string
128 return rsp
129 end
130
131 end
132
133 # Any kind of REST request to Opportunity
134 class OpportunityRESTAction
135 super OpportunityAction
136
137 redef fun answer(request, uri) do
138 print "Received REST request from {uri}"
139 var get = request.get_args
140 var req = uri.split("/")
141 if req.has("people") then
142 return (new OpportunityPeopleREST).answer(request, uri)
143 else if req.has("answer") then
144 return (new OpportunityAnswerREST).answer(request, uri)
145 else if req.has("meetup") then
146 return (new OpportunityMeetupREST).answer(request, uri)
147 else
148 return new HttpResponse(400)
149 end
150 end
151
152 end
153
154 # REST Actions working on People
155 class OpportunityPeopleREST
156 super OpportunityAction
157
158 redef fun answer(request, uri) do
159 # Should be DELETE for true REST API
160 # TODO : change method to DELETE once supported by Nitcorn
161 if request.method == "POST" then
162 var meth = request.string_arg("method")
163 if meth == null then return bad_req
164 if meth != "DELETE" then return bad_req
165 var pid = request.int_arg("p_id")
166 if pid == null then return bad_req
167 var db = new OpportunityDB.open(db_path)
168 db.remove_people_by_id(pid)
169 db.close
170 return new HttpResponse(200)
171 end
172 return new HttpResponse(400)
173 end
174
175 end
176
177 # REST Actions working on Answers
178 class OpportunityAnswerREST
179 super OpportunityAction
180
181 redef fun answer(request, uri) do
182 var persid = request.int_arg("pers_id")
183 var ansid = request.int_arg("answer_id")
184 var ans = request.int_arg("answer")
185 if persid == null or ansid == null or ans == null then return bad_req
186 var db = new OpportunityDB.open(db_path)
187 db.change_answer(ansid, persid, ans)
188 db.close
189 return new HttpResponse(200)
190 end
191 end
192
193 # REST Actions working on Meetups
194 class OpportunityMeetupREST
195 super OpportunityAction
196
197 redef fun answer(request, uri) do
198 var args = uri.split("/")
199 if args.has("new_pers") then
200 var name = request.string_arg("persname")
201 var m_id = request.string_arg("meetup_id")
202 var ans_str = request.string_arg("answers")
203 if name == null or m_id == null or ans_str == null then return bad_req
204 var ans = ans_str.split("&")
205 var ansmap = new HashMap[Int, Int]
206 for i in ans do
207 var mp = i.split("=")
208 var id = mp.first.split("_").last
209 var b = mp.last.to_i
210 if not id.is_numeric then continue
211 ansmap[id.to_i] = b
212 end
213 var db = new OpportunityDB.open(db_path)
214 var m = db.find_meetup_by_id(m_id)
215 var sublen = name.index_of(' ')
216 var rname = ""
217 var rsurname = ""
218 if sublen == -1 then
219 rsurname = name
220 else
221 rsurname = name.substring(0, sublen)
222 rname = name.substring_from(sublen + 1)
223 end
224 var p = new People(rname, rsurname)
225 for i in m.answers(db) do
226 if not ansmap.has_key(i.id) then
227 p.answers[i] = 0
228 else
229 p.answers[i] = ansmap[i.id]
230 end
231 end
232 p.commit(db)
233 db.close
234 var rsp = new HttpResponse(200)
235 rsp.body = p.id.to_s
236 return rsp
237 end
238 return new HttpResponse(400)
239 end
240 end