Spaces:
Paused
Paused
| from flask import Flask, render_template, request, jsonify | |
| from flask_sqlalchemy import SQLAlchemy | |
| from datetime import datetime | |
| from utils import predict_url | |
| import re | |
| app = Flask(__name__) | |
| app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///scans.db' | |
| app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False | |
| db = SQLAlchemy(app) | |
| # ββ Database Model βββββββββββββββββββββββββββββββββββββββββββββ | |
| class ScanHistory(db.Model): | |
| id = db.Column(db.Integer, primary_key=True) | |
| url = db.Column(db.String(2000), nullable=False) | |
| verdict = db.Column(db.String(20), nullable=False) | |
| label = db.Column(db.String(20), nullable=False) | |
| confidence = db.Column(db.Float, nullable=False) | |
| scanned_at = db.Column(db.DateTime, default=datetime.utcnow) | |
| with app.app_context(): | |
| db.create_all() | |
| # ββ Routes βββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def index(): | |
| stats = { | |
| 'total': ScanHistory.query.count(), | |
| 'safe': ScanHistory.query.filter_by(verdict='SAFE').count(), | |
| 'phishing': ScanHistory.query.filter_by(label='phishing').count(), | |
| 'malware': ScanHistory.query.filter_by(label='malware').count(), | |
| } | |
| return render_template('index.html', stats=stats) | |
| def history(): | |
| scans = ScanHistory.query.order_by(ScanHistory.scanned_at.desc()).limit(100).all() | |
| return render_template('history.html', scans=scans) | |
| def predict(): | |
| data = request.get_json() | |
| url = (data.get('url') or '').strip() | |
| if not url: | |
| return jsonify({'error': 'Please enter a URL'}) | |
| if not re.match(r'https?://', url): | |
| url = 'https://' + url | |
| try: | |
| result = predict_url(url) | |
| scan = ScanHistory( | |
| url = url, | |
| verdict = result['verdict'], | |
| label = result['ensemble']['label'], | |
| confidence = result['ensemble']['confidence'], | |
| ) | |
| db.session.add(scan) | |
| db.session.commit() | |
| return jsonify({'url': url, **result}) | |
| except Exception as e: | |
| return jsonify({'error': f'Prediction failed: {str(e)}'}) | |
| def predict_bulk(): | |
| data = request.get_json() | |
| urls = (data.get('urls') or '').strip().split('\n') | |
| urls = [u.strip() for u in urls if u.strip()][:20] | |
| if not urls: | |
| return jsonify({'error': 'No URLs provided'}) | |
| results = [] | |
| for url in urls: | |
| if not re.match(r'https?://', url): | |
| url = 'https://' + url | |
| try: | |
| result = predict_url(url) | |
| scan = ScanHistory( | |
| url = url, | |
| verdict = result['verdict'], | |
| label = result['ensemble']['label'], | |
| confidence = result['ensemble']['confidence'], | |
| ) | |
| db.session.add(scan) | |
| results.append({'url': url, **result}) | |
| except Exception as e: | |
| results.append({'url': url, 'error': str(e)}) | |
| db.session.commit() | |
| return jsonify({'results': results}) | |
| def clear_history(): | |
| ScanHistory.query.delete() | |
| db.session.commit() | |
| return jsonify({'status': 'cleared'}) | |
| if __name__ == "__main__": | |
| app.run(host="0.0.0.0", port=7860, debug=False) |