# app.py - VERSI FIX LOGIN (PASTI BERHASIL) import os from flask import Flask, render_template, request, redirect, url_for, flash, jsonify, send_file, session from flask_sqlalchemy import SQLAlchemy from werkzeug.security import generate_password_hash, check_password_hash from werkzeug.utils import secure_filename from datetime import datetime app = Flask(__name__) app.config['SECRET_KEY'] = 'angkatan-rahasia-2024-2026' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///gallery.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['UPLOAD_FOLDER'] = 'static/uploads' app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) db = SQLAlchemy(app) # ==================== MODEL DATABASE ==================== class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) password_hash = db.Column(db.String(200), nullable=False) is_admin = db.Column(db.Boolean, default=False) def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password) class Photo(db.Model): id = db.Column(db.Integer, primary_key=True) filename = db.Column(db.String(200), nullable=False) caption = db.Column(db.String(500)) upload_date = db.Column(db.DateTime, default=datetime.utcnow) uploader_id = db.Column(db.Integer, db.ForeignKey('user.id')) likes = db.Column(db.Integer, default=0) file_type = db.Column(db.String(10), default='photo') uploader = db.relationship('User', backref='photos') # ==================== BUAT 11 ADMIN ==================== with app.app_context(): db.create_all() admins = [ ('Hilbraaaam', 'Ketua Angkatan 24-26'), ('Hudzaifahh', 'Wakil ketua Angkatan 24-26'), ('Rafasyahh', 'Humas Kesayangan'), ('Elazzam', 'Eos 800 D'), ('Azzam Diq', 'Shidiq'), ('Dzikrii', 'Bayar woe'), ('Ibrahim', 'Mboh'), ('Yusupp', 'Bangun'), ('Azzam JR', 'Saturn'), ('MK Azzam', 'Aneka Gold'), ('Sami abd', 'TamTam') ] for username, password in admins: if not User.query.filter_by(username=username).first(): user = User(username=username, is_admin=True) user.set_password(password) db.session.add(user) db.session.commit() print(f"✅ Database siap dengan {User.query.count()} users") # ==================== ROUTES ==================== @app.route('/') def home(): photos = Photo.query.filter_by(file_type='photo').order_by(Photo.upload_date.desc()).all() videos = Photo.query.filter_by(file_type='video').order_by(Photo.upload_date.desc()).all() trending = Photo.query.order_by(Photo.likes.desc()).limit(5).all() user = None if 'user_id' in session: user = User.query.get(session['user_id']) print(f"User in session: {user.username if user else None}") return render_template('index.html', photos=photos, videos=videos, trending=trending, user=user) # ==================== LOGIN FIX ==================== @app.route('/login', methods=['GET', 'POST']) def login(): # Kalau sudah login, langsung ke home if 'user_id' in session: print("Already logged in, redirecting to home") return redirect(url_for('home')) if request.method == 'POST': username = request.form.get('username') password = request.form.get('password') print(f"Login attempt: {username}") # Cari user user = User.query.filter_by(username=username).first() if user and user.check_password(password): print(f"Login SUCCESS: {username}") # Set session session['user_id'] = user.id session['username'] = user.username session['is_admin'] = user.is_admin # Flash message flash('✅ Login berhasil!', 'success') # Redirect ke admin return redirect(url_for('admin')) else: print(f"Login FAILED: {username}") flash('❌ Username atau password salah!', 'error') return redirect(url_for('login')) return render_template('login.html') @app.route('/logout') def logout(): session.clear() flash('👋 Logout berhasil!', 'info') return redirect(url_for('home')) @app.route('/admin') def admin(): if 'user_id' not in session: flash('🔐 Silakan login dulu!', 'warning') return redirect(url_for('login')) user = User.query.get(session['user_id']) if not user or not user.is_admin: flash('⛔ Anda bukan admin!', 'error') return redirect(url_for('home')) photos = Photo.query.order_by(Photo.upload_date.desc()).all() return render_template('admin.html', photos=photos, user=user) @app.route('/upload', methods=['POST']) def upload(): if 'user_id' not in session: return redirect(url_for('login')) user = User.query.get(session['user_id']) if not user or not user.is_admin: return redirect(url_for('home')) if 'file' not in request.files: flash('❌ Pilih file!', 'error') return redirect(url_for('admin')) file = request.files['file'] if file.filename == '': flash('❌ Pilih file!', 'error') return redirect(url_for('admin')) # Validasi file photo_ext = {'png', 'jpg', 'jpeg', 'gif', 'webp'} video_ext = {'mp4', 'webm', 'mov', 'avi', 'mkv'} ext = file.filename.rsplit('.', 1)[1].lower() if '.' in file.filename else '' if ext in photo_ext: file_type = 'photo' elif ext in video_ext: file_type = 'video' else: flash('❌ Format tidak didukung!', 'error') return redirect(url_for('admin')) # Simpan file filename = secure_filename(file.filename) filename = datetime.now().strftime('%Y%m%d%H%M%S') + '_' + filename file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) # Simpan ke DB photo = Photo( filename=filename, caption=request.form.get('caption', ''), uploader_id=user.id, file_type=file_type ) db.session.add(photo) db.session.commit() flash(f'✅ Upload berhasil!', 'success') return redirect(url_for('admin')) @app.route('/delete/') def delete(photo_id): if 'user_id' not in session: return redirect(url_for('login')) user = User.query.get(session['user_id']) if not user or not user.is_admin: return redirect(url_for('home')) photo = Photo.query.get(photo_id) if photo: filepath = os.path.join(app.config['UPLOAD_FOLDER'], photo.filename) if os.path.exists(filepath): os.remove(filepath) db.session.delete(photo) db.session.commit() flash('✅ File dihapus!', 'success') return redirect(url_for('admin')) @app.route('/like/') def like(photo_id): photo = Photo.query.get(photo_id) if photo: photo.likes += 1 db.session.commit() return redirect(url_for('home')) @app.route('/slideshow') def slideshow(): photos = Photo.query.filter_by(file_type='photo').order_by(Photo.upload_date.desc()).limit(10).all() return jsonify([p.filename for p in photos]) @app.route('/test') def test(): return jsonify({ 'session': dict(session), 'user_logged_in': 'user_id' in session }) if __name__ == '__main__': port = int(os.environ.get('PORT', 7860)) app.run(host='0.0.0.0', port=port, debug=True)