Example #1
0
def delete_user_image(user_id):
    # Check to see if the user exists
    u = User.get_by_id(user_id)
    if u is None:
        raise InvalidUsage('UserID does not match any existing user',
                           status_code=400)

    path = u.profile_picture_path
    if path is None:
        raise InvalidUsage('User has no profile picture.', status_code=400)

    # Create client for interfacing with Cloud Storage API
    client = storage.Client()
    bucket = client.get_bucket(global_vars.USER_IMG_BUCKET)

    bucket.delete_blob(path)

    u.profile_picture_path = None
    u.put()

    now = datetime.datetime.now()

    # Return response
    resp = jsonify({'picture_id deleted': path, 'date_deleted': now})
    resp.status_code = 200
    return resp
Example #2
0
def reactivate_user(user_id):
    # Get the user
    u = User.get_by_id(user_id)
    if u is None:
        raise InvalidUsage('User ID does not match any existing user', 400)

    if u.status == 'Active':
        raise InvalidUsage('User is already active!', 400)

    # Set user status to 'Active'
    u.status = 'Active'

    u.is_phone_number_verified = False
    u.is_email_verified = False

    first_name = u.first_name
    last_name = u.last_name
    email = u.email
    phone_number = u.phone_number
    date_created = u.date_created

    # Add the updated user status to the Datastore
    try:
        u.put()
    except:
        abort(500)

    # Add reactivated user to the Search App
    reactivated_user = search.Document(
        doc_id=str(user_id),
        fields=[
            search.TextField(name='name', value=first_name + ' ' + last_name),
            search.TextField(name='phone_number', value=phone_number),
            search.TextField(name='email', value=email)
        ])
    try:
        index = search.Index(name='User')
        index.put(reactivated_user)
    except:
        abort(500)

    data = {
        'user_id': user_id,
        'date_created': date_created,
        'date_last_modified': u.date_last_modified
    }
    resp = jsonify(data)
    resp.status_code = 201
    return resp
Example #3
0
def get_advertised_listings_partial_snapshots(user_id, radius_miles, page_number):
	# Get the user
	u = User.get_by_id(user_id)
	if u is None:
		raise InvalidUsage('UserID does not match any existing user', status_code=400)

	# Calculate radius in meters
	radius_meters = radius_miles*METERS_PER_MILE

	# Get all of the Listings local to the current user
	index = search.Index(name='Listing')
	query_string = 'distance(location, geopoint('+str(u.last_known_location.lat)+','+str(u.last_known_location.lon)+')) < '+str(radius_meters)+' AND NOT owner_id='+str(user_id)



	# get the first set of results
	# results = index.search(search.Query(query_string=query_string,
							# options=search.QueryOptions(limit=ListingsPerPage, ids_only=True)))

	

	# user chooses page and hence an offset into results
	next_page = page_number * ListingsPerPage

	# get the search results for that page
	results = index.search(search.Query(query_string=query_string,
							options=search.QueryOptions(limit=ListingsPerPage, offset=next_page, ids_only=True)))

	# calculate pages
	pages = results.number_found / ListingsPerPage

	if next_page > pages:
		raise InvalidUsage('No more pages exist!', status_code=400)


	# FIXME: Currently returns only 20 items at a time (search limit). Also, return ids_only!
	# try:
	# 	# FIXME: add limit to the number of items returned
	# 	results = index.search(query_string)
	# except search.Error:
	# 	abort(500)


	matched_listings = get_matched_listings(u, radius_miles, results)

	resp 			 = jsonify({'current_page':next_page+1,'total_pages':pages+1,'listings':matched_listings})
	resp.status_code = 200
	return resp
Example #4
0
def update_meeting_location(location_id):
    json_data = request.get_json()
    google_places_id = json_data.get('google_places_id', '')
    address = json_data.get('address', '')
    name = json_data.get('name', '')
    is_private = bool(json_data.get('is_private', ''))

    l = Meeting_Location.get_by_id(location_id)
    if l is None:
        raise InvalidUsage('LocationID does not match any existing location.',
                           status_code=400)

    l.google_places_id = google_places_id
    l.address = address
    l.name = name
    l.is_private = is_private

    try:
        location_key = l.put()
    except:
        abort(500)

    data = {
        'location_id': location_key.id(),
        'date_created': l.date_created,
        'date_last_modified': l.date_last_modified
    }
    resp = jsonify(data)
    resp.status_code = 200
    return resp
Example #5
0
def create_meeting_location(user_id):
    json_data = request.get_json()
    google_places_id = json_data.get('google_places_id', '')
    address = json_data.get('address', '')
    name = json_data.get('name', '')
    is_private = bool(json_data.get('is_private', ''))

    u = User.get_by_id(user_id)
    if u is None:
        raise InvalidUsage('UserID does not match any existing user',
                           status_code=400)

    u_key = ndb.Key('User', user_id)

    l = Meeting_Location(user=u_key,
                         google_places_id=google_places_id,
                         address=address,
                         name=name,
                         is_private=is_private)

    try:
        location_key = l.put()
    except:
        abort(500)

    data = {
        'location_id': location_key.id(),
        'date_created': l.date_created,
        'date_last_modified': l.date_last_modified
    }
    resp = jsonify(data)
    resp.status_code = 201
    return resp
Example #6
0
def validate_email(email):
    if email is not None:
        q = User.query(ndb.AND(User.email == email, User.status == 'Active'))
        u = q.get()
        if u is not None:
            raise InvalidUsage('Email address is already registered.',
                               status_code=400)
Example #7
0
def delete_listing(listing_id):
    # Edit Datastore entity
    # Get the listing
    l = Listing.get_by_id(listing_id)
    if l is None:
        raise InvalidUsage('Listing ID does not match any existing listing.',
                           400)

    # Set listing status to 'Deleted'
    l.status = 'Deleted'

    # Add the updated listing status to the Datastore
    try:
        l.put()
    except:
        abort(500)

    # Delete Search App entity
    try:
        index = search.Index(name='Listing')
        index.delete(str(listing_id))
    except:
        abort(500)

    # Return response
    data = {
        'listing_id deleted': listing_id,
        'date_deleted': l.date_last_modified
    }
    resp = jsonify(data)
    resp.status_code = 200
    return resp
Example #8
0
def get_user_rented_listings(user_id):
    u = User.get_by_id(user_id)
    if u is None:
        raise InvalidUsage('User ID does not match any existing user', 400)

    u_key = ndb.Key('User', user_id)
    qry = Listing.query(Listing.renter == u_key)
    listings = qry.fetch()

    data = []
    for l in listings:
        listing_data = {
            'listing_id': l.key.id(),
            'name': l.name,
            'owner_id': l.owner.id(),
            'renter_id': l.renter.id() if l.renter else None,
            'status': l.status,
            'item_description': l.item_description,
            'rating': l.rating,
            'total_value': l.total_value,
            'hourly_rate': l.hourly_rate,
            'daily_rate': l.daily_rate,
            'weekly_rate': l.weekly_rate,
            'date_last_modified': l.date_last_modified,
            'image_media_links': get_listing_images(l.key.id())
        }
        data += [listing_data]

    resp = jsonify({'listings': data})
    resp.status_code = 200
    return resp
Example #9
0
def get_listing_info(listing_id):
    l = Listing.get_by_id(listing_id)
    if l is None:
        raise InvalidUsage('Listing does not exist!', status_code=400)

    listing_img_media_links = get_listing_images(listing_id)

    # Add function for related items?

    # Return the attributes of the new item
    listing_data = {
        'listing_id': l.key.id(),
        'name': l.name,
        'owner_id': l.owner.id(),
        'renter_id': l.renter.id() if l.renter else None,
        'status': l.status,
        'item_description': l.item_description,
        'rating': l.rating,
        'total_value': l.total_value,
        'hourly_rate': l.hourly_rate,
        'daily_rate': l.daily_rate,
        'weekly_rate': l.weekly_rate,
        'date_last_modified': l.date_last_modified,
        'image_media_links': listing_img_media_links
    }

    resp = jsonify(listing_data)
    resp.status_code = 200
    return resp
Example #10
0
def new_listing_image(listing_id):
    # user_id = request.form['user_id']
    # listing_id = request.form['listing_id']
    userfile = request.files['userfile']
    filename = userfile.filename

    # Check if listing exists
    l = Listing.get_by_id(listing_id)
    if l is None:
        raise InvalidUsage('Listing does not exist!', status_code=400)

    # Create client for interfacing with Cloud Storage API
    client = storage.Client()
    bucket = client.get_bucket(global_vars.LISTING_IMG_BUCKET)

    # Calculating size this way is not very efficient. Is there another way?
    userfile.seek(0, 2)
    size = userfile.tell()
    userfile.seek(0)

    # upload the item image
    path = str(listing_id) + '/' + filename
    image = bucket.blob(blob_name=path)
    image.upload_from_file(file_obj=userfile,
                           size=size,
                           content_type='image/jpeg')

    # Hacky way of making the image public..
    image.acl.all().grant_read()
    image.acl.save()

    resp = jsonify({'image_path': path, 'image_media_link': image.media_link})
    resp.status_code = 201
    return resp
Example #11
0
def get_user_rent_requests(user_id):
    u = User.get_by_id(user_id)
    if u is None:
        raise InvalidUsage('User ID does not match any existing user', 400)

    u_key = ndb.Key('User', user_id)
    # rent_requests = Rent_Event.query(Rent_Event.owner == u_key).fetch()
    rent_requests = Rent_Event.query(Rent_Event.owner == u_key,
                                     Rent_Event.status == 'Proposed').fetch()

    data = []
    for re in rent_requests:
        re_data = {
            'listing_id': re.listing.id(),
            'date_received': re.date_created,
            'renter_id': re.renter.id(),
            'rental_time': re.rental_time,
            'rental_time_frame': re.rental_time_frame,
            'rental_rate': re.rental_rate
        }
        data += [re_data]

    resp = jsonify({'listings': data})
    resp.status_code = 200
    return resp
Example #12
0
def deactivate_user(user_id):  # Edit Datastore entity
    # Get the user
    u = User.get_by_id(user_id)
    if u is None:
        raise InvalidUsage('User ID does not match any existing user', 400)

    if u.status == 'Deactivated':
        raise InvalidUsage('User is already deactivated!', 400)

    # Set user status to 'Deactivated'
    u.status = 'Deactivated'

    # Set all of the user's listings to 'Deactivated'
    u_key = ndb.Key('User', user_id)
    qry = Listing.query(Listing.owner == u_key)
    listings = qry.fetch()
    for l in listings:
        if l.status != 'Deleted':
            l.status = 'Deactivated'
            try:
                l.put()
            except:
                abort(500)

    # Add the updated user status to the Datastore
    try:
        u.put()
    except:
        abort(500)

    # Delete Search App entity
    try:
        index = search.Index(name='User')
        index.delete(str(user_id))
    except:
        abort(500)

    # Return response
    data = {
        'user_id deactivated': user_id,
        'date_deactivated': u.date_last_modified
    }
    resp = jsonify(data)
    resp.status_code = 200
    return resp
Example #13
0
def validate_phone(phone_number):
    if phone_number is not None:
        q = User.query(
            ndb.AND(User.phone_number == phone_number,
                    User.status == 'Active'))
        u = q.get()
        if u is not None:
            raise InvalidUsage('Phone number is already registered.',
                               status_code=400)
def search_advertised_listings(user_id, radius_miles, search_string):
	# Get the user
	u = User.get_by_id(user_id)
	if u is None:
		raise InvalidUsage('UserID does not match any existing user', status_code=400)

	# Calculate radius in meters
	radius_meters = radius_miles*METERS_PER_MILE

	
	query_string = 'distance(location, geopoint('+str(u.last_known_location.lat)+','+str(u.last_known_location.lon)+')) < '+str(radius_meters)+' AND NOT owner_id='+str(user_id)+' AND name: '+search_string

	listing_ids, num_results = get_matched_listings_ids(query_string)

	resp 			 = jsonify({'num_results':num_results,'listing_ids':listing_ids})
	resp.status_code = 200
	return resp
def get_listing_snapshot(listing_id):
	l = Listing.get_by_id(listing_id)
	if l is None:
		raise InvalidUsage('Listing does not exist!', status_code=400)

	listing_img_media_links = get_listing_images(listing_id)

	# Add function for related items?

	# Return the attributes of the new item
	# Figure out what we want to send in a snapshot..
	listing_data = {'name':l.name,'rating':l.rating,'hourly_rate':l.hourly_rate,
					'daily_rate':l.daily_rate,'weekly_rate':l.weekly_rate,
					'image_media_links':listing_img_media_links}

	resp = jsonify(listing_data)
	resp.status_code = 200
	return resp
Example #16
0
def get_user_info(user_id):
    u = User.get_by_id(user_id)
    if u is None:
        raise InvalidUsage('User ID does not match any existing user', 400)

    # Get user data from Datastore
    first_name = u.first_name
    last_name = u.last_name
    phone_number = u.phone_number
    email = u.email
    path = u.profile_picture_path

    # Get user's profile picture
    if path != None:
        client = storage.Client()
        bucket = client.get_bucket(global_vars.USER_IMG_BUCKET)

        # path = str(user_id) + '/profile_picture.jpg'
        user_img = bucket.get_blob(path)
    else:
        user_img = None

    if user_img == None:
        user_img_media_link = None
        image_path = None
    else:
        user_img_media_link = user_img.media_link
        image_path = user_img.path

    data = {
        'user_id': str(user_id),
        'first_name': first_name,
        'last_name': last_name,
        'phone_number': phone_number,
        'email': email,
        'image_path': image_path,
        'image_media_link': user_img_media_link
    }

    resp = jsonify(data)
    resp.status_code = 200
    return resp
Example #17
0
def new_user_image(user_id):
    userfile = request.files['userfile']
    filename = userfile.filename

    # Check to see if the user exists
    u = User.get_by_id(user_id)
    if u is None:
        raise InvalidUsage('UserID does not match any existing user',
                           status_code=400)

    # Create client for interfacing with Cloud Storage API
    client = storage.Client()
    bucket = client.get_bucket(global_vars.USER_IMG_BUCKET)

    # Calculating size this way is not very efficient. Is there another way?
    userfile.seek(0, 2)
    size = userfile.tell()
    userfile.seek(0)

    # Upload the user's profile image
    # image = bucket.blob(blob_name=str(user_id)+'/'+filename)
    # path = str(user_id)+'/profile_picture.jpg'
    path = str(user_id) + '/' + filename
    image = bucket.blob(blob_name=path)
    image.upload_from_file(file_obj=userfile,
                           size=size,
                           content_type='image/jpeg')

    # Hacky way of making our files public..
    image.acl.all().grant_read()
    image.acl.save()

    u.profile_picture_path = path
    u.put()

    resp = jsonify({'image_path': path, 'image_media_link': image.media_link})
    resp.status_code = 201
    return resp
Example #18
0
def get_user_meeting_locations(user_id):
    u = User.get_by_id(user_id)
    if u is None:
        raise InvalidUsage('User ID does not match any existing user', 400)

    u_key = ndb.Key('User', user_id)
    qry = Meeting_Location.query(Meeting_Location.user == u_key)
    listings = qry.fetch()

    data = []
    for l in listings:
        listing_data = {
            'location_id': l.key.id(),
            'name': l.name,
            'google_places_id': l.google_places_id,
            'address': l.address,
            'is_private': l.is_private
        }
        data += [listing_data]

    resp = jsonify({'meeting locations': data})
    resp.status_code = 200
    return resp
Example #19
0
def search_listings(user_id, radius_miles, search_string):
	# Get the user
	u = User.get_by_id(user_id)
	if u is None:
		raise InvalidUsage('UserID does not match any existing user', status_code=400)

	# Calculate radius in meters
	radius_meters = radius_miles*METERS_PER_MILE

	index = search.Index(name='Listing')
	query_string = 'distance(location, geopoint('+str(u.last_known_location.lat)+','+str(u.last_known_location.lon)+')) < '+str(radius_meters)+' AND NOT owner_id='+str(user_id)+' AND name: '+search_string

	# FIXME: Currently returns only 20 items at a time (search limit). Also, return ids_only!
	try:
		# FIXME: add limit to the number of items returned
		results = index.search(query_string)
	except search.Error:
		abort(500)

	matched_listings = get_matched_listings(u, radius_miles, results)

	resp 			 = jsonify({'results matching '+search_string:matched_listings})
	resp.status_code = 200
	return resp
Example #20
0
def update_listing(listing_id):
    json_data = request.get_json()
    name = json_data.get('name', '')
    total_value = float(json_data.get('total_value', ''))
    hourly_rate = float(json_data.get('hourly_rate', ''))
    daily_rate = float(json_data.get('daily_rate', ''))
    weekly_rate = float(json_data.get('weekly_rate', ''))
    status = json_data.get('status', '')
    item_description = json_data.get('item_description', '')

    # Get the listing
    l = Listing.get_by_id(listing_id)
    if l is None:
        raise InvalidUsage('ItemID does not match any existing item',
                           status_code=400)

    # Update the item attributes
    l.name = name
    l.total_value = total_value
    l.hourly_rate = hourly_rate
    l.daily_rate = daily_rate
    l.weekly_rate = weekly_rate
    l.item_description = item_description
    l.status = status

    # Add the updated item to the Datastore
    try:
        l.put()
    except:
        abort(500)

    # Add the updated item to the Search API
    if l.status == 'Available':
        updated_item = search.Document(
            doc_id=str(listing_id),
            fields=[
                search.TextField(name='name', value=name),
                search.GeoField(name='location',
                                value=search.GeoPoint(l.location.lat,
                                                      l.location.lon)),
                search.TextField(name='owner_id', value=str(l.owner.id()))
            ])

        try:
            index = search.Index(name='Listing')
            index.put(updated_item)
        except:
            abort(500)
    else:
        try:
            index = search.Index(name='Listing')
            index.delete(str(listing_id))
        except:
            abort(500)

    # Return the attributes of the new item
    data = {
        'name': name,
        'total_value': total_value,
        'hourly_rate': hourly_rate,
        'daily_rate': daily_rate,
        'weekly_rate': weekly_rate,
        'status': status,
        'item_description': item_description
    }
    resp = jsonify(data)
    resp.status_code = 200
    return resp
Example #21
0
def create_new_listing(user_id):
    json_data = request.get_json()
    name = json_data.get('name', '')
    item_description = json_data.get('item_description', '')
    total_value = float(json_data.get('total_value', ''))
    # location_lat 		= float(json_data.get('location_lat',''))
    # location_lon		= float(json_data.get('location_lon',''))

    # Check to see if the user exists
    u = User.get_by_id(user_id)
    if u is None:
        raise InvalidUsage('UserID does not match any existing user',
                           status_code=400)

    u_key = ndb.Key('User', user_id)

    # if total_value > MAX_ITEM_VALUE:
    # 	raise InvalidUsage('Total value is too large', status_code=400)

    status = 'Available'
    rating = -1.0
    location = ndb.GeoPt(40.112814, -88.231786)

    # INSERT FUNCTION TO CALCULATE RENTAL RATES HERE
    hourly_rate, daily_rate, weekly_rate = get_rates(total_value)

    # Add listing to Datastore
    l = Listing(owner=u_key,
                status=status,
                name=name,
                item_description=item_description,
                rating=rating,
                total_value=total_value,
                hourly_rate=hourly_rate,
                daily_rate=daily_rate,
                weekly_rate=weekly_rate,
                location=location)
    try:
        listing_key = l.put()
        listing_id = str(listing_key.id())
    except:
        abort(500)

    # Add listing to Search App
    new_item = search.Document(doc_id=listing_id,
                               fields=[
                                   search.TextField(name='name', value=name),
                                   search.GeoField(name='location',
                                                   value=search.GeoPoint(
                                                       location.lat,
                                                       location.lon)),
                                   search.TextField(name='owner_id',
                                                    value=str(user_id))
                               ])
    try:
        index = search.Index(name='Listing')
        index.put(new_item)
    except:
        abort(500)

    data = {
        'listing_id': listing_id,
        'date_created': l.date_created,
        'date_last_modified': l.date_last_modified,
        'status': status
    }
    resp = jsonify(data)
    resp.status_code = 201
    return resp
Example #22
0
def validate_password(password):
    if password is not None and len(password) < MIN_PASSWORD_SIZE:
        raise InvalidUsage('Password is too short.', status_code=400)
Example #23
0
def propose_rent_request(listing_id, renter_id):
    json_data = request.get_json()
    rental_rate = float(json_data.get('rental_rate', ''))
    rental_time = int(json_data.get('rental_time', ''))
    rental_time_frame = json_data.get('rental_time_frame', '')
    message = json_data.get('message', '')
    proposed_meeting_times_data = json_data.get('proposed_meeting_times', '')
    proposed_meeting_location_ids = json_data.get('proposed_meeting_location',
                                                  '')

    # Check to see if the listing exists
    l = Listing.get_by_id(listing_id)
    if l is None:
        raise InvalidUsage('ListingID does not match any existing listing',
                           status_code=400)

    o_key = l.owner
    r_key = ndb.Key('User', renter_id)

    # Check to see if owner == renter
    if o_key == r_key:
        raise InvalidUsage("Cannot request to an item that you own", 400)

    # Check to see if owner and renter exists
    o = o_key.get()
    if o is None:
        raise InvalidUsage('OwnerID does not match any existing user',
                           status_code=400)
    r = r_key.get()
    if r is None:
        raise InvalidUsage('RenterID does not match any existing user',
                           status_code=400)

    # Check that a proposed Rent_Event does not already exist with this listing_id and this renter_id
    rent_events = Rent_Event.query(Rent_Event.listing == l.key).fetch()
    # rent_events = qry.fetch(projection=[Rent_Event.renter,Rent_Event.status])
    # qry1 = qry.filter(Rent_Event.renter == r_key)
    # qry2 = qry1.filter(Rent_Event.status == 'Proposed')
    # re = qry2.fetch()
    for re in rent_events:
        if re.renter == r_key and re.status == 'Proposed':
            raise InvalidUsage('Rent request already proposed!',
                               status_code=400)

    re = Rent_Event(owner=o.key,
                    renter=r.key,
                    listing=l.key,
                    rental_rate=rental_rate,
                    rental_time=rental_time,
                    rental_time_frame=rental_time_frame,
                    message=message,
                    status='Proposed')

    proposed_meeting_times = []
    for proposed_meeting_time_data in proposed_meeting_times_data:
        time_str = proposed_meeting_time_data['time']
        time = datetime.datetime.strptime(time_str, '%Y %m %d %H:%M:%S')
        duration = float(proposed_meeting_time_data['duration'])
        is_available = bool(proposed_meeting_time_data['is_available'])
        proposed_meeting_time = Proposed_Meeting_Time(
            time=time, duration=duration, is_available=is_available)
        proposed_meeting_times.append(proposed_meeting_time)

    proposed_meeting_locations = []
    for location_id in proposed_meeting_location_ids:
        location_key = ndb.Key('Meeting_Location', int(location_id))
        proposed_meeting_locations.append(location_key)

    # Create start_meeting_event
    sme = Meeting_Event(owner=o.key,
                        renter=r.key,
                        listing=l.key,
                        deliverer='Owner',
                        status='Proposed',
                        proposed_meeting_times=proposed_meeting_times,
                        proposed_meeting_locations=proposed_meeting_locations)

    start_meeting_event_key = sme.put()
    re.start_meeting_event = start_meeting_event_key
    rent_event_key = re.put()

    # TODO: Ask Nick how push notification stuff works..
    # Send Push Notification to the Owner informing them of the new Rent Request
    # if owner.notification_tokens is not None:
    # if len(o.notification_tokens) > 0:
    # message_url 		= 'http://gcm-http.googleapis.com/gcm/send'
    # message_headers 	= {'Authorization':'key=AIzaSyBca5FNN9IUIwZuZFECDWL-jEkgMRQofW0', 'Content-Type':'application/json'}
    # message_title 		= 'New Rent Request'
    # message_body 		= renter.first_name + ' wants to borrow your ' + listing.name
    # message_sound 		= 'default'
    # m_data 				= {'type':'Rent_Request_Proposed', 'meeting_id':start_meeting_event_key.id(), 'event_id':str(event_id)}
    # message_note		= {'title':message_title, 'body':message_body, 'sound':message_sound, 'badge':1}
    # message_data		= {'data':m_data, 'content_available':True, 'priority':'high', 'to':owner.notification_tokens[0], 'notification':message_note}
    # message_response 	= requests.post(message_url, headers=message_headers, json=message_data)

    data = {
        'event_id': rent_event_key.id(),
        'start_meeting_id': start_meeting_event_key.id(),
        'date_created': re.date_created
    }
    resp = jsonify(data)
    resp.status_code = 201
    return resp
Example #24
0
def update_user(user_id):
    json_data = request.get_json()
    first_name = json_data.get('first_name', '')
    last_name = json_data.get('last_name', '')
    email = json_data.get('email', '')
    phone_number = json_data.get('phone_number', '')

    if not bool(first_name):
        raise InvalidUsage('First name cannot be left empty.', 400)
    if not bool(last_name):
        raise InvalidUsage('Last name cannot be left empty.', 400)
    if not bool(email):
        raise InvalidUsage('Email cannot be left empty.', 400)
    if not bool(phone_number):
        raise InvalidUsage('Phone number cannot be left empty.', 400)

    # Get the user
    u = User.get_by_id(user_id)
    if u is None:
        raise InvalidUsage('User ID does not match any existing user', 400)

    # Validate email and phone number before updating anything
    if u.email != email:
        validate_email(email)
    if u.phone_number != phone_number:
        validate_phone(phone_number)

    # If the phone number is different, phone number is no longer verified
    if phone_number != u.phone_number:
        u.is_phone_number_verified = False

    # If the email is different, email is no longer verified
    if email != u.email:
        u.is_email_verified = False

    # Update user attributes
    u.first_name = first_name
    u.last_name = last_name
    u.email = email
    u.phone_number = phone_number

    # Add the updated user to the Datastore
    try:
        u.put()
    except:
        abort(500)

    # Add updated user to the Search App
    updated_user = search.Document(doc_id=str(user_id),
                                   fields=[
                                       search.TextField(name='name',
                                                        value=first_name +
                                                        ' ' + last_name),
                                       search.TextField(name='phone_number',
                                                        value=phone_number),
                                       search.TextField(name='email',
                                                        value=email)
                                   ])
    try:
        index = search.Index(name='User')
        index.put(updated_user)
    except:
        abort(500)

    # Return the fields of the new user
    data = {
        'first_name': first_name,
        'last_name': last_name,
        'phone_number': phone_number,
        'is_phone_number_verified': u.is_phone_number_verified,
        'email': email,
        'is_email_verified': u.is_email_verified,
        'date_last_modified': u.date_last_modified
    }
    resp = jsonify(data)
    resp.status_code = 200
    return resp
Example #25
0
def create_user():
    json_data = request.get_json()
    first_name = json_data.get('first_name', '')
    last_name = json_data.get('last_name', '')
    email = json_data.get('email', '')
    phone_number = json_data.get('phone_number', '')
    facebook_id = json_data.get('facebook_id', '')
    password = json_data.get('password', '')
    signup_method = json_data.get('signup_method', '')
    # location_lat 	= float(json_data.get('location_lat',''))
    # location_lon 	= float(json_data.get('location_lon',''))

    # TODO: get location from client

    # If object string is empty '', then set object = None
    if not bool(password):
        password = None
    if not bool(phone_number):
        phone_number = None
    if not bool(email):
        email = None
    if not bool(facebook_id):
        facebook_id = None

    if signup_method != 'Facebook':
        if not phone_number:
            raise InvalidUsage('Phone number is required!', 400)
        if not password:
            raise InvalidUsage('Password is required!', 400)
    else:
        if not facebook_id:
            raise InvalidUsage('No facebook id given!', 400)

    # Validate password, email, and phone_number
    validate_password(password)
    validate_email(email)
    validate_phone(phone_number)

    # Create category weight vector
    # category_weights = []
    # categories = Category.query()
    # for cat in categories.iter():
    # 	cat_weight = CategoryWeight(category=cat.key, weight=1.0)
    # 	category_weights.append(cat_weight)

    # Add user to Datastore
    u = User(first_name=first_name,
             last_name=last_name,
             phone_number=phone_number,
             email=email,
             password=password,
             facebook_id=facebook_id,
             signup_method=signup_method)
    try:
        user_key = u.put()
        user_id = str(user_key.id())
    except:
        abort(500)

    # Add user to Search App
    new_user = search.Document(doc_id=user_id,
                               fields=[
                                   search.TextField(name='name',
                                                    value=first_name + ' ' +
                                                    last_name),
                                   search.TextField(name='phone_number',
                                                    value=phone_number),
                                   search.TextField(name='email', value=email)
                               ])
    try:
        index = search.Index(name='User')
        index.put(new_user)
    except:
        abort(500)

    data = {
        'user_id': user_id,
        'date_created': u.date_created,
        'date_last_modified': u.date_last_modified
    }
    resp = jsonify(data)
    resp.status_code = 201
    return resp