def increment_trip_db(self,eatery,couple_key,first_trip_date,last_visit_date,number_of_trips,edit): """ Checks if a new Trip entity needs to be created. """ new_trip = False if edit: if not eatery.FirstTripDate and first_trip_date: # Couple visited a place for the 1st time. new_trip = True new_trip_date = first_trip_date elif number_of_trips > eatery.NumberOfTrips: # Couple visited a place again. new_trip = True if not last_visit_date: # Set trip date to today in case they didn't enter a last visit date. last_visit_date = datetime.date.today() new_trip_date = last_visit_date else: # Handle a new Eatery entity creation and maybe a new trip. if first_trip_date: new_trip = True new_trip_date = first_trip_date if new_trip: trip = models.Trip(LocationID=eatery.key().id(),Type="EATERY",Date=new_trip_date,parent=couple_key) trip.put() # Update memcache. key = "Trip|" + str(trip.key().id()) ra_memcache.cache_entity(key=key,query_key=eatery.key().id(), parent_key=couple_key,entity_query_function=models.Trip.by_location_id,update=True)
def process_csv(self,blob_info,couple_key): blob_reader = blobstore.BlobReader(blob_info.key()) reader = csv.reader(blob_reader, delimiter=',', quotechar='"') for row in reader: city_state = row[2].split(',') if row[11] == '': average_rating = None else: average_rating = float(row[11]) r = dict(RestaurantName = row[0] ,CuisineType = row[1] ,City = city_state[0].strip() ,State = city_state[1].strip() ,NotesComments = row[3] ,Completed = bool(int(row[4])) ,FirstTripDate = helpers.convert_string_to_date(row[5]) ,LastVisitDate = helpers.convert_string_to_date(row[6]) ,NumberOfTrips = helpers.int_or_null(row[7]) ,DaysSinceLastTrip = helpers.int_or_null(row[8]) ,P1Rating = helpers.int_or_null(row[9]) ,P2Rating = helpers.int_or_null(row[10]) ,AverageRating = average_rating ,parent=couple_key ) entry = models.Eatery(**r) entry.put() entry_id = entry.key().id() key = "Eatery|" + str(entry_id) # Add Eatery entry to memcache. ra_memcache.cache_entity(key,entry_id,couple_key,models.Eatery.by_id,update=True)
def get(self): key = "Couple|" + self.user.user_id() couple = ra_memcache.cache_entity(key,self.user.user_id(),None,models.Couple.by_user_id,keys_only=False) if couple: eatery_id = self.request.get("id") if eatery_id: if eatery_id.isnumeric(): eatery_id = int(eatery_id) found = self.check_hitlist(couple.key(), eatery_id) if found: # Get cache eatery key = 'Eatery|' + str(eatery_id) eatery = ra_memcache.cache_entity(key,eatery_id,couple.key(),models.Eatery.by_id) self.render('hitlist-edit.html',eatery=eatery,couple=couple) else: self.error(403) elif eatery_id.upper() == "NEW": # Render html template for creating a new eatery. self.render('hitlist-create.html',couple=couple) else: self.redirect("/") else: self.redirect("/") else: # If user is not associated with a couple redirect to registration page. self.redirect('/register')
def add_trip(self,location_id,trip_date,parent): # check if trip already exists in the db. trip_check = models.Trip.all(keys_only=True).filter("Date =",trip_date) trip_check.filter("Type = ","EATERY") trip_check.filter("LocationID = ",location_id) if not trip_check.get(): trip = models.Trip(LocationID=location_id,Type="EATERY",Date=trip_date,parent=parent) trip.put() # Update memcache. key = "Trip|" + str(trip.key().id()) ra_memcache.cache_entity(key=key,query_key=location_id, parent_key=parent,entity_query_function=models.Trip.by_location_id,update=True)
def get(self): key = "Couple_Key|" + self.user.user_id() couple_key = ra_memcache.cache_entity(key,self.user.user_id(),None,models.Couple.by_user_id,keys_only=True) if couple_key: self.render('hitlist-map.html') else: self.redirect('/')
def get(self): key = "Couple_Key|" + self.user.user_id() couple_key = ra_memcache.cache_entity(key,self.user.user_id(),None,models.Couple.by_user_id,keys_only=True) if couple_key: # get their hitlist. hitlist_key = "Hitlist|" + str(couple_key.id()) hitlist_keys = ra_memcache.hitlist_cache(hitlist_key,couple_key) # Build a list of Eatery entities to render. hitlist = [] for e_key in hitlist_keys: key = 'Eatery|' + str(e_key.id()) eatery = ra_memcache.cache_entity(key,e_key.id(),couple_key,models.Eatery.by_id) # filter for Eateries with a last visit date. if eatery.LastVisitDate: # Add Trip for each Eatery, if FirstTripDate != Last Trip add another trip on First Trip date self.add_trip(eatery.key().id(),eatery.LastVisitDate,couple_key) if eatery.FirstTripDate and eatery.LastVisitDate > eatery.FirstTripDate: self.add_trip(eatery.key().id(),eatery.FirstTripDate,couple_key) self.redirect('/')
def eatery_geocode_insert(self,request): status_code,couple_key = self.auth_api_user() if status_code == -2: raise endpoints.UnauthorizedException("Please sign in.") elif status_code == -1: return EateryLocation(status_code=-1) key = 'Eatery|' + str(request.eatery_id) eatery = ra_memcache.cache_entity(key,request.eatery_id,couple_key,Eatery.by_id) if eatery: eatery.Latitude = request.latitude eatery.Longitude = request.longitude eatery.put() # Refresh memcache eatery = ra_memcache.cache_entity(key,request.eatery_id,couple_key,Eatery.by_id,update=True) geocoded_hitlist_key = "GeocodedHitlist|" + str(couple_key.key().id()) geocoded_hitlist = ra_memcache.geocoded_hitlist_cache(geocoded_hitlist_key,couple_key,update=True) else: return EateryLocation(status_code=-2) return EateryLocation(status_code=0)
def post(self): upload_files = self.get_uploads('file') # 'file' is file upload field in the form blob_info = upload_files[0] # Get the current user's Couple entity to set it as a ancestor for each entry in the csv.Dialect key = "Couple_Key|" + self.user.user_id() couple_key = ra_memcache.cache_entity(key,self.user.user_id(),None,models.Couple.by_user_id,keys_only=True) self.process_csv(blob_info,couple_key) # Delete file after import blobstore.delete(blob_info.key()) # Update Couple hitlist hitlist_key = "Hitlist|" + str(couple_key.id()) ra_memcache.hitlist_cache(hitlist_key,couple_key,update=True) self.redirect("/")
def auth_api_user(self): current_user = endpoints.get_current_user() if not current_user: logging.error("Yup not signed in!!!") return -2,None else: # Get couple key key = "Couple_Key|" + current_user.email() couple_key = ra_memcache.cache_entity(key,current_user.email(),None,Couple.by_email,keys_only=False) # couple_key = Couple.by_email(current_user.email(),keys_only=True) if not couple_key: return -1,None return 0,couple_key
def eatery_notes_get(self, request): status_code,couple_key = self.auth_api_user() if status_code == -2: raise endpoints.UnauthorizedException("Please sign in.") elif status_code == -1: return EateryNotes(status_code=-1) # Retreive the eatery key = 'Eatery|' + str(request.id) e = ra_memcache.cache_entity(key,request.id,couple_key,Eatery.by_id) # e = Eatery.by_id(request.id,couple_key,None) if e: # Initialize the EateryMessage e_message = EateryNotes(restaurant_name=e.RestaurantName,notes_comments=e.NotesComments,status_code=0) return e_message else: raise endpoints.NotFoundException('Eatery %s not found.' % request.id)
def post(self): search_button = self.request.get('search') # Check which button was pressed by the user. if search_button: key = "Couple_Key|" + self.user.user_id() couple_key = ra_memcache.cache_entity(key,self.user.user_id(),None,models.Couple.by_user_id,keys_only=True) if couple_key: search_attribute = self.request.get('attribute') allowed_attributes = set(['RestaurantName','City','State','CuisineType']) # Check that requested attribute is valid. if search_attribute in allowed_attributes: search_string = self.request.get('search_string').upper() url_search = search_attribute + "=" + search_string self.redirect('/?filter=TRUE&%s' %url_search) else: self.render('index.html', error_search='Invalid attribute selected!') else: self.redirect('/register')
def eatery_location_get(self, request): status_code,couple_key = self.auth_api_user() if status_code == -2: raise endpoints.UnauthorizedException("Please sign in.") elif status_code == -1: return EateryLocation(status_code=-1) # Retreive the eatery key = 'Eatery|' + str(request.id) e = ra_memcache.cache_entity(key,request.id,couple_key,Eatery.by_id) if e: # Check if this eatery has been geocoded. if e.Latitude and e.Longitude: geocoded = True else: geocoded = False # Initialize the EateryMessage e_message = EateryLocation(restaurant_name=e.RestaurantName,latitude=e.Latitude ,longitude=e.Longitude,geocoded=geocoded,status_code=status_code) return e_message else: raise endpoints.NotFoundException('Eatery %s not found.' % request.id)
def get_hitlist(self,couple_key,filters): hitlist_key = "Hitlist|" + str(couple_key.id()) # Get a list of Entity keys that are associated with this user. hitlist_keys = ra_memcache.hitlist_cache(hitlist_key,couple_key) # Build a list of Eatery entities to render. hitlist = [] for e_key in hitlist_keys: key = 'Eatery|' + str(e_key.id()) eatery = ra_memcache.cache_entity(key,e_key.id(),couple_key,models.Eatery.by_id) if filters: match = True # Go through dictionary of filters, if a property of the entity doesn't match a filter do not include in result. for f in filters: if hasattr(eatery,f): if filters[f] and not re.search(filters[f].upper(),getattr(eatery,f).upper()): match = False break if match: hitlist.append(eatery) else: hitlist.append(eatery) return hitlist
def get(self): key = "Couple_Key|" + self.user.user_id() couple_key = ra_memcache.cache_entity(key,self.user.user_id(),None,models.Couple.by_user_id,keys_only=True) # Get the user's Couple's key # couple_key = models.Couple.by_user_id(self.user.user_id(),keys_only=True) if couple_key: # get url arguments for filters filter_flag = self.request.get('filter') filters = None if filter_flag.upper() == 'TRUE': restaurant_name = self.request.get('RestaurantName') city = self.request.get('City') state = self.request.get('State') cuisine_type = self.request.get('CuisineType') filters = dict(RestaurantName=restaurant_name ,City=city ,State=state ,CuisineType=cuisine_type) hitlist = self.get_hitlist(couple_key,filters) self.render('index.html',hitlist=hitlist) else: # If user is not associated with a couple redirect to registration page. self.redirect('/register')
def post(self): submit = self.request.get('submit') if submit: couple_memcache_key = "Couple_Key|" + self.user.user_id() couple_key = ra_memcache.cache_entity(couple_memcache_key,self.user.user_id(),None,models.Couple.by_user_id,keys_only=True) if couple_key: eatery_id = self.request.get("id") if eatery_id: if eatery_id.isnumeric(): eatery_id = int(eatery_id) # check if valid eatery id for the couple_key. edit_found = self.check_hitlist(couple_key, eatery_id) new = False elif eatery_id.upper() == "NEW": # User is posting data for new Eatery edit_found = False new = True else: # Fail the post attempt and 403 it. edit_found = False new = False if edit_found or new: # verify user inputs failed = False error_dict = {} # Verify that the user entered a restaurant name. restaurant_name = self.request.get("restaurantName") if not restaurant_name: failed = True error_name = "You must enter a name." error_dict['error_name'] = error_name cuisine_type = self.request.get("cuisineType") city = self.request.get("city") state = self.request.get("state") notes_comments = self.request.get("notesComments") completed = self.request.get("completed").upper() if completed == "TRUE": completed = True else: completed = False first_trip_date = self.request.get("firstTripDate") # Check if a value was entered first. if first_trip_date: first_trip_date = helpers.convert_string_to_date(first_trip_date) if not first_trip_date: failed = True error_first_trip = "Invalid date format." error_dict['error_first_trip'] = error_first_trip else: first_trip_date = None last_visit_date = self.request.get("lastVisitDate") # Check if a value was entered first. if last_visit_date: last_visit_date = helpers.convert_string_to_date(last_visit_date) if not last_visit_date: failed = True error_last_visit = "Invalid date format." error_dict['error_last_visit'] = error_last_visit else: last_visit_date = None number_of_trips = self.request.get("numberOfTrips") if number_of_trips and not number_of_trips.isnumeric(): failed = True error_number_of_trips = "Invalid number entered." error_dict['error_number_of_trips'] = error_number_of_trips else: number_of_trips = int(number_of_trips) p1_Rating = self.request.get("p1Rating") if p1_Rating: check = self.check_rating(1,p1_Rating) if check[0]: p1_Rating = int(p1_Rating) else: error_dict[check[1]] = check[2] else: p1_Rating = None p2_Rating = self.request.get("p2Rating") if p2_Rating: check = self.check_rating(2,p2_Rating) if check[0]: p2_Rating = int(p2_Rating) else: error_dict[check[1]] = check[2] else: p2_Rating = None # Get additional fields. street_address = self.request.get("streetAddress") # Verify that the zip code is a number. zip_code = self.request.get("zipCode") if zip_code: if zip_code.isnumeric(): zip_code = int(zip_code) else: failed = True error_zip_code = "Please enter a valid 5 digit zip code." else: zip_code = None # Get yelp ID yelp_business_id = self.request.get("yelpBusinessID") # Get eatery entity. if edit_found: # handler for edits. key = 'Eatery|' + str(eatery_id) eatery = ra_memcache.cache_entity(key,eatery_id,couple_key,models.Eatery.by_id) if failed: if edit_found: # add eatery to render dictionary error_dict['eatery'] = eatery # get couple object couple_memcache_key = "Couple|" + self.user.user_id() couple = ra_memcache.cache_entity(couple_memcache_key,self.user.user_id(),None,models.Couple.by_user_id,keys_only=False) # add couple to render dictionary error_dict['couple'] = couple if edit_found: # render edit template for edits. self.render('hitlist-edit.html',**error_dict) else: # Render create template for creates. self.render('hitlist-create.html',**error_dict) else: # User inputs validated prepare to commit to days_last_trip = 0 # Calculate average rating. if p1_Rating and p2_Rating: average_rating = (p1_Rating + p2_Rating) / 2.0 elif p1_Rating: average_rating = float(p1_Rating) elif p2_Rating: average_rating = float(p2_Rating) else: average_rating = None # change eatery entry to reflect changes. if edit_found: eatery.RestaurantName = restaurant_name else: # Or create new entity. eatery = models.Eatery(RestaurantName=restaurant_name,parent=couple_key) eatery.CuisineType = cuisine_type eatery.City = city eatery.State = state eatery.NotesComments = notes_comments eatery.Completed = completed eatery.FirstTripDate = first_trip_date eatery.LastVisitDate = last_visit_date eatery.NumberOfTrips = number_of_trips eatery.P1Rating = p1_Rating eatery.P2Rating = p2_Rating eatery.AverageRating = average_rating eatery.StreetAddress = street_address eatery.ZipCode = zip_code eatery.YelpBusinessID = yelp_business_id # Save new Eatery to DB eatery.put() # if new trip add to trip db. self.increment_trip_db(eatery=eatery, couple_key=couple_key, first_trip_date=first_trip_date, last_visit_date=last_visit_date, number_of_trips=number_of_trips, edit=edit_found) if new: eatery_id = eatery.key().id() key = 'Eatery|' + str(eatery_id) hitlist_key = "Hitlist|" + str(couple_key.id()) ra_memcache.hitlist_cache(hitlist_key,couple_key,update=True) # refresh memcache eatery = ra_memcache.cache_entity(key,eatery_id,couple_key,models.Eatery.by_id,update=True) # Redirect to hitlist. self.redirect("/") else: self.error(403) else: self.redirect("/") else: self.redirect("/register")