Esempio n. 1
0
def box_terminator_nag(member_number=None, box_label_id=None, nag_type=None):
    try:
        box = db_session.query(Box).filter(
            Box.box_label_id == box_label_id,
            Member.member_number == member_number).one()
    except NoResultFound:
        raise NotFound("Bloop, lådan finns i Lettland")

    try:
        template = {
            "nag-warning": MessageTemplate.BOX_WARNING,
            "nag-last-warning": MessageTemplate.BOX_FINAL_WARNING,
            "nag-terminated": MessageTemplate.BOX_TERMINATED,
        }[nag_type]

    except KeyError:
        raise BadRequest(f"Bad nag type {nag_type}")

    today = date.today()
    end_date = get_labacess_end_date(box)
    terminate_date = get_expire_date_from_labaccess_end_date(end_date)

    send_message(
        template,
        box.member,
        labaccess_end_date=date_to_str(end_date),
        to_termination_days=(terminate_date - today).days,
        days_after_expiration=(today - end_date).days,
    )

    box.last_nag_at = datetime.utcnow()
Esempio n. 2
0
def send_membership_updated_email(member_id, extended_days, end_date):
    member = db_session.query(Member).get(member_id)

    send_message(MessageTemplate.ADD_MEMBERSHIP_TIME,
                 member,
                 extended_days=extended_days,
                 end_date=date_to_str(end_date))
Esempio n. 3
0
def send_key_updated_email(member_id, extended_days, end_date):
    member = db_session.query(Member).get(member_id)

    send_message(MessageTemplate.ADD_LABACCESS_TIME,
                 member,
                 extended_days=extended_days,
                 end_date=date_to_str(end_date))
Esempio n. 4
0
def send_receipt_email(transaction):
    contents = transaction.contents
    products = [content.product for content in contents]

    send_message(
        MessageTemplate.RECEIPT,
        transaction.member,
        cart=list(zip(products, contents)),
        transaction=transaction,
        currency="kr",
    )
Esempio n. 5
0
def request_password_reset(user_identification):
    member = get_member_by_user_identification(user_identification)

    token = generate_token()

    db_session.add(PasswordResetToken(member_id=member.member_id, token=token))
    db_session.flush()

    send_message(
        MessageTemplate.PASSWORD_RESET,
        member,
        url=config.get_admin_url(
            f"/password-reset?reset_token={quote_plus(token)}"),
    )
Esempio n. 6
0
def membership_reminder():
    now = datetime.utcnow().date()

    members, memberships = get_members_and_membership()
    members = list(members)
    end_date_reminder_target = now + timedelta(
        days=MEMBERSHIP_REMINDER_DAYS_BEFORE)

    for member, membership in zip(members, memberships):
        if membership.membership_end is None:
            # Not a member
            continue

        if membership.membership_end < now and not membership.effective_labaccess_active:
            # Membership already expired
            # If the member has labaccess active then the member has likely forgot to renew the yearly membership.
            # Having a yearly membership is a requirement for being allowed to purchase lab membership.
            continue

        if membership.membership_end > end_date_reminder_target:
            # Membership is valid for a long time
            continue

        # Don't send a reminder if we sent a reminder the last 28 days.
        if already_sent_message(MessageTemplate.MEMBERSHIP_REMINDER, member,
                                MEMBERSHIP_REMINDER_GRACE_PERIOD):
            continue

        already_purchased = \
            pending_action_value_sum(member_id=member.member_id, action_type=ProductAction.ADD_MEMBERSHIP_DAYS) > 0
        if already_purchased:
            # Member has already purchased extra membership
            continue

        url = get_login_link(member, "membership reminder", "/shop")

        send_message(
            template=MessageTemplate.MEMBERSHIP_REMINDER,
            member=member,
            url=url,
            db_session=db_session,
            render_template=render_template,
            expiration_date=membership.membership_end,
        )

        logger.info(
            f'sending yearly membership reminder to member with id {member.member_id}. Expires '
            + str(membership.membership_end))
Esempio n. 7
0
def labaccess_reminder(render_template):
    now = datetime.utcnow()

    end_date_reminder_target = now.date() + timedelta(
        days=LABACCESS_REMINDER_DAYS_BEFORE)

    query = db_session.query(Member)
    query = query.join(Span)
    query = query.filter(
        Member.deleted_at.is_(None),
        Span.type == Span.LABACCESS,
        Span.deleted_at.is_(None),
        Span.enddate == end_date_reminder_target,
    )

    for member in query:
        # We have a candidate, now check if we should send a reminder.

        # First double check the end date so we don't send reminder if there is another span further in the future.
        end_date = db_session.query(func.max(Span.enddate)).filter(
            Span.member == member, Span.type == Span.LABACCESS,
            Span.deleted_at.is_(None)).scalar()
        if end_date != end_date_reminder_target:
            continue

        # Don't send a reminder if we sent a reminder the last 28 days.
        if already_sent_message(MessageTemplate.LABACCESS_REMINDER, member,
                                LABACCESS_REMINDER_GRACE_PERIOD):
            continue

        already_purchased = \
            pending_action_value_sum(member_id=member.member_id, action_type=ProductAction.ADD_LABACCESS_DAYS) > 0
        if already_purchased:
            continue

        logger.info(
            f'sending labaccess reminder to member with id {member.member_id}')

        send_message(
            template=MessageTemplate.LABACCESS_REMINDER,
            member=member,
            db_session=db_session,
            render_template=render_template,
            expiration_date=end_date,
        )
Esempio n. 8
0
def send_access_token_email(redirect, user_identification, ip, browser):
    member = get_member_by_user_identification(user_identification)

    access_token = create_access_token(ip, browser,
                                       member.member_id)['access_token']

    url = config.get_public_url(f"/member/login/{access_token}?redirect=" +
                                quote_plus(redirect))

    logger.info(f"sending login link {url!r} to member_id {member.member_id}")

    send_message(
        MessageTemplate.LOGIN_LINK,
        member,
        url=url,
        now=format_datetime(datetime.now()),
    )

    return {"status": "sent"}
Esempio n. 9
0
def quiz_reminders():
    # Assume quiz 1 is the get started quiz
    quiz_id = 1
    quiz_members = quiz_member_answer_stats(quiz_id)
    now = datetime.utcnow()

    members, memberships = get_members_and_membership()
    id_to_member = {
        member.member_id: (member, membership)
        for member, membership in zip(members, memberships)
    }

    # Get all pending shop actions and check which members have pending purchases of lab access
    actions = pending_actions()
    members_with_pending_labaccess = set()
    for action in actions:
        if action["action"]["action"] == "add_labaccess_days" and action[
                "action"]["value"] > 0:
            members_with_pending_labaccess.add(action["member_id"])

    recently_sent_messages_by_member = set(
        x[0] for x in db_session.query(Message.member_id).filter(
            ((Message.template == MessageTemplate.QUIZ_FIRST_NEWMEMBER.value)
             & (now - timedelta(days=QUIZ_DAYS_FROM_FIRST_EMAIL_TO_REMINDER) <
                Message.created_at))
            | ((Message.template == MessageTemplate.QUIZ_FIRST_OLDMEMBER.value)
               & (now - timedelta(days=QUIZ_DAYS_FROM_FIRST_EMAIL_TO_REMINDER)
                  < Message.created_at))
            | ((Message.template == MessageTemplate.QUIZ_REMINDER.value)
               & (now - timedelta(days=QUIZ_DAYS_BETWEEN_REMINDERS) <
                  Message.created_at))).group_by(Message.member_id).all())

    sent_first_message_by_member = set(
        x[0] for x in db_session.query(Message.member_id).filter(
            (Message.template == MessageTemplate.QUIZ_FIRST_NEWMEMBER.value)
            | (Message.template == MessageTemplate.QUIZ_FIRST_OLDMEMBER.value)
        ).group_by(Message.member_id).all())

    for quiz_member in quiz_members:
        if quiz_member.remaining_questions > 0:
            member, membership = id_to_member.get(quiz_member.member_id)
            # Shouldn't really happen, but best check (db race conditions might cause it I guess)
            if member is None:
                continue

            # We need an email
            if member.email is None or len(member.email) == 0:
                continue

            # Check if the member has any pending purchase of lab access (important to ensure new members get the quiz before the key handout if possible)
            pending_labaccess = member.member_id in members_with_pending_labaccess

            # Only send messages to members whose labaccess is active or pending
            if not (membership.effective_labaccess_active
                    or pending_labaccess):
                continue

            # Check if a message has already been sent within given time periods
            if member.member_id in recently_sent_messages_by_member:
                continue

            firstmessage_sent = member.member_id in sent_first_message_by_member

            template = MessageTemplate.QUIZ_REMINDER
            if not firstmessage_sent:
                # An old member has been member for more than 30 days.
                # The oldmember template was used when the quiz was first introduced to give
                # existing members a customized message.
                # It also applies to those who haven't been members for a long time and become members again.
                is_oldmember = member.created_at < now - timedelta(days=14)
                if is_oldmember:
                    template = MessageTemplate.QUIZ_FIRST_OLDMEMBER
                    # Ignore old members. We don't send the quiz to them right now
                    continue
                else:
                    template = MessageTemplate.QUIZ_FIRST_NEWMEMBER

            url = get_login_link(member, "automatic quiz reminder",
                                 "/member/quiz/1")

            send_message(
                template=template,
                member=member,
                db_session=db_session,
                render_template=render_template,
                remaining_questions=quiz_member.remaining_questions,
                correctly_answered_questions=quiz_member.
                correctly_answered_questions,
                url=url,
            )
Esempio n. 10
0
def send_new_member_email(member):
    send_message(
        MessageTemplate.NEW_MEMBER,
        member,
    )