Example #1
0
    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)
Example #2
0
    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)
Example #3
0
    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})
Example #4
0
    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)
Example #5
0
    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})
Example #6
0
    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)
Example #7
0
    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)
Example #8
0
    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)
Example #9
0
    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)
Example #10
0
    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)
Example #11
0
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,
    )
Example #12
0
def page_not_found(e):
    return json_response({"error": "Ressource not found"}, status=404)