var mname = request.string_arg("meetup_name")
var mdate = request.string_arg("meetup_date")
var mplace = request.string_arg("meetup_place")
+ var mmodestr = request.string_arg("meetup_mode")
+ var mmode = 0
if mdate == null then mdate = ""
if mplace == null then mplace = ""
+ if mmodestr != null then
+ mmode = 1
+ end
if mname == null then
mname = ""
var rsp = new HttpResponse(200)
var meetpage = new MeetupCreationPage
- var meet = new Meetup(mname, mdate, mplace)
+ var meet = new Meetup(mname, mdate, mplace, mmode)
meetpage.ans = ansset
meetpage.meet = meet
meetpage.error = "'Meetup name' is a mandatory fields."
end
var db = new OpportunityDB.open(db_path)
- var meet = new Meetup(mname, mdate, mplace)
+ var meet = new Meetup(mname, mdate, mplace, mmode)
if ansset.is_empty then
db.close
var rsp = new HttpResponse(200)
redef fun answer(request, uri) do
var persid = request.int_arg("pers_id")
var ansid = request.int_arg("answer_id")
- var ans = request.bool_arg("answer")
+ var ans = request.int_arg("answer")
if persid == null or ansid == null or ans == null then return bad_req
var db = new OpportunityDB.open(db_path)
db.change_answer(ansid, persid, ans)
var ans = request.string_arg("answers").split("&")
if name == null or m_id == null then return bad_req
print ans
- var ansmap = new HashMap[Int, Bool]
+ var ansmap = new HashMap[Int, Int]
for i in ans do
var mp = i.split("=")
- var b = false
- if mp.last == "true" then b = true
var id = mp.first.split("_").last
+ var b = mp.last.to_i
if not id.is_numeric then continue
ansmap[id.to_i] = b
end
var p = new People(rname, rsurname)
for i in m.answers(db) do
if not ansmap.has_key(i.id) then
- p.answers[i] = false
+ p.answers[i] = 0
else
p.answers[i] = ansmap[i.id]
end
# Creates the tables and triggers for Opportunity (SQLite3 DB)
fun create_db do
- assert create_table("IF NOT EXISTS meetups (id CHAR(40) PRIMARY KEY, name TEXT, date TEXT, place TEXT);") else
+ assert create_table("IF NOT EXISTS meetups (id CHAR(40) PRIMARY KEY, name TEXT, date TEXT, place TEXT, answer_mode INTEGER DEFAULT 0);") else
print error or else "?"
end
assert create_table("IF NOT EXISTS people(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, surname TEXT);") else
fun find_meetup_by_id(id: String): nullable Meetup do
var req = select("* FROM meetups where id={id.to_sql_string};")
for i in req do
- return new Meetup.from_db(i[0].to_s, i[1].to_s, i[2].to_s, i[3].to_s)
+ return new Meetup.from_db(i[0].to_s, i[1].to_s, i[2].to_s, i[3].to_s, i[4].to_i)
+ end
+ return null
+ end
+
+ # Find an `Answer` by its `id` or `null` if it could not be found
+ fun find_answer_by_id(id: Int): nullable Answer do
+ var req = select("* FROM answers WHERE id={id};")
+ for i in req do
+ return new Answer.from_db(i[0].to_i, i[2].to_s)
end
return null
end
# Change an Answer `ansid` for someone with an id `pid` to `resp`
#
# Returns `true` if the request was sucessful, false otherwise
- fun change_answer(pid: Int, ansid: Int, resp: Bool): Bool do
- var rsp = 0
- if resp then rsp = 1
- var rq = execute("INSERT OR REPLACE INTO part_answers(id_part, id_ans, value) VALUES({pid},{ansid},{rsp});")
- if not rq then
+ fun change_answer(pid: Int, ansid: Int, resp: Int): Bool do
+ var p = find_people_by_id(pid)
+ if p == null then
print "Error while updating answer {ansid}:{pid}"
- print error or else "Unknown error"
return false
end
- return true
+ var a = find_answer_by_id(ansid)
+ if a == null then
+ print "Error while updating answer {ansid}:{pid}"
+ return false
+ end
+ p.answers[a] = resp
+ if p.commit(self) then return true
+ return false
end
# Removes a person in the Database by its `id`
# Surname of the participant
var surname: String
# Map of the answers of a Meetup and the answers of the participant
- var answers: Map[Answer, Bool] = new HashMap[Answer, Bool]
+ # 0 = No
+ # 1 = Maybe
+ # 2 = Yes
+ var answers: Map[Answer, Int] = new HashMap[Answer, Int]
# To be used internally when fetching the `People` in Database
private init from_db(id: Int, name, surname: String) do
end
# Changes an answer `ans` (or adds it)
- fun answer=(ans: Answer, resp: Bool) do
+ fun answer=(ans: Answer, resp: Int) do
answers[ans] = resp
end
#
# NOTE: If `self` does not exist in the Database, no answers will be fetched
fun load_answers(db: OpportunityDB, meetup: Meetup) do
- self.answers = new HashMap[Answer, Bool]
- var req = db.select("answers.id, answers.name, part_answers.value FROM part_answers, answers WHERE part_answers.id_part={id} AND answers.id=part_answers.id_ans AND answers.meetup_id={meetup.id.to_sql_string} GROUP BY answers.id;")
+ self.answers = new HashMap[Answer, Int]
+ var req = db.select("answers.id, answers.name, part_answers.value FROM part_answers, answers WHERE part_answers.id_part={id} AND answers.id=part_answers.id_ans AND answers.meetup_id={meetup.id.html_escape.to_sql_string} GROUP BY answers.id;")
for i in req do
var ans = new Answer.from_db(i[0].to_i, i[1].to_s)
- answers[ans] = false
- if i[2].to_i == 1 then answers[ans] = true
+ answers[ans] = i[2].to_i
end
end
redef fun commit(db) do
if id == -1 then
- if not db.execute("INSERT INTO people (name,surname) VALUES ({name.to_sql_string}, {surname.to_sql_string});") then
+ if not db.execute("INSERT INTO people (name,surname) VALUES ({name.html_escape.to_sql_string}, {surname.html_escape.to_sql_string});") then
print "Error while adding people {self}"
print db.error or else "Unknown error"
return false
end
id = db.last_insert_rowid
else
- if not db.execute("UPDATE people SET name={name.to_sql_string}, surname={surname.to_sql_string} WHERE ID={id};") then
+ if not db.execute("UPDATE people SET name={name.html_escape.to_sql_string}, surname={surname.html_escape.to_sql_string} WHERE ID={id};") then
print "Error while updating people {self}"
print db.error or else "Unknown error"
return false
end
for i,j in answers do
if i.id == -1 then i.commit(db)
- var val = 0
- if j then val = 1
- if not db.execute("INSERT OR REPLACE INTO part_answers(id_part, id_ans, value) VALUES ({id},{i.id},{val});") then
- print("Error while adding/replacing part_answers {id}|{i.id}|{j}")
+ var val = j
+ var s = db.select("* FROM part_answers WHERE id_part={id} AND id_ans={i.id}")
+ if s != null and s.iterator.is_ok then
+ if not db.execute("UPDATE part_answers SET value={j} WHERE id_part={id} AND id_ans={i.id};") then
+ print "Error while updating part_answers {id}|{i.id} = {j}"
+ print db.error or else "Unknown error"
+ return false
+ end
+ continue
+ end
+ if not db.execute("INSERT INTO part_answers(id_part, id_ans, value) VALUES ({id},{i.id},{val});") then
+ print("Error while adding part_answers {id}|{i.id}|{j}")
print db.error or else "Unknown error"
return false
end
var date: String
# Place of the meetup
var place: String
+ # Mode of answering to the meetup (atm supports with or without Maybe)
+ var answer_mode: Int
# Builds the object with all the informations found in the database
- private init from_db(id, name, date, place: String) do
+ private init from_db(id, name, date, place: String, mode: Int) do
self.id = id
- self.name = name
- self.date = date
- self.place = place
+ init(name, date, place, mode)
end
# Gets the answers bound to the current `Meetup`
if id == "" then
var time = get_time
var tmpid = (name + date + place + time.to_s).sha1_to_s
- if not db.execute("INSERT INTO meetups (id, name, date, place) VALUES({tmpid.to_sql_string}, {name.to_sql_string}, {date.to_sql_string}, {place.to_sql_string});") then
+ if not db.execute("INSERT INTO meetups (id, name, date, place, answer_mode) VALUES({tmpid.to_sql_string}, {name.html_escape.to_sql_string}, {date.html_escape.to_sql_string}, {place.html_escape.to_sql_string}, {answer_mode});") then
print "Error recording entry Meetup {self}"
print db.error or else "Null error"
return false
id = tmpid
return true
else
- return db.execute("UPDATE meetups (name, date, place) VALUES({name.to_sql_string}, {date.to_sql_string}, {place.to_sql_string}) WHERE ID={id.to_sql_string};")
+ return db.execute("UPDATE meetups SET name={name.html_escape.to_sql_string}, date={date.html_escape.to_sql_string}, place={place.html_escape.to_sql_string}, answer_mode={answer_mode} WHERE ID={id.to_sql_string};")
end
end
self.id = id
end
+ redef fun hash do
+ if id != -1 then return id
+ return super
+ end
+
# Loads the Meetup associated to `self`
#
# REQUIRE: is loaded in database
assert id != -1
var res = db.select("meetups.* FROM meetups, answers WHERE answers.id={id} AND answers.meetup_id=meetups.id;")
for i in res do
- return new Meetup.from_db(i[0].to_s, i[1].to_s, i[2].to_s, i[3].to_s)
+ return new Meetup.from_db(i[0].to_s, i[1].to_s, i[2].to_s, i[3].to_s, i[4].to_i)
end
# If no Meetup could be loaded, the contract was not respected
abort
end
+ # Counts the number of positive or maybe answers
+ fun count(db: OpportunityDB): Int do
+ if id == -1 then return -1
+ var count = 0
+ var res = db.select("part_answers.value FROM part_answers WHERE part_answers.id_ans={id};")
+ if meetup == null then meetup = load_meetup(db)
+ for i in res do
+ if meetup.answer_mode == 0 then
+ count += i[0].to_i
+ else
+ if i[0].to_i == 2 then count += 1
+ end
+ end
+ return count
+ end
+
+ # Counts the score for this particular answer
+ fun score(db: OpportunityDB): Int do
+ if id == -1 then return -1
+ var score = 0
+ var res = db.select("part_answers.value FROM part_answers WHERE part_answers.id_ans={id};")
+ for i in res do
+ score += i[0].to_i
+ end
+ return score
+ end
+
redef fun commit(db) do
var m = meetup
if m == null then return false
end
end
if id == -1 then
- if not db.execute("INSERT INTO answers (name, meetup_id) VALUES({name.to_sql_string}, {m.id.to_sql_string});") then
+ if not db.execute("INSERT INTO answers (name, meetup_id) VALUES({name.html_escape.to_sql_string}, {m.id.to_sql_string});") then
print "Cannot create {self} in database"
print db.error or else "Unknown error"
return false
end
id = db.last_insert_rowid
else
- if not db.execute("UPDATE answers (name) VALUES ({name.to_sql_string}) WHERE meetup_id={m.id.to_sql_string};") then
+ if not db.execute("UPDATE answers SET name=({name.html_escape.to_sql_string}) WHERE meetup_id={m.id.to_sql_string};") then
print "Error updating {self} in database"
print db.error or else "Unknown error"
return false
# Meetup the page is supposed to show
var meetup: nullable Meetup = null
+ # Answer mode for the meetup
+ var mode = 0
init from_id(id: String) do
var db = new OpportunityDB.open("opportunity")
meetup = db.find_meetup_by_id(id)
db.close
+ if meetup != null then mode = meetup.answer_mode
+ init
end
init do
- header.page_js = """
+ header.page_js = "mode = {mode};\n"
+ header.page_js += """
+ function update_scores(){
+ var anss = $('.answer');
+ var count = {};
+ var scores = {};
+ var answers = [];
+ var maxscore = 0;
+ for(i=0; i < anss.length; i++){
+ var incscore = 0;
+ var inccount = 0;
+ var idparts = anss[i].id.split("_");
+ var ansid = idparts[1];
+ var html = anss[i].innerHTML;
+ if(html === "<center>✔</center>"){
+ inccount = 1;
+ incscore = 2;
+ }else if(html === "<center>❓</center>"){
+ incscore = 1;
+ }
+ var intansid = parseInt(ansid)
+ if(answers.indexOf(intansid) == -1){
+ answers.push(intansid);
+ }
+ if(ansid in count){
+ count[ansid] += inccount;
+ }else{
+ count[ansid] = inccount;
+ }
+ if(ansid in scores){
+ scores[ansid] += incscore;
+ }else{
+ scores[ansid] = incscore;
+ }
+ if(scores[ansid] > maxscore){
+ maxscore = scores[ansid];
+ }
+ }
+ for(i=0; i < answers.length; i++){
+ var ansid = answers[i].toString();
+ var el = $('#total'+ansid)[0];
+ var ins = "<center>"+count[ansid];
+ if(scores[ansid] >= maxscore){
+ ins += "<br/><span style=\\"color:blue\\">★</span>";
+ }
+ ins += "</center>";
+ el.innerHTML = ins;
+ }
+ }
function change_answer(ele, id){
// modify only the currently selected entry
if (in_modification_id != id) return;
var e = document.getElementById(ele.id);
var i = e.innerHTML;
- var ans = true;
+ var ans = true;"""
+ if mode == 0 then
+ header.page_js += """
if(i === "<center>✔</center>"){
- ans = false;
+ ans = 0;
e.innerHTML = "<center>✘</center>"
e.style.color = "red";
}else{
+ ans = 1;
e.innerHTML = "<center>✔</center>";
e.style.color = "green";
- }
+ }"""
+
+ else
+ header.page_js += """
+ if(i === "<center>✔</center>"){
+ ans = 1;
+ e.innerHTML = "<center>❓</center>"
+ e.style.color = "#B8860B";
+ }else if(i === "<center>❓</center>"){
+ ans = 0;
+ e.innerHTML = "<center>✘</center>"
+ e.style.color = "red";
+ }else{
+ ans = 2;
+ e.innerHTML = "<center>✔</center>";
+ e.style.color = "green";
+ }"""
+ end
+ header.page_js += """
var a = ele.id.split('_')
var pid = a[1]
var aid = a[2]
+ update_scores();
$.ajax({
type: "POST",
url: "./rest/answer",
}
function change_temp_answer(ele){
var e = document.getElementById(ele.id);
- var i = e.innerHTML;
- var ans = true;
+ var i = e.innerHTML;"""
+ if mode == 0 then
+ header.page_js += """
+ if(i === "<center>✔</center>"){
+ e.innerHTML = "<center>✘</center>"
+ e.style.color = "red";
+ }else{
+ e.innerHTML = "<center>✔</center>";
+ e.style.color = "green";
+ }
+ """
+ else
+ header.page_js += """
if(i === "<center>✔</center>"){
- ans = false;
- e.innerHTML = "<center>✘</center>";
+ e.innerHTML = "<center>❓</center>";
+ e.style.color = "#B8860B";
+ }else if(i === "<center>❓</center>"){
+ e.innerHTML = "<center>✘</center>"
e.style.color = "red";
}else{
e.innerHTML = "<center>✔</center>";
e.style.color = "green";
}
+ """
+ end
+ header.page_js += """
+ update_scores();
}
function add_part(ele){
var e = document.getElementById(ele.id);
ansmap = {};
for(i=0;i<ans.length;i++){
var curr = ans.eq(i)
+ """
+ if mode == 0 then
+ header.page_js += """
if(curr[0].innerHTML === "<center>✔</center>"){
- ansmap[curr.attr('id')] = true
+ ansmap[curr.attr('id')] = 1
}else{
- ansmap[curr.attr('id')] = false
- }
+ ansmap[curr.attr('id')] = 0
+ }"""
+ else
+ header.page_js += """
+ if(curr[0].innerHTML === "<center>✔</center>"){
+ ansmap[curr.attr('id')] = 2
+ }else if(curr[0].innerHTML === "<center>❓</center>"){
+ ansmap[curr.attr('id')] = 1
+ }else{
+ ansmap[curr.attr('id')] = 0
+ }"""
+ end
+ header.page_js += """
}
$.ajax({
type: "POST",
var arr = ele.id.split("_")
var pid = arr[1]
$('#' + ele.id).parent().parent().parent().remove();
+ update_scores();
$.ajax({
type: "POST",
url: "./rest/people",
}
});
}
-
// ID of line currently open for modification
var in_modification_id = null;
function modify_people(ele, id){
t.add "<td>"
t.add i.to_s
t.add "</td>"
- for j,k in i.answers do
+ for j, k in i.answers do
var color
- if k then
- color = "green"
- else color = "red"
-
+ if answer_mode == 0 then
+ if k == 1 then
+ color = "green"
+ else
+ color = "red"
+ end
+ else
+ if k == 2 then
+ color = "green"
+ else if k == 1 then
+ color = "#B8860B"
+ else
+ color = "red"
+ end
+ end
t.add """<td class="answer" onclick="change_answer(this, {{{i.id}}})" id="answer_{{{j.id}}}_{{{i.id}}}" style="color:{{{color}}}">"""
t.add "<center>"
- if k then
- t.add "✔"
+ if answer_mode == 0 then
+ if k == 1 then
+ t.add "✔"
+ else
+ t.add "✘"
+ end
else
- t.add "✘"
+ if k == 2 then
+ t.add "✔"
+ else if k == 1 then
+ t.add "❓"
+ else
+ t.add "✘"
+ end
end
t.add "</center></td>"
end
t.add """
<td><center><span id="add_{{{id}}}" onclick="add_part(this)" style="color:green;" class="action"><button class="btn btn-xs btn-success" type="button">Done</button></span></center></td>"""
t.add "</tr>"
+ # Compute score for each answer
+ var scores = new HashMap[Int, Int]
+ var maxsc = 0
+ for i in answers(db) do
+ scores[i.id] = i.score(db)
+ if scores[i.id] > maxsc then maxsc = scores[i.id]
+ end
+ t.add """
+<tr id="total">
+ <th>Total</th>
+ """
+ for i in answers(db) do
+ t.add """<th id="total{{{i.id}}}"><center>{{{i.count(db)}}}"""
+ if scores.has_key(i.id) and scores[i.id] >= maxsc then
+ t.add """<br/><span style="color:blue">★</span>"""
+ end
+ t.add "</center></th>"
+ end
+ t.add "</th>"
+ t.add """
+ <th></th>
+</tr>"""
t.add "</table>"
t.add "</div>"
return t