def test_removing_user(self): self.db.set_user_stage(1, Stage.START) self.db.add_place(1, Place("Good restaurant", 65.13, 66.14)) self.db.add_place(1, Place("Very Good restaurant", 62.12, 66.14)) self.assertTrue(self.db.has_user(1)) self.db.reset_user(1) self.assertFalse(self.db.has_user(1))
def run_tests(): """Test Place class.""" # Test empty place (defaults) print("Test empty place:") default_place = Place("Townsville", "Australia", 0, "v") print(default_place) assert default_place.name == "Townsville" assert default_place.country == "Australia" assert default_place.priority == 0 assert default_place.is_visited # Test initial-value place print("Test initial-value place:") new_place = Place("Malagar", "Spain", 2, False) # TODO: Write tests to show this initialisation works print(new_place) print(new_place.name) print(new_place.country) print(new_place.priority) print(new_place.visited) print(f"Dict: {new_place.__dict__}") # TODO: Add more tests, as appropriate, for each method print("Is important: {}".format(new_place.is_important())) print("Visited? {}".format(new_place.is_visited()))
def test_places(self): self.db.add_place(1, Place("Good restaurant", 65.13, 66.14)) self.db.add_place(1, Place("Very Good restaurant", 62.12, 66.14)) places = self.db.get_places(1) self.assertIn(Place("Good restaurant", 65.13, 66.14), places) self.assertIn(Place("Very Good restaurant", 62.12, 66.14), places) self.assertEqual(self.db.get_place_by_name(1, "Good restaurant"), Place("Good restaurant", 65.13, 66.14))
def CrossStreet(CrossStreetName=None, StreetName=None, StreetType=None, City=None, State=None, Zip=None): try: return Place(city=City, state=State, zip=Zip, street_name=StreetName, street_type=StreetType, cross_street=CrossStreetName) except ValueError: return None
def find_places_in_lyrics(lyrics, song_title, song_artist): st = StanfordNERTagger( '/Users/yuvalhering/Desktop/stanford-ner-2018-10-16/classifiers/english.all.3class.distsim.crf.ser.gz', '/Users/yuvalhering/Desktop/stanford-ner-2018-10-16/stanford-ner.jar', encoding='utf-8') tokenized_text = word_tokenize(lyrics) classified_text = st.tag(tokenized_text) ner_places = [] for classification in classified_text: if classification[1] == 'LOCATION': ner_places.append(classification[0]) extracted_places = list(set(ner_places)) places = [] for new_place_name in extracted_places: exists = False for place in places: if place.name == new_place_name: place.add_song(song_title, song_artist) exists = True break if not exists: p = Place(new_place_name) p.add_song(song_title, song_artist) places.append(p) json_places = [] for p in places: place_dict = p.to_json() json_places.append(place_dict) with open('places.json', 'w', encoding='utf-8') as places_file: json.dump(json_places, places_file, indent=2)
def __init__(self, config_places, config_crowd, config_isolation, config_preventions, medicalModel): self.config_places = config_places self.config_crowd = config_crowd self.config_isolation = dict(config_isolation.items()) self.enableIsolation = self.config_isolation['enable'] if not self.enableIsolation: self.config_isolation['agreeIsolationRate'] = 0 self.config_preventions = config_preventions self.medicalModel = medicalModel self.flexPlaces = {} self.day = 0 # step 1: create citizens self.crowd = [] for config in config_crowd: for i in range(config['number']): healthStage = self.medicalModel.initIllnessStage if i < config[ 'patient'] else self.medicalModel.healthStage prevention = [ preventionType for preventionType, config in config_preventions.items() if random.random() < config['applicationRatio'] ] newPerson = Person( config, healthStage, prevention, random.random() < config_isolation['agreeIsolationRate'], config_isolation['selfDiscipline']) self.crowd.append(newPerson) self.population = self.crowd.copy() random.shuffle(self.crowd) # step 2: create (fixed) locations self.fixedPlaces = {} for config in config_places: if config['number'] is None: continue self.fixedPlaces[config['type']] = [ Place(config) for i in range(config['number']) ] # step 3: randomly link people with fixed locations according to the 'fixedActivity' allPossibleDefaultPlaceTypes = [ person.defaultActivity for person in self.crowd ] allPossibleFixedPlaceTypes = itertools.chain( *[person.fixedActivityTypes() for person in self.crowd], allPossibleDefaultPlaceTypes) allPossibleFixedPlaceTypes = set(allPossibleFixedPlaceTypes) for placeType in allPossibleFixedPlaceTypes: people = [ person for person in self.crowd if placeType in person.fixedActivityTypes() or placeType == person.defaultActivity ] places = [place for place in self.fixedPlaces[placeType]] # randomly link the remaining people with places allocation = self.randomlyAllocate(people, places) for place, person in allocation: person.linkedPlace[placeType] = place place.linkedPeople.append(person)
def Add_New_Place(): Location = Location_Error_Checking() Country = Country_Error_Checking() Priority_Input = Integer_Error_Checking() print( f"{Location} in {Country} (priority {Priority_Input}) added to Travel Tracker" ) file_entry.insert(0, Place(Location, Country, Priority_Input, 'n'))
def add_place_location(message): print(f"Adding place location with {message.chat.id}") lat, lon = message.location.latitude, message.location.longitude name = db.get_staged_place_name(message.chat.id) db.add_place(message.chat.id, Place(name, lat, lon)) db.clean_staged_place_name(message.chat.id) memorizer.send_message(message.chat.id, "Новое место успешно добавлено") db.set_user_stage(message.chat.id, Stage.START)
def BasicAddress(StreetNumber=None, UnitLetter=None, StreetDirection=None, StreetName=None, StreetType=None, City=None, State=None, Zip=None): try: return Place(city=City, state=State, zip=Zip, street_number=StreetNumber, street_name=StreetName, street_direction=StreetDirection, street_type=StreetType, unit_letter=UnitLetter) except ValueError: return None
def generate_map(self): #for x in range(0, 20): # for y in range(0, 20): # if(x == 1 and y == 1): # self.map_locations[x][y] = Place(1) # else: # self.map_locations[x][y] = Place(0) for x in range(0, 19): for y in range(0, 13): self.map_locations[x][y] = Place(self.temp_map[y][x], self, x, y)
def add_place(data): global count dao_db = MongoDBHelper() results = data['results'] for item in range(0, len(results)): count = count + 1 print(len(results)) data = Place() if MongoDBHelper.KEY_PLACE_ID in results[item]: data.setplaceid(str(count)) if MongoDBHelper.KEY_NAME in results[item]: data.setname(results[item][MongoDBHelper.KEY_NAME]) if MongoDBHelper.KEY_PHOTOS in results[item]: if MongoDBHelper.KEY_PHOTO_REFERENCE in results[item][ MongoDBHelper.KEY_PHOTOS][0]: data.setphoto( str(results[item][MongoDBHelper.KEY_PHOTOS][0][ MongoDBHelper.KEY_PHOTO_REFERENCE])) if MongoDBHelper.KEY_TYPES in results[item]: data.settypes(','.join( str(element) for element in results[item][MongoDBHelper.KEY_TYPES])) if MongoDBHelper.KEY_OPENING_HOURS in results[item]: data.setopeninghours(','.join( str(element) for element in results[item][ MongoDBHelper.KEY_OPENING_HOURS]['weekday_text'])) if MongoDBHelper.KEY_RATING in results[item]: data.setrating(str(results[item][MongoDBHelper.KEY_RATING])) if MongoDBHelper.KEY_GEOMETRY in results[item]: if MongoDBHelper.KEY_LOCATION in results[item][ MongoDBHelper.KEY_GEOMETRY]: data.setlatitude( str(results[item][MongoDBHelper.KEY_GEOMETRY][ MongoDBHelper.KEY_LOCATION][ MongoDBHelper.KEY_LATITUDE])) data.setlongitude( str(results[item][MongoDBHelper.KEY_GEOMETRY][ MongoDBHelper.KEY_LOCATION][ MongoDBHelper.KEY_LONGITUDE])) if MongoDBHelper.KEY_VICINITY in results[item]: data.setvicinity(results[item][MongoDBHelper.KEY_VICINITY]) print(data) dao_db.addPlace(data)
def movePeople(self, hourId): flexPlaceBuffers = {} for person in self.crowd: if hourId > 0 and person.schedule[hourId] == person.schedule[hourId - 1]: continue # don't need to move the person if person.currentPlace is not None: person.currentPlace.removePerson(person) activity, type = person.schedule[hourId] if type == 'isolating': person.currentPlace = None elif type == 'fixed': newPlace = person.linkedPlace[activity] newPlace.addPerson(person) person.currentPlace = newPlace else: # type==flex buffer = flexPlaceBuffers.setdefault(activity, []) buffer.append(person) pass for placeType, people in flexPlaceBuffers.items(): if placeType in self.fixedPlaces: # if people visit a fixed place as a flex activity, just put them in existing fixed places. (ignore the place capacity) currentPlaces = self.fixedPlaces[placeType] allocation = self.randomlyAllocate(people, currentPlaces) else: # people visit flex places currentPlaces = self.flexPlaces.setdefault(placeType, []) # remore the empty places currentPlaces = [ place for place in currentPlaces if len(place.currentPeople) == 0 ] self.flexPlaces[placeType] = currentPlaces placeConfig = [ placeConfig for placeConfig in self.config_places if placeConfig['type'] == placeType ][0] singleCapacity = placeConfig['capacity'] currentPopulation = sum( [len(place.currentPeople) for place in currentPlaces]) + len(people) number_newPlaceRequired = math.ceil( currentPopulation / (singleCapacity * 0.75)) - len(currentPlaces) if number_newPlaceRequired > 0: # create new places currentPlaces += [ Place(placeConfig) for _ in range(number_newPlaceRequired) ] allocation = self.randomlyAllocate(people, currentPlaces) for place, person in allocation: place.addPerson(person) person.currentPlace = place
def load_places(self, filename): self.filename = filename with open(filename) as file: for line in file: parts = line.strip().split(',') place = Place(parts[0], parts[1], parts[2], parts[3]) if parts[3] == 'v' or parts[3] == True: place.is_visited = True else: place.is_visited = False self.file_places.append(place)
def test_removing_place(self): self.db.add_place(1, Place("Good restaurant", 65.13, 66.14)) self.db.add_place(1, Place("Very Good restaurant", 62.12, 66.14)) self.db.add_place(2, Place("Very Good restaurant", 62.12, 66.14)) self.db.remove_place(1, Place("Very Good restaurant", 62.12, 66.14)) places = self.db.get_places(1) self.assertIn(Place("Good restaurant", 65.13, 66.14), places) self.assertNotIn(Place("Very Good restaurant", 62.12, 66.14), places) self.assertIn(Place("Very Good restaurant", 62.12, 66.14), self.db.get_places(2))
def simulatedAnnealing(data, hotel, maxIterations = 10): finalBestOrdering = {} finalBestTime = 0 hotelObj = Place(None, None, None, None, None) hotelObj.pos = hotel foodLists = {} entertainLists = {} #get all food places out #edited this block for key in data: foodLists[key], entertainLists[key] = [], [] for attraction in data[key]: if attraction.category == 'FOOD_BEVERAGE': foodLists[key].append(attraction) else: entertainLists[key].append(attraction) for key in data: if len(data[key]) == 0: finalBestOrdering[key] = data[key] continue elif len(data[key]) == 1: finalBestOrdering[key] = data[key] finalBestTime += getTime(hotelObj, data[key][0]) + getTime(data[key][0], hotelObj) continue ##edited these 2 lines curr = [hotelObj] + getInitialOrdering(foodLists[key], entertainLists[key]) + [hotelObj] foodIndeces, entertainIndeces = getIndeces(curr) bestOrdering = curr bestTime = getTime(curr) for i in range(maxIterations): curr = randomizeOrdering(curr, foodIndeces, entertainIndeces) val = getTime(curr) if val < bestTime: bestTime = val bestOrdering = curr else: rand = random.random() if rand < temperature(i): bestTime = val bestOrdering = curr finalBestOrdering[key] = bestOrdering[1:-1] finalBestTime += bestTime return finalBestOrdering, finalBestTime
def run_tests(): """Test PlaceCollection class.""" # Test empty PlaceCollection (defaults) print("Test empty PlaceCollection:") place_collection = PlaceCollection() print(place_collection) assert not place_collection.file_places # an empty list is considered False # Test loading places print("Test loading places:") place_collection.load_places('places.csv') print(place_collection) assert place_collection.file_places # assuming CSV file is non-empty, non-empty list is considered True # Test adding a new Place with values print("Test adding new place:") place_collection.add_place(Place("Smithfield", "Australia", 5, False)) print(place_collection) # Test sorting places print("Test sorting - priority:") place_collection.sort("priority") print(place_collection) # TODO: Add more sorting tests place_collection.sort("country") print(place_collection) # TODO: Test saving places (check CSV file manually to see results) place_collection.save_places() print(place_collection) place_collection.add_place(Place("Townsville", "Australia", 7, True)) print(f"Updated: {place_collection}") # TODO: Add more tests, as appropriate, for each method print(place_collection.total_unvisited_places())
def getGeo(s): s.lat = None s.lon = None s.place_id = None s.place = None s.geo_type = "not" if 'place' in s.json and s.json['place'] is not None: s.geo_type = 'place' s.place_id = s.json['place']['id'] s.place = Place(s.place_id) s.place.loadJSON(s.json['place']) if 'coordinates' in s.json and s.json['coordinates'] is not None: s.geo_type = 'precise' s.lat = s.json['coordinates']['coordinates'][1] s.lon = s.json['coordinates']['coordinates'][0]
def query_potential_locations(self, center_lat, center_lon, interests = ["FOOD_BEVERAGE"], categories = ['ARTS_ENTERTAINMENT','SHOPPING_RETAIL'], num_locations=50, dist=500): ''' Queries num_locations near the center (lat, lon) using Facebook Places API_KEY ''' center = center_lat + ", " + center_lon API_KEY = "MyhhJX525dvRwSUWpKHNOTKDjJaK59WX" access_token = "2210087485905915|vSCL_c4XqrU_ABMFWOdzbyhh_jk" FB_URL = "https://graph.facebook.com/search?type=place" cat = 'FOOD_BEVERAGE' FB_PARAMS = {'categories' : str([cat]), \ 'fields': ['name,checkins,overall_star_rating,location, category_list, price_range'], \ 'center': center, \ 'distance': 2000, \ 'access_token': access_token} res = requests.get(url = FB_URL, params = FB_PARAMS) all_locations = res.json()['data'] all_locations.sort(key = lambda place: -place['checkins']) attractions_with_rating = [a for a in all_locations if 'overall_star_rating' in a] places = [] attractions = [] price_mapping = {"$": 10, "$$": 20, "$$$": 40, "$$$$": 200, "Unspecified": 15} for category in categories: FB_PARAMS = {'categories' : str([category]), \ 'fields': ['name,checkins,overall_star_rating,location, price_range'], \ 'center': center, \ 'distance': 2000, \ 'access_token': access_token} res = requests.get(url = FB_URL, params = FB_PARAMS) all_locations = res.json()['data'] all_locations.sort(key = lambda place: -place['checkins']) attractions_with_rating = [a for a in all_locations if 'overall_star_rating' in a] for attraction in attractions_with_rating: if 'price_range' in attraction.keys(): price = price_mapping[str(attraction['price_range'])] else: price = 10 place = \ Place(attraction["name"], \ attraction["location"]["latitude"], \ attraction["location"]["longitude"], \ attraction, attraction["checkins"], \ attraction["overall_star_rating"], category, price) places.append(place) filtered_places = self.filter_user_interests(interests, places) #need to get user input return filtered_places[:num_locations]
def press_add(self, name_input, country_input, priority_input): # if any text_input boxes on app.kv are empty, display message if self.root.ids.name_input.text == '' or self.root.ids.country_input.text == '' or self.root.ids.priority_input.text == '': self.root.ids.location_clicked_status.text = "All fields must be completed" # if priority input is less than 0, display message elif int(self.root.ids.priority_input.text) < 0: self.root.ids.location_clicked_status.text = "Priority must be > 0" else: # append new entry to main list and create widget place = Place(name_input, country_input, priority_input, False) location_button = Button(text=str(place)) location_button.place = place location_button.bind(on_release=self.press_entry) self.root.ids.locations_box.add_widget(location_button) self.place_collection.add_place(place)
def save(): nazwa = nazwa_input.get() opis = opis_input.get(1.0, END) miasto = miasto_input.get() adres = adres_input.get() fb = fb_input.get() ig = ig_input.get() email = email_input.get() tel = tel_input.get() web = web_input.get() if fb and nazwa and miasto and adres: place = Place(nazwa, opis, miasto, adres, fb, ig, email, tel, web) Ins.insert(place, inserter) else: fb_input.delete(0, END) fb_input.insert(INSERT, "Brak inforamcji.")
def simulatedAnnealing(data, hotel, maxIterations=100): finalBestOrdering = {} finalBestTime = 0 hotelObj = Place(None, None, None, None) hotelObj.pos = hotel for key in data: if len(data[key]) == 0: finalBestOrdering[key] = data[key] continue elif len(data[key]) == 1: finalBestOrdering[key] = data[key] finalBestTime += getTime(hotelObj, data[key][0]) + getTime( data[key][0], hotelObj) continue curr = [hotelObj] + data[key] + [hotelObj] #numAttractions = len(data[key]) # for _ in range(numAttractions): # rand = random.randint(0, len(data[key])) # curr.append(data[key][rand]) # data[key].remove(data[key][rand]) #curr.append(hotelObj) bestOrdering = curr bestTime = getTime(curr) for i in range(maxIterations): curr = randomizeOrdering(curr) val = getTime(curr) if val < bestTime: bestTime = val bestOrdering = curr else: rand = random.random() if rand < temperature(i): bestTime = val bestOrdering = curr finalBestOrdering[key] = bestOrdering[1:-1] finalBestTime += bestTime return finalBestOrdering, finalBestTime
def filter_by_popularity(self, center, attractions): ''' Filters attractions using knapsack. weights = a weighted average of estimated time spent at location and distance from center values = a weighted average of num checkins and overall star rating ''' places, weights, values = [], [], [] for attraction in attractions: place = \ Place(attraction["name"], \ attraction["location"]["latitude"], \ attraction["location"]["longitude"], \ attraction) val = place.calculate_value(attraction["checkins"], attraction["overall_star_rating"]) weight = place.calculate_weight(center) values.append(val) weights.append(weight) places.append(place) return self.knapsack(5000000, weights, values, len(places), places)
def init_graph(self): # read venue (node) data # node_data = {} self.pos_dict = { } # will be used to draw the nodes in the graph with geographic topology for l in open('./shared_data/newyork_anon_locationData_newcrawl.txt'): splits = l.split('*;*') venue_id = int(splits[0]) venue_info = eval(splits[1]) # add place to graph self.NYC_graph.add_node(venue_id) self.NYC_graph.nodes[venue_id][ 'info'] = venue_info # (40.760265, -73.989105, 'Italian', '217', '291', 'Ristorante Da Rosina') # initialise placee and within place, population information self.places[venue_id] = Place(venue_info) # this will be used for drawing the network self.pos_dict[venue_id] = (venue_info[1], venue_info[0])
def gen_specified_locations(self, user_locs): """ Generate data for a list of user specified locations of interests, which will be combined with the generic list of attractions. Will be passed into k-means. """ API_KEY = "AIzaSyC2Sixwd61MWgbL6qxCrX1JTAEotj5RWDs" URL = "https://maps.googleapis.com/maps/api/place/findplacefromtext/json?" #change output and parameters fields = 'name,rating,geometry,formatted_address' places = [] for l in user_locs: r = requests.get(URL + 'input=' + l + \ '&inputtype=textquery' + '&fields=' + fields + \ '&key=' + API_KEY) attraction = r.json()['candidates'][0] place = \ Place(attraction["name"], \ attraction["geometry"]["location"]["lat"], \ attraction["geometry"]["location"]["lng"], \ attraction, attraction['formatted_address']) places.append(place) return places
def init_graph_period(self): # the following requires a small change in the NYC_movements_v2 file # remove the \" from the strings # change the month-year column to two separate columns # TODO: the following is timeconsuming (~ 5 seconds each time that it is loaded), so most probably we can pass it as an argument as well self.df_transitions_all = pd.read_csv( './shared_data/NYC_movements_v2.csv', error_bad_lines=False, names=['venue1', 'venue2', 'year', 'month', 'period', 'weight']) for p in [ 'OVERNIGHT', 'MORNING', 'MIDDAY', 'AFTERNOON', 'NIGHT', 'OVERNIGHT' ]: self.df_transitions = self.df_transitions_all[ self.df_transitions_all['period'] == p] period_groups = self.df_transitions.groupby('period') p_group = period_groups.get_group(p) p_places_group = p_group.groupby('venue1') for l in open('./shared_data/NYC_venue_info_v2.csv'): splits = l.split(";") venue_id = splits[0] venue_info = splits[ 2] ## this does not include information such number of users/checkins self.NYC_graph_periods[p].add_node(venue_id) self.NYC_graph_periods[p].nodes[venue_id]['info'] = venue_info self.NYC_graph_periods[p].nodes[venue_id][ 'infected_status'] = 0 # TODO: the initialization at class Place will need to change to account for the fact that each entry is weighted with the number of transitions of the type observed rather than corresponding to one only transition self.places_periods[p][venue_id] = Place( venue_info, p_places_group, venue_id) self.places_periods[p][venue_id].add_main_graph( self.NYC_graph_periods[p]) try: initial_place_population = int( sum(p_places_group.get_group(venue_id)['weight']) * 0.2) self.places_periods[p][venue_id].set_total_movements( initial_place_population) except KeyError: self.places_periods[p][venue_id].set_total_movements(0)
def simulatedAnnealing(data, hotel, maxIterations=10): finalBestOrdering = {} finalBestTime = 0 hotelObj = Place(None, None, None, None, None) hotelObj.pos = hotel for key in data: if len(data[key]) == 0: finalBestOrdering[key] = data[key] continue elif len(data[key]) == 1: finalBestOrdering[key] = data[key] finalBestTime += getTime([hotelObj] + [data[key][0]]) + getTime([data[key][0]] + [hotelObj]) continue curr = [hotelObj] + data[key] + [hotelObj] bestOrdering = curr bestTime = getTime(curr) for i in range(maxIterations): curr = randomizeOrdering(curr) val = getTime(curr) if val < bestTime: bestTime = val bestOrdering = curr else: rand = random.random() if rand < temperature(i): bestTime = val bestOrdering = curr finalBestOrdering[key] = bestOrdering[1:-1] finalBestTime += bestTime return finalBestOrdering, finalBestTime
def init_graph(self): #read venue (node) data # node_data = {} self.pos_dict = { } #will be used to draw the nodes in the graph with geographic topology self.df_transitions = pd.read_csv( './shared_data/newyork_placenet_transitions.csv', error_bad_lines=False) places_group = self.df_transitions.groupby('venue1') for l in open('./shared_data/newyork_anon_locationData_newcrawl.txt'): splits = l.split('*;*') venue_id = int(splits[0]) venue_info = eval(splits[1]) #add place to graph self.NYC_graph.add_node(venue_id) # at the venue info we need to add an average duration as well self.NYC_graph.nodes[venue_id][ 'info'] = venue_info #(40.760265, -73.989105, 'Italian', '217', '291', 'Ristorante Da Rosina') #NEW: 0 means initially place is not infected. We will set to 1 if it is. self.NYC_graph.nodes[venue_id]['infected_status'] = 0 #initialise place and within place, population information self.places[venue_id] = Place(venue_info, places_group, venue_id) #NEW: add reference to main graph to Place Object so we can track which parts of the graph are infected. self.places[venue_id].add_main_graph(self.NYC_graph) try: initial_place_population = int( len(places_group.get_group(venue_id)) * 0.2) self.places[venue_id].set_total_movements( initial_place_population) except KeyError: self.places[venue_id].set_total_movements(0) #this will be used for drawing the network self.pos_dict[venue_id] = (venue_info[1], venue_info[0])
def initplaces(self, maxsize=4): # For each speaker encode samples into vectors and store it self.places.clear() for label in self.speakers: place_obj = Place(label, maxsize=maxsize) self.places[label] = place_obj
def test_adding(self): self.assertFalse(self.db.has_user(1)) self.db.set_user_stage(1, Stage.START) self.db.add_place(1, Place("Good restaurant", 65.13, 66.14)) self.assertTrue(self.db.has_user(1))
def readnFormatResults(self, placeResult): responseText = "" shortlistPlaces = [] data = {} #if there are results if (placeResult.get("status") == "OK"): #responseText = "Okay, showing " + categoryText responseText = "Okay, here are some suggestions." #pluck information from placeResult #get place ID and get image, website results = placeResult.get("results") counter = 0 for items in results: if (counter < 7): if ("opening_hours" in items): openNow = items["opening_hours"].get("open_now") # print(openNow) else: openNow = 'false' placeName = items["name"] placeID = items["place_id"] if ("rating" in items): rating = items["rating"] else: rating = '0' #obtain photo reference to get image to display in cards if ("photos" in items): photoDeets = items["photos"] for x in photoDeets: if ("photo_reference" in x): photoRef = x.get("photo_reference", 'none') else: photoRef = 'none' #using photo reference to get image if (photoRef != 'none'): photoRequest = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&key=AIzaSyBMfB2YS4eye4FNNWvyv71DV5HN3ld8GDs&photoreference=" + photoRef photoURL = urllib.request.urlopen( photoRequest).geturl() #print(photoURL) else: photoURL = "https://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png" else: photoRef = 'none' photoURL = "https://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png" #get types that categorise the place stringTypes = "" if ("types" in items): types = items["types"] for x in types: stringTypes += x + ", " #remove last 2 characters of the string stringTypes = stringTypes[:-2] if '_' in stringTypes: stringTypes = stringTypes.replace('_', " ") #create the Place object containing all required values newPlace = Place(placeID, placeName, rating, openNow, photoRef, photoURL, stringTypes) #add to array to be displayed shortlistPlaces.append(newPlace) counter += 1 elif (counter == 7): stringTypes = [] #create the Place object containing all required values newPlace = Place( "-", "There are more results found on Google Maps!", "-", "-", "-", "-", stringTypes) #add to array to be displayed shortlistPlaces.append(newPlace) counter += 1 else: break #googleLogo = Image.open("powered_by_google_on_white.png") data = { "source": "Google Places API", "outputContexts": [{ "name": "projects/${PROJECT_ID}/agent/sessions/${SESSION_ID}/contexts/jk-travelPurpose-followup", "lifespanCount": 2, "parameters": { "longitude": self.longitude, "latitude": self.latitude } }], "fulfillmentMessages": [{ "text": { "text": [responseText] } }] } for x in range(len(shortlistPlaces)): place = shortlistPlaces[x] if (x < 7): data["fulfillmentMessages"].append({ "card": { "title": place.getPlaceName(), "subtitle": place.getRating() + "\n" + place.getOpenNow() + "\n" + place.getPlaceTypes( ), #+ "\n" + googleLogo.show(), "imageUri": place.getPhotoURL(), "buttons": [{ "text": "Map", #link to open in google maps "postback": "https://www.google.com/maps/search/?api=1&query=" + place.getPlaceName() + "&query_place_id=" + place.getPlaceID() }] } }) elif (x == 7): data["fulfillmentMessages"].append({ "card": { "title": place.getPlaceName(), "subtitle": "Powered by Google", "imageUri": "https://www.televox.com/webvox/wp-content/uploads/2015/09/9-8-15_1.png", "buttons": [{ "text": "Show Results", #link to open in google maps "postback": "https://www.google.com/maps/search/?api=1&query=" + (self.travelPurpose).replace(' ', '+') }] } }) # this section is for LINE platform lineData = { "payload": { "line": { "type": "template", "altText": "Results found.", "template": { "type": "carousel", "columns": [], "imageAspectRatio": "rectangle", "imageSize": "cover" } } } } lineCarousel = lineData["payload"]["line"]["template"]["columns"] for x in range(len(shortlistPlaces)): place = shortlistPlaces[x] if (x < 7): lineCarousel.append({ "thumbnailImageUrl": place.getPhotoURL(), "imageBackgroundColor": "#FFFFFF", "title": (place.getPlaceName())[:40], "text": place.getRating() + "\n" + place.getOpenNow(), "actions": [{ "type": "uri", "label": "Map", "uri": "https://www.google.com/maps/search/?api=1&query=" + (place.getPlaceName()).replace(' ', '+') + "&query_place_id=" + place.getPlaceID() }] }) else: break data["fulfillmentMessages"].append(lineData) if len(shortlistPlaces) > 7: data["fulfillmentMessages"].append({ "payload": { "line": { "type": "template", "altText": "More results found.", # "thumbnailImageUrl": "https://example.com/bot/images/image.jpg", # "imageAspectRatio": "rectangle", # "imageSize": "cover", "template": { "type": "buttons", "imageBackgroundColor": "#FFFFFF", "title": "More results in Google Maps.", "text": "Powered by Google", "actions": [ { "type": "uri", "label": "View results", "uri": "https://www.google.com/maps/search/?api=1&query=" + (self.travelPurpose).replace(' ', '+') }, ] } } } }) data["fulfillmentMessages"].append({ "quickReplies": { "title": "What else can I help you with?", "quickReplies": ["Weather", "Events", "About Penang", "Bye!"] } }) elif (placeResult.get("status") == "ZERO_RESULTS"): responseText = "No results found :(" return { "fulfillmentMessages": [{ "text": { "text": [responseText] } }, { "quickReplies": { "title": "Explore other options!", "quickReplies": [ "Travel Purpose", "Weather", "About Penang", "Events" ] } }], "source": "Google Places API", "outputContexts": [{ "name": "projects/${PROJECT_ID}/agent/sessions/${SESSION_ID}/contexts/jk-travelPurpose-followup", "lifespanCount": 5, "parameters": { "longitude": self.longitude, "latitude": self.latitude } }] } elif (placeResult.get("status") == "OVER_QUERY_LIMIT"): responseText = "Over query limit. Please try again in a few moments" return {"fulfillmentText": responseText} else: responseText = "API Error encountered" return {"fulfillmentText": responseText} return data