Пример #1
0
def get_template_statistics_for_7_days(limit_days, service_id):
    cache_key = cache_key_for_service_template_counter(service_id)
    template_stats_by_id = redis_store.get_all_from_hash(cache_key)
    if not template_stats_by_id:
        stats = dao_get_template_usage(service_id, limit_days=limit_days)
        cache_values = dict([(x.template_id, x.count) for x in stats])
        if cache_values:
            redis_store.set_hash_and_expire(
                cache_key, cache_values,
                current_app.config['EXPIRE_CACHE_TEN_MINUTES'])
    else:
        stats = dao_get_templates_for_cache(template_stats_by_id.items())
    return stats
Пример #2
0
def _get_template_statistics_for_last_n_days(service_id, whole_days):
    template_stats_by_id = Counter()

    # 0 whole_days = last 1 days (ie since midnight today) = today.
    # 7 whole days = last 8 days (ie since midnight this day last week) = a week and a bit
    for day in last_n_days(whole_days + 1):
        # "{SERVICE_ID}-template-usage-{YYYY-MM-DD}"
        key = cache_key_for_service_template_usage_per_day(service_id, day)
        stats = redis_store.get_all_from_hash(key)
        if stats:
            stats = {k.decode('utf-8'): int(v) for k, v in stats.items()}
        else:
            # key didn't exist (or redis was down) - lets populate from DB.
            stats = {
                str(row.id): row.count
                for row in dao_get_template_usage(service_id, day=day)
            }
            # if there is data in db, but not in redis - lets put it in redis so we don't have to do
            # this calc again next time. If there isn't any data, we can't put it in redis.
            # Zero length hashes aren't a thing in redis. (There'll only be no data if the service has no templates)
            # Nothing is stored if redis is down.
            if stats:
                redis_store.set_hash_and_expire(
                    key, stats, current_app.config['EXPIRE_CACHE_EIGHT_DAYS'])
        template_stats_by_id += Counter(stats)

    # attach count from stats to name/type/etc from database
    template_details = dao_get_multiple_template_details(
        template_stats_by_id.keys())
    return [
        {
            'count': template_stats_by_id[str(template.id)],
            'template_id': str(template.id),
            'template_name': template.name,
            'template_type': template.template_type,
            'is_precompiled_letter': template.is_precompiled_letter
        } for template in template_details
        # we don't want to return templates with no count to the front-end,
        # but they're returned from the DB and might be put in redis like that (if there was no data that day)
        if template_stats_by_id[str(template.id)] != 0
    ]
Пример #3
0
def persist_notification(
    *,
    template_id,
    template_version,
    recipient,
    service,
    personalisation,
    notification_type,
    api_key_id,
    key_type,
    created_at=None,
    job_id=None,
    job_row_number=None,
    reference=None,
    client_reference=None,
    notification_id=None,
    simulated=False,
    created_by_id=None,
    status=NOTIFICATION_CREATED,
    reply_to_text=None,
    status_callback_url=None,
    status_callback_bearer_token=None,
):
    notification_created_at = created_at or datetime.utcnow()
    if not notification_id:
        notification_id = uuid.uuid4()
    notification = Notification(
        id=notification_id,
        template_id=template_id,
        template_version=template_version,
        to=recipient,
        service_id=service.id,
        service=service,
        personalisation=personalisation,
        notification_type=notification_type,
        api_key_id=api_key_id,
        key_type=key_type,
        created_at=notification_created_at,
        job_id=job_id,
        job_row_number=job_row_number,
        client_reference=client_reference,
        reference=reference,
        created_by_id=created_by_id,
        status=status,
        reply_to_text=reply_to_text,
        status_callback_url=status_callback_url,
        status_callback_bearer_token=status_callback_bearer_token,
    )

    if notification_type == SMS_TYPE:
        formatted_recipient = validate_and_format_phone_number_and_allow_international(
            recipient)
        recipient_info = get_international_phone_info(formatted_recipient)
        notification.normalised_to = formatted_recipient
        notification.international = recipient_info.international
        notification.phone_prefix = recipient_info.country_prefix
        notification.rate_multiplier = recipient_info.billable_units

        # We can't use a sender name/ID if the text is sending to an
        # international number. At the time of writing, this is because Telstra
        # won't send to an international number unless sending from the number
        # associated with the subscription. Additionally, Twilio can send from a
        # sender name/ID, however, it requires configuration and it depends on
        # the countries in play.
        if notification.international:
            notification.reply_to_text = None

    elif notification_type == EMAIL_TYPE:
        notification.normalised_to = format_email_address(notification.to)

    # if simulated create a Notification model to return but do not persist the Notification to the dB
    if not simulated:
        dao_create_notification(notification)
        if key_type != KEY_TYPE_TEST:
            if redis_store.get(redis.daily_limit_cache_key(service.id)):
                redis_store.incr(redis.daily_limit_cache_key(service.id))
            if redis_store.get_all_from_hash(
                    cache_key_for_service_template_counter(service.id)):
                redis_store.increment_hash_value(
                    cache_key_for_service_template_counter(service.id),
                    template_id)

            increment_template_usage_cache(service.id, template_id,
                                           notification_created_at)

        current_app.logger.info("{} {} created at {}".format(
            notification_type, notification_id, notification_created_at))
    return notification
def persist_notification(*,
                         template_id,
                         template_version,
                         recipient,
                         service,
                         personalisation,
                         notification_type,
                         api_key_id,
                         key_type,
                         created_at=None,
                         job_id=None,
                         job_row_number=None,
                         reference=None,
                         client_reference=None,
                         notification_id=None,
                         simulated=False,
                         created_by_id=None,
                         status=NOTIFICATION_CREATED,
                         reply_to_text=None):
    notification_created_at = created_at or datetime.utcnow()
    if not notification_id:
        notification_id = uuid.uuid4()
    notification = Notification(
        id=notification_id,
        template_id=template_id,
        template_version=template_version,
        to=recipient,
        service_id=service.id,
        service=service,
        personalisation=personalisation,
        notification_type=notification_type,
        api_key_id=api_key_id,
        key_type=key_type,
        created_at=notification_created_at,
        job_id=job_id,
        job_row_number=job_row_number,
        client_reference=client_reference,
        reference=reference,
        created_by_id=created_by_id,
        status=status,
        reply_to_text=reply_to_text,
    )

    if notification_type == SMS_TYPE:
        formatted_recipient = validate_and_format_phone_number(
            recipient, international=True)
        recipient_info = get_international_phone_info(formatted_recipient)
        notification.normalised_to = formatted_recipient
        notification.international = recipient_info.international
        notification.phone_prefix = recipient_info.country_prefix
        notification.rate_multiplier = recipient_info.billable_units
    elif notification_type == EMAIL_TYPE:
        notification.normalised_to = format_email_address(notification.to)

    # if simulated create a Notification model to return but do not persist the Notification to the dB
    if not simulated:
        dao_create_notification(notification)
        if key_type != KEY_TYPE_TEST:
            if redis_store.get(redis.daily_limit_cache_key(service.id)):
                redis_store.incr(redis.daily_limit_cache_key(service.id))
            if redis_store.get_all_from_hash(
                    cache_key_for_service_template_counter(service.id)):
                redis_store.increment_hash_value(
                    cache_key_for_service_template_counter(service.id),
                    template_id)

            increment_template_usage_cache(service.id, template_id,
                                           notification_created_at)

        current_app.logger.info("{} {} created at {}".format(
            notification_type, notification_id, notification_created_at))
    return notification