| from flask import Flask, jsonify, request |
| from flask_cors import CORS |
| import json |
| import os |
| import random |
| from src.crawler import Crawler |
| from src.analyzer import ImageAnalyzer |
|
|
| app = Flask(__name__) |
| CORS(app) |
|
|
| REPORT_FILE = 'seo_report.json' |
|
|
| @app.route('/') |
| def home(): |
| return "Antigravity API is Running. Use /health to check status." |
|
|
| @app.route('/health') |
| def health_check(): |
| return jsonify({"status": "alive"}), 200 |
|
|
| @app.route('/api/seo-report', methods=['GET', 'POST']) |
| def get_seo_report(): |
| |
| if not hasattr(get_seo_report, "cache"): |
| get_seo_report.cache = {"data": None, "mtime": 0} |
|
|
| def get_cached_report(): |
| if not os.path.exists(REPORT_FILE): |
| return None |
| |
| current_mtime = os.path.getmtime(REPORT_FILE) |
| if get_seo_report.cache["data"] is None or current_mtime > get_seo_report.cache["mtime"]: |
| try: |
| with open(REPORT_FILE, 'r', encoding='utf-8') as f: |
| get_seo_report.cache["data"] = json.load(f) |
| get_seo_report.cache["mtime"] = current_mtime |
| except Exception as e: |
| |
| return None |
| return get_seo_report.cache["data"] |
|
|
| def get_param(name, default): |
| val = request.args.get(name) or request.form.get(name) |
| if val is None and request.is_json: |
| val = request.json.get(name) |
| return val if val is not None else default |
|
|
| |
| if not hasattr(get_seo_report, "domain_cache"): |
| get_seo_report.domain_cache = {} |
|
|
| domain = get_param('domain', None) |
| limit = int(get_param('limit', 25)) |
|
|
| if domain: |
| |
| cache_key = f"{domain}_{limit}" |
| cached_item = get_seo_report.domain_cache.get(cache_key) |
| |
| import time |
| if cached_item: |
| timestamp, data = cached_item |
| |
| if time.time() - timestamp < 600: |
| print(f"Returning Cached Result for {domain}") |
| return jsonify(data) |
|
|
| try: |
| print(f"Starting live scan for: {domain}") |
| |
| |
| crawler = Crawler() |
| |
| site_data, total_discovered, _ = crawler.crawl_domain(domain, max_pages=limit) |
| |
| if not site_data: |
| response = { |
| "summary": { |
| "total_pages_scanned": 0, |
| "total_images_found": 0, |
| "total_images_missing_alt": 0, |
| "total_pages_discovered": 0 |
| }, |
| "details": [] |
| } |
| return jsonify(response) |
|
|
| |
| analyzer = ImageAnalyzer() |
| results = analyzer.analyze_site(site_data) |
| |
| |
| results['summary']['total_pages_discovered'] = total_discovered |
| results['details_count'] = len(results['details']) |
| |
| |
| get_seo_report.domain_cache[cache_key] = (time.time(), results) |
| |
| return jsonify(results) |
|
|
| except Exception as e: |
| return jsonify({"error": f"Scraping failed: {str(e)}"}), 500 |
|
|
| if not os.path.exists(REPORT_FILE): |
| return jsonify({"error": "Report file not found. Please run result logic first."}), 404 |
|
|
| try: |
| data = get_cached_report() |
| if data is None: |
| |
| |
| |
| |
| |
| return jsonify({"error": "Report file not found or unreadable."}), 404 |
| |
| |
| |
| random_param = str(get_param('random', 'true')).lower() |
| is_random = random_param == 'true' |
|
|
| summary = data.get('summary', {}) |
| details = data.get('details', []) |
|
|
| |
| if limit is not None and limit > 0: |
| if is_random and limit < len(details): |
| details = random.sample(details, limit) |
| else: |
| details = details[:limit] |
| |
| response = { |
| "summary": summary, |
| "details_count": len(details), |
| "details": details |
| } |
| |
| return jsonify(response) |
|
|
| except Exception as e: |
| return jsonify({"error": f"Failed to read report: {str(e)}"}), 500 |
|
|
| if __name__ == '__main__': |
| |
| app.run(debug=True, host='0.0.0.0', port=5050) |
|
|