| |
| 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) |
|
|
| |
| 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') |
|
|
| |
| 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") |
|
|
| |
| @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) |
|
|
| |
| @app.route('/login', methods=['GET', 'POST']) |
| def login(): |
| |
| 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}") |
| |
| |
| user = User.query.filter_by(username=username).first() |
| |
| if user and user.check_password(password): |
| print(f"Login SUCCESS: {username}") |
| |
| |
| session['user_id'] = user.id |
| session['username'] = user.username |
| session['is_admin'] = user.is_admin |
| |
| |
| flash('β
Login berhasil!', 'success') |
| |
| |
| 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')) |
| |
| |
| 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')) |
| |
| |
| 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)) |
| |
| |
| 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/<int:photo_id>') |
| 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/<int:photo_id>') |
| 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) |