|
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/<filename>')
|
|
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/<filename>', 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) |