def calc_passenger_rides(offset=0, data=None): if not data: data = {"active":0, "non-active": 0} batch_size = 500 logging.info("querying passengers %s->%s" % (offset, offset + batch_size)) passengers = Passenger.objects.all()[offset: offset + batch_size] for p in passengers: try: bi = p.billing_info except BillingInfo.DoesNotExist: continue orders = list(Order.objects.filter(passenger=p, type__in=[OrderType.SHARED, OrderType.PRIVATE])) if not orders: continue active = False for o in orders: if o.ride: active = True break if active: data["active"] += 1 else: data["non-active"] += 1 if passengers: deferred.defer(calc_passenger_rides, offset=offset + batch_size + 1, data=data) else: logging.info("all done, sending report\n%s" % data) send_mail_as_noreply("*****@*****.**", "passenger rides", msg="%s" % data)
def calc_kpi3(start_index=0, two_address=0, single_address=0, order_count=0): logging.info("calc_kpi3: starting at: %d" % start_index) orders = Order.objects.filter(type=OrderType.PICKMEAPP)[start_index:] first = False order = None try: for o in orders: order = o if not first: logging.info("First order = %s" % o) first = True order_count += 1 if o.from_raw and o.to_raw: two_address += 1 else: single_address +=1 except : logging.info("DB timeout raised after %d\nlast order = %s" % (order_count, order)) deferred.defer(calc_kpi3, start_index=order_count, two_address=two_address, single_address=single_address, order_count=order_count) if orders: deferred.defer(calc_kpi3, start_index=order_count, two_address=two_address, single_address=single_address, order_count=order_count) else: # send_mail_as_noreply("*****@*****.**", "KPIs", attachments=[("kpis.csv", csv_file)]) send_mail_as_noreply("*****@*****.**", "KPIs - Order Addresses", msg="count=%d, single=%d, double=%d" % (order_count, single_address, two_address))
def create_user(username, password="", email="", first_name="", last_name="", save=True): user = User.objects.create_user(username, email, password) user.first_name = (first_name or "").strip() user.last_name = (last_name or "").strip() if email and not user.first_name: user.first_name = email.split("@")[0] if save: user.save() # welcome the new user if user.email: t = get_template("welcome_email.html") context = Context({'passenger_name': user.first_name or ''}) send_mail_as_noreply(user.email, u"WAYbetter - %s" % ugettext("Shared Taxi Rides"), html=t.render(context)) logging.info("welcome new user: %s" % user) return user
def feb_statistics(): sharing_launched = set_default_tz_time( datetime.datetime(2011, 10, 1, 0, 0, 0)) feb_start = datetime.date(2012, 2, 1) feb_end = datetime.date(2012, 3, 1) - datetime.timedelta(days=1) rides = filter( lambda ride: ride.debug == False, SharedRide.objects.filter(create_date__gte=sharing_launched)) orders = [order for ride in rides for order in ride.orders.all()] sharing_passengers = set([order.passenger for order in orders]) feb_rides = [] pre_feb_sharing_passengers = set() for ride in rides: if feb_start <= ride.create_date.date() <= feb_end: feb_rides.append(ride) feb_orders = [order for ride in feb_rides for order in ride.orders.all()] for order in feb_orders: if order.passenger.create_date.date() < feb_start: pre_feb_sharing_passengers.add(order.passenger) msg = """ total sharing passengers: %s total orders: %s orders in february: %s passengers registered before feb 1st and ordered in feb: %s """ % (len(sharing_passengers), len(orders), len(feb_orders), len(pre_feb_sharing_passengers)) send_mail_as_noreply("*****@*****.**", "feb stats", msg)
def calc_passenger_order_freq(offset=0, data=None): if not data: data = {"7": 0, "14":0, "30": 0, "longer": 0, "avg": 0, "count": 0} batch_size = 500 logging.info("querying passengers %s->%s" % (offset, offset + batch_size)) passengers = Passenger.objects.all()[offset: offset + batch_size] for p in passengers: orders = list(Order.objects.filter(passenger=p, type__in=[OrderType.SHARED, OrderType.PRIVATE])) orders = sorted(orders, key=lambda o: o.create_date) orders = filter(lambda o: o.ride, orders) for i, o in enumerate(orders): if len(orders) > i + 1: td = orders[i + 1].create_date - o.create_date days = td.days if not days: days = td.seconds / 60.0 / 60.0 / 24.0 data["avg"] = (data["avg"] * data["count"] + days) / float(data["count"] + 1) data["count"] += 1 if days <= 7: data["7"] += 1 elif days <= 14: data["14"] += 1 elif days <= 30: data["30"] += 1 else: data["longer"] += 1 if passengers: deferred.defer(calc_passenger_order_freq, offset=offset + batch_size + 1, data=data) else: logging.info("all done, sending report\n%s" % data) send_mail_as_noreply("*****@*****.**", "Order freq", msg="%s" % data)
def calc_passenger_ride_freq(offset=0, data=None): if not data: data = [["id", "orders", "days"]] else: data = pickle.loads(gzip.zlib.decompress(data)) batch_size = 500 logging.info("querying passengers %s->%s" % (offset, offset + batch_size)) passengers = Passenger.objects.all()[offset: offset + batch_size] for p in passengers: try: bi = p.billing_info except BillingInfo.DoesNotExist: continue days = (default_tz_now() - bi.create_date).days if days: orders = list(Order.objects.filter(passenger=p, type__in=[OrderType.SHARED, OrderType.PRIVATE])) orders = filter(lambda o: o.ride, orders) data.append([p.id, len(orders), days]) if passengers: data = gzip.zlib.compress(pickle.dumps(data), 9) deferred.defer(calc_passenger_ride_freq, offset=offset + batch_size + 1, data=data) else: logging.info("all done, sending report\n%s" % data) csv_string = "" for line in data: csv_string += ",".join([str(i) for i in line]) + "\n" send_mail_as_noreply("*****@*****.**", "Passenger ride freq", attachments=[("passenger_freq.csv", csv_string)])
def calc_order_timing(offset=0, hours=None): if not hours: hours = {} batch_size = 500 logging.info("querying shared rides %s->%s" % (offset, offset + batch_size)) orders = Order.objects.filter(type=OrderType.PICKMEAPP)[offset:offset + batch_size] for o in orders: hour = str(o.create_date.hour) if hour in hours: hours[hour] += 1 else: hours[hour] = 1 if orders: deferred.defer(calc_order_timing, offset=offset + batch_size + 1, hours=hours) else: logging.info("all done, sending report\n%s" % hours) csv = ",".join(hours.keys()) + "\n" + ",".join( [str(v) for v in hours.values()]) send_mail_as_noreply("*****@*****.**", "Shared rides data for NY", attachments=[("order_timing.csv", csv)])
def calc_station_rating(offset=0, data=None): if not data: data = {} batch_size = 500 logging.info("querying orders %s->%s" % (offset, offset + batch_size)) orders = Order.objects.filter(type=OrderType.PICKMEAPP)[offset: offset + batch_size] for o in orders: if not o.station: continue if not o.passenger_rating: continue station_name = o.station.name if station_name in data: count, avg = data[station_name] avg = (count*avg + o.passenger_rating) / float(count+1) count += 1 data[station_name] = (count, avg) else: data[station_name] = (1, o.passenger_rating) if orders: deferred.defer(calc_station_rating, offset=offset + batch_size + 1, data=data) else: logging.info("all done, sending report\n%s" % data) csv = [["Station Name", "Ratings", "Avg"]] for s in data.keys(): csv.append([s, data[s][0], data[s][1]]) csv_string = "" logging.info("csv = %s" % csv) for line in csv: csv_string += ",".join(line) + "\n" send_mail_as_noreply("*****@*****.**", "Shared rides data for NY", attachments=[("stations_ratings.csv", csv_string)])
def calc_orders_data_csv(recipient, batch_size, offset=0, csv_bytestring=u"", calc_cost=False): link_domain = "www.waybetter.com" logging.info("querying computations %s->%s" % (offset, offset + batch_size)) start_dt = set_default_tz_time(datetime(2012, 1, 1)) end_dt = set_default_tz_time(datetime.now()) station, station_cost_rules = None, [] computations = [] #TODO_WB: no computations any more... fix if needed for computation in computations: if computation.debug: continue rides = computation.rides.all() total_interval_orders = sum([ride.orders.count() for ride in rides]) for ride in rides: orders = ride.orders.all() count_orders = len(orders) for order in orders: depart_day = order.depart_time.date().isoformat() if order.depart_time else "" depart_time = order.depart_time.time().strftime("%H:%M") if order.depart_time else "" arrive_day = order.arrive_time.date().isoformat() if order.arrive_time else "" arrive_time = order.arrive_time.time().strftime("%H:%M") if order.arrive_time else "" hotspot_type = computation.get_hotspot_type_display() ordering_td = (order.depart_time or order.arrive_time) - order.create_date ordering_td_format = str(ordering_td).split(".")[0] # trim microseconds passenger_name = order.passenger.full_name shared = "yes" if count_orders > 1 else "" price = order.get_billing_amount() cost = 0 if calc_cost: if ride.station and ride.station != station: # store the rules in memory to reduce queries station = ride.station station_cost_rules = list(ride.station.fixed_prices.all()) logging.info("got new prices from station %s (was %s)" % (ride.station, station)) for rule in station_cost_rules: if rule.is_active(order.from_lat, order.from_lon, order.to_lat, order.to_lon, ride.depart_time): cost = rule.price link = "http://%s/%s" % (link_domain , reverse(ride_page, args=[ride.id])) order_data = [depart_day, depart_time, arrive_day, arrive_time, ordering_td_format, passenger_name, order.from_raw, order.from_lat, order.from_lon, order.to_raw, order.to_lat, order.to_lon, hotspot_type, shared, order.computation_id, total_interval_orders, price, cost, link] csv_bytestring += u";".join([unicode(i).replace(";", "").replace('"', '') for i in order_data]) csv_bytestring += u"\n" if computations: deferred.defer(calc_orders_data_csv, recipient, batch_size, offset=offset + batch_size + 1, csv_bytestring=csv_bytestring, calc_cost=calc_cost) else: logging.info("all done, sending data...") timestamp = date.today() send_mail_as_noreply(recipient, "Orders data %s" % timestamp, attachments=[("orders_data_%s.csv" % timestamp, csv_bytestring)])
def calc_users_data_csv(recipient ,offset=0, csv_bytestring=u""): batch_size = 500 datetime_format = "%d/%m/%y" link_domain = "www.waybetter.com" logging.info("querying users %s->%s" % (offset, offset + batch_size)) users = User.objects.order_by("-last_login")[offset: offset + batch_size] for user in users: link = "" last_login = user.last_login.strftime(datetime_format) date_joined = user.date_joined.strftime(datetime_format) first_name = user.first_name last_name = user.last_name email = user.email phone = "" billing_info = "" first_order_date = "" last_order_date = "" num_orders_mobile = "" num_orders_website = "" num_rides = "" total_payment = "" try: passenger = user.passenger link = "http://%s/%s" % (link_domain , reverse(view_passenger_orders, args=[passenger.id])) phone = passenger.phone if hasattr(passenger, "billing_info"): billing_info = "yes" orders = sorted(passenger.orders.filter(type=OrderType.SHARED, debug=False), key=lambda order: order.create_date) num_orders = len(orders) if num_orders: first_order_date = orders[0].create_date.strftime(datetime_format) last_order_date = orders[-1].create_date.strftime(datetime_format) dispatched_orders = filter(lambda o: o.ride, orders) total_payment = sum([order.get_billing_amount() for order in dispatched_orders]) num_rides = len(dispatched_orders) num_orders_mobile = len(filter(lambda o: o.mobile, orders)) num_orders_website = num_orders - num_orders_mobile except Passenger.DoesNotExist: pass except Passenger.MultipleObjectsReturned: pass user_data = [last_login, first_order_date, last_order_date, date_joined, first_name, last_name, email, phone, num_orders_mobile, num_orders_website, num_rides, billing_info, total_payment, link] csv_bytestring += u",".join([unicode(i).replace(",", "") for i in user_data]) csv_bytestring += u"\n" if users: deferred.defer(calc_users_data_csv, recipient, offset=offset + batch_size + 1, csv_bytestring=csv_bytestring) else: logging.info("all done, sending data...") timestamp = date.today() logging.info(csv_bytestring) send_mail_as_noreply(recipient, "Users data %s" % timestamp, attachments=[("users_data_%s.csv" % timestamp, csv_bytestring)])
def calc_ny_sharing(offset=0, count=0, value=0): batch_size = 500 logging.info("querying shared rides %s->%s" % (offset, offset + batch_size)) s = Station.by_id(1529226) shared_rides = SharedRide.objects.filter(station=s)[offset: offset + batch_size] for sr in shared_rides: count += 1 value += sr.cost if shared_rides: deferred.defer(calc_ny_sharing, offset=offset + batch_size + 1, count=count, value=value) else: logging.info("all done, sending report") send_mail_as_noreply("*****@*****.**", "Shared rides data for NY", msg="count=%d, value=%f" % (count, value))
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 calc_pickmeapp_passenger_count(offset=0, count=0): batch_size = 500 logging.info("querying passengers %s->%s" % (offset, offset + batch_size)) passengers = Passenger.objects.all()[offset: offset + batch_size] for p in passengers: pickemapp_orders = p.orders.filter(type=OrderType.PICKMEAPP) if pickemapp_orders: count +=1 if passengers: logging.info("continue to next batch: %s" % count) deferred.defer(calc_pickmeapp_passenger_count, offset=offset + batch_size + 1, count=count) else: logging.info("all done, sending report\n%s" % count) send_mail_as_noreply("*****@*****.**", "Passenger count - pickmeapp", msg="count = %s" % count)
def calc_order_timing(offset=0, hours=None): if not hours: hours = {} batch_size = 500 logging.info("querying shared rides %s->%s" % (offset, offset + batch_size)) orders = Order.objects.filter(type=OrderType.PICKMEAPP)[offset: offset + batch_size] for o in orders: hour = str(o.create_date.hour) if hour in hours: hours[hour] += 1 else: hours[hour] = 1 if orders: deferred.defer(calc_order_timing, offset=offset + batch_size + 1, hours=hours) else: logging.info("all done, sending report\n%s" % hours) csv = ",".join(hours.keys()) + "\n" + ",".join([str(v) for v in hours.values()]) send_mail_as_noreply("*****@*****.**", "Shared rides data for NY", attachments=[("order_timing.csv", csv)])
def calc_pickmeapp_passenger_count(offset=0, count=0): batch_size = 500 logging.info("querying passengers %s->%s" % (offset, offset + batch_size)) passengers = Passenger.objects.all()[offset:offset + batch_size] for p in passengers: pickemapp_orders = p.orders.filter(type=OrderType.PICKMEAPP) if pickemapp_orders: count += 1 if passengers: logging.info("continue to next batch: %s" % count) deferred.defer(calc_pickmeapp_passenger_count, offset=offset + batch_size + 1, count=count) else: logging.info("all done, sending report\n%s" % count) send_mail_as_noreply("*****@*****.**", "Passenger count - pickmeapp", msg="count = %s" % count)
def calc_passenger_order_freq(offset=0, data=None): if not data: data = {"7": 0, "14": 0, "30": 0, "longer": 0, "avg": 0, "count": 0} batch_size = 500 logging.info("querying passengers %s->%s" % (offset, offset + batch_size)) passengers = Passenger.objects.all()[offset:offset + batch_size] for p in passengers: orders = list( Order.objects.filter( passenger=p, type__in=[OrderType.SHARED, OrderType.PRIVATE])) orders = sorted(orders, key=lambda o: o.create_date) orders = filter(lambda o: o.ride, orders) for i, o in enumerate(orders): if len(orders) > i + 1: td = orders[i + 1].create_date - o.create_date days = td.days if not days: days = td.seconds / 60.0 / 60.0 / 24.0 data["avg"] = (data["avg"] * data["count"] + days) / float(data["count"] + 1) data["count"] += 1 if days <= 7: data["7"] += 1 elif days <= 14: data["14"] += 1 elif days <= 30: data["30"] += 1 else: data["longer"] += 1 if passengers: deferred.defer(calc_passenger_order_freq, offset=offset + batch_size + 1, data=data) else: logging.info("all done, sending report\n%s" % data) send_mail_as_noreply("*****@*****.**", "Order freq", msg="%s" % data)
def calc_ny_sharing(offset=0, count=0, value=0): batch_size = 500 logging.info("querying shared rides %s->%s" % (offset, offset + batch_size)) s = Station.by_id(1529226) shared_rides = SharedRide.objects.filter(station=s)[offset:offset + batch_size] for sr in shared_rides: count += 1 value += sr.cost if shared_rides: deferred.defer(calc_ny_sharing, offset=offset + batch_size + 1, count=count, value=value) else: logging.info("all done, sending report") send_mail_as_noreply("*****@*****.**", "Shared rides data for NY", msg="count=%d, value=%f" % (count, value))
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 calc_kpi3(start_index=0, two_address=0, single_address=0, order_count=0): logging.info("calc_kpi3: starting at: %d" % start_index) orders = Order.objects.filter(type=OrderType.PICKMEAPP)[start_index:] first = False order = None try: for o in orders: order = o if not first: logging.info("First order = %s" % o) first = True order_count += 1 if o.from_raw and o.to_raw: two_address += 1 else: single_address += 1 except: logging.info("DB timeout raised after %d\nlast order = %s" % (order_count, order)) deferred.defer(calc_kpi3, start_index=order_count, two_address=two_address, single_address=single_address, order_count=order_count) if orders: deferred.defer(calc_kpi3, start_index=order_count, two_address=two_address, single_address=single_address, order_count=order_count) else: # send_mail_as_noreply("*****@*****.**", "KPIs", attachments=[("kpis.csv", csv_file)]) send_mail_as_noreply("*****@*****.**", "KPIs - Order Addresses", msg="count=%d, single=%d, double=%d" % (order_count, single_address, two_address))
def calc_passenger_ride_freq(offset=0, data=None): if not data: data = [["id", "orders", "days"]] else: data = pickle.loads(gzip.zlib.decompress(data)) batch_size = 500 logging.info("querying passengers %s->%s" % (offset, offset + batch_size)) passengers = Passenger.objects.all()[offset:offset + batch_size] for p in passengers: try: bi = p.billing_info except BillingInfo.DoesNotExist: continue days = (default_tz_now() - bi.create_date).days if days: orders = list( Order.objects.filter( passenger=p, type__in=[OrderType.SHARED, OrderType.PRIVATE])) orders = filter(lambda o: o.ride, orders) data.append([p.id, len(orders), days]) if passengers: data = gzip.zlib.compress(pickle.dumps(data), 9) deferred.defer(calc_passenger_ride_freq, offset=offset + batch_size + 1, data=data) else: logging.info("all done, sending report\n%s" % data) csv_string = "" for line in data: csv_string += ",".join([str(i) for i in line]) + "\n" send_mail_as_noreply("*****@*****.**", "Passenger ride freq", attachments=[("passenger_freq.csv", csv_string)])
def calc_passenger_rides(offset=0, data=None): if not data: data = {"active": 0, "non-active": 0} batch_size = 500 logging.info("querying passengers %s->%s" % (offset, offset + batch_size)) passengers = Passenger.objects.all()[offset:offset + batch_size] for p in passengers: try: bi = p.billing_info except BillingInfo.DoesNotExist: continue orders = list( Order.objects.filter( passenger=p, type__in=[OrderType.SHARED, OrderType.PRIVATE])) if not orders: continue active = False for o in orders: if o.ride: active = True break if active: data["active"] += 1 else: data["non-active"] += 1 if passengers: deferred.defer(calc_passenger_rides, offset=offset + batch_size + 1, data=data) else: logging.info("all done, sending report\n%s" % data) send_mail_as_noreply("*****@*****.**", "passenger rides", msg="%s" % data)
def calc_station_rating(offset=0, data=None): if not data: data = {} batch_size = 500 logging.info("querying orders %s->%s" % (offset, offset + batch_size)) orders = Order.objects.filter(type=OrderType.PICKMEAPP)[offset:offset + batch_size] for o in orders: if not o.station: continue if not o.passenger_rating: continue station_name = o.station.name if station_name in data: count, avg = data[station_name] avg = (count * avg + o.passenger_rating) / float(count + 1) count += 1 data[station_name] = (count, avg) else: data[station_name] = (1, o.passenger_rating) if orders: deferred.defer(calc_station_rating, offset=offset + batch_size + 1, data=data) else: logging.info("all done, sending report\n%s" % data) csv = [["Station Name", "Ratings", "Avg"]] for s in data.keys(): csv.append([s, data[s][0], data[s][1]]) csv_string = "" logging.info("csv = %s" % csv) for line in csv: csv_string += ",".join(line) + "\n" send_mail_as_noreply("*****@*****.**", "Shared rides data for NY", attachments=[("stations_ratings.csv", csv_string) ])
def generate_passengers_list(): jan_first = datetime.datetime.combine(datetime.date(2012, 1, 1), default_tz_time_min()) rides = SharedRide.objects.filter(depart_time__gte=jan_first) passengers = [] for ride in rides: if ride.debug: continue for o in ride.orders.all(): if o.passenger.create_date > jan_first: passengers.append(o.passenger) passengers = set(passengers) csv = u"" for p in passengers: user = p.user csv += u",".join([user.email, user.get_full_name()]) csv += u"\n" send_mail_as_noreply("*****@*****.**", "passengers list", attachments=[("passengers.csv", csv.encode("utf-8"))])
def notify(self): subject = u"WAYbetter - מהפכה בתחבורה, מוניות ספיישל לכולם!" t = get_template("pilot_interest_email.html") html = t.render(Context({})) send_mail_as_noreply(self.email, subject, html=html)
my_orders = filter(lambda o: o.passenger == passenger, orders) if my_orders: my_first_order = sorted(my_orders, key=lambda o: o.create_date)[0] try: csv += u",".join([ unicode(v) for v in [ my_first_order.depart_time.date().isoformat(), passenger.full_name, passenger.phone ] ]) csv += u"\n" except Exception, e: logging.error("order[%s]: %s" % (my_first_order.id, e.message)) send_mail_as_noreply("*****@*****.**", "first rides data", attachments=[("first_ride_stats.csv", csv)]) def feb_statistics(): sharing_launched = set_default_tz_time( datetime.datetime(2011, 10, 1, 0, 0, 0)) feb_start = datetime.date(2012, 2, 1) feb_end = datetime.date(2012, 3, 1) - datetime.timedelta(days=1) rides = filter( lambda ride: ride.debug == False, SharedRide.objects.filter(create_date__gte=sharing_launched)) orders = [order for ride in rides for order in ride.orders.all()] sharing_passengers = set([order.passenger for order in orders])
def calc_users_data_csv(recipient, offset=0, csv_bytestring=u""): batch_size = 500 datetime_format = "%d/%m/%y" link_domain = "www.waybetter.com" logging.info("querying users %s->%s" % (offset, offset + batch_size)) users = User.objects.order_by("-last_login")[offset:offset + batch_size] for user in users: link = "" last_login = user.last_login.strftime(datetime_format) date_joined = user.date_joined.strftime(datetime_format) first_name = user.first_name last_name = user.last_name email = user.email phone = "" billing_info = "" first_order_date = "" last_order_date = "" num_orders_mobile = "" num_orders_website = "" num_rides = "" total_payment = "" try: passenger = user.passenger link = "http://%s/%s" % (link_domain, reverse(view_passenger_orders, args=[passenger.id])) phone = passenger.phone if hasattr(passenger, "billing_info"): billing_info = "yes" orders = sorted(passenger.orders.filter(type=OrderType.SHARED, debug=False), key=lambda order: order.create_date) num_orders = len(orders) if num_orders: first_order_date = orders[0].create_date.strftime( datetime_format) last_order_date = orders[-1].create_date.strftime( datetime_format) dispatched_orders = filter(lambda o: o.ride, orders) total_payment = sum([ order.get_billing_amount() for order in dispatched_orders ]) num_rides = len(dispatched_orders) num_orders_mobile = len(filter(lambda o: o.mobile, orders)) num_orders_website = num_orders - num_orders_mobile except Passenger.DoesNotExist: pass except Passenger.MultipleObjectsReturned: pass user_data = [ last_login, first_order_date, last_order_date, date_joined, first_name, last_name, email, phone, num_orders_mobile, num_orders_website, num_rides, billing_info, total_payment, link ] csv_bytestring += u",".join( [unicode(i).replace(",", "") for i in user_data]) csv_bytestring += u"\n" if users: deferred.defer(calc_users_data_csv, recipient, offset=offset + batch_size + 1, csv_bytestring=csv_bytestring) else: logging.info("all done, sending data...") timestamp = date.today() logging.info(csv_bytestring) send_mail_as_noreply(recipient, "Users data %s" % timestamp, attachments=[("users_data_%s.csv" % timestamp, csv_bytestring)])
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 calc_kpi2(r): data = [[ "Month", "New Users", "Active Users", "Avg. Rides per User", "Avg. Occupancy", "Stickiness", "Income" ]] for month_offset in xrange(0, r): logging.info("kpi for %s" % month_offset) def get_query_date_range_by_month_offset(month_offset): now = default_tz_now() if now.month > month_offset: d = now.replace(month=now.month - month_offset) else: d = now.replace(month=now.month - month_offset + 12, year=now.year - 1) start_day, end_day = calendar.monthrange(d.year, d.month) start_date = default_tz_now_min().replace(day=1, month=d.month, year=d.year) end_date = default_tz_now_max().replace(day=end_day, month=d.month, year=d.year) return start_date, end_date start_date, end_date = get_query_date_range_by_month_offset( month_offset) rides = SharedRide.objects.filter(create_date__gte=start_date, create_date__lte=end_date, debug=False) all_bi = BillingInfo.objects.filter(create_date__gte=start_date, create_date__lte=end_date) new_passengers = set() income = 0 for bi in all_bi: try: p = bi.passenger new_passengers.add(p) except Passenger.DoesNotExist: pass active_passengers = set() number_of_people_in_rides = 0 for ride in rides: orders = ride.orders.all() for o in orders: try: p = o.passenger active_passengers.add(p) except Passenger.DoesNotExist: pass number_of_people_in_rides += o.num_seats income += sum( [bt.amount for bt in o.billing_transactions.all()]) sticky_passengers = set() for a_p in active_passengers: prev_orders = Order.objects.filter( passenger=a_p, depart_time__lte=start_date, type=OrderType.SHARED, status__in=[APPROVED, ACCEPTED, CHARGED]).order_by( "-depart_time") # sorting to re-use existing index if prev_orders: sticky_passengers.add(a_p) line = [ end_date.strftime( "%m/%d/%Y"), # prepared for google docs trend chart len(new_passengers), len(active_passengers), len(rides) / float(len(active_passengers)) if len(active_passengers) else "NA", number_of_people_in_rides / float(len(rides)) if len(rides) else "NA", len(sticky_passengers) / float(len(active_passengers)) * 100 if len(active_passengers) else "NA", income / float(1000) ] data.append(line) csv_file = "" for line in data: logging.info("line = %s" % line) line = [round(i, 2) if isinstance(i, float) else i for i in line] csv_file += u",".join([unicode(i) for i in line]) csv_file += "\n" send_mail_as_noreply("*****@*****.**", "KPIs", attachments=[("kpis.csv", csv_file)])
def calc_orders_data_csv(recipient, batch_size, offset=0, csv_bytestring=u"", calc_cost=False): link_domain = "www.waybetter.com" logging.info("querying computations %s->%s" % (offset, offset + batch_size)) start_dt = set_default_tz_time(datetime(2012, 1, 1)) end_dt = set_default_tz_time(datetime.now()) station, station_cost_rules = None, [] computations = [] #TODO_WB: no computations any more... fix if needed for computation in computations: if computation.debug: continue rides = computation.rides.all() total_interval_orders = sum([ride.orders.count() for ride in rides]) for ride in rides: orders = ride.orders.all() count_orders = len(orders) for order in orders: depart_day = order.depart_time.date().isoformat( ) if order.depart_time else "" depart_time = order.depart_time.time().strftime( "%H:%M") if order.depart_time else "" arrive_day = order.arrive_time.date().isoformat( ) if order.arrive_time else "" arrive_time = order.arrive_time.time().strftime( "%H:%M") if order.arrive_time else "" hotspot_type = computation.get_hotspot_type_display() ordering_td = (order.depart_time or order.arrive_time) - order.create_date ordering_td_format = str(ordering_td).split(".")[ 0] # trim microseconds passenger_name = order.passenger.full_name shared = "yes" if count_orders > 1 else "" price = order.get_billing_amount() cost = 0 if calc_cost: if ride.station and ride.station != station: # store the rules in memory to reduce queries station = ride.station station_cost_rules = list( ride.station.fixed_prices.all()) logging.info( "got new prices from station %s (was %s)" % (ride.station, station)) for rule in station_cost_rules: if rule.is_active(order.from_lat, order.from_lon, order.to_lat, order.to_lon, ride.depart_time): cost = rule.price link = "http://%s/%s" % (link_domain, reverse(ride_page, args=[ride.id])) order_data = [ depart_day, depart_time, arrive_day, arrive_time, ordering_td_format, passenger_name, order.from_raw, order.from_lat, order.from_lon, order.to_raw, order.to_lat, order.to_lon, hotspot_type, shared, order.computation_id, total_interval_orders, price, cost, link ] csv_bytestring += u";".join([ unicode(i).replace(";", "").replace('"', '') for i in order_data ]) csv_bytestring += u"\n" if computations: deferred.defer(calc_orders_data_csv, recipient, batch_size, offset=offset + batch_size + 1, csv_bytestring=csv_bytestring, calc_cost=calc_cost) else: logging.info("all done, sending data...") timestamp = date.today() send_mail_as_noreply(recipient, "Orders data %s" % timestamp, attachments=[("orders_data_%s.csv" % timestamp, csv_bytestring)])
def calc_order_per_day_pickmeapp(offset=0, data=None): if not data: data = {"avg": 0, "count": 0} batch_size = 500 days_threshold = 3 logging.info("querying passengers %s->%s" % (offset, offset + batch_size)) passengers = Passenger.objects.all()[offset:offset + batch_size] for p in passengers: skip_passenger = False orders = list( Order.objects.filter(passenger=p, type=OrderType.PICKMEAPP)) orders = filter(lambda o: not o.debug, orders) orders = sorted(orders, key=lambda o: o.create_date) if len(p.phone) != 10 or (not p.phone.startswith("05")): skip_passenger = True if len(orders) < 2: # logging.info("skipping passenger[%s]: not enough orders (%d)" % (p.id, len(orders))) skip_passenger = True if not skip_passenger: used_days = {} for o in orders: day = o.create_date.strftime("%Y/%m/%d") if day in used_days: if used_days[day] >= days_threshold: logging.info( "skipping passenger[%s]: too many orders per day: %s" % (p.id, day)) skip_passenger = True break else: used_days[day] += 1 else: used_days[day] = 1 if skip_passenger: continue first_order = orders[0] last_order = orders[-1] td = (last_order.create_date - first_order.create_date) interval = td.days if interval < 3: continue # if not interval: # if td.seconds >= 60 * 15: # interval += td.seconds / 60.0 / 60.0 / 24.0 if interval: avg = len(orders) / float(interval) data["avg"] = (data["avg"] * data["count"] + avg) / float(data["count"] + 1) data["count"] += 1 logging.info( "avg for passenger: %s is %f (orders=%d, interval=%f)\ndata=%s" % (p, avg, len(orders), interval, data)) else: logging.info( "skipping passenger[%s]: interval=0 for orders[%s, %s]" % (p.id, first_order, last_order)) if passengers: logging.info("continue to next batch: %s" % data) deferred.defer(calc_order_per_day_pickmeapp, offset=offset + batch_size + 1, data=data) else: logging.info("all done, sending report\n%s" % data) send_mail_as_noreply("*****@*****.**", "Order freq - pickmeapp", msg="%s" % data)
def notify(self): subject = u"תודה על התעניינותך ב WAYbetter" t = get_template("m2m_interest_email.html") html = t.render(Context({})) send_mail_as_noreply(self.email, subject, html=html)
def calc_order_per_day_pickmeapp(offset=0, data=None): if not data: data = {"avg": 0, "count": 0} batch_size = 500 days_threshold = 3 logging.info("querying passengers %s->%s" % (offset, offset + batch_size)) passengers = Passenger.objects.all()[offset: offset + batch_size] for p in passengers: skip_passenger = False orders = list(Order.objects.filter(passenger=p, type=OrderType.PICKMEAPP)) orders = filter(lambda o: not o.debug, orders) orders = sorted(orders, key=lambda o: o.create_date) if len(p.phone) != 10 or (not p.phone.startswith("05")): skip_passenger = True if len(orders) < 2: # logging.info("skipping passenger[%s]: not enough orders (%d)" % (p.id, len(orders))) skip_passenger = True if not skip_passenger: used_days = {} for o in orders: day = o.create_date.strftime("%Y/%m/%d") if day in used_days: if used_days[day] >= days_threshold: logging.info("skipping passenger[%s]: too many orders per day: %s" % (p.id, day)) skip_passenger = True break else: used_days[day] += 1 else: used_days[day] = 1 if skip_passenger: continue first_order = orders[0] last_order = orders[-1] td = (last_order.create_date - first_order.create_date) interval = td.days if interval < 3: continue # if not interval: # if td.seconds >= 60 * 15: # interval += td.seconds / 60.0 / 60.0 / 24.0 if interval: avg = len(orders) / float(interval) data["avg"] = (data["avg"] * data["count"] + avg) / float(data["count"] + 1) data["count"] += 1 logging.info("avg for passenger: %s is %f (orders=%d, interval=%f)\ndata=%s" % (p, avg, len(orders), interval, data)) else: logging.info("skipping passenger[%s]: interval=0 for orders[%s, %s]" % (p.id, first_order, last_order)) if passengers: logging.info("continue to next batch: %s" % data) deferred.defer(calc_order_per_day_pickmeapp, offset=offset + batch_size + 1, data=data) else: logging.info("all done, sending report\n%s" % data) send_mail_as_noreply("*****@*****.**", "Order freq - pickmeapp", msg="%s" % data)
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 calc_kpi2(r): data = [["Month", "New Users", "Active Users", "Avg. Rides per User", "Avg. Occupancy", "Stickiness", "Income"]] for month_offset in xrange(0,r): logging.info("kpi for %s" % month_offset) def get_query_date_range_by_month_offset(month_offset): now = default_tz_now() if now.month > month_offset: d = now.replace(month=now.month - month_offset) else: d = now.replace(month=now.month - month_offset + 12, year=now.year -1) start_day, end_day = calendar.monthrange(d.year, d.month) start_date = default_tz_now_min().replace(day=1, month=d.month, year=d.year) end_date = default_tz_now_max().replace(day=end_day, month=d.month, year=d.year) return start_date, end_date start_date, end_date = get_query_date_range_by_month_offset(month_offset) rides = SharedRide.objects.filter(create_date__gte=start_date, create_date__lte=end_date, debug=False) all_bi = BillingInfo.objects.filter(create_date__gte=start_date, create_date__lte=end_date) new_passengers = set() income = 0 for bi in all_bi: try: p = bi.passenger new_passengers.add(p) except Passenger.DoesNotExist: pass active_passengers = set() number_of_people_in_rides = 0 for ride in rides: orders = ride.orders.all() for o in orders: try: p = o.passenger active_passengers.add(p) except Passenger.DoesNotExist: pass number_of_people_in_rides += o.num_seats income += sum([bt.amount for bt in o.billing_transactions.all()]) sticky_passengers = set() for a_p in active_passengers: prev_orders = Order.objects.filter(passenger=a_p, depart_time__lte=start_date, type=OrderType.SHARED, status__in=[APPROVED, ACCEPTED, CHARGED]).order_by("-depart_time") # sorting to re-use existing index if prev_orders: sticky_passengers.add(a_p) line = [ end_date.strftime("%m/%d/%Y"), # prepared for google docs trend chart len(new_passengers), len(active_passengers), len(rides) / float(len(active_passengers)) if len(active_passengers) else "NA", number_of_people_in_rides / float(len(rides)) if len(rides) else "NA", len(sticky_passengers) / float(len(active_passengers)) * 100 if len(active_passengers) else "NA", income / float(1000) ] data.append(line) csv_file = "" for line in data: logging.info("line = %s" % line) line = [round(i, 2) if isinstance(i, float) else i for i in line] csv_file += u",".join([unicode(i) for i in line]) csv_file += "\n" send_mail_as_noreply("*****@*****.**", "KPIs", attachments=[("kpis.csv", csv_file)])