82 lines
2.7 KiB
Python
82 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Payment Recon Search Engine
|
|
Flask API + static frontend — searches the web for payment processor usage,
|
|
takes screenshots, and classifies sites with local vision models.
|
|
"""
|
|
import json, time, threading, urllib.parse
|
|
from pathlib import Path
|
|
from flask import Flask, request, jsonify, send_from_directory
|
|
from search_engine import search_processor, search_all, PROCESSORS
|
|
from vision import batch_analyze
|
|
|
|
app = Flask(__name__, static_folder='static', static_url_path='')
|
|
|
|
# In-memory job queue
|
|
jobs = {}
|
|
job_lock = threading.Lock()
|
|
|
|
@app.route('/')
|
|
def index():
|
|
return send_from_directory('static', 'index.html')
|
|
|
|
@app.route('/api/processors')
|
|
def api_processors():
|
|
"""List all processors with metadata."""
|
|
return jsonify(PROCESSORS)
|
|
|
|
@app.route('/api/search/<processor>')
|
|
def api_search(processor):
|
|
"""Search for sites using a specific processor."""
|
|
industry = request.args.get('industry', '')
|
|
country = request.args.get('country', 'US')
|
|
max_results = int(request.args.get('max', 8))
|
|
|
|
result = search_processor(processor, industry or None, country or None, max_results)
|
|
return jsonify(result)
|
|
|
|
@app.route('/api/search-all')
|
|
def api_search_all():
|
|
"""Search across all processors."""
|
|
industry = request.args.get('industry', '')
|
|
country = request.args.get('country', 'US')
|
|
result = search_all(industry or None, country or None, max_per_processor=4)
|
|
return jsonify(result)
|
|
|
|
@app.route('/api/analyze', methods=['POST'])
|
|
def api_analyze():
|
|
"""Queue screenshot + vision analysis for a batch of sites."""
|
|
data = request.get_json()
|
|
sites = data.get('sites', [])
|
|
processor = data.get('processor', 'Unknown')
|
|
|
|
job_id = str(int(time.time() * 1000))
|
|
|
|
with job_lock:
|
|
jobs[job_id] = {'status': 'running', 'progress': 0, 'results': [], 'total': len(sites)}
|
|
|
|
def run():
|
|
results = batch_analyze(sites, processor, max_screenshots=min(len(sites), 8))
|
|
with job_lock:
|
|
jobs[job_id] = {'status': 'complete', 'progress': 100, 'results': results, 'total': len(sites)}
|
|
|
|
threading.Thread(target=run, daemon=True).start()
|
|
return jsonify({'job_id': job_id, 'status': 'queued', 'total': len(sites)})
|
|
|
|
@app.route('/api/job/<job_id>')
|
|
def api_job_status(job_id):
|
|
"""Check analysis job status."""
|
|
with job_lock:
|
|
job = jobs.get(job_id, {'status': 'not_found'})
|
|
return jsonify(job)
|
|
|
|
@app.route('/api/health')
|
|
def api_health():
|
|
return jsonify({'status': 'ok', 'processors': len(PROCESSORS['processors'])})
|
|
|
|
if __name__ == '__main__':
|
|
print("🔍 Payment Recon Engine")
|
|
print(f" {len(PROCESSORS['processors'])} processors loaded")
|
|
print(f" http://localhost:5052")
|
|
app.run(host='0.0.0.0', port=5052, debug=False)
|