def street_desc(street_nom: str, street_num: int, locality_nom: str) -> str: """ Generate description of being on a particular (Icelandic) street with correct preposition and case + locality e.g. 'á Fiskislóð 31 í Reykjavík'. """ street_dat = None locality_dat = None # Start by looking up address in staðfangaskrá to get # the dative case of street name and locality. # This works better than BÍN lookup since not all street # names are present in BÍN. addrinfo = iceaddr_lookup(street_nom, placename=locality_nom, limit=1) if len(addrinfo): street_dat = addrinfo[0]["heiti_tgf"] if locality_nom and locality_nom == addrinfo[0]["stadur_nf"]: locality_dat = addrinfo[0]["stadur_tgf"] # OK, if staðfangaskrá can't help us, try to use BÍN to # get dative version of name. Some names given by Google's # API are generic terms such as "Göngustígur" and the like. if not street_dat: street_dat = nom2dat(street_nom) if not locality_dat: locality_dat = nom2dat(locality_nom) # Create street descr. ("á Fiskislóð 31") street_comp = iceprep_for_street(street_nom) + " " + street_dat if street_num: street_comp += " " + str(street_num) # Append locality if available ("í Reykjavík") if locality_dat: ldesc = iceprep_for_placename(locality_nom) + " " + locality_dat street_comp += " " + ldesc return street_comp
def _answer_phonenum4name_query(q: Query, result: Result) -> AnswerTuple: """ Answer query of the form "hvað er síminn hjá [íslenskt mannsnafn]?" """ res = query_ja_api(result.qkey) nþgf = NounPhrase(result.qkey).dative or result.qkey # Verify that we have a sane response with at least 1 result if not res or not res.get("people") or not res["people"].get("items"): return gen_answer("Ekki tókst að fletta upp {0}.".format(nþgf)) # Check if we have a single canonical match from API allp = res["people"]["items"] single = len(allp) == 1 first = allp[0] fname = first["name"] if not single: # Many found with that name, generate smart message asking for disambiguation name_components = result.qkey.split() one_name_only = len(name_components) == 1 with GreynirBin.get_db() as bdb: fn = name_components[0].title() gender = bdb.lookup_name_gender(fn) msg = ( "Það fundust {0} með það nafn. Prófaðu að tilgreina {1}heimilisfang" .format( "margar" if gender == "kvk" else "margir", "fullt nafn og " if one_name_only else "", )) # Try to generate example, e.g. "Jón Jónssón á Smáragötu" for i in allp: try: street_nf = i["address_nominative"].split()[0] street_þgf = i["address"].split()[0] msg = msg + " t.d. {0} {1} {2}".format( fname, iceprep_for_street(street_nf), street_þgf) break except (KeyError, ValueError) as e: logging.warning("Exception: " + str(e)) continue return gen_answer(msg) # Scan API call result, try to find the best phone nuber to provide phone_number = _best_number(first) if not phone_number: return gen_answer("Ég finn ekki símanúmerið hjá {0}".format(nþgf)) # Sanitize number and generate answer phone_number = phone_number.replace("-", "").replace(" ", "") answ = phone_number fn = NounPhrase(fname).dative or fname voice = "Síminn hjá {0} er {1}".format(fn, " ".join(list(phone_number))) q.set_context(dict(phone_number=phone_number, name=fname)) q.set_source(_JA_SOURCE) return dict(answer=answ), answ, voice
def _whatsmyaddr_handler(q: Query, ql: str) -> bool: """ Handle queries of the form "Hvar á ég heima?" """ if ql not in _WHATS_MY_ADDR: return False answ = None ad = q.client_data("address") if not ad: answ = _DUNNO_ADDRESS else: addr = cast(Dict[str, str], ad) street = addr["street"] prep = iceprep_for_street(street) answ = "Þú átt heima {0} {1}".format(prep, _addr2str(addr, case="þgf")) q.set_answer(*gen_answer(answ)) return True
def answ_address(placename: str, loc: LatLonTuple, qtype: str) -> AnswerTuple: """ Generate answer to a question concerning the address of a place. """ # Look up placename in places API res = query_places_api(placename, userloc=loc, fields="formatted_address,name,geometry") if (not res or res["status"] != "OK" or "candidates" not in res or not res["candidates"]): return gen_answer(_PLACES_API_ERRMSG) # Use top result in Iceland place = _top_candidate(res["candidates"]) if not place: return gen_answer(_NOT_IN_ICELAND_ERRMSG) # Remove superfluous "Ísland" in addr string addr = re.sub(r", Ísland$", "", place["formatted_address"]) # Get street name without number to get preposition street_name = addr.split()[0].rstrip(",") maybe_postcode = re.search(r"^\d\d\d", street_name) is not None prep = "í" if maybe_postcode else iceprep_for_street(street_name) # Split addr into street name w. number, and remainder street_addr = addr.split(",")[0] remaining = re.sub(r"^{0}".format(street_addr), "", addr) # Get street name in dative case addr_þgf = NounPhrase(street_addr).dative or street_addr # Assemble final address final_addr = "{0}{1}".format(addr_þgf, remaining) # Create answer answer = final_addr voice = "{0} er {1} {2}".format(placename, prep, numbers_to_neutral(final_addr)) response = dict(answer=answer) return response, answer, voice
def answ_openhours(placename: str, loc: LatLonTuple, qtype: str) -> AnswerTuple: """ Generate answer to a question concerning the opening hours of a place. """ # Look up placename in places API res = query_places_api( placename, userloc=loc, fields="opening_hours,place_id,formatted_address,geometry", ) if (res is None or res["status"] != "OK" or "candidates" not in res or not res["candidates"]): return gen_answer(_PLACES_API_ERRMSG) # Use top result place = _top_candidate(res["candidates"]) if place is None: return gen_answer(_NOT_IN_ICELAND_ERRMSG) if "opening_hours" not in place: return gen_answer("Ekki tókst að sækja opnunartíma fyrir " + icequote(placename)) place_id = place["place_id"] is_open = place["opening_hours"]["open_now"] # needs_disambig = len(res["candidates"]) > 1 fmt_addr = place["formatted_address"] # Look up place ID in Place Details API to get more information res = query_place_details(place_id, fields="opening_hours,name") if not res or res.get("status") != "OK" or "result" not in res: return gen_answer(_PLACES_API_ERRMSG) now = datetime.utcnow() wday = now.weekday() answer = voice = "" try: name = res["result"]["name"] name_gender = NounPhrase(name).gender or "hk" # Generate placename w. street, e.g. "Forréttabarinn á Nýlendugötu" street = fmt_addr.split()[0].rstrip(",") street_þgf = NounPhrase(street).dative or street name = "{0} {1} {2}".format(name, iceprep_for_street(street), street_þgf) # Get correct "open" adjective for place name open_adj_map = {"kk": "opinn", "kvk": "opin", "hk": "opið"} open_adj = open_adj_map.get(name_gender) or "opið" # Get opening hours for current weekday # TODO: Handle when place is closed (no entry in periods) periods = res["result"]["opening_hours"]["periods"] if len(periods) == 1 or wday >= len(periods): # Open 24 hours a day today_desc = p_desc = "{0} er {1} allan sólarhringinn".format( name, open_adj) else: # Get period p = periods[wday] opens = p["open"]["time"] closes = p["close"]["time"] # Format correctly, e.g. "12:00 - 19:00" openstr = opens[:2] + ":" + opens[2:] closestr = closes[:2] + ":" + opens[2:] p_desc = "{0} - {1}".format(openstr, closestr) p_voice = p_desc.replace("-", "til") today_desc = "Í dag er {0} {1} frá {2}".format( name, open_adj, p_voice) except Exception as e: logging.warning( "Exception generating answer for opening hours: {0}".format(e)) return gen_answer(_PLACES_API_ERRMSG) # Generate answer if qtype == "OpeningHours": answer = p_desc voice = today_desc # Is X open? Is X closed? elif qtype == "IsOpen" or qtype == "IsClosed": yes_no = ("Já" if ((is_open and qtype == "IsOpen") or (not is_open and qtype == "IsClosed")) else "Nei") answer = "{0}. {1}.".format(yes_no, today_desc) voice = answer response = dict(answer=answer) return response, answer, voice
def test_geo(): """ Test geography and location-related functions in geo.py """ from geo import ( icelandic_city_name, continent_for_country, coords_for_country, coords_for_street_name, country_name_for_isocode, isocode_for_country_name, icelandic_addr_info, lookup_city_info, parse_address_string, iceprep_for_street, iceprep_for_placename, iceprep_for_country, iceprep_for_cc, capitalize_placename, distance, in_iceland, code_for_us_state, coords_for_us_state_code, location_info, ) assert icelandic_city_name("London") == "Lundúnir" assert icelandic_city_name("Rome") == "Róm" assert continent_for_country("IS") == "EU" assert continent_for_country("no") == "EU" assert continent_for_country("MX") == "NA" assert coords_for_country("DE") is not None assert coords_for_country("it") is not None assert coords_for_street_name("Austurstræti") is not None assert coords_for_street_name("Háaleitisbraut") is not None assert country_name_for_isocode("DE", lang="is") == "Þýskaland" assert country_name_for_isocode("DE") == "Þýskaland" assert isocode_for_country_name("Danmörk", lang="is") == "DK" assert isocode_for_country_name("Danmörk", lang="IS") == "DK" assert isocode_for_country_name("Noregur") == "NO" addr_info = icelandic_addr_info("Fiskislóð 31") assert addr_info and addr_info["stadur_tgf"] == "Reykjavík" # Test city info lookup city_info = lookup_city_info("Kænugarður") assert city_info and len( city_info) == 1 and city_info[0]["country"] == "UA" city_info = lookup_city_info("Kaupmannahöfn") assert city_info and len( city_info) == 1 and city_info[0]["country"] == "DK" city_info = lookup_city_info("Pjongjang") assert city_info and len( city_info) == 1 and city_info[0]["country"] == "KP" city_info = lookup_city_info("Pyongyang") assert city_info and len( city_info) == 1 and city_info[0]["country"] == "KP" # Test address string parsing assert parse_address_string(" Fiskislóð 31") == { "street": "Fiskislóð", "number": 31, "letter": "", } assert parse_address_string("Öldugata 19c ") == { "street": "Öldugata", "number": 19, "letter": "c", } assert parse_address_string(" Dúfnahólar 10 ") == { "street": "Dúfnahólar", "number": 10, "letter": "", } # Test prepositions for street names assert iceprep_for_street("Öldugata") == "á" assert iceprep_for_street("Fiskislóð") == "á" assert iceprep_for_street("Austurstræti") == "í" assert iceprep_for_street("Hamrahlíð") == "í" # Test prepositions for placenames assert iceprep_for_placename("Dalvík") == "á" assert iceprep_for_placename("Akureyri") == "á" assert iceprep_for_placename("Ísafjörður") == "á" assert iceprep_for_placename("Reykjavík") == "í" assert iceprep_for_placename("Hafnarfjörður") == "í" assert iceprep_for_placename("London") == "í" assert iceprep_for_placename("Dyflinni") == "í" # Test prepositions for countries assert iceprep_for_country("Ítalía") == "á" assert iceprep_for_country("Ísland") == "á" assert iceprep_for_country("Þýskaland") == "í" assert iceprep_for_country("Japan") == "í" assert iceprep_for_country("spánn") == "á" # Test prepositions for countries, queried by CC assert iceprep_for_cc("IS") == "á" assert iceprep_for_cc("US") == "í" assert iceprep_for_cc("ES") == "á" assert iceprep_for_cc("es") == "á" # Test placename capitalization assert capitalize_placename("ríó de janeiro") == "Ríó de Janeiro" assert capitalize_placename("vík í mýrdal") == "Vík í Mýrdal" assert capitalize_placename("Vík í mýrdal") == "Vík í Mýrdal" assert capitalize_placename("frankfúrt am main") == "Frankfúrt am Main" assert capitalize_placename("mið-afríkulýðveldið") == "Mið-Afríkulýðveldið" assert capitalize_placename("Norður-kórea") == "Norður-Kórea" assert capitalize_placename("norður-Kórea") == "Norður-Kórea" assert capitalize_placename( "bosnía og hersegóvína") == "Bosnía og Hersegóvína" assert capitalize_placename("Norður-Makedónía") == "Norður-Makedónía" # Distance assert int(distance((64.141439, -21.943944), (65.688131, -18.102528))) == 249 assert in_iceland((66.462205, -15.968417)) assert not in_iceland((62.010846, -6.776709)) assert not in_iceland((62.031342, -18.539553)) # US States assert code_for_us_state("Flórída") == "FL" assert code_for_us_state("Norður-Karólína") == "NC" assert code_for_us_state("Kalifornía") == "CA" assert coords_for_us_state_code("CA") == [36.778261, -119.417932] # Generic location info lookup functions assert "country" in location_info("Reykjavík", "placename") assert "continent" in location_info("Minsk", "placename") assert location_info("Japan", "country")["continent"] == "AS" assert location_info("Danmörk", "country")["continent"] == "EU" assert location_info("Mexíkó", "country")["continent"] == "NA" assert location_info("ísafjörður", "placename")["continent"] == "EU" assert location_info("Meðalfellsvatn", "placename")["country"] == "IS" assert location_info("Georgía", "country")["country"] != "US" assert location_info("Virginía", "placename")["country"] == "US" assert location_info("Norður-Dakóta", "country")["country"] == "US" assert location_info("Kænugarður", "placename")["continent"] == "EU" assert location_info("Fiskislóð 31", "address")["country"] == "IS"