from flask import Flask, render_template, request, redirect, url_for, send_from_directory, session from flask_socketio import SocketIO, emit import os from werkzeug.security import generate_password_hash, check_password_hash from PIL import Image from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler app = Flask(__name__) app.config['SECRET_KEY'] = 'your_secret_key' # Replace with a strong secret key socketio = SocketIO(app) app.config['UPLOAD_FOLDER'] = 'images' # Folder to store images app.config['CACHE_FOLDER'] = 'cache' # Folder to store cached resized images app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'gif'} # Fixed username and password USERNAME = 'user' PASSWORD = generate_password_hash('password') # Hashed password def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS'] def resize_image(image_path, cache_path, size=(800, 450)): with Image.open(image_path) as img: img.thumbnail(size) img.save(cache_path) @app.route('/') def index(): return redirect(url_for('login')) @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] if username == USERNAME and check_password_hash(PASSWORD, password): session['logged_in'] = True return redirect(url_for('gallery')) else: error = 'Invalid credentials' return render_template('login.html', error=error) return render_template('login.html') @app.route('/logout') def logout(): session.pop('logged_in', None) return redirect(url_for('login')) @app.route('/gallery') def gallery(): if not session.get('logged_in'): return redirect(url_for('login')) images = os.listdir(app.config['UPLOAD_FOLDER']) cached_images = [] if not os.path.exists(app.config['CACHE_FOLDER']): os.makedirs(app.config['CACHE_FOLDER']) for image in images: image_path = os.path.join(app.config['UPLOAD_FOLDER'], image) cache_path = os.path.join(app.config['CACHE_FOLDER'], image) if not os.path.exists(cache_path): resize_image(image_path, cache_path) cached_images.append(image) return render_template('gallery.html', images=cached_images) @app.route('/images/') def uploaded_file(filename): return send_from_directory(app.config['CACHE_FOLDER'], filename) def emit_gallery_update(): socketio.emit('update_gallery') class Watcher(FileSystemEventHandler): def on_modified(self, event): if not event.is_directory: emit_gallery_update() def on_created(self, event): if not event.is_directory: emit_gallery_update() def on_deleted(self, event): if not event.is_directory: emit_gallery_update() if __name__ == '__main__': observer = Observer() observer.schedule(Watcher(), path=app.config['UPLOAD_FOLDER'], recursive=False) observer.start() try: context = ('cert.pem', 'key.pem') # Replace with your self-signed certificate and key files socketio.run(app, debug=True, ssl_context=context) except KeyboardInterrupt: observer.stop() observer.join()