This commit is contained in:
+27
-1
@@ -310,9 +310,35 @@ class GatedSource(_Base):
|
||||
raise RuntimeError("network_adapter_not_configured")
|
||||
|
||||
|
||||
class GooglePlacesSource(GatedSource):
|
||||
kind = source_code = "google_places"
|
||||
display_name = "Google Places"
|
||||
available = True
|
||||
|
||||
def validate_config(self, config):
|
||||
result = super().validate_config(config)
|
||||
if not result.valid: return result
|
||||
if not str(config.get("query", "")).strip(): return ValidationResult(False, ["query is required"])
|
||||
return ValidationResult(True)
|
||||
|
||||
def discover(self, config, cursor=None):
|
||||
result = self.validate_config(config)
|
||||
if not result.valid: raise ValueError(result.errors[0])
|
||||
api_key = str(config.get("_api_key", "")).strip()
|
||||
if not api_key: raise ValueError("Google Places API key is not configured")
|
||||
body = {"textQuery": str(config["query"]).strip(), "pageSize": max(1, min(20, int(config.get("max_records", 20))))}
|
||||
if config.get("region_code"): body["regionCode"] = str(config["region_code"]).upper()[:2]
|
||||
request = Request("https://places.googleapis.com/v1/places:searchText", data=json.dumps(body).encode(), method="POST", headers={"Content-Type":"application/json", "X-Goog-Api-Key":api_key, "X-Goog-FieldMask":"places.displayName,places.websiteUri,places.nationalPhoneNumber,places.internationalPhoneNumber,places.formattedAddress,places.googleMapsUri"})
|
||||
with urlopen(request, timeout=12) as response:
|
||||
payload=json.loads(response.read(2*1024*1024).decode("utf-8", "replace"))
|
||||
records=[]
|
||||
for place in payload.get("places", [])[:20]:
|
||||
name=(place.get("displayName") or {}).get("text", "")
|
||||
records.append(normalize_record({"name":name, "website":place.get("websiteUri", ""), "phone":place.get("nationalPhoneNumber") or place.get("internationalPhoneNumber", ""), "location":place.get("formattedAddress", ""), "source_url":place.get("googleMapsUri", "") , "description":"Google Places result"}))
|
||||
return DiscoveryPage(records, metadata={"adapter":self.source_code,"record_count":len(records),"provider":"google_places"})
|
||||
|
||||
def _gated(code, name):
|
||||
return type(name.replace(" ", ""), (GatedSource,), {"kind":code, "source_code":code, "display_name":name})
|
||||
GooglePlacesSource = _gated("google_places", "Google Places")
|
||||
BingLocalSource = _gated("bing_local", "Bing / approved local API")
|
||||
ApprovedDirectorySource = _gated("approved_directory", "Approved directory")
|
||||
PermittedSocialSource = _gated("permitted_social", "Permitted social")
|
||||
|
||||
Reference in New Issue
Block a user