Ejemplo n.º 1
0
def sync_app_state(request):
    earliest_pickup_time = ceil_datetime(trim_seconds(default_tz_now()) + datetime.timedelta(minutes=asap_interval()), minutes=booking_interval())
    latest_pickup_time = earliest_pickup_time + datetime.timedelta(hours=(24*14))
    dt_options = list(datetimeIterator(earliest_pickup_time, latest_pickup_time, delta=datetime.timedelta(minutes=booking_interval())))

    response = {
        "logged_in": request.user.is_authenticated(),
        "pickup_datetime_options": [to_js_date(opt) for opt in dt_options],
        "pickup_datetime_default_idx": 0,
        "asap_as_default": True,
        "booking_data": request.session.get(CURRENT_BOOKING_DATA_KEY)
    }

    passenger = Passenger.from_request(request)
    response["show_url"] = "" # change to cause child browser to open with passed url

    if passenger:
        response["authenticated"] = True
        response["passenger_picture_url"] = passenger.picture_url

        ongoing_order = get_ongoing_order(passenger)
        if ongoing_order:
            response["ongoing_order_id"] = ongoing_order.id

        future_orders = get_future_orders_for(passenger)
        response["future_orders_count"] = len(future_orders)

    trimed_response = response.copy()
    trimed_response['pickup_datetime_options'] = response['pickup_datetime_options'][:9] + ['...']
    logging.info("get_initial_status: %s" % trimed_response)

    return JSONResponse(response)
Ejemplo n.º 2
0
def track_order(request, order_id):
    order = Order.by_id(order_id)
    use_mock = False
    ride = None
    expiration_date = default_tz_now()
    if order:
        try:
            ride = order.ride or order.pickmeapp_ride
        except (SharedRide.DoesNotExist, PickMeAppRide.DoesNotExist):
            pass
    else:
        error_message = _("This ride is invalid")

    if not ride:
        error_message = _("This ride is invalid")
    else:
        expiration_date = ride.arrive_time + timedelta(minutes=15)
        if expiration_date < default_tz_now():
            error_message = _("This ride has expired")

    if ride.station:
        station_icon_url = ride.station.app_icon_url
        station_phone = ride.station.phone

    if request.GET.get("use_mock"):
        error_message = ""
        station_icon_url = "https://s3.amazonaws.com/stations_icons/ny_icon.png"
        use_mock = True
        expiration_date = default_tz_now() + timedelta(minutes=15)

    expiration_date = to_js_date(expiration_date)  # prepare for JS consumption

    return custom_render_to_response('track_order.html',
                                     locals(),
                                     context_instance=RequestContext(request))
Ejemplo n.º 3
0
def track_order(request, order_id):
    order = Order.by_id(order_id)
    use_mock = False
    ride = None
    expiration_date = default_tz_now()
    if order:
        try:
            ride = order.ride or order.pickmeapp_ride
        except (SharedRide.DoesNotExist, PickMeAppRide.DoesNotExist):
            pass
    else:
        error_message = _("This ride is invalid")

    if not ride:
        error_message = _("This ride is invalid")
    else:
        expiration_date = ride.arrive_time + timedelta(minutes=15)
        if expiration_date < default_tz_now():
            error_message = _("This ride has expired")

    if ride.station:
        station_icon_url = ride.station.app_icon_url
        station_phone = ride.station.phone

    if request.GET.get("use_mock"):
        error_message = ""
        station_icon_url = "https://s3.amazonaws.com/stations_icons/ny_icon.png"
        use_mock = True
        expiration_date = default_tz_now() + timedelta(minutes=15)

    expiration_date = to_js_date(expiration_date)  # prepare for JS consumption

    return custom_render_to_response("track_order.html", locals(), context_instance=RequestContext(request))
Ejemplo n.º 4
0
def get_discounted_offers(request, order_settings, start_ride_algo_data):
    user = request.user if request.user.is_authenticated() else None

    discounted_offers = []

    earliest_offer_dt = ceil_datetime(max(trim_seconds(default_tz_now()) + datetime.timedelta(minutes=asap_interval()), order_settings.pickup_dt - OFFERS_TIMEDELTA), minutes=booking_interval())
    discounts_data = compute_discounts_data(order_settings,
        earliest_offer_dt,
        order_settings.pickup_dt + OFFERS_TIMEDELTA,
        datetime.timedelta(minutes=booking_interval()),
        user = user
    )

    for discount_data in discounts_data:
        discount_rule = discount_data.discount_rule
        discount_dt = discount_data.pickup_dt

        tariff_for_discount_offer = RuleSet.get_active_set(discount_dt)
        base_price_for_discount_offer = start_ride_algo_data.order_price(NEW_ORDER_ID, tariff_for_discount_offer)
        if base_price_for_discount_offer:
            discount = discount_rule.get_discount(base_price_for_discount_offer)
            if discount == 0:
                logging.info(u"skipping %s: grants zero discount" % discount_rule.name)
                continue

            offer_key = "%s_%s" % (DISCOUNTED_OFFER_PREFIX, get_uuid())
            memcache.set(offer_key, DiscountData.dump(discount_data), namespace=DISCOUNTED_OFFERS_NS)

            offer_text = _(u"The price includes a discount of %g NIS") % discount
            if discount_rule.offer_text:
                offer_text = discount_rule.offer_text
                if offer_text.find("%g") > -1:  # render discount amount
                    offer_text %= discount

            discount_offer_data = {
                "ride_id": offer_key,
                "pickup_time": to_js_date(discount_dt),
                "discount_picture_url": discount_rule.picture_url,
                "discount_name": discount_rule.display_name,
                "passengers": [],
                "seats_left": MAX_SEATS,
                "price": base_price_for_discount_offer - discount,
                "new_ride": True,
                "comment": offer_text
            }


            user_agent = request.META.get("HTTP_USER_AGENT", "")
            if RE_2_1_AGENT.match(user_agent) is None:  # only for client < 1.2.1
                discount_offer_data.update({
                    "seats_left": MAX_SEATS - 1,
                    "passengers": [{'name': discount_rule.display_name, 'picture_url': discount_rule.picture_url}]
                })

            discounted_offers.append(discount_offer_data)

    return discounted_offers
Ejemplo n.º 5
0
 def serialize(self):
     d = {}
     for attr in [
             "id", "status", "taxi_id", "station_id", "lat", "lon",
             "raw_status"
     ]:
         d[attr] = getattr(self, attr)
     d["timestamp"] = to_js_date(self.timestamp)
     return d
Ejemplo n.º 6
0
def get_previous_rides(request, passenger):
    data = []

    orders = passenger.orders.filter(depart_time__lt=utc_now(), status__in=ORDER_SUCCESS_STATUS).order_by('-depart_time')
    orders = orders.filter(type__in=[OrderType.PRIVATE, OrderType.SHARED])[:PREVIOUS_RIDES_TO_DISPLAY]
    seen_rides = []

    for order in orders:
        ride = order.ride
        if not ride:
            logging.error("order [%s] not valid for previous rides (order.ride is None" % order.id)
            continue
        if ride in seen_rides:
            continue  # skip duplicates (in case ride has multiple orders by same passenger)

        seen_rides.append(ride)

        ride_orders = ride.orders.all()
        ride_mates_orders = filter(lambda o: o != order, ride_orders)
        ride_mates = [{'name': mate_order.passenger.name, 'picture_url': mate_order.passenger.picture_url}
                                    for mate_order in ride_mates_orders for seat in range(order.num_seats)]

        dispatching_event = first(lambda e: e.taxi_id, ride.events.all())

        ride_data = {
            "order_id": order.id,
            "pickup_time": to_js_date(order.pickup_point.stop_time),
            "passengers": ride_mates,
            "seats_left": MAX_SEATS - sum([o.num_seats for o in ride_orders]),
            "your_seats": order.num_seats,
            "taxi_number": dispatching_event.taxi_id if dispatching_event else None,
            "station_name": ride.station.name if ride.station else WAYBETTER_STATION_NAME,
            "price": order.get_billing_amount(),
            "price_alone": order.price_alone,
            "billing_status": ugettext_lazy(order.get_status_display().title()),
            "pickup": order.from_raw,
            "dropoff": order.to_raw,
            "is_private": order.type == OrderType.PRIVATE,
            "comment": ""
            }

        data.append(ride_data)

    return JSONResponse(data)
Ejemplo n.º 7
0
def get_next_rides(request, passenger):
    data = []
    future_orders = get_future_orders_for(passenger)
    seen_rides = []

    for order in future_orders:
        ride = order.ride
        if not ride:
            logging.error("order [%s] not valid for previous rides (order.ride is None" % order.id)
            continue
        if ride in seen_rides:
            continue  # skip duplicates (in case ride has multiple orders by same passenger)
        seen_rides.append(ride)

        ride_orders = ride.orders.all()
        ride_mates_orders = filter(lambda o: o != order, ride_orders)
        ride_mates = [{'name': o.passenger.name, 'picture_url': o.passenger.picture_url}
                        for o in ride_mates_orders for seat in range(o.num_seats)]

        ride_data = {
            "order_id": order.id,
            "pickup_time": to_js_date(order.pickup_point.stop_time),
            "passengers": ride_mates,
            "seats_left": MAX_SEATS - sum([o.num_seats for o in ride_orders]),
            "your_seats": order.num_seats,
            "price": order.get_billing_amount(),
            "price_alone": order.price_alone,
            "is_private": order.type == OrderType.PRIVATE,
            "pickup": order.from_raw,
            "dropoff": order.to_raw,
            "billing_status": _("or less"),
            "comment": ""
        }

        data.append(ride_data)

    return JSONResponse(data)
Ejemplo n.º 8
0
        else:
            return JSONResponse({'error': 'error'})
    else:
        form = DatePickerForm()
        init_end_date = init_end_date or default_tz_now_max()
        init_start_date = init_start_date or default_tz_now_min()
        if async:
            assert wrapper_locals.get('channel_id')
            assert wrapper_locals.get('token')
            async_computation_submitted_signal.send(sender="base_datepicker_page", channel_id=wrapper_locals.get('channel_id'))
            deferred.defer(f_data, init_start_date, init_end_date, channel_id=wrapper_locals.get('channel_id'), token=wrapper_locals.get('token'))
            data = simplejson.dumps({'status': 'submitted', 'token': wrapper_locals.get('token')})
        else:
            data = simplejson.dumps(f_data(init_start_date, init_end_date))

        start_date, end_date = to_js_date(init_start_date), to_js_date(init_end_date)

        extended_locals = wrapper_locals.copy()
        extended_locals.update(locals())

        return render_to_response(template_name, extended_locals, context_instance=RequestContext(request))


def has_caller(caller_name):
    """
    Check if the stack contains a caller with caller_name
    returns: True if a caller with caller_name is in the stack, False otherwise.
    """
    result = False
    try:
        result = caller_name in [frame[3] for frame in inspect.getouterframes(inspect.currentframe())]
Ejemplo n.º 9
0
def book_ride(request):
    return JSONResponse({
        'status': 'failed',
        'error': SERVICE_NOT_AVAILABLE_MSG
    })

    passenger = Passenger.from_request(request)
    request_data = simplejson.loads(request.POST.get('data'))
    logging.info(u"book ride: %s\n%s" % (passenger, unicode(simplejson.dumps(request_data), "unicode-escape")))

    result = {
        'status': '',
        'order_id': None,
        'redirect': '',
        'error': '',
        'pickup_dt': None
    }

    if passenger and passenger.user and hasattr(passenger, "billing_info"): # we have logged-in passenger with billing_info - let's proceed
        order_settings = OrderSettings.fromRequest(request)
        ride_id = request_data.get("ride_id")

        new_ride = (ride_id == NEW_ORDER_ID)
        discounted_ride = (ride_id and str(ride_id).startswith(DISCOUNTED_OFFER_PREFIX))

        join_ride = not (new_ride or discounted_ride)
        ride_to_join = SharedRide.by_id(ride_id) if join_ride else None

        order = None
        if ride_to_join:  # check it is indeed a valid candidate
            if is_valid_candidate(ride_to_join, order_settings):
                order = create_order(order_settings, passenger, ride=ride_to_join)
            else:
                logging.warning("tried booking an invalid ride candidate")
                result['error'] = _("Sorry, but this ride has been closed for booking")

        else:  # new or discounted ride, check pickup time isn't before ASAP (minus a couple seconds to allow booking to exactly ASAP)
            if order_settings.pickup_dt <= default_tz_now() + datetime.timedelta(minutes=asap_interval()) - datetime.timedelta(seconds=10):
                logging.warning("tried booking to expired pickup time %s" % order_settings.pickup_dt)
                result['error'] = _("Please choose a later pickup time")
            else:
                if discounted_ride:
                    cached_discount_data = memcache.get(ride_id, namespace=DISCOUNTED_OFFERS_NS)
                    discount_data = DiscountData.load(cached_discount_data)
                    logging.info("[book_ride] discount_data = %s" % discount_data)
                    order = create_order(order_settings, passenger, discount_data=discount_data)
                else:
                    order = create_order(order_settings, passenger)


        if order:
            result['status'] = 'success'
            result['order_id'] = order.id
            result['pickup_formatted'] = order.from_raw
            result['pickup_dt'] = to_js_date(order.depart_time)
            result["price"] = order.get_billing_amount()

            ride_orders = [order] + ( list(ride_to_join.orders.all()) if ride_to_join else [] )
            result["passengers"] = [{'name': o.passenger.name, 'picture_url': o.passenger.picture_url, 'is_you': o==order} for o in ride_orders for seat in range(o.num_seats)]
            result["seats_left"] = MAX_SEATS - sum([o.num_seats for o in ride_orders])

            deferred.defer(join_offer_and_order, order, request_data)

        else:
            result['status'] = 'failed'

    else:  # not authorized for booking, save current booking state in session
        set_current_booking_data(request)

        if passenger and not hasattr(passenger, "billing_info"):
            result['status'] = 'billing_failed'
            result['redirect'] = get_token_url(request) # go to billing
        else:
            result['status'] = 'auth_failed'

    logging.info("book ride result: %s" % result)
    return JSONResponse(result)
Ejemplo n.º 10
0
def get_offers(request):
    return JSONResponse({
        'status': 'failed',
        'error': SERVICE_NOT_AVAILABLE_MSG
    })

    order_settings = OrderSettings.fromRequest(request)

    # TODO_WB: save the requested search params and associate with a push_token from request for later notifications of similar searches

    if not order_settings.private:
        candidate_rides = get_candidate_rides(order_settings)
        look_for_discounts = True
    else:
        candidate_rides = []
        look_for_discounts = False

    matching_rides = get_matching_rides(candidate_rides, order_settings)
    if not matching_rides:
        return JSONResponse({'error': u'מצטערים, הכתובת המבוקשת אינה באיזורי הכיסוי עדיין'})

    offers = []

    start_ride_algo_data = None

    for ride_data in matching_rides:
        ride_id = ride_data.ride_id
        ride = SharedRide.by_id(ride_id)

        # get price for offer according to tariff
        tariff = RuleSet.get_active_set(order_settings.pickup_dt)
        price = ride_data.order_price(NEW_ORDER_ID, tariff)
        price_alone = ride_data.order_price(NEW_ORDER_ID, tariff, sharing=False)

        if not price > 0:
            logging.warning("get_offers missing price for %s" % order_settings.pickup_dt)
            continue

        if ride_id == NEW_ORDER_ID:  # start a new ride
            start_ride_algo_data = ride_data
            offer = {
                "asap": order_settings.asap,
                "pickup_time": to_js_date(order_settings.pickup_dt),
                "price": price,
                "seats_left": MAX_SEATS,
                "new_ride": True,
                "comment": _(u"You will be updated when someone joins")  # TODO_WB: sharing chances
            }

        else:  # sharing offers
            time_sharing = ride_data.order_time(NEW_ORDER_ID)
            time_alone = ride_data.order_time(NEW_ORDER_ID, sharing=False)
            time_addition = int((time_sharing - time_alone) / 60)

            pickup_point = ride_data.order_pickup_point(NEW_ORDER_ID)
            ride_orders = ride.orders.all()
            pickup_time = compute_new_departure(ride, ride_data) + datetime.timedelta(seconds=pickup_point.offset)
            if pickup_time < default_tz_now() + datetime.timedelta(minutes=asap_interval()):
                logging.info("skipping offer because pickup_time is too soon: %s" % pickup_time)
                continue

            offer = {
                "ride_id": ride_id,
                "pickup_time": to_js_date(pickup_time),
                "passengers": [{'name': order.passenger.name, 'picture_url': order.passenger.picture_url} for order in ride_orders for seat in range(order.num_seats)],
                "seats_left": MAX_SEATS - sum([order.num_seats for order in ride_orders]),
                "price": price,
                "new_ride": False,
                "comment": _(u"Money saved: %(money_saved)s NIS or more – additional time: %(time_added)s min") % {'time_added': time_addition, 'money_saved': "%g" % (price_alone - price)}
            }

            # good enough offer found, no discounts
            if order_settings.pickup_dt - datetime.timedelta(minutes=30) < pickup_time < order_settings.pickup_dt + datetime.timedelta(minutes=30):
                look_for_discounts = False

        offers.append(offer)

    # add discounted offers if relevant

    ## override
    look_for_discounts = True
    ## override

    if look_for_discounts and start_ride_algo_data:
        offers += get_discounted_offers(request, order_settings, start_ride_algo_data)

    offers = sorted(offers, key=lambda  o: o["pickup_time"], reverse=False)

    deferred.defer(save_search_req_and_offers, Passenger.from_request(request), order_settings, offers)
    return JSONResponse({'offers': offers})
Ejemplo n.º 11
0
 def serialize(self):
     d = {}
     for attr in ["station_id", "taxi_id", "ride_uuid", "lat", "lon"]:
         d[attr] = getattr(self, attr)
     d["timestamp"] = to_js_date(self.timestamp)
     return d
Ejemplo n.º 12
0
            async_computation_submitted_signal.send(
                sender="base_datepicker_page",
                channel_id=wrapper_locals.get('channel_id'))
            deferred.defer(f_data,
                           init_start_date,
                           init_end_date,
                           channel_id=wrapper_locals.get('channel_id'),
                           token=wrapper_locals.get('token'))
            data = simplejson.dumps({
                'status': 'submitted',
                'token': wrapper_locals.get('token')
            })
        else:
            data = simplejson.dumps(f_data(init_start_date, init_end_date))

        start_date, end_date = to_js_date(init_start_date), to_js_date(
            init_end_date)

        extended_locals = wrapper_locals.copy()
        extended_locals.update(locals())

        return render_to_response(template_name,
                                  extended_locals,
                                  context_instance=RequestContext(request))


def has_caller(caller_name):
    """
    Check if the stack contains a caller with caller_name
    returns: True if a caller with caller_name is in the stack, False otherwise.
    """