- worker.py: _take_screenshot() via Chrome CDP (JPEG 55%, max 3000px)
- worker.py: alle Scraper geben (results, screenshot_b64) Tuple zurück
- agent.py: screenshot_b64 in API-Response enthalten
- scheduler.py: speichere_screenshot() Funktion + Verknüpfung mit prices
- db.py: screenshots-Tabelle + screenshot_id FK in prices
- web.py: /api/screenshot/<id> Endpoint (base64→JPEG Response)
- web.py: 📷 Button in Preistabelle → Lightbox mit Full-Page Screenshot
Co-authored-by: Cursor <cursoragent@cursor.com>
58 lines
2.2 KiB
Python
58 lines
2.2 KiB
Python
import os
|
|
from flask import Flask, jsonify, request
|
|
from worker import scrape
|
|
|
|
app = Flask(__name__)
|
|
NODE_NAME = os.environ.get("NODE_NAME", "unknown-node")
|
|
|
|
|
|
@app.route("/status")
|
|
def status():
|
|
return jsonify({"status": "online", "node": NODE_NAME})
|
|
|
|
|
|
@app.route("/job", methods=["POST"])
|
|
def job():
|
|
data = request.json
|
|
scanner = data.get("scanner", "google_flights")
|
|
von = data.get("von", "FRA")
|
|
nach = data.get("nach", "KTI")
|
|
tage = data.get("tage", 30)
|
|
aufenthalt = data.get("aufenthalt_tage", 60)
|
|
trip_type = data.get("trip_type", "roundtrip")
|
|
kabine = data.get("kabine", "premium_economy")
|
|
gepaeck = data.get("gepaeck", "1koffer+handgepaeck")
|
|
airline_filter = data.get("airline_filter", "")
|
|
layover_min = data.get("layover_min", 120)
|
|
layover_max = data.get("layover_max", 300)
|
|
max_flugzeit_h = data.get("max_flugzeit_h", 22)
|
|
max_stops = data.get("max_stops", 2)
|
|
via = data.get("via", "")
|
|
stopover_min_h = data.get("stopover_min_h", 20)
|
|
stopover_max_h = data.get("stopover_max_h", 30)
|
|
|
|
airline_label = f" [{airline_filter}]" if airline_filter else ""
|
|
via_label = f" via {via}" if via else ""
|
|
print(f"[{NODE_NAME}] Job: {scanner}{airline_label}{via_label} {von}→{nach} | {kabine} | "
|
|
f"Umstieg {layover_min}-{layover_max}min | max {max_flugzeit_h}h/{max_stops} Stopps")
|
|
|
|
try:
|
|
results, screenshot_b64 = scrape(
|
|
scanner, von, nach, tage, aufenthalt, trip_type, kabine,
|
|
gepaeck, airline_filter, layover_min, layover_max,
|
|
max_flugzeit_h, max_stops, via, stopover_min_h, stopover_max_h)
|
|
print(f"[{NODE_NAME}] {len(results)} Preise | Screenshot: {len(screenshot_b64)//1024} KB")
|
|
return jsonify({
|
|
"results": results,
|
|
"node": NODE_NAME,
|
|
"count": len(results),
|
|
"screenshot_b64": screenshot_b64,
|
|
})
|
|
except Exception as e:
|
|
print(f"[{NODE_NAME}] Fehler: {e}")
|
|
return jsonify({"error": str(e), "node": NODE_NAME}), 500
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print(f"Node-Agent gestartet: {NODE_NAME}")
|
|
app.run(host="0.0.0.0", port=5010)
|