Spaces:
Sleeping
Sleeping
| # app.py - Main Flask Application | |
| from flask import Flask, render_template, request, jsonify, session, redirect | |
| from flask_cors import CORS | |
| import os | |
| import uuid | |
| from werkzeug.utils import secure_filename | |
| from detector import AIDetector | |
| from database import Database | |
| from auth import auth_bp | |
| from datetime import timedelta | |
| from datetime import datetime | |
| app = Flask(__name__) | |
| app.secret_key = os.environ.get('SECRET_KEY', 'dtector-ai-secret-key-2026') | |
| # Konfigurasi session | |
| app.config['SESSION_COOKIE_SECURE'] = False # Set True jika pakai HTTPS | |
| app.config['SESSION_COOKIE_HTTPONLY'] = True | |
| app.config['SESSION_COOKIE_SAMESITE'] = 'Lax' | |
| app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7) | |
| CORS(app, supports_credentials=True) | |
| # Register blueprint | |
| app.register_blueprint(auth_bp) | |
| # Config | |
| app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 | |
| app.config['UPLOAD_FOLDER'] = 'uploads' | |
| ALLOWED_EXTENSIONS = {'pdf', 'txt', 'docx'} | |
| os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) | |
| detector = AIDetector() | |
| db = Database() | |
| def allowed_file(filename): | |
| return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS | |
| def get_current_user(): | |
| user_id = session.get('user_id') | |
| if not user_id: | |
| return None | |
| return {'id': user_id, 'username': session.get('username')} | |
| # ============ PAGE ROUTES ============ | |
| def splash(): | |
| return render_template('splash.html') | |
| def landing(): | |
| return render_template('landing.html') | |
| def login_page(): | |
| # Jika sudah login, redirect ke dashboard | |
| if session.get('user_id'): | |
| return redirect('/dashboard') | |
| return render_template('login.html') | |
| def register_page(): | |
| # Jika sudah login, redirect ke dashboard | |
| if session.get('user_id'): | |
| return redirect('/dashboard') | |
| return render_template('register.html') | |
| def dashboard(): | |
| if not session.get('user_id'): | |
| return redirect('/login') | |
| return render_template('dashboard.html') | |
| def profile_page(): | |
| if not session.get('user_id'): | |
| return redirect('/login') | |
| return render_template('profile.html') | |
| def change_password_page(): | |
| if not session.get('user_id'): | |
| return redirect('/login') | |
| return render_template('change_password.html') | |
| # ============ API ROUTES ============ | |
| def detect_text(): | |
| data = request.get_json() | |
| text = data.get('text', '') | |
| user = get_current_user() | |
| if not text: | |
| return jsonify({'error': 'Text is required'}), 400 | |
| result = detector.detect(text) | |
| if not result.get('error') and user: | |
| db.add_detection(user['id'], text, result, file_name=None, file_type='text') | |
| return jsonify(result) | |
| def detect_file(): | |
| if 'file' not in request.files: | |
| return jsonify({'error': 'No file uploaded'}), 400 | |
| file = request.files['file'] | |
| user = get_current_user() | |
| if file.filename == '': | |
| return jsonify({'error': 'Empty filename'}), 400 | |
| if not allowed_file(file.filename): | |
| return jsonify({'error': 'File type not allowed'}), 400 | |
| filename = secure_filename(file.filename) | |
| unique_filename = f"{uuid.uuid4().hex}_{filename}" | |
| filepath = os.path.join(app.config['UPLOAD_FOLDER'], unique_filename) | |
| file.save(filepath) | |
| try: | |
| file_ext = filename.rsplit('.', 1)[1].lower() | |
| result = detector.detect_file(filepath, file_ext) | |
| if not result.get('error') and user: | |
| text = result.get('preview', '') | |
| db.add_detection(user['id'], text, result, file_name=filename, file_type=file_ext) | |
| return jsonify(result) | |
| except Exception as e: | |
| return jsonify({'error': str(e)}), 500 | |
| finally: | |
| if os.path.exists(filepath): | |
| os.remove(filepath) | |
| def get_history(): | |
| user = get_current_user() | |
| if not user: | |
| return jsonify([]) | |
| limit = request.args.get('limit', 50, type=int) | |
| history = db.get_user_history(user['id'], limit) | |
| result = [] | |
| for item in history: | |
| result.append({ | |
| 'id': item.id, | |
| 'text_preview': item.text_preview, | |
| 'file_name': item.file_name, | |
| 'file_type': item.file_type, | |
| 'ai_probability': item.ai_probability, | |
| 'human_probability': item.human_probability, | |
| 'confidence': item.confidence, | |
| 'is_ai': bool(item.is_ai), | |
| 'created_at': item.created_at.strftime('%Y-%m-%d %H:%M:%S') | |
| }) | |
| return jsonify(result) | |
| def get_stats(): | |
| user = get_current_user() | |
| if not user: | |
| return jsonify({'total': 0, 'ai_count': 0, 'human_count': 0}) | |
| stats = db.get_user_stats(user['id']) | |
| return jsonify(stats) | |
| def health(): | |
| return jsonify({ | |
| 'status': 'healthy', | |
| 'model_loaded': detector.model is not None, | |
| 'session_user_id': session.get('user_id'), | |
| 'timestamp': datetime.now().isoformat() | |
| }) | |
| if __name__ == '__main__': | |
| port = int(os.environ.get('PORT', 5001)) | |
| app.run(host='0.0.0.0', port=port, debug=True) |