from flask import Flask, render_template, send_file, jsonify, request, redirect, url_for, flash, abort from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user from flask_sqlalchemy import SQLAlchemy from werkzeug.security import generate_password_hash, check_password_hash from werkzeug.utils import secure_filename from pathlib import Path import os app = Flask(__name__) app.config['SECRET_KEY'] = 'your-secret-key' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # Папка для хранения музыкальных файлов MUSIC_FOLDER = Path('static/music') app.config['MUSIC_FOLDER'] = MUSIC_FOLDER # Инициализация базы данных и менеджера авторизации db = SQLAlchemy(app) login_manager = LoginManager(app) login_manager.login_view = 'login' # Модель пользователя class User(UserMixin, 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(120), nullable=False) favorite_tracks = db.relationship('FavoriteTrack', backref='user', lazy=True) # Модель избранных треков class FavoriteTrack(db.Model): id = db.Column(db.Integer, primary_key=True) track_name = db.Column(db.String(200), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) created_at = db.Column(db.DateTime, default=db.func.current_timestamp()) @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) # Создаем папку для музыки, если её нет if not os.path.exists(MUSIC_FOLDER): os.makedirs(MUSIC_FOLDER) @app.route('/register', methods=['GET', 'POST']) def register(): if request.method == 'POST': username = request.form.get('username') password = request.form.get('password') if User.query.filter_by(username=username).first(): flash('Пользователь с таким именем уже существует') return redirect(url_for('register')) user = User(username=username, password_hash=generate_password_hash(password)) db.session.add(user) db.session.commit() return redirect(url_for('login')) return render_template('register.html') @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form.get('username') password = request.form.get('password') user = User.query.filter_by(username=username).first() if user and check_password_hash(user.password_hash, password): login_user(user) return redirect(url_for('index')) flash('Неверное имя пользователя или пароль') return render_template('login.html') @app.route('/logout') @login_required def logout(): logout_user() return redirect(url_for('index')) @app.route('/') def index(): music_files = [f for f in os.listdir(MUSIC_FOLDER) if f.endswith(('.mp3', '.wav', '.m4a', '.webm'))] favorites = [] if current_user.is_authenticated: # Получаем избранные треки, отсортированные по дате добавления (новые сверху) favorite_tracks = FavoriteTrack.query.filter_by(user_id=current_user.id).order_by(FavoriteTrack.created_at.desc()).all() favorites = [track.track_name for track in favorite_tracks] return render_template('index.html', music_files=music_files, favorites=favorites) @app.route('/play/') def play_music(filename): try: return send_file(MUSIC_FOLDER / filename) except Exception as e: return str(e) @app.route('/tracks') def get_tracks(): music_files = [f for f in os.listdir(MUSIC_FOLDER) if f.endswith(('.mp3', '.wav', '.m4a', '.webm'))] return jsonify(music_files) @app.route('/favorite/', methods=['POST']) @login_required def toggle_favorite(filename): track = FavoriteTrack.query.filter_by(user_id=current_user.id, track_name=filename).first() if track: db.session.delete(track) db.session.commit() return jsonify({'status': 'removed'}) else: # Добавляем трек в избранное с текущим временем from datetime import datetime new_favorite = FavoriteTrack(track_name=filename, user_id=current_user.id, created_at=datetime.now()) db.session.add(new_favorite) db.session.commit() return jsonify({'status': 'added'}) @app.route('/favorites') @login_required def get_favorites(): # Получаем избранные треки, отсортированные по дате добавления (новые сверху) favorite_tracks = FavoriteTrack.query.filter_by(user_id=current_user.id).order_by(FavoriteTrack.created_at.desc()).all() favorites = [track.track_name for track in favorite_tracks] return jsonify(favorites) @app.route('/upload', methods=['POST']) @login_required def upload_music(): if 'file' not in request.files: return jsonify({'status': 'error', 'message': 'Файл не найден'}), 400 file = request.files['file'] if file.filename == '': return jsonify({'status': 'error', 'message': 'Файл не выбран'}), 400 if file and file.filename.endswith(('.mp3', '.wav', '.m4a', '.webm')): filename = secure_filename(file.filename) # Проверяем, существует ли файл с таким именем if os.path.exists(os.path.join(MUSIC_FOLDER, filename)): # Добавляем временную метку к имени файла, чтобы избежать перезаписи from datetime import datetime timestamp = datetime.now().strftime('%Y%m%d%H%M%S') name, ext = os.path.splitext(filename) filename = f"{name}_{timestamp}{ext}" file.save(os.path.join(MUSIC_FOLDER, filename)) return jsonify({'status': 'success', 'filename': filename}) else: return jsonify({'status': 'error', 'message': 'Недопустимый формат файла'}), 400 if __name__ == '__main__': with app.app_context(): db.create_all() app.run(host='0.0.0.0', port=5000, debug=True)