def log_connection_events(sender, signal_type, obj, **kwargs): from common.tz_support import utc_now from django.core.urlresolvers import reverse from google.appengine.api.taskqueue import taskqueue from analytics.models import AnalyticsEvent from common.util import log_event, EventType, notify_by_email from ordering.signals import SignalType from ordering.station_connection_manager import ALERT_DELTA, handle_dead_workstations last_event_qs = AnalyticsEvent.objects.filter(work_station=obj, type__in=[EventType.WORKSTATION_UP, EventType.WORKSTATION_DOWN]).order_by('-create_date')[:1] station = obj.station if signal_type == SignalType.WORKSTATION_ONLINE: if last_event_qs: # send workstation reconnect mail last_event = last_event_qs[0] if last_event.type == EventType.WORKSTATION_DOWN and (utc_now() - last_event.create_date) >= ALERT_DELTA and station.show_on_list: msg = u"Workstation is up again:\n\tid = %d station = %s" % (obj.id, obj.dn_station_name) notify_by_email(u"Workstation Reconnected", msg=msg) elif station.show_on_list: # send "new workstation" mail msg = u"A new workstation just connected: id = %d station = %s" % (obj.id, obj.dn_station_name) notify_by_email(u"New Workstation", msg=msg) log_event(EventType.WORKSTATION_UP, station=station, work_station=obj) elif signal_type == SignalType.WORKSTATION_OFFLINE: log_event(EventType.WORKSTATION_DOWN, station=station, work_station=obj) if station.show_on_list: # add task to check if workstation is still dead after ALERT_DELTA task = taskqueue.Task(url=reverse(handle_dead_workstations), countdown=ALERT_DELTA.seconds + 1, params={"workstation_id": obj.id}) taskqueue.Queue('log-events').add(task)
def invoices_task(request): action = int(request.POST.get("action", -1)) now = default_tz_now() last_month_date = (now - timedelta(days=now.day)) month = last_month_date.month year = last_month_date.year start_date = datetime.combine(date(year=year, month=month, day=1), default_tz_time_min()) end_date = datetime.combine(date(year=year, month=month, day=calendar.monthrange(year, month)[1]), default_tz_time_max()) trx_qs = BillingTransaction.objects.filter(debug=False, invoice_sent=False, status=BillingStatus.CHARGED, charge_date__gte=start_date, charge_date__lte=end_date) if action == InvoiceActions.CREATE_ID: logging.info("Creating invoice ids: %s - %s" % (start_date, end_date)) failed = do_create_invoice_ids(trx_qs) elif action == InvoiceActions.SEND: logging.info("Sending invoices: %s - %s" % (start_date, end_date)) failed = do_send_invoices(trx_qs) else: raise RuntimeError("NOT A VALID INVOICE ACTION") action_name = InvoiceActions.get_name(action) if failed: notify_by_email("Error %s invoices for month %s/%s" % (action_name, month, year), "failed with following passenger ids %s" % failed) else: notify_by_email("Success %s invoices for month %s/%s" % (action_name, month, year)) return HttpResponse("OK")
def notify(self): subject = "New mobile interest" msg = """ from email: %s """ % (self.email) notify_by_email(subject, msg)
def handle_dead_workstations(request): ws_id = request.POST.get("workstation_id") workstation = None try: workstation = WorkStation.objects.get(id=ws_id) except WorkStation.DoesNotExist: logging.error("handle_dead_workstations: invalid workstation_id '%s" % ws_id) if workstation: last_event = AnalyticsEvent.objects.filter( work_station=workstation, type__in=[EventType.WORKSTATION_UP, EventType.WORKSTATION_DOWN]).order_by('-create_date')[:1] if last_event: last_event = last_event[0] if last_event.type == EventType.WORKSTATION_DOWN and ( utc_now() - last_event.create_date) >= ALERT_DELTA: # send station down mail msg = u"Workstation has been down for the last %d minutes:\n\tid = %d station = %s" % ( ALERT_DELTA.seconds / 60, workstation.id, workstation.dn_station_name) notify_by_email(u"Workstation down", msg) return HttpResponse("OK")
def assign_ride(ride, force_station=None): station = force_station or choose_station(ride) assigned_station = None logging.info(u"assigning ride [%s] to station: %s" % (ride.id, station)) if station: try: old_station = ride.station ride.station = station ride.dn_fleet_manager_id = station.fleet_manager_id if old_station: remove_ride(old_station, ride) if force_station and ride.change_status( new_status=RideStatus.ASSIGNED): # calls save() assigned_station = station elif ride.change_status( old_status=RideStatus.PROCESSING, new_status=RideStatus.ASSIGNED): # calls save() assigned_station = station except Exception: notify_by_email(u"Cannot assign ride [%s]" % ride.id, msg="%s\n%s" % (ride.get_log(), traceback.format_exc())) if assigned_station: ride.update_cost() logging.info(u"ride[%s] was successfully assigned to station %s" % (ride.id, assigned_station)) return assigned_station return None
def assign_ride(ride, force_station=None): station = force_station or choose_station(ride) assigned_station = None logging.info(u"assigning ride [%s] to station: %s" % (ride.id, station)) if station: try: old_station = ride.station ride.station = station ride.dn_fleet_manager_id = station.fleet_manager_id if old_station: remove_ride(old_station, ride) if force_station and ride.change_status(new_status=RideStatus.ASSIGNED): # calls save() assigned_station = station elif ride.change_status(old_status=RideStatus.PROCESSING, new_status=RideStatus.ASSIGNED): # calls save() assigned_station = station except Exception: notify_by_email(u"Cannot assign ride [%s]" % ride.id, msg="%s\n%s" % (ride.get_log(), traceback.format_exc())) if assigned_station: ride.update_cost() logging.info(u"ride[%s] was successfully assigned to station %s" % (ride.id, assigned_station)) return assigned_station return None
def validate_passenger_phone(request, local_phone, country, verification_code): """ Validate a passenger by phone and verification code. Return a response and the passenger (if exists) and save the passenger to the session. """ response = HttpResponse("OK") passenger = None intl_phone_number = get_international_phone(country, local_phone) stored_code, stored_phone = request.session.get(SESSION_VERIFICATION_KEY, (None, None)) if not (stored_code and stored_phone): response = HttpResponseBadRequest(_("Error validating phone (check that your browser accepts cookies)")) elif intl_phone_number != stored_phone or verification_code != int(stored_code): response = HttpResponseBadRequest(_("Invalid verification code")) else: try: passenger = Passenger.objects.get(phone=local_phone, country=country) except Passenger.DoesNotExist: pass except Passenger.MultipleObjectsReturned: msg = "Phone registered to multiple passengers: %s" % local_phone logging.error(msg) notify_by_email(msg) response = HttpResponseBadRequest(_("We're sorry but your phone appears to used by multiple users. Please contact [email protected] to resolve this issue.")) request.session[CURRENT_PASSENGER_KEY] = passenger return response, passenger
def request_phone_activation(request): app_udid = request.POST.get("APP_UDID") phone = request.POST.get("phone") notify_by_email("Phone Activation Request: %s" % app_udid, "phone: %s, app_udid: %s" % (phone, app_udid)) return HttpResponse("OK")
def wrapper_catch_view_exceptions(*args, **kwargs): try: return function(*args, **kwargs) except Exception, e: trace = traceback.format_exc() logging.error("Exception caught by decorator:\n %s" % trace) notify_by_email("Exception caught by decorator", trace) return HttpResponse("Exception caught by decorator")
def track_sms(passenger, sms_id): sms_data = get_sms_status_data(sms_id) logging.info("track sms_id=%s: %s" % (sms_id, sms_data)) if sms_data.get('status') != SMSStatus.OK: notify_by_email("SMS not received after %s seconds" % SMS_DELIVERY_GRACE, msg=(u"%s\nsms_data: %s" % (passenger, sms_data)))
def test_gcp_service_task(request): gcp_backend = GoogleCloudPrintBackend() result = gcp_backend.get_printers() logging.info("test_gcp_service_task: %s" % result) if not result or not result.get("success"): notify_by_email("Google Cloud Print service appears to be down") return HttpResponse("OK")
def generate_dead_users_list(): list = "" for user in User.objects.all(): if has_related_objects(user): user_link = '<a href="http://www.waybetter.com/admin/auth/user/%d/">%d</a>' % ( user.id, user.id) list += "user [%s]: %s<br/>" % (user.username, user_link) notify_by_email("Dead users list", html=list)
def on_billing_trx_failed(sender, signal_type, obj, **kwargs): from billing.billing_backend import get_custom_message trx = obj sbj, msg = "Billing Failed [%s]" % sender, u"" for att_name in ["id", "provider_status", "comments", "order", "passenger", "debug"]: msg += u"trx.%s: %s\n" % (att_name, getattr(trx, att_name)) msg += u"custom msg: %s" % get_custom_message(trx.provider_status, trx.comments) logging.error(u"%s\n%s" % (sbj, msg)) notify_by_email(sbj, msg=msg)
def connection_check_passed(request, work_station): logging.info("connection check passed for workstation: %s" % work_station) msg = u""" Workstation responded to to a connection check: \t%s """ % work_station notify_by_email(u"Connection check passed", msg=msg) return HttpResponse("OK")
def do_register_passenger(request): """ A one stop shop for handling registration of a new phone number, generationg a login token and updating the session. We make sure the request is made by an authenticated user. In case of validating: 1. Existing phone number (existing passenger) If request.user is already a passenger, merge request.user.passenger into the existing passenger. Connect the (merged) existing passenger to request.user and delete any previous passenger.user. 2. New phone number (new passenger) If request.user is already a passenger change his phone number. Otherwise, create a new passenger connected to request.user. """ if not request.user.is_authenticated(): return HttpResponseForbidden(_("You must be logged in to validate your phone.")) local_phone = request.POST.get('local_phone') country = Country.objects.get(code=settings.DEFAULT_COUNTRY_CODE) verification_code = int(request.POST.get('verification_code', -1)) response, passenger = validate_passenger_phone(request, local_phone, country, verification_code) if response.status_code != 200: # verification failed return response if passenger: # existing passenger try: user_passenger = request.user.passenger except Passenger.DoesNotExist: user_passenger = None if user_passenger and passenger != user_passenger: #TODO_WB: merge passengers notify_by_email("Merge Passengers Required", u"request.user.passenger:%s\nvalidated passenger:%s" % (request.user.passenger, passenger)) return HttpResponseBadRequest(_("We are sorry but your phone cannot be changed now. We will contact you to resolve this issue as soon as possible")) # request.user should be is_authenticated if we get here if passenger.user and passenger.user != request.user: safe_delete_user(passenger.user, remove_from_db=True) passenger.user = request.user else: # new passenger try: # user is already a passenger, change phone passenger = request.user.passenger passenger.phone = local_phone except Passenger.DoesNotExist: # user is not a passenger, create new passenger = create_passenger(request.user, country, local_phone, save=False) # request.session[CURRENT_PASSENGER_KEY] = passenger passenger.login_token = hashlib.sha1(generate_random_token(length=40)).hexdigest() passenger.save() request.session[CURRENT_PASSENGER_KEY] = passenger return JSONResponse({"redirect": reverse(post_login_redirect)})
def notify(self): subject = "New station interest" msg = """ Station name: %s Contact person: %s City: %s Phone: %s """ % (self.name, self.contact_person, self.city, self.phone) notify_by_email(subject, msg)
def handle_cancelled_orders(sender, signal_type, order, status, **kwargs): from ordering.models import CANCELLED, PromoCodeActivation from ordering.ordering_controller import update_ride_remove_order if status == CANCELLED: notify_by_email("Order Confirmation [%s]%s" % (order.id, " (DEBUG)" if order.debug else ""), msg="CANCELLED") update_ride_remove_order(order) if order.promo_code: promo_activation = PromoCodeActivation.objects.get(passenger=order.passenger, promo_code=order.promo_code) promo_activation.forfeit()
def workstation_exit(request): workstation_id = request.GET.get("id") ws = WorkStation.by_id(workstation_id) if ws and not ws.station.debug: msg = u"%s closed the workstation module" % ws.station.name notify_by_email("Module Closed by Station", msg=msg) for num in CRITICAL_MESSAGES_CONTACT_LIST: send_sms(num, msg) return HttpResponse("OK")
def print_voucher(printer_id, html, title, ride_id): print_backend = DEFAULT_BACKEND logging.info(u"print_voucher: printer_id: %s" % printer_id) job_id = _do_voucher_send(printer_id, html, title, ride_id, print_backend, check_print_job_status) if not job_id: ride = SharedRide.by_id(ride_id) if ride.station.fax_number: notify_by_email(u"WARNING: Voucher printing failed, will try to send fax for ride: %s" % ride_id) logging.warning("printing failed, will send fax") fax_voucher(ride.station.fax_number, html, title, ride_id) else: send_ride_in_risk_notification(u"Ride voucher failed to print and station has no fax number defined.", ride_id)
def notify(self): subject = "New business interest" registration_link = 'www.waybetter.com/business_registration/?from_interest_id=%d' % self.id msg = """ Contact person: %s Phone: %s Email: %s Registration form link: %s """ % (self.contact_person, self.phone, self.email, registration_link) notify_by_email(subject, msg)
def handle_cancelled_orders(sender, signal_type, order, status, **kwargs): from ordering.models import CANCELLED, PromoCodeActivation from ordering.ordering_controller import update_ride_remove_order if status == CANCELLED: notify_by_email("Order Confirmation [%s]%s" % (order.id, " (DEBUG)" if order.debug else ""), msg="CANCELLED") update_ride_remove_order(order) if order.promo_code: promo_activation = PromoCodeActivation.objects.get( passenger=order.passenger, promo_code=order.promo_code) promo_activation.forfeit()
def generate_passengers_with_non_existing_users(): passengers_list = "" for passenger in Passenger.objects.all(): try: passenger.user except: passenger_link = '<a href="http://www.waybetter.com/admin/ordering/passenger/%d/">%d</a>' % ( passenger.id, passenger.id) passengers_list += "passenger [%s]: %s<br/>" % (passenger.phone, passenger_link) notify_by_email("Passengers linked to users which do not exist", html=passengers_list)
def send_ride_in_risk_notification(msg, ride_id): msg_key = u"%s_%s" % (ride_id, msg) namespace = "ride_in_risk_notifications" msg_sent = memcache.get(msg_key, namespace=namespace) if msg_sent: logging.info(u"skipping sending: %s" % msg) return ride = SharedRide.by_id(ride_id) if ride and ride.debug: logging.info("skipping notification for debug ride %s" % ride_id) elif ride: t = get_template("ride_in_risk_email.html") orders = ride.orders.all() passengers = [o.passenger for o in orders.all()] station = ride.station try: sharing_ws = station.work_stations.filter( accept_shared_rides=True)[0] except Exception: sharing_ws = None html = t.render( Context({ "passengers": [u"%s (%s)" % (p.full_name, p.phone) for p in passengers], "station_phones": station.phones.all() if station else [], "station_name": station.name if station else "[NO STATION]", "online_status": sharing_ws.is_online if sharing_ws else None, "ride_id": ride_id, "depart_time": ride.depart_time.strftime("%H:%M"), "ride_status": RideStatus.get_name(ride.status), "msg": msg })) logging.info("sending risk mail: %s" % html) notify_by_email("IMPORTANT: Ride In Risk [%s]" % ride_id, html=html) memcache.set(msg_key, True, namespace=namespace) for num in CRITICAL_MESSAGES_CONTACT_LIST: send_sms(num, msg)
def handle_approved_orders(sender, signal_type, order, status, **kwargs): from common.util import notify_by_email, send_mail_as_noreply from common.langsupport.util import translate_to_lang from ordering.models import APPROVED from sharing.passenger_controller import get_passenger_ride_email logging.info("handle_approved_orders: %s" % status) if status == APPROVED: # send confirmation email passenger = order.passenger if passenger.user and passenger.user.email: msg = get_passenger_ride_email(order) send_mail_as_noreply(passenger.user.email, translate_to_lang("WAYbetter Order Confirmation", order.language_code), html=msg) notify_by_email("Order Confirmation [%s]%s" % (order.id, " (DEBUG)" if order.debug else ""), html=msg)
def create_passenger_dup_phones(): phones_counter = {} for p in Passenger.objects.all(): phone = p.phone if phone in phones_counter: phones_counter[phone] += 1 else: phones_counter[phone] = 1 dup_phones = [] for phone, val in phones_counter.iteritems(): if val > 1: dup_phones.append(phone) notify_by_email("Dup phones list", str(dup_phones))
def print_voucher(printer_id, html, title, ride_id): print_backend = DEFAULT_BACKEND logging.info(u"print_voucher: printer_id: %s" % printer_id) job_id = _do_voucher_send(printer_id, html, title, ride_id, print_backend, check_print_job_status) if not job_id: ride = SharedRide.by_id(ride_id) if ride.station.fax_number: notify_by_email( u"WARNING: Voucher printing failed, will try to send fax for ride: %s" % ride_id) logging.warning("printing failed, will send fax") fax_voucher(ride.station.fax_number, html, title, ride_id) else: send_ride_in_risk_notification( u"Ride voucher failed to print and station has no fax number defined.", ride_id)
def handle_dead_workstations(request): ws_id = request.POST.get("workstation_id") workstation = None try: workstation = WorkStation.objects.get(id=ws_id) except WorkStation.DoesNotExist: logging.error("handle_dead_workstations: invalid workstation_id '%s" % ws_id) if workstation: last_event = AnalyticsEvent.objects.filter(work_station=workstation, type__in=[EventType.WORKSTATION_UP, EventType.WORKSTATION_DOWN]).order_by('-create_date')[:1] if last_event: last_event = last_event[0] if last_event.type == EventType.WORKSTATION_DOWN and (utc_now() - last_event.create_date) >= ALERT_DELTA: # send station down mail msg = u"Workstation has been down for the last %d minutes:\n\tid = %d station = %s" % (ALERT_DELTA.seconds / 60, workstation.id, workstation.dn_station_name) notify_by_email(u"Workstation down", msg) return HttpResponse("OK")
def log_connection_events(sender, signal_type, obj, **kwargs): from common.tz_support import utc_now from django.core.urlresolvers import reverse from google.appengine.api.taskqueue import taskqueue from analytics.models import AnalyticsEvent from common.util import log_event, EventType, notify_by_email from ordering.signals import SignalType from ordering.station_connection_manager import ALERT_DELTA, handle_dead_workstations last_event_qs = AnalyticsEvent.objects.filter( work_station=obj, type__in=[EventType.WORKSTATION_UP, EventType.WORKSTATION_DOWN]).order_by('-create_date')[:1] station = obj.station if signal_type == SignalType.WORKSTATION_ONLINE: if last_event_qs: # send workstation reconnect mail last_event = last_event_qs[0] if last_event.type == EventType.WORKSTATION_DOWN and ( utc_now() - last_event.create_date ) >= ALERT_DELTA and station.show_on_list: msg = u"Workstation is up again:\n\tid = %d station = %s" % ( obj.id, obj.dn_station_name) notify_by_email(u"Workstation Reconnected", msg=msg) elif station.show_on_list: # send "new workstation" mail msg = u"A new workstation just connected: id = %d station = %s" % ( obj.id, obj.dn_station_name) notify_by_email(u"New Workstation", msg=msg) log_event(EventType.WORKSTATION_UP, station=station, work_station=obj) elif signal_type == SignalType.WORKSTATION_OFFLINE: log_event(EventType.WORKSTATION_DOWN, station=station, work_station=obj) if station.show_on_list: # add task to check if workstation is still dead after ALERT_DELTA task = taskqueue.Task(url=reverse(handle_dead_workstations), countdown=ALERT_DELTA.seconds + 1, params={"workstation_id": obj.id}) taskqueue.Queue('log-events').add(task)
def handle_approved_orders(sender, signal_type, order, status, **kwargs): from common.util import notify_by_email, send_mail_as_noreply from common.langsupport.util import translate_to_lang from ordering.models import APPROVED from sharing.passenger_controller import get_passenger_ride_email logging.info("handle_approved_orders: %s" % status) if status == APPROVED: # send confirmation email passenger = order.passenger if passenger.user and passenger.user.email: msg = get_passenger_ride_email(order) send_mail_as_noreply(passenger.user.email, translate_to_lang( "WAYbetter Order Confirmation", order.language_code), html=msg) notify_by_email("Order Confirmation [%s]%s" % (order.id, " (DEBUG)" if order.debug else ""), html=msg)
def send_ride_in_risk_notification(msg, ride_id): msg_key = u"%s_%s" % (ride_id, msg) namespace = "ride_in_risk_notifications" msg_sent = memcache.get(msg_key, namespace=namespace) if msg_sent: logging.info(u"skipping sending: %s" % msg) return ride = SharedRide.by_id(ride_id) if ride and ride.debug: logging.info("skipping notification for debug ride %s" % ride_id) elif ride: t = get_template("ride_in_risk_email.html") orders = ride.orders.all() passengers = [o.passenger for o in orders.all()] station = ride.station try: sharing_ws = station.work_stations.filter(accept_shared_rides=True)[0] except Exception: sharing_ws = None html = t.render(Context({ "passengers": [u"%s (%s)" % (p.full_name, p.phone) for p in passengers], "station_phones": station.phones.all() if station else [], "station_name": station.name if station else "[NO STATION]", "online_status": sharing_ws.is_online if sharing_ws else None, "ride_id": ride_id, "depart_time": ride.depart_time.strftime("%H:%M"), "ride_status": RideStatus.get_name(ride.status), "msg": msg })) logging.info("sending risk mail: %s" % html) notify_by_email("IMPORTANT: Ride In Risk [%s]" % ride_id, html=html) memcache.set(msg_key, True, namespace=namespace) for num in CRITICAL_MESSAGES_CONTACT_LIST: send_sms(num, msg)
def validate_passenger_phone(request, local_phone, country, verification_code): """ Validate a passenger by phone and verification code. Return a response and the passenger (if exists) and save the passenger to the session. """ response = HttpResponse("OK") passenger = None intl_phone_number = get_international_phone(country, local_phone) stored_code, stored_phone = request.session.get(SESSION_VERIFICATION_KEY, (None, None)) if not (stored_code and stored_phone): response = HttpResponseBadRequest( _("Error validating phone (check that your browser accepts cookies)" )) elif intl_phone_number != stored_phone or verification_code != int( stored_code): response = HttpResponseBadRequest(_("Invalid verification code")) else: try: passenger = Passenger.objects.get(phone=local_phone, country=country) except Passenger.DoesNotExist: pass except Passenger.MultipleObjectsReturned: msg = "Phone registered to multiple passengers: %s" % local_phone logging.error(msg) notify_by_email(msg) response = HttpResponseBadRequest( _("We're sorry but your phone appears to used by multiple users. Please contact [email protected] to resolve this issue." )) request.session[CURRENT_PASSENGER_KEY] = passenger return response, passenger
if result.status_code != 200: success = False err_msg = "status_code: %s" % result.status_code except Exception, e: err_msg = "There was an exception: %s\nTraceback:%s" % ( e, traceback.format_exc()) success = False if success: memcache.set(key=failures_counter, value=0) else: memcache.incr(failures_counter, initial_value=0) if memcache.get(failures_counter) == max_strikes: notify_by_email( "billing service appears to be down (strike #%s)" % max_strikes, err_msg) return HttpResponse("OK") @catch_view_exceptions def run_routing_service_test(request): task = taskqueue.Task(url=reverse(test_routing_service_task)) q = taskqueue.Queue('maintenance') q.add(task) return HttpResponse("Task Added") def run_gcp_service_test(request):
def send_ride_voucher(ride_id): ride = SharedRide.by_id(ride_id) if not (ride and ride.station): logging.error("can't send voucher ride_id=%s" % ride_id) return current_lang = translation.get_language() station_lang_code = settings.LANGUAGES[ride.station.language][0] translation.activate(station_lang_code) pickups = [] dropoffs = [] for p in sorted(ride.points.all(), key=lambda point: point.stop_time): orders = p.pickup_orders.all( ) if p.type == StopType.PICKUP else p.dropoff_orders.all() stop = { "count": sum([order.num_seats for order in orders]), "address": p.address } phones = [ "%s - %s" % (o.passenger.name, o.passenger.phone) for o in orders ] if len(phones) == 1: stop["phones"] = phones if p.type == StopType.PICKUP: pickups.append(stop) if p.type == StopType.DROPOFF: dropoffs.append(stop) tariff = RuleSet.get_active_set(ride.depart_time) srz_cost_details = CostDetails.serialize(ride.cost_details) template_args = { "ride": ride, "taxi": ride.taxi_number, "ride_date": ride.depart_time.strftime("%d/%m/%y"), "ride_time": (ride.first_pickup.stop_time - STATION_PICKUP_OFFSET).strftime("%H:%M"), "pickups": pickups, "dropoffs": dropoffs, "charged_stops": max(0, len(pickups) - 1), "cost_details": srz_cost_details, "distance": "%.1f" % float(ride.distance / 1000.0) if ride.distance else "", "additional_km": "%.1f" % float(srz_cost_details["additional_meters"] / 1000.0) if (srz_cost_details and srz_cost_details["additional_meters"]) else "", "tariff": tariff.name if tariff else "" } subject = "WAYBetter Ride: %s" % ride.id t = get_template("voucher_email.html") html = t.render(Context(template_args)) # logging.info(html) if ride.station.vouchers_emails: emails = filter(lambda i: bool(i), COMMA_SPLITTER.split(ride.station.vouchers_emails)) # let us know so we will contact the station resend_voucher_html = html.replace( "</body>", "<br><br><a href='http://www.waybetter.com%s'>Resend Voucher</a></body>" % reverse(resend_voucher, kwargs={"ride_id": ride_id})) notify_by_email(u"Ride [%s] Voucher sent to %s [%s]" % (ride.id, ride.station.name, ",".join(emails)), html=resend_voucher_html, attachments=[("voucher.html", html.encode("utf-8"))]) for email in emails: try: validate_email(email) send_mail_as_noreply(email, subject, html=html) except ValidationError: logging.warning(u"Strange email number: %s" % email) if ride.station.printer_id: # send print job to printer print_voucher(ride.station.printer_id, html, subject, ride_id) elif ride.station.fax_number: # send fax to station logging.warning("No printer_id defined. Sending Fax") fax_voucher(ride.station.fax_number, html, subject, ride_id) else: logging.info("no voucher sent for station [%s]" % ride.station) translation.activate(current_lang) logging.info("ride [%s] voucher sent" % ride.id)
def registration_view(request): if request.user.is_authenticated(): return HttpResponseRedirect(reverse(account_view)) if request.method == "GET": BIEvent.log(BIEventType.REGISTRATION_START, request=request) title = _("Join WAYbetter") return render_to_response("mobile/account_registration.html", locals(), RequestContext(request)) elif request.method == "POST": email = request.POST.get("email") phone = request.POST.get("phone") try: validate_email(email) except ValidationError: return JSONResponse({"error": _("Invalid email")}) # fail if email is registered if User.objects.filter(username=email).count() > 0: notify_by_email("Help! I can't register!", msg="email %s already registered\n%s" % (email, phone)) return JSONResponse( {"account_exists": True, "error": _("This email address was registered by another user.")} ) # fail if phone is registered to more than 1 passenger country = Country.objects.get(code=settings.DEFAULT_COUNTRY_CODE) existing_passengers = Passenger.objects.filter(phone=phone, country=country) if len(existing_passengers) > 1: notify_by_email( "Help! I can't register!", msg="phone %s registered to multiple passengers\n%s" % (phone, existing_passengers), ) return JSONResponse( { "failed": True, "error": _( "This phone number is registered to multiple passengers. Please contact support for help." ), } ) # fail if phone is registered to 1 passenger but this passenger has a user existing_passengers_users = [existing_passenger.user for existing_passenger in existing_passengers] if any(existing_passengers_users): notify_by_email( "Help! I can't register!", msg="phone %s already registered to another user\n%s\n%s" % (phone, email, existing_passengers_users), ) return JSONResponse( { "failed": True, "error": _("This phone number was registered by another user. Please contact support for help."), } ) # by now we know: # 1. email is not registered; we will create a new user # 2. phone is not registered; we will create a new passenger # OR # 3. phone registered to a passenger with NO user; we will keep the passenger and create a user for her passenger = existing_passengers[0] if existing_passengers else None user = register_new_user(request, passenger) if user: redirect = settings.CLOSE_CHILD_BROWSER_URI return JSONResponse({"redirect": redirect, "billing_url": (get_token_url(request))}) else: return JSONResponse({"error": _("Registration failed")}) else: return HttpResponseNotAllowed(request.method)
def do_register_passenger(request): """ A one stop shop for handling registration of a new phone number, generationg a login token and updating the session. We make sure the request is made by an authenticated user. In case of validating: 1. Existing phone number (existing passenger) If request.user is already a passenger, merge request.user.passenger into the existing passenger. Connect the (merged) existing passenger to request.user and delete any previous passenger.user. 2. New phone number (new passenger) If request.user is already a passenger change his phone number. Otherwise, create a new passenger connected to request.user. """ if not request.user.is_authenticated(): return HttpResponseForbidden( _("You must be logged in to validate your phone.")) local_phone = request.POST.get('local_phone') country = Country.objects.get(code=settings.DEFAULT_COUNTRY_CODE) verification_code = int(request.POST.get('verification_code', -1)) response, passenger = validate_passenger_phone(request, local_phone, country, verification_code) if response.status_code != 200: # verification failed return response if passenger: # existing passenger try: user_passenger = request.user.passenger except Passenger.DoesNotExist: user_passenger = None if user_passenger and passenger != user_passenger: #TODO_WB: merge passengers notify_by_email( "Merge Passengers Required", u"request.user.passenger:%s\nvalidated passenger:%s" % (request.user.passenger, passenger)) return HttpResponseBadRequest( _("We are sorry but your phone cannot be changed now. We will contact you to resolve this issue as soon as possible" )) # request.user should be is_authenticated if we get here if passenger.user and passenger.user != request.user: safe_delete_user(passenger.user, remove_from_db=True) passenger.user = request.user else: # new passenger try: # user is already a passenger, change phone passenger = request.user.passenger passenger.phone = local_phone except Passenger.DoesNotExist: # user is not a passenger, create new passenger = create_passenger(request.user, country, local_phone, save=False) # request.session[CURRENT_PASSENGER_KEY] = passenger passenger.login_token = hashlib.sha1( generate_random_token(length=40)).hexdigest() passenger.save() request.session[CURRENT_PASSENGER_KEY] = passenger return JSONResponse({"redirect": reverse(post_login_redirect)})
def registration_view(request): if request.user.is_authenticated(): return HttpResponseRedirect(reverse(account_view)) if request.method == 'GET': BIEvent.log(BIEventType.REGISTRATION_START, request=request) title = _("Join WAYbetter") return render_to_response("mobile/account_registration.html", locals(), RequestContext(request)) elif request.method == 'POST': email = request.POST.get("email") phone = request.POST.get("phone") try: validate_email(email) except ValidationError: return JSONResponse({'error': _("Invalid email")}) # fail if email is registered if User.objects.filter(username=email).count() > 0: notify_by_email("Help! I can't register!", msg="email %s already registered\n%s" % (email, phone)) return JSONResponse({ 'account_exists': True, 'error': _("This email address was registered by another user.") }) # fail if phone is registered to more than 1 passenger country = Country.objects.get(code=settings.DEFAULT_COUNTRY_CODE) existing_passengers = Passenger.objects.filter(phone=phone, country=country) if len(existing_passengers) > 1: notify_by_email( "Help! I can't register!", msg="phone %s registered to multiple passengers\n%s" % (phone, existing_passengers)) return JSONResponse({ 'failed': True, 'error': _("This phone number is registered to multiple passengers. Please contact support for help." ) }) # fail if phone is registered to 1 passenger but this passenger has a user existing_passengers_users = [ existing_passenger.user for existing_passenger in existing_passengers ] if any(existing_passengers_users): notify_by_email( "Help! I can't register!", msg="phone %s already registered to another user\n%s\n%s" % (phone, email, existing_passengers_users)) return JSONResponse({ 'failed': True, 'error': _("This phone number was registered by another user. Please contact support for help." ) }) # by now we know: # 1. email is not registered; we will create a new user # 2. phone is not registered; we will create a new passenger # OR # 3. phone registered to a passenger with NO user; we will keep the passenger and create a user for her passenger = existing_passengers[0] if existing_passengers else None user = register_new_user(request, passenger) if user: redirect = settings.CLOSE_CHILD_BROWSER_URI return JSONResponse({ 'redirect': redirect, 'billing_url': (get_token_url(request)) }) else: return JSONResponse({'error': _("Registration failed")}) else: return HttpResponseNotAllowed(request.method)
def send_ride_voucher(ride_id): ride = SharedRide.by_id(ride_id) if not (ride and ride.station): logging.error("can't send voucher ride_id=%s" % ride_id) return current_lang = translation.get_language() station_lang_code = settings.LANGUAGES[ride.station.language][0] translation.activate(station_lang_code) pickups = [] dropoffs = [] for p in sorted(ride.points.all(), key=lambda point: point.stop_time): orders = p.pickup_orders.all() if p.type == StopType.PICKUP else p.dropoff_orders.all() stop = { "count": sum([order.num_seats for order in orders]), "address": p.address } phones = ["%s - %s" % (o.passenger.name, o.passenger.phone) for o in orders] if len(phones) == 1: stop["phones"] = phones if p.type == StopType.PICKUP: pickups.append(stop) if p.type == StopType.DROPOFF: dropoffs.append(stop) tariff = RuleSet.get_active_set(ride.depart_time) srz_cost_details = CostDetails.serialize(ride.cost_details) template_args = { "ride": ride, "taxi": ride.taxi_number, "ride_date": ride.depart_time.strftime("%d/%m/%y"), "ride_time": (ride.first_pickup.stop_time - STATION_PICKUP_OFFSET).strftime("%H:%M"), "pickups": pickups, "dropoffs": dropoffs, "charged_stops": max(0, len(pickups) - 1), "cost_details": srz_cost_details, "distance": "%.1f" % float(ride.distance/1000.0) if ride.distance else "", "additional_km": "%.1f" % float(srz_cost_details["additional_meters"]/1000.0) if (srz_cost_details and srz_cost_details["additional_meters"]) else "", "tariff": tariff.name if tariff else "" } subject = "WAYBetter Ride: %s" % ride.id t = get_template("voucher_email.html") html = t.render(Context(template_args)) # logging.info(html) if ride.station.vouchers_emails: emails = filter(lambda i: bool(i), COMMA_SPLITTER.split(ride.station.vouchers_emails)) # let us know so we will contact the station resend_voucher_html = html.replace("</body>", "<br><br><a href='http://www.waybetter.com%s'>Resend Voucher</a></body>" % reverse(resend_voucher, kwargs={"ride_id": ride_id})) notify_by_email(u"Ride [%s] Voucher sent to %s [%s]" % (ride.id, ride.station.name, ",".join(emails)), html=resend_voucher_html, attachments=[("voucher.html", html.encode("utf-8"))]) for email in emails: try: validate_email(email) send_mail_as_noreply(email, subject, html=html) except ValidationError: logging.warning(u"Strange email number: %s" % email) if ride.station.printer_id: # send print job to printer print_voucher(ride.station.printer_id, html, subject, ride_id) elif ride.station.fax_number: # send fax to station logging.warning("No printer_id defined. Sending Fax") fax_voucher(ride.station.fax_number, html, subject, ride_id) else: logging.info("no voucher sent for station [%s]" % ride.station) translation.activate(current_lang) logging.info("ride [%s] voucher sent" % ride.id)