예제 #1
0
def to_time_string(state, datetime_obj):
    """
    Converts python datetime object to a string to be displayed on front end.

    Compares to today's date in order to display "Today" or "Tomorrow".

    Timezone to get today's date is computed using the state the ride departs from.
    """

    tz = state_to_timezone(state)

    today = datetime.now(pytz.timezone(tz)).date()

    if datetime_obj.date() == today:
        datetime_str = "Today, {}".format(datetime_obj.strftime('%-I:%M %p'))

    # If ride is tomorrow, adjust attribute to indicate
    elif datetime_obj.date() == (today + timedelta(days=1)):
        datetime_str = "Tomorrow, {}".format(
            datetime_obj.strftime('%-I:%M %p'))
    # Otherwise change attribute to formatted timestamp string
    else:
        datetime_str = datetime_obj.strftime('%A, %b %d, %Y %-I:%M %p')

    return datetime_str
예제 #2
0
def to_local(state, datetime_obj):
    """
    Convert timestamp from database to local time.
    First converts to tz-aware UTC, then to local time given the rides
    starting state.
    """
    # Use state from database to determine timezone
    tz = state_to_timezone(state)
    # Convert timestamp from db to be aware that it is in utc
    utc = datetime_obj.replace(tzinfo=pytz.utc)
    # Convert start_timestamp attribute to timezone of state
    local = pytz.timezone(tz).normalize(utc)

    return local
예제 #3
0
def to_utc(state, datetime_obj):
    """
    Takes in unaware python datetime object, converts to tz aware, then 
    converts to UTC.

    """
    # Get timezone of starting state or user's state
    tz = state_to_timezone(state)
    # Localize to timezone of state the ride is leaving from
    datetime_aware = pytz.timezone(tz).localize(datetime_obj)
    # Normalize to UTC in order to search DB
    datetime_utc = pytz.utc.normalize(datetime_aware)

    return datetime_utc
예제 #4
0
def to_utc_db_time(state, datetime_obj):
    """
    Takes in unaware python datetime object, converts to tz aware, adding 8hour offset, then 
    converts to UTC.

    """
    # Get timezone of starting state or user's state
    tz = state_to_timezone(state)
    # Localize to timezone of state the ride is leaving from
    datetime_aware = pytz.timezone(tz).localize(datetime_obj)
    utc_offset = datetime_aware.utcoffset().total_seconds() / 60 / 60
    datetime_aware = datetime_aware + timedelta(hours=utc_offset)
    # Normalize to UTC in order to search DB
    datetime_utc = pytz.utc.normalize(datetime_aware)

    return datetime_utc
예제 #5
0
def search_rides():
    """Searches database for rides"""

    # initialize to show 10 results ordered by date
    limit = 10
    cost = 50
    order_by = 'date'

    ### If user clicks 'All Rides' ###
    if request.args.get('query'):

        # Defaulting to the starting toggle points when viewing all rides
        state = ''
        start_time = datetime.strptime("12:00 AM", '%I:%M %p')
        start_time = datetime.combine(datetime.now().date(), start_time.time())
        start_time = to_utc(state, start_time).time()
        date_from = to_utc(state, datetime.now()).date()

        # Query database for all rides
        rides = Ride.get_rides(start_time=start_time,
                               date_from=date_from,
                               cost=cost,
                               limit=limit,
                               order_by=order_by)

        total_count = Ride.get_rides(start_time=start_time,
                                     date_from=date_from,
                                     cost=cost,
                                     order_by=order_by,
                                     count=True)
        # Round up page count with + 1
        page_count = int(math.ceil(float(total_count) / float(limit)))

        for ride in rides:
            # convert ride to local timezone
            ride.start_timestamp = to_local(ride.start_state,
                                            ride.start_timestamp)
            # turn date object into string for front end
            ride.start_timestamp = to_time_string(ride.start_state,
                                                  ride.start_timestamp)

        # Render search page, passing rides and page_count for pagination
        return render_template('search.html',
                               rides=rides,
                               page_count=page_count)

    ### If user enters search terms ###
    else:

        # Start with 15mile square search
        miles = 25
        deg = miles_to_degrees(miles)

        # Get search terms lat/lng
        start_lat = request.args.get('lat')
        start_lng = request.args.get('lng')
        end_lat = request.args.get('lat2')
        end_lng = request.args.get('lng2')

        if not start_lat or not start_lng:
            start_lat = 0.0
            start_lng = 0.0
        else:
            start_lat = float(start_lat)
            start_lng = float(start_lng)

        if not end_lat or not end_lng:
            end_lat = 0.0
            end_lng = 0.0
        else:
            end_lat = float(end_lat)
            end_lng = float(end_lng)

        # Dicts holding search terms to be placed in DOM and used by AJAX when
        #   user toggles search parameters
        start_search = {
            "term": request.args.get('searchstring', ''),
            "state": request.args.get('administrative_area_level_1', ''),
            "lat": start_lat,
            "lng": start_lng
        }
        end_search = {
            "term": request.args.get('searchstring2', ''),
            "state": request.args.get('administrative_area_level_1_2', ''),
            "lat": end_lat,
            "lng": end_lng
        }

        state = start_search['state']
        if not state_to_timezone(state):
            state = ''
        start_time = datetime.strptime("12:00 AM", '%I:%M %p')
        start_time = datetime.combine(datetime.now().date(), start_time.time())
        start_time = to_utc(state, start_time).time()
        date_from = to_utc(state, datetime.now()).date()
        # Get the first 10 results for query
        rides = Ride.get_rides(deg=deg,
                               start_lat=start_lat,
                               start_lng=start_lng,
                               end_lat=end_lat,
                               end_lng=end_lng,
                               limit=limit,
                               start_time=start_time,
                               date_from=date_from,
                               order_by=order_by)
        if len(rides) > limit:
            total_count = Ride.get_rides(deg=deg,
                                         start_lat=start_lat,
                                         start_lng=start_lng,
                                         end_lat=end_lat,
                                         end_lng=end_lng,
                                         limit=limit,
                                         start_time=start_time,
                                         date_from=date_from,
                                         order_by=order_by,
                                         count=True)
            # Round up page count with + 1
            page_count = int(math.ceil(float(total_count) / float(limit)))
        else:
            page_count = 1

        for ride in rides:
            # convert ride to local timezone
            ride.start_timestamp = to_local(ride.start_state,
                                            ride.start_timestamp)
            # turn date object into string for front end
            ride.start_timestamp = to_time_string(ride.start_state,
                                                  ride.start_timestamp)

        return render_template('search.html',
                               rides=rides,
                               start_search=start_search,
                               end_search=end_search,
                               page_count=page_count)
예제 #6
0
def json_test():
    """Return new ride results"""

    #Get search terms

    start_term = request.args.get('start_term')
    end_term = request.args.get('end_term')

    user_lat = request.args.get('user_lat')
    user_lng = request.args.get('user_lng')

    start_lat = request.args.get('start_lat')
    start_lng = request.args.get('start_lng')
    end_lat = request.args.get('end_lat')
    end_lng = request.args.get('end_lng')
    start_state = request.args.get("start_state")

    # Get search toggles (time, cost, date)

    start_time = request.args.get("start")
    cost = request.args.get("cost")

    date_from = request.args.get("date_from")
    date_to = request.args.get("date_to")

    limit = request.args.get("limit")
    offset = request.args.get("offset")
    offset = int(offset) * int(limit)
    order_by = request.args.get("order")

    # If there are no search terms, start_state will be an empty string. In this
    # case it it best to use the clients timezone to cater results to dates/ times in their
    # tz.
    if not start_state:
        # Using a try statement, because if google is unable to geocode the user,
        # I don't want this to error out, any would rather default to 'US/Pacific'
        try:
            start_state = (geocoder.google('{}, {}'.format(user_lat,
                                                           user_lng))).state
            # adding this check, because sometimes this returns odd strings
            if len(start_state) > 2:
                start_state = ''
        except:
            # Blank start states default to 'US/Pacific'
            start_state = ''
    if not state_to_timezone(start_state):
        start_state = ''

    # convert dates and time to utc to be queried against db
    if date_from:
        date_from = datetime.strptime(date_from, '%m/%d/%Y')
        date_from = to_utc(start_state, date_from).date()

    if date_to:
        date_to = datetime.strptime(date_to, '%m/%d/%Y')
        date_to = to_utc(start_state, date_to).date()

    start_time = datetime.strptime(start_time, '%I:%M %p')
    start_time = datetime.combine(datetime.now().date(), start_time.time())
    start_time = to_utc(start_state, start_time).time()
    print '\n\n*******\n{}\n****\n\n'.format(start_time)

    # Convert miles to lat/lng degrees
    deg = miles_to_degrees(25)

    rides = Ride.get_rides(deg=deg,
                           start_lat=start_lat,
                           start_lng=start_lng,
                           end_lat=end_lat,
                           end_lng=end_lng,
                           start_time=start_time,
                           cost=cost,
                           date_to=date_to,
                           date_from=date_from,
                           limit=limit,
                           offset=offset,
                           order_by=order_by)

    print '\nlimit: {}\noffset: {}\norder_by: {}\ndate_from: {}\nstart_time: {}\ncost: {}'.format(
        limit, offset, order_by, date_from, start_time, cost)

    total_count = Ride.get_rides(deg=deg,
                                 start_lat=start_lat,
                                 start_lng=start_lng,
                                 end_lat=end_lat,
                                 end_lng=end_lng,
                                 start_time=start_time,
                                 cost=cost,
                                 date_to=date_to,
                                 date_from=date_from,
                                 count=True)
    print '\ntotal_count: {}\n'.format(total_count)

    json_list = sqlalchemy_to_json(rides, total_count, limit)

    return jsonify(json_list)
예제 #7
0
def all_data():
    """Create some sample data."""

    # In case this is run more than once, empty out existing data
    print "deleting data"
    db.drop_all()

    db.create_all()

    # Add sample employees and departments
    with open('seed-data/users_seed.csv', 'rb') as ride_data:
        reader = csv.reader(ride_data,
                            quotechar="'",
                            delimiter=',',
                            quoting=csv.QUOTE_ALL,
                            skipinitialspace=True)
        reader.next()
        for row in reader:
            user = User(user_id=row[0],
                        fb_userid=row[1],
                        first_name=row[2],
                        last_name=row[3],
                        email=row[4],
                        image=row[5])
            db.session.add(user)
            db.session.commit()

    with open('seed-data/rides_seed.csv', 'rb') as ride_data:

        reader = csv.reader(ride_data,
                            quotechar="'",
                            delimiter=',',
                            quoting=csv.QUOTE_ALL,
                            skipinitialspace=True)
        reader.next()
        gmaps = googlemaps.Client(key=GOOGLE_KEY)

        geocode = defaultdict(defaultdict)

        for row in reader:
            route = row[15]

            if not geocode[route]:

                start_lat = row[3]
                start_lng = row[4]
                end_lat = row[5]
                end_lng = row[6]
                time.sleep(1)
                g_start = geocoder.google('{}, {}'.format(
                    start_lat, start_lng))
                time.sleep(1)
                g_end = geocoder.google('{}, {}'.format(end_lat, end_lng))

                geocode[route]['start_lat'] = start_lat
                geocode[route]['start_lng'] = start_lng
                geocode[route]['start_number'] = g_start.housenumber
                geocode[route]['start_street'] = g_start.street
                geocode[route]['start_city'] = g_start.city
                geocode[route]['start_state'] = g_start.state
                geocode[route]['start_zip'] = g_start.postal

                geocode[route]['end_lat'] = end_lat
                geocode[route]['end_lng'] = end_lng
                geocode[route]['end_number'] = g_end.housenumber
                geocode[route]['end_street'] = g_end.street
                geocode[route]['end_city'] = g_end.city
                geocode[route]['end_state'] = g_end.state
                geocode[route]['end_zip'] = g_end.postal

                start_time = datetime.strptime('4:00 PM', '%I:%M %p')
                today = datetime.now().date()
                start_datetime = datetime.combine(
                    datetime.now().date() + timedelta(days=1),
                    start_time.time())

                tz = state_to_timezone(geocode[route]['start_state'])
                start_time_aware = pytz.timezone(tz).localize(start_datetime)

                try:
                    directions_result = gmaps.directions(
                        "{},{}".format(start_lat, start_lng),
                        "{},{}".format(end_lat, end_lng),
                        traffic_model='best_guess',
                        departure_time=start_time_aware)

                    geocode[route]['duration'] = directions_result[0]['legs'][
                        0]['duration']['text']

                    geocode[route]['mileage'] = directions_result[0]['legs'][
                        0]['distance']['text']

                    print '\n\nduration: {}, mileage{}\n\n'.format(
                        geocode[route]['duration'], geocode[route]['mileage'])
                except Exception, e:
                    print '\n\nDuration/Mileage API Failed\n\n'
                    geocode[route]['mileage'] = None
                    geocode[route]['duration'] = None
                    print "Unexpected error:", start_lat, start_lng, end_lat, end_lng
                    print str(e)

            start_time = datetime.strptime(row[7], '%I:%M %p')
            today = datetime.now().date()
            day_offset = int(row[14])
            start_datetime = datetime.combine(
                datetime.now().date() + timedelta(days=day_offset),
                start_time.time())

            tz = state_to_timezone(geocode[route]['start_state'])
            # localize to US/Pacific
            start_time_aware = pytz.timezone(tz).localize(start_datetime)

            # Normalize to UTC
            start_time_utc = pytz.utc.normalize(start_time_aware)

            ride = Ride(
                driver=row[0],
                seats=row[1],
                cost=row[2],

                # Start Location
                start_lat=geocode[route]['start_lat'],
                start_lng=geocode[route]['start_lng'],
                start_number=geocode[route]['start_number'],
                start_street=geocode[route]['start_street'],
                start_city=geocode[route]['start_city'],
                start_state=geocode[route]['start_state'],
                start_zip=geocode[route]['start_zip'],
                # End Location
                end_lat=geocode[route]['end_lat'],
                end_lng=geocode[route]['end_lng'],
                end_number=geocode[route]['end_number'],
                end_street=geocode[route]['end_street'],
                end_city=geocode[route]['end_city'],
                end_state=geocode[route]['end_state'],
                end_zip=geocode[route]['end_zip'],

                # Date/Time
                start_timestamp=start_time_utc,

                #Details
                car_type=row[9],
                luggage=row[10],
                comments=row[11],
                pickup_window=row[12],
                detour=row[13],
                mileage=geocode[route]['mileage'],
                duration=geocode[route]['duration'])

            db.session.add(ride)
            db.session.commit()
        print geocode
예제 #8
0
 def test_state_to_timezone2(self):
     self.assertEqual(state_to_timezone(''), 'US/Pacific')
예제 #9
0
 def test_state_to_timezone(self):
     self.assertEqual(state_to_timezone('NY'), 'US/Eastern')