示例#1
0
    def task_message_handler(message,
                             body,
                             ack,
                             reject,
                             callbacks,
                             to_timestamp=to_timestamp):
        req = Req(body,
                  on_ack=ack,
                  on_reject=reject,
                  app=app,
                  hostname=hostname,
                  eventer=eventer,
                  task=task,
                  connection_errors=connection_errors,
                  message=message)
        if req.revoked():
            return

        if _does_info:
            info('Received task: %s', req)

        if events:
            send_event(
                'task-received',
                uuid=req.id,
                name=req.name,
                args=safe_repr(req.args),
                kwargs=safe_repr(req.kwargs),
                retries=req.request_dict.get('retries', 0),
                eta=req.eta and req.eta.isoformat(),
                expires=req.expires and req.expires.isoformat(),
            )

        if req.eta:
            try:
                if req.utc:
                    eta = to_timestamp(to_system_tz(req.eta))
                else:
                    eta = to_timestamp(req.eta, timezone.local)
            except OverflowError as exc:
                error("Couldn't convert eta %s to timestamp: %r. Task: %r",
                      req.eta,
                      exc,
                      req.info(safe=True),
                      exc_info=True)
                req.acknowledge()
            else:
                consumer.qos.increment_eventually()
                call_at(eta, apply_eta_task, (req, ), priority=6)
        else:
            if rate_limits_enabled:
                bucket = get_bucket(task.name)
                if bucket:
                    return limit_task(req, bucket, 1)
            task_reserved(req)
            if callbacks:
                [callback() for callback in callbacks]
            handle(req)
示例#2
0
    def task_message_handler(message, body, ack, reject, callbacks,
                             to_timestamp=to_timestamp):
        if body is None:
            body, headers, decoded, utc = (
                message.body, message.headers, False, app.uses_utc_timezone(),
            )
            if not body_can_be_buffer:
                body = bytes(body) if isinstance(body, buffer_t) else body
        else:
            body, headers, decoded, utc = proto1_to_proto2(message, body)

        req = Req(
            message,
            on_ack=ack, on_reject=reject, app=app, hostname=hostname,
            eventer=eventer, task=task, connection_errors=connection_errors,
            body=body, headers=headers, decoded=decoded, utc=utc,
        )
        if _does_info:
            info('Received task: %s', req)
        if (req.expires or req.id in revoked_tasks) and req.revoked():
            return

        if task_sends_events:
            send_event(
                'task-received',
                uuid=req.id, name=req.name,
                args=req.argsrepr, kwargs=req.kwargsrepr,
                root_id=req.root_id, parent_id=req.parent_id,
                retries=req.request_dict.get('retries', 0),
                eta=req.eta and req.eta.isoformat(),
                expires=req.expires and req.expires.isoformat(),
            )

        if req.eta:
            try:
                if req.utc:
                    eta = to_timestamp(to_system_tz(req.eta))
                else:
                    eta = to_timestamp(req.eta, app.timezone)
            except (OverflowError, ValueError) as exc:
                error("Couldn't convert ETA %r to timestamp: %r. Task: %r",
                      req.eta, exc, req.info(safe=True), exc_info=True)
                req.reject(requeue=False)
            else:
                consumer.qos.increment_eventually()
                call_at(eta, apply_eta_task, (req,), priority=6)
        else:
            if rate_limits_enabled:
                bucket = get_bucket(task.name)
                if bucket:
                    return limit_task(req, bucket, 1)
            task_reserved(req)
            if callbacks:
                [callback(req) for callback in callbacks]
            handle(req)
示例#3
0
    def task_message_handler(message, body, ack, reject, callbacks,
                             to_timestamp=to_timestamp):
        req = Req(body, on_ack=ack, on_reject=reject,
                  app=app, hostname=hostname,
                  eventer=eventer, task=task,
                  connection_errors=connection_errors,
                  message=message)
        # do check revoke purge befor task handler, skip the expired revoke
        revoked_tasks.purge(limit=None, offset=REVOKES_MAX)
        # paused.purge(limit=None, offset=REVOKES_MAX)
        if req.revoked():
            return

        if _does_info:
            logger.info('hera Received task: %s', req)

        if events:
            send_event(
                'task-received',
                uuid=req.id, name=req.name,
                args=safe_repr(req.args), kwargs=safe_repr(req.kwargs),
                retries=req.request_dict.get('retries', 0),
                eta=req.eta and req.eta.isoformat(),
                expires=req.expires and req.expires.isoformat(),
            )

        if req.eta:
            try:
                if req.utc:
                    eta = to_timestamp(to_system_tz(req.eta))
                else:
                    eta = to_timestamp(req.eta, timezone.local)
            except OverflowError as exc:
                error("Couldn't convert eta %s to timestamp: %r. Task: %r",
                      req.eta, exc, req.info(safe=True), exc_info=True)
                req.acknowledge()
            else:
                consumer.qos.increment_eventually()
                call_at(eta, apply_eta_task, (req, ), priority=6)
        else:
            if rate_limits_enabled:
                bucket = get_bucket(task.name)
                if bucket:
                    return limit_task(req, bucket, 1)
            task_reserved(req)
            if callbacks:
                [callback() for callback in callbacks]
            handle(req)
示例#4
0
def get_many_cached_price_info(context, item, quantity=1, **context_args):
    """
    Get cached prices info list

    :param object|WSGIRequest context: the context should contain at least a shop and a customer property
    :param object item
    :param float|Decimal quantity
    """
    key, prices_infos = context_cache.get_cached_value(
        many=True,
        **_get_price_info_cache_key_params(context, item, quantity, **context_args)
    )

    if prices_infos:
        try:
            iter(prices_infos)
        except TypeError:
            return None

        from django.utils.timezone import now
        now_timestamp = to_timestamp(now())

        # make sure to check all experiration dates
        for price_info in prices_infos:
            # if one price has expired, we invalidate the entire cache
            if isinstance(price_info, PriceInfo) and price_info.expires_on and price_info.expires_on < now_timestamp:
                return None

    return prices_infos
示例#5
0
    def task_message_handler(message, body, ack, reject,
                             to_timestamp=to_timestamp):
        req = Req(body, on_ack=ack, on_reject=reject,
                  app=app, hostname=hostname,
                  eventer=eventer, task=task,
                  connection_errors=connection_errors,
                  delivery_info=message.delivery_info)
        if req.revoked():
            return

        if _does_info:
            info('Got task from broker: %s', req)

        if events:
            send_event(
                'task-received',
                uuid=req.id, name=req.name,
                args=safe_repr(req.args), kwargs=safe_repr(req.kwargs),
                retries=req.request_dict.get('retries', 0),
                eta=req.eta and req.eta.isoformat(),
                expires=req.expires and req.expires.isoformat(),
            )

        if req.eta:
            try:
                if req.utc:
                    eta = to_timestamp(to_system_tz(req.eta))
                else:
                    eta = to_timestamp(req.eta, timezone.local)
            except OverflowError as exc:
                error("Couldn't convert eta %s to timestamp: %r. Task: %r",
                      req.eta, exc, req.info(safe=True), exc_info=True)
                req.acknowledge()
            else:
                consumer.qos.increment_eventually()
                call_at(eta, apply_eta_task, (req, ), priority=6)
        else:
            if rate_limits_enabled:
                if bucket:
                    return limit_task(req, bucket, 1)
            task_reserved(req)
            handle(req)
示例#6
0
def get_cached_price_info(context, item, quantity=1, **context_args):
    """
    Get a cached price info

    :param object|WSGIRequest context: the context should contain at least a shop and a customer property
    :param object item
    :param float|Decimal quantity
    """
    key, price_info = context_cache.get_cached_value(
        **_get_price_info_cache_key_params(context, item, quantity, **context_args)
    )

    from django.utils.timezone import now
    now_ts = to_timestamp(now())

    # price has expired
    if price_info and isinstance(price_info, PriceInfo) and price_info.expires_on and price_info.expires_on < now_ts:
        price_info = None

    return price_info
示例#7
0
 def test_to_timestamp(self):
     self.assertIs(to_timestamp(3.13), 3.13)
示例#8
0
 def test_datetime(self):
     assert to_timestamp(datetime.utcnow())
示例#9
0
 def test_timestamp(self):
     assert to_timestamp(3.13) is 3.13
示例#10
0
def get_price_expiration(context, product):
    """
    Returns the price expiration for the product through a UNIX timestamp

    This routine loads all dates that can possibly affect the price of the product in the future.

    After fetching all the event dates, the expiration time will
        be the minimum datetime that is greater than now:

        expire_on = min(
            event_date for event_dates in [
                next_discount_start,
                next_discount_ends,
                next_happy_hour_start,
                next_happy_hour_end,
                next_availability_exception_start,
                next_availability_exception_end
            ]
            if event_date > now
        )

    :rtype numbers.Number|None
    :returns the price expiration time timestamp
    """
    cache_params = dict(
        identifier="price_expiration",
        item=_get_price_expiration_cache_key(context.shop.pk),
        context={}
    )

    if settings.E-Commerce_DISCOUNTS_PER_PRODUCT_EXPIRATION_DATES:
        cache_params["customer"] = getattr(context, "customer", None)
        cache_params["product"] = product

    key, value = context_cache.get_cached_value(**cache_params)
    if value is not None:
        return value

    context_cache_key = "price_expiration_%(shop_id)s" % dict(shop_id=context.shop.pk)
    if hasattr(context, "context_cache_key"):
        return getattr(context, context_cache_key)

    from E-Commerce.discounts.models import AvailabilityException, Discount, TimeRange

    if settings.E-Commerce_DISCOUNTS_PER_PRODUCT_EXPIRATION_DATES:
        potential_discounts = get_potential_discounts_for_product(context, product, available_only=False)
    else:
        potential_discounts = Discount.objects.active(context.shop)

    event_dates = []

    availability_exceptions = AvailabilityException.objects.filter(discounts__in=potential_discounts).distinct()
    for start_datetime, end_datetime in availability_exceptions.values_list("start_datetime", "end_datetime"):
        event_dates.extend([start_datetime, end_datetime])

    time_ranges = TimeRange.objects.filter(happy_hour__discounts__in=potential_discounts).distinct()
    for weekday, from_hour, to_hour in time_ranges.values_list("weekday", "from_hour", "to_hour"):
        event_dates.extend(get_next_dates_for_range(weekday, from_hour, to_hour))

    from django.utils.timezone import now
    now_datetime = now()

    if event_dates:
        min_event_date = (
            min(event_date for event_date in event_dates if event_date > now_datetime)
        )
        min_event_date_timestamp = to_timestamp(min_event_date)

        # cache the value in the context cache, setting the timeout as the price expiration time
        cache_timeout = max((min_event_date - now_datetime).total_seconds(), 0)
        context_cache.set_cached_value(key, min_event_date_timestamp, timeout=cache_timeout)

        # cache the context in the context, so if it is used again it will contain the calculated value
        setattr(context, context_cache_key, min_event_date_timestamp)

        return min_event_date_timestamp
示例#11
0
 def test_datetime(self):
     self.assertTrue(to_timestamp(datetime.utcnow()))
示例#12
0
 def test_timestamp(self):
     self.assertIs(to_timestamp(3.13), 3.13)
 def test_datetime(self):
     self.assertTrue(to_timestamp(datetime.utcnow()))
示例#14
0
def test_happy_hour_prices_expiration(rf):
    with override_settings(
        CACHES={
            'default': {
                'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
                'LOCATION': 'test_happy_hour_prices_bump',
            }
        }
    ):
        happy_hour = init_test()

        # it is now: 2018-01-01 09:00 AM
        before_happy_hour = datetime.datetime(2018, 1, 1, 9, 0, tzinfo=pytz.UTC)    # 09:00 AM
        inside_happy_hour = datetime.datetime(2018, 1, 1, 10, 30, tzinfo=pytz.UTC)  # 10:30 AM
        after_happy_hours = datetime.datetime(2018, 1, 1, 11, 20, tzinfo=pytz.UTC)  # 11:30 AM

        # Create condition from 10am to 11am
        hour_start = datetime.datetime(2018, 1, 1, 10, 0, tzinfo=pytz.UTC).time()  # 10:00 AM
        hour_end = datetime.datetime(2018, 1, 1, 11, 0, tzinfo=pytz.UTC).time()  # 11:00 AM
        set_valid_times_condition(happy_hour, hour_start, hour_end, str(before_happy_hour.weekday()))

        shop = happy_hour.shops.first()
        discount = happy_hour.discounts.first()
        product = discount.product
        shop_product = product.get_shop_instance(shop)
        assert shop_product.default_price_value == 10
        assert discount.discounted_price_value == 6

        def get_request():
            return apply_request_middleware(rf.get("/"))

        price_template = engines["jinja2"].from_string("{{ product|price }}")
        is_discounted_template = engines["jinja2"].from_string("{{ product|is_discounted }}")
        discount_percent_template = engines["jinja2"].from_string("{{ product|discount_percent }}")

        # we start with time being before happy hour
        with patch("django.utils.timezone.now", new=lambda: before_happy_hour):
            # mock also time.time so the cache timeout will be calculated correctly
            with patch("time.time", new=lambda: to_timestamp(before_happy_hour)):
                # check that product price is still the orignal (€10.00)
                # run twice to make sure caches are being used
                for cache_test in range(2):
                    context = dict(product=product, request=get_request())
                    assert price_template.render(context) == format_money(shop_product.default_price)
                    assert is_discounted_template.render(context) == "False"
                    assert discount_percent_template.render(context) == "0%"

                    if cache_test == 1:
                        assert get_cached_price_info(get_request(), product, 1, supplier=shop_product.get_supplier())

        # now we are inside happy hour range
        with patch("django.utils.timezone.now", new=lambda: inside_happy_hour):
            # mock also time.time so the cache timeout will be calculated correctly
            with patch("time.time", new=lambda: to_timestamp(inside_happy_hour)):
                # check that product price is the discounted one (€6.00)
                # run twice to make sure caches are being used
                for cache_test in range(2):
                    context = dict(product=product, request=get_request())
                    assert price_template.render(context) == format_money(
                        shop.create_price(discount.discounted_price_value)
                    )
                    assert is_discounted_template.render(context) == "True"
                    assert discount_percent_template.render(context) == "40%"

                    if cache_test == 1:
                        assert get_cached_price_info(get_request(), product, 1, supplier=shop_product.get_supplier())

                # we change the discounted price from $6 to $7
                # cached should be bumped
                discount.discounted_price_value = 7
                discount.save()
                for cache_test in range(2):
                    context = dict(product=product, request=get_request())
                    assert price_template.render(context) == format_money(
                        shop.create_price(discount.discounted_price_value)
                    )
                    assert is_discounted_template.render(context) == "True"
                    assert discount_percent_template.render(context) == "30%"

                    if cache_test == 1:
                        assert get_cached_price_info(get_request(), product, 1, supplier=shop_product.get_supplier())

        # now we are inside happy hour range
        with patch("django.utils.timezone.now", new=lambda: after_happy_hours):
            # mock also time.time so the cache timeout will be calculated correctly
            with patch("time.time", new=lambda: to_timestamp(after_happy_hours)):
                # check that product price is the orignal (€10.00)
                # run twice to make sure caches are being used
                for cache_test in range(2):
                    context = dict(product=product, request=get_request())
                    assert price_template.render(context) == format_money(shop_product.default_price)
                    assert is_discounted_template.render(context) == "False"
                    assert discount_percent_template.render(context) == "0%"

                    if cache_test == 1:
                        assert get_cached_price_info(get_request(), product, 1, supplier=shop_product.get_supplier())
示例#15
0
 def test_datetime(self):
     assert to_timestamp(datetime.utcnow())
示例#16
0
 def test_timestamp(self):
     assert to_timestamp(3.13) is 3.13