Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
 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')
Пример #4
0
 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)
Пример #5
0
 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('/')
Пример #6
0
 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)
Пример #8
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)
Пример #11
0
 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)
Пример #13
0
 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
Пример #14
0
 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')
Пример #15
0
    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")