|  | 
| 2 | 2 | from flask_jwt_extended import get_current_user, jwt_optional | 
| 3 | 3 | from flask_mail import Message | 
| 4 | 4 | from itsdangerous import URLSafeSerializer | 
|  | 5 | +from sqlalchemy import or_ | 
| 5 | 6 | 
 | 
| 6 | 7 | from .. import core | 
| 7 | 8 | from ..auth import Users | 
| @@ -49,25 +50,14 @@ def get_contestants(): | 
| 49 | 50 |  contestants = [] | 
| 50 | 51 |  for ans in p.items: # type: Answer | 
| 51 | 52 | 
 | 
| 52 |  | - display = None | 
| 53 |  | - if ans.user.studentfirstname \ | 
| 54 |  | - and ans.user.studentlastname: | 
| 55 |  | - display = f"{ans.user.studentfirstname} " \ | 
| 56 |  | - f"{ans.user.studentlastname[0]}." | 
| 57 |  | - | 
| 58 |  | - confirmed_votes = [] | 
| 59 |  | - for v in ans.votes: | 
| 60 |  | - if v.confirmed: | 
| 61 |  | - confirmed_votes.append(v) | 
| 62 |  | - | 
| 63 | 53 |  contestants.append(dict( | 
| 64 | 54 |  id=ans.id, | 
| 65 | 55 |  text=ans.text, | 
| 66 |  | - numVotes=len(confirmed_votes), | 
|  | 56 | + numVotes=ans.confirmed_votes(), | 
| 67 | 57 |  firstName=ans.user.studentfirstname, | 
| 68 | 58 |  lastName=ans.user.studentlastname, | 
| 69 | 59 |  username=ans.user.username, | 
| 70 |  | - display=display | 
|  | 60 | + display=ans.user.display() | 
| 71 | 61 |  )) | 
| 72 | 62 | 
 | 
| 73 | 63 |  return jsonify( | 
| @@ -188,3 +178,51 @@ def vote_confirm(): | 
| 188 | 178 | 
 | 
| 189 | 179 |  return jsonify(status="success", | 
| 190 | 180 |  reason="vote confirmed") | 
|  | 181 | + | 
|  | 182 | + | 
|  | 183 | +@bp.route("/search", methods=["GET"]) | 
|  | 184 | +def search(): | 
|  | 185 | + keyword = request.args.get("q") | 
|  | 186 | + try: | 
|  | 187 | + page = int(request.args.get("page", 1)) | 
|  | 188 | + per = int(request.args.get("per", 20)) | 
|  | 189 | + except ValueError: | 
|  | 190 | + return jsonify(status="error", | 
|  | 191 | + reason="invalid 'page' or 'per' parameter"), 400 | 
|  | 192 | + | 
|  | 193 | + if keyword is None: | 
|  | 194 | + return jsonify(status="error", reason="missing 'q' parameter"), 400 | 
|  | 195 | + | 
|  | 196 | + keyword = f"%{keyword}%" | 
|  | 197 | + | 
|  | 198 | + p = Answer.query \ | 
|  | 199 | + .join(Answer.question) \ | 
|  | 200 | + .join(Answer.user) \ | 
|  | 201 | + .filter(Question.rank == core.max_rank(), | 
|  | 202 | + Answer.correct, or_(Users.username.ilike(keyword), Users.studentlastname.ilike(keyword), | 
|  | 203 | + Users.studentlastname.ilike(keyword))) \ | 
|  | 204 | + .paginate(page=page, per_page=per) | 
|  | 205 | + | 
|  | 206 | + results = [] | 
|  | 207 | + | 
|  | 208 | + for ans in p.items: # type: Answer | 
|  | 209 | + results.append(dict( | 
|  | 210 | + id=ans.id, | 
|  | 211 | + text=ans.text, | 
|  | 212 | + numVotes=ans.confirmed_votes(), | 
|  | 213 | + firstName=ans.user.studentfirstname, | 
|  | 214 | + lastName=ans.user.studentlastname, | 
|  | 215 | + username=ans.user.username, | 
|  | 216 | + display=ans.user.display() | 
|  | 217 | + )) | 
|  | 218 | + | 
|  | 219 | + return jsonify( | 
|  | 220 | + items=results, | 
|  | 221 | + totalItems=p.total, | 
|  | 222 | + page=p.page, | 
|  | 223 | + totalPages=p.pages, | 
|  | 224 | + hasNext=p.has_next, | 
|  | 225 | + nextNum=p.next_num, | 
|  | 226 | + hasPrev=p.has_prev, | 
|  | 227 | + prevNum=p.prev_num | 
|  | 228 | + ) | 
0 commit comments