STABLE: Final schema sync, optimized gitignore
This commit is contained in:
74
backend/app/workers/osm_scout.py
Normal file
74
backend/app/workers/osm_scout.py
Normal file
@@ -0,0 +1,74 @@
|
||||
# /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())
|
||||
Reference in New Issue
Block a user