Exemplo n.º 1
0
    def create(self, data=None, commit=True):
        if data is None:
            data = request.json or {}

        handle_password(data)

        status, = db_session.execute(
            "SELECT GET_LOCK('member_number', 20)").fetchone()
        if not status:
            raise InternalServerError(
                "Failed to create member, try again later.",
                log="failed to aquire member_number lock")
        try:
            if data.get('member_number') is None:
                sql = "SELECT COALESCE(MAX(member_number), 999) FROM membership_members"
                max_member_number, = db_session.execute(sql).fetchone()
                data['member_number'] = max_member_number + 1
            obj = self.to_obj(self._create_internal(data, commit=commit))
            return obj
        except Exception:
            # Rollback session if anything went wrong or we can't release the lock.
            db_session.rollback()
            raise
        finally:
            db_session.execute("DO RELEASE_LOCK('member_number')")
Exemplo n.º 2
0
 def register_login_success(ip, user_id):
     db_session.execute(
         "INSERT INTO login (success, user_id, ip) VALUES (1, :user_id, :ip)",
         {
             'user_id': user_id,
             'ip': ip
         })
Exemplo n.º 3
0
 def get_failed_login_count(ip):
     count, = db_session.execute(
         "SELECT count(1) FROM login"
         "   WHERE ip = :ip AND NOT success AND date >= DATE_SUB(NOW(), INTERVAL 1 HOUR)",
         {
             'ip': ip
         }).fetchone()
     return count
Exemplo n.º 4
0
 def create(self, data=None, commit=True):
     if data is None:
         data = request.json or {}
     
     status, = db_session.execute("SELECT GET_LOCK('display_order', 20)").fetchone()
     if not status:
         raise InternalServerError("Failed to create, try again later.",
                                   log="failed to aquire display_order lock")
     try:
         if data.get('display_order') is None:
             data['display_order'] = (db_session.query(func.max(self.model.display_order)).scalar() or 0) + 1
         obj = self.to_obj(self._create_internal(data, commit=commit))
         return obj
     except Exception:
         # Rollback session if anything went wrong or we can't release the lock.
         db_session.rollback()
         raise
     finally:
         db_session.execute("DO RELEASE_LOCK('display_order')")
Exemplo n.º 5
0
def commit_transaction_to_db(member_id=None,
                             total_amount=None,
                             contents=None,
                             stripe_card_source_id=None,
                             activates_member=False):
    """ Save as new transaction with transaction content in db and return it transaction. """

    transaction = Transaction(member_id=member_id,
                              amount=total_amount,
                              status=Transaction.PENDING)

    db_session.add(transaction)
    db_session.flush()

    for content in contents:
        content.transaction_id = transaction.id
        db_session.add(content)
        db_session.flush()

        db_session.execute(
            """
            INSERT INTO webshop_transaction_actions (content_id, action_type, value, status)
            SELECT :content_id AS content_id, action_type, SUM(:count * value) AS value, :pending AS status
            FROM webshop_product_actions WHERE product_id=:product_id AND deleted_at IS NULL GROUP BY action_type
            """, {
                'content_id': content.id,
                'count': content.count,
                'pending': TransactionAction.PENDING,
                'product_id': content.product_id
            })

    if activates_member:
        # Mark this transaction as one that is for registering a member.
        db_session.add(PendingRegistration(transaction_id=transaction.id))

    db_session.add(
        StripePending(transaction_id=transaction.id,
                      stripe_token=stripe_card_source_id))

    return transaction
Exemplo n.º 6
0
 def get_member_number(self):
     # Ugly but will work most of the time.
     sql = "SELECT COALESCE(MAX(member_number), 0) FROM membership_members"
     member_number = db_session.execute(sql).fetchone()[0] + randint(1000, 2000)
     return member_number
Exemplo n.º 7
0
def quiz_statistics(quiz_id: int):
    # How many members have answered the quiz that should have

    # Correct percentage per question
    # Average correct percentage per member

    questions = db_session.query(QuizQuestion).filter(
        QuizQuestion.deleted_at == None, QuizQuestionOption.deleted_at == None,
        QuizQuestion.quiz_id == quiz_id).join(QuizQuestion.options).all()

    # Note: counts each member at most once per question. So multiple mistakes on the same question are not counted
    incorrect_answers_by_question = mapify(
        db_session.query(QuizAnswer.question_id,
                         func.count(distinct(QuizAnswer.member_id))).join(
                             QuizAnswer.question).filter(
                                 QuizQuestion.quiz_id == quiz_id).filter(
                                     QuizAnswer.correct == False).group_by(
                                         QuizAnswer.question_id).all())
    answers_by_question = mapify(
        db_session.query(QuizAnswer.question_id,
                         func.count(distinct(QuizAnswer.member_id))).join(
                             QuizAnswer.question).filter(
                                 QuizQuestion.quiz_id).filter(
                                     QuizAnswer.deleted_at == None).group_by(
                                         QuizAnswer.question_id).all())

    first_answer_by_member = db_session.query(
        QuizAnswer.member_id, QuizAnswer.question_id,
        func.min(QuizAnswer.id).label("id")).filter(
            QuizAnswer.deleted_at == None).group_by(
                QuizAnswer.member_id, QuizAnswer.question_id).subquery()

    answers_by_option = mapify(
        db_session.query(QuizAnswer.option_id, func.count(distinct(QuizAnswer.member_id))) \
        .join(first_answer_by_member, (QuizAnswer.question_id == first_answer_by_member.c.question_id) & (QuizAnswer.member_id == first_answer_by_member.c.member_id)) \
        .join(QuizAnswer.question)
        .filter(QuizAnswer.id == first_answer_by_member.c.id) \
        .filter(QuizQuestion.quiz_id == quiz_id)
        .group_by(QuizAnswer.option_id) \
        .all()
    )

    seconds_to_answer_quiz = list(
        db_session.execute(
            "select TIME_TO_SEC(TIMEDIFF(max(quiz_answers.created_at), min(quiz_answers.created_at))) as t from quiz_answers JOIN quiz_questions ON question_id=quiz_questions.id where quiz_questions.quiz_id=:quiz_id group by member_id order by t asc;",
            {"quiz_id": quiz_id}))
    print(seconds_to_answer_quiz)
    median_seconds_to_answer_quiz = seconds_to_answer_quiz[
        len(seconds_to_answer_quiz) //
        2][0] if len(seconds_to_answer_quiz) > 0 else 0

    return {
        "median_seconds_to_answer_quiz":
        median_seconds_to_answer_quiz,
        # Maximum number members that have answered any question.
        # This ensures we also account for questions added later (which may not have as many answers)
        # We iterate through the questions list to ensure we dont count deleted questions
        "answered_quiz_member_count":
        max([
            answers_by_question.get(question.id, 0) for question in questions
        ]),
        "questions": [
            {
                "question":
                quiz_question_entity.to_obj(question),
                "options": [{
                    "answer_count":
                    answers_by_option.get(option.id, 0),
                    "option":
                    quiz_question_option_entity.to_obj(option)
                } for option in question.options],
                # Number of unique members that have answered this question
                "member_answer_count":
                answers_by_question.get(question.id, 0),
                "incorrect_answer_fraction":
                sum(
                    answers_by_option.get(option.id, 0)
                    for option in question.options if not option.correct) /
                answers_by_question.get(question.id, 1),
            } for question in questions
        ]
    }
Exemplo n.º 8
0
 def remove(self, entity_ids, related_entity_id):
     for entity_id in entity_ids:
         db_session.execute(self.delete, {
             'entity_id': entity_id,
             'related_entity_id': related_entity_id
         })
Exemplo n.º 9
0
 def add(self, entity_ids, related_entity_id):
     for entity_id in entity_ids:
         db_session.execute(self.insert, {
             'entity_id': entity_id,
             'related_entity_id': related_entity_id
         })
Exemplo n.º 10
0
 def register_login_failed(ip):
     db_session.execute("INSERT INTO login (success, ip) VALUES (0, :ip)",
                        {'ip': ip})