74 lines
2.9 KiB
Python
74 lines
2.9 KiB
Python
# /opt/docker/dev/service_finder/backend/app/workers/osm_scout.py
|
|
import asyncio
|
|
import json
|
|
import httpx
|
|
import hashlib
|
|
import logging
|
|
from urllib.parse import quote
|
|
from sqlalchemy import select
|
|
from app.database import AsyncSessionLocal
|
|
from app.models.staged_data import ServiceStaging
|
|
|
|
logger = logging.getLogger("Robot-OSM-Scout")
|
|
|
|
class OSMScout:
|
|
"""
|
|
Robot: OSM Scout (V2)
|
|
Feladata: Országos, ingyenes adatgyűjtés az OpenStreetMap hálózatából.
|
|
"""
|
|
HUNGARY_BBOX = "45.7,16.1,48.6,22.9"
|
|
OVERPASS_URL = "http://overpass-api.de/api/interpreter?data="
|
|
|
|
@staticmethod
|
|
def generate_fingerprint(name: str, city: str) -> str:
|
|
raw = f"{str(name).lower()}|{str(city).lower()}"
|
|
return hashlib.md5(raw.encode()).hexdigest()
|
|
|
|
async def fetch_osm_data(self, query_part: str):
|
|
query = f'[out:json][timeout:120];(node{query_part}({self.HUNGARY_BBOX});way{query_part}({self.HUNGARY_BBOX}););out center;'
|
|
async with httpx.AsyncClient(timeout=150) as client:
|
|
try:
|
|
resp = await client.get(self.OVERPASS_URL + quote(query))
|
|
return resp.json().get('elements', []) if resp.status_code == 200 else []
|
|
except Exception as e:
|
|
logger.error(f"❌ Overpass hiba: {e}")
|
|
return []
|
|
|
|
async def run(self):
|
|
logger.info("🛰️ OSM Scout ONLINE - Országos porszívózás indítása...")
|
|
|
|
queries = ['["shop"~"car_repair|tyres"]', '["amenity"="car_wash"]']
|
|
all_elements = []
|
|
for q in queries:
|
|
all_elements.extend(await self.fetch_osm_data(q))
|
|
|
|
async with AsyncSessionLocal() as db:
|
|
added = 0
|
|
for node in all_elements:
|
|
tags = node.get('tags', {})
|
|
if not tags.get('name'): continue
|
|
|
|
name = tags.get('name', tags.get('operator', 'Ismeretlen'))
|
|
city = tags.get('addr:city', 'Ismeretlen')
|
|
f_print = self.generate_fingerprint(name, city)
|
|
|
|
# Deduplikáció check
|
|
stmt = select(ServiceStaging).where(ServiceStaging.fingerprint == f_print)
|
|
if not (await db.execute(stmt)).scalar():
|
|
db.add(ServiceStaging(
|
|
name=name,
|
|
source="osm_scout_v2",
|
|
fingerprint=f_print,
|
|
city=city,
|
|
full_address=f"{city}, {tags.get('addr:street', '')} {tags.get('addr:housenumber', '')}".strip(", "),
|
|
status="pending",
|
|
trust_score=20,
|
|
raw_data=tags
|
|
))
|
|
added += 1
|
|
|
|
await db.commit()
|
|
logger.info(f"✅ OSM Scout végzett. {added} új potenciális szerviz a Stagingben.")
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(OSMScout().run()) |