def get(self): """Return base data set required by the web client.""" if not is_cache_filler(): logger.info("Cache miss for {}".format(request.path)) rv = {"data": dict()} # Elections try: elections = db.session.query(Election).all() except SQLAlchemyError as e: logger.error(e) return json_response({"error": "Server Error"}) rv["data"]["elections"] = defaultdict(list) for election in elections: rv["data"]["elections"][election.territory].append( election.to_dict(thesis_data=False)) # Tags tagItems = (db.session.query(Tag, func.count(Thesis.id)).join( Tag.theses).group_by(Tag.title).all()) rv["data"]["tags"] = [ item[0].to_dict( thesis_count=item[1], query_root_status=True, include_related_tags="simple", ) for item in tagItems ] return json_response(rv)
def delete(self, slug: str): admin_key = request.get_json().get("admin_key", "") if admin_key != current_app.config.get("ADMIN_KEY"): logger.warning("Invalid admin password") return json_response({"error": "Invalid admin password"}, status=401) tag = db.session.query(Tag).filter(Tag.slug == slug).first() if tag is None: return json_response({"error": "Tag not found"}, status=404) logger.warning("Removing {}".format(tag)) db.session.delete(tag) db.session.commit() rv = { "data": tag.to_dict(include_related_tags="full"), "theses": [thesis.to_dict() for thesis in tag.theses], "elections": { thesis.election_id: thesis.election.to_dict() for thesis in tag.theses }, } return json_response(rv)
def post(self, thesis_id: str): log_request_info("Thesis tags update", request) thesis = db.session.query(Thesis).get(thesis_id) data = request.get_json() error = None if thesis is None: return json_response({"error": "Thesis not found"}, status=404) if data is None or data.get("admin_key", "") != current_app.config.get("ADMIN_KEY"): logger.warning("Invalid admin key") error = "Invalid admin key" else: for tag_data in data.get("add", []): tag = (db.session.query(Tag).filter( Tag.wikidata_id == tag_data["wikidata_id"]).first()) if tag is None: tag = db.session.query(Tag).filter_by( title=tag_data["title"]).first() if tag is None: tag = Tag( description=tag_data.get("description", None), title=tag_data["title"], url=tag_data["url"], wikidata_id=tag_data["wikidata_id"], image=tag_data.get("image", None), ) tag.make_slug() logger.info("New tag {}".format(tag)) tag.wikipedia_title = tag_data.get("wikipedia_title", None) tag.labels = ";".join(tag_data.get("labels", [])) tag.aliases = ";".join(tag_data.get("aliases", [])) logger.info("Appending {} to {}".format(tag, thesis)) thesis.tags.append(tag) if len(data.get("remove", [])) > 0: logger.info("Removing tags {}".format(", ".join( data.get("remove")))) thesis.tags = [ tag for tag in thesis.tags if tag.title not in data.get("remove") ] db.session.add(thesis) db.session.commit() if error is not None: return json_response({"error": error}) else: return json_response({"data": thesis.to_dict(), "error": error})
def get(self, thesis_id: str): """Return metadata for a specific thesis.""" if not is_cache_filler(): logger.info("Cache miss for {}".format(request.path)) thesis = Thesis.query.get(thesis_id) if thesis is None: return json_response({"error": "Thesis not found"}, status=404) rv = {"data": thesis.to_dict(), "related": thesis.related()} return json_response(rv)
def get(self, election_num, thesis_num=None): """Return a tally of how many users guessed yes/no for each thesis""" rv = {} error = None election = Election.query.get(election_num) if election is None: return json_response({"error": "Election not found"}, status=404) for thesis in election.theses: thesis_num = int(thesis.id[-2:]) rv[thesis_num] = thesis.quiz_tally() return json_response({"error": error, "data": rv})
def get(self, filename=None): """List all tags.""" if not is_cache_filler(): logger.info("Cache miss for {}".format(request.path)) if request.args.get("include_theses_ids", False) or filename != None: results = (db.session.query(Tag).join(Tag.theses).group_by( Tag.title).order_by(Tag.title).all()) rv = { "data": [tag.to_dict(include_theses_ids=True) for tag in results] } else: results = (db.session.query(Tag, func.count(Thesis.id)).join( Tag.theses).group_by(Tag.title).all()) rv = { "data": [item[0].to_dict(thesis_count=item[1]) for item in results] } return json_response(rv, filename=filename)
def get(self, wom_id: int): """Election data and a list of its theses.""" if not is_cache_filler(): logger.info("Cache miss for {}".format(request.path)) election = Election.query.get(wom_id) if election is None: return json_response({"error": "Election not found"}, status=404) rv = { "data": election.to_dict(), "theses": [thesis.to_dict() for thesis in election.theses], } return json_response(rv)
def post(self, election_num, thesis_num=None): """Record an answer given by a user in a quiz.""" if thesis_num == None: return json_response( {"error": "Missing path parameter for thesis number"}, status=422) log_request_info("Quiz answer post", request) rv = None error = None status = 200 thesis_id = "WOM-{:03d}-{:02d}".format(election_num, thesis_num) data = request.get_json() if data is not None: uuid = data.get("uuid", None) answer = data.get("answer", None) if data is None or uuid is None or answer is None: logger.warning("Request missing data: {}".format(data)) error = "The request is missing data" status = 422 else: thesis = Thesis.query.get(thesis_id) if thesis is None: error = "Thesis not found" status = 404 else: qa = QuizAnswer(uuid=uuid, answer=answer, thesis=thesis) try: db.session.add(qa) db.session.commit() except IntegrityError: error = "Ignored duplicate quiz answer" logger.info("Ignored duplicate quiz answer") else: logger.info("Added {}".format(qa)) if error is None: rv = qa.to_dict() return json_response({"error": error, "data": rv}, status=status)
def get(self, slug: str): """Tag metadata, list of all related theses and their elections.""" if not is_cache_filler(): logger.info("Cache miss for {}".format(request.path)) tag = db.session.query(Tag).filter(Tag.slug == slug.lower()).first() if tag is None: return json_response({"error": "Tag not found"}, status=404) rv = { "data": tag.to_dict(include_related_tags="full"), "theses": [thesis.to_dict() for thesis in tag.theses], "elections": { thesis.election_id: thesis.election.to_dict() for thesis in tag.theses }, } return json_response(rv)
def get(self): """A list of all elections.""" if not is_cache_filler(): logger.info("Cache miss for {}".format(request.path)) try: elections = Election.query.all() except SQLAlchemyError as e: logger.error(e) return json_response({"error": "Server Error"}) thesis_data = request.args.get("thesis_data", False) rv = {"data": defaultdict(list)} for election in elections: rv["data"][election.territory].append( election.to_dict(thesis_data=thesis_data)) return json_response(rv)
def exceptions(e): ts = datetime.utcnow().strftime("[%Y-%b-%d %H:%M]") tb = traceback.format_exc() logger.error( "%s %s %s %s %s 5xx INTERNAL SERVER ERROR\n%s", ts, request.remote_addr, request.method, request.scheme, request.full_path, tb, ) return json_response( { "error": "AAAHH! Serverfehler. Rute ist gezückt, Computer wird bestraft." }, status=500, )
def page_not_found(e): return json_response({"error": "Ressource not found"}, status=404)