Spaces:
Sleeping
Sleeping
File size: 5,214 Bytes
d08010b 6c64f41 d08010b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | from flask import Flask, request, jsonify, render_template, send_file
from PIL import Image
import io
import requests
from text_detector import predict_text
from image_detector import predict_image_combined
from url_handler import scrape_url
app = Flask(__name__)
# =======================
# HOME
# =======================
@app.route("/")
def home():
return render_template("index.html")
# =======================
# TEXT
# =======================
@app.route("/predict-text", methods=["POST"])
def predict_text_api():
data = request.get_json()
text = data.get("text", "").strip()
if not text or len(text) < 50:
return jsonify({"error": "Please provide at least 50 characters."}), 400
try:
result = predict_text(text)
return jsonify({
"label": result["final"]["label"],
"confidence": result["final"]["confidence"],
"warning": result.get("warning"),
"details": result
})
except Exception as e:
return jsonify({"error": str(e)}), 500
# =======================
# IMAGE
# =======================
@app.route("/predict-image", methods=["POST"])
def predict_image_api():
if "image" not in request.files:
return jsonify({"error": "No image provided."}), 400
file = request.files["image"]
if file.filename == "":
return jsonify({"error": "Empty filename."}), 400
try:
image = Image.open(file.stream).convert("RGB")
result = predict_image_combined(image)
return jsonify(result)
except Exception as e:
return jsonify({"error": str(e)}), 500
# =======================
# URL
# =======================
@app.route("/predict-url", methods=["POST"])
def predict_url_api():
data = request.get_json()
url = data.get("url", "").strip()
if not url:
return jsonify({"error": "No URL provided."}), 400
if not url.startswith("http"):
url = "https://" + url
# ββ Scrape ββββββββββββββββββββββββββββββββββββββββββββββββ
try:
scraped = scrape_url(url)
except Exception as e:
return jsonify({"error": f"Failed to scrape URL: {str(e)}"}), 400
if not scraped.get("text"):
return jsonify({"error": "Could not extract text from this URL."}), 400
# ββ Text analysis βββββββββββββββββββββββββββββββββββββββββ
try:
text_result = predict_text(scraped["text"])
text_final = text_result["final"]
text_ai_score = (
text_final["confidence"]
if text_final["label"] == "AI-generated"
else 1 - text_final["confidence"]
)
except Exception as e:
text_final = {"label": "Error", "confidence": 0.5}
text_ai_score = 0.5
# ββ Image analysis (first 5 images) ββββββββββββββββββββββ
image_results = []
images_checked = 0
for img_url in scraped.get("images", [])[:5]:
try:
resp = requests.get(img_url, timeout=8, headers={"User-Agent": "Mozilla/5.0"})
img = Image.open(io.BytesIO(resp.content)).convert("RGB")
r = predict_image_combined(img)
image_results.append(r)
images_checked += 1
except Exception:
continue
if image_results:
avg_ai = sum(r["ai_score"] for r in image_results) / len(image_results)
image_final = {
"label": "AI-generated" if avg_ai >= 0.5 else "Real",
"confidence": round(float(avg_ai), 3)
}
img_ai_score = avg_ai
else:
image_final = None
img_ai_score = None
# ββ Combined score (60% text, 40% image) βββββββββββββββββ
if img_ai_score is not None:
combined_score = round(0.60 * text_ai_score + 0.40 * img_ai_score, 3)
else:
combined_score = round(text_ai_score, 3)
return jsonify({
"title": scraped.get("title", ""),
"text_preview": scraped["text"][:300] + "..." if len(scraped["text"]) > 300 else scraped["text"],
"image_url": scraped.get("images", [None])[0],
"image_urls": scraped.get("images", []),
"images_checked": images_checked,
"text_result": text_final,
"image_result": image_final,
"combined_score": combined_score,
"combined_label": "AI-generated" if combined_score >= 0.5 else "Human-written"
})
# =======================
# PDF DOWNLOAD (optional)
# =======================
@app.route("/download-pdf", methods=["POST"])
def download_pdf():
try:
from pdf_generator import generate_pdf
data = request.get_json()
filename = generate_pdf(data)
return send_file(filename, as_attachment=True)
except Exception as e:
return jsonify({"error": str(e)}), 500
# =======================
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860, debug=False)
# .venv\Scripts\activate
# python app.py |