204941a1dc
- Created a detailed database schema document outlining tables, relationships, and key fields. - Added OAuth integration documentation covering Spotify and Dropbox authentication processes. - Introduced a FAQ section addressing common user inquiries about the application. - Developed a user-friendly index page for easy navigation of the documentation. - Specified documentation dependencies in requirements.txt for building the documentation site. - Expanded user guide with sections on account management, creating rounds, exporting rounds, getting started, importing songs, and user interface navigation. - Updated mkdocs.yml for improved site structure and navigation.
285 lines
9.5 KiB
Markdown
285 lines
9.5 KiB
Markdown
# Architecture Overview
|
|
|
|
This document provides a comprehensive overview of the Quizzical Beats architecture, designed to help developers understand the system structure and components.
|
|
|
|
## Application Structure
|
|
|
|
Quizzical Beats follows a modular Flask application structure:
|
|
|
|
```
|
|
musicround/
|
|
├── __init__.py # Application factory
|
|
├── config.py # Configuration management
|
|
├── models.py # Database models
|
|
├── version.py # Version information
|
|
├── errors.py # Error handling
|
|
├── deezer_client.py # Deezer API integration
|
|
├── helpers/ # Utility modules
|
|
│ ├── __init__.py
|
|
│ ├── auth_helpers.py # Authentication utilities
|
|
│ ├── backup_helper.py # Backup management
|
|
│ ├── dropbox_helper.py # Dropbox integration
|
|
│ ├── email_helper.py # Email functionality
|
|
│ ├── import_helper.py # Song import utilities
|
|
│ ├── metadata.py # Song metadata processing
|
|
│ ├── spotify_direct.py # Spotify API client
|
|
│ └── utils.py # General utilities
|
|
├── mp3/ # Audio file storage
|
|
├── routes/ # Route definitions
|
|
│ ├── __init__.py
|
|
│ ├── api.py # API endpoints
|
|
│ ├── auth.py # Authentication routes
|
|
│ ├── core.py # Core application routes
|
|
│ ├── db_admin.py # Database administration
|
|
│ ├── deezer_routes.py # Deezer integration
|
|
│ ├── generate.py # Content generation
|
|
│ ├── import.py # Generic import functionality
|
|
│ ├── import_routes.py # Import interface routes
|
|
│ ├── import_songs.py # Song import functionality
|
|
│ ├── process.py # Audio processing
|
|
│ ├── rounds.py # Quiz round management
|
|
│ └── users.py # User account management
|
|
├── static/ # Static files (CSS, JS, images)
|
|
└── templates/ # Jinja2 HTML templates
|
|
├── admin/ # Admin interface templates
|
|
├── auth/ # Authentication templates
|
|
└── ... (other template categories)
|
|
```
|
|
|
|
## Key Components
|
|
|
|
### Application Factory
|
|
|
|
The application is initialized using a factory pattern in `__init__.py`. This allows for flexible configuration and testing:
|
|
|
|
```python
|
|
def create_app():
|
|
app = Flask(__name__)
|
|
|
|
# Load configuration
|
|
app.config.from_object(Config)
|
|
|
|
# Initialize extensions
|
|
db.init_app(app)
|
|
login_manager.init_app(app)
|
|
|
|
# Register blueprints
|
|
from musicround.routes import core, auth, rounds, users, import_songs, import_routes, generate, process, api, deezer_routes, db_admin
|
|
|
|
app.register_blueprint(core.bp)
|
|
app.register_blueprint(auth.bp)
|
|
app.register_blueprint(rounds.bp)
|
|
app.register_blueprint(users.bp)
|
|
app.register_blueprint(import_songs.bp)
|
|
app.register_blueprint(import_routes.bp)
|
|
app.register_blueprint(generate.bp)
|
|
app.register_blueprint(process.bp)
|
|
app.register_blueprint(api.bp)
|
|
app.register_blueprint(deezer_routes.bp)
|
|
app.register_blueprint(db_admin.bp)
|
|
|
|
return app
|
|
```
|
|
|
|
### Configuration Management
|
|
|
|
Configuration is handled in `config.py` using environment variables loaded from a `.env` file:
|
|
|
|
```python
|
|
class Config:
|
|
# Core configuration
|
|
DEBUG = os.getenv("DEBUG", "True") == "True"
|
|
SECRET_KEY = os.getenv('SECRET_KEY', 'dev-key-please-change')
|
|
|
|
# API keys for various services
|
|
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
|
DEEPL_API_KEY = os.getenv("DEEPL_API_KEY")
|
|
MEANINGCLOUD_API_KEY = os.getenv("MEANINGCLOUD_API_KEY")
|
|
LASTFM_API_KEY = os.getenv("LASTFM_API_KEY")
|
|
|
|
# Database configuration
|
|
SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI', 'sqlite:///data/song_data.db')
|
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
|
|
# OAuth provider configurations
|
|
SPOTIFY_CLIENT_ID = os.getenv("SPOTIFY_CLIENT_ID")
|
|
SPOTIFY_CLIENT_SECRET = os.getenv("SPOTIFY_CLIENT_SECRET")
|
|
DROPBOX_APP_KEY = os.getenv("DROPBOX_APP_KEY")
|
|
GOOGLE_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
|
|
# ... other configuration
|
|
```
|
|
|
|
### Database Models
|
|
|
|
The data model is defined in `models.py` using SQLAlchemy ORM:
|
|
|
|
```python
|
|
class User(db.Model, UserMixin):
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
username = db.Column(db.String(80), unique=True, nullable=False)
|
|
email = db.Column(db.String(120), unique=True, nullable=True)
|
|
password_hash = db.Column(db.String(128))
|
|
is_admin = db.Column(db.Boolean, default=False)
|
|
rounds = db.relationship('Round', backref='author', lazy=True)
|
|
# OAuth tokens and preferences
|
|
|
|
class Song(db.Model):
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
title = db.Column(db.String(200), nullable=False)
|
|
artist = db.Column(db.String(200), nullable=False)
|
|
spotify_id = db.Column(db.String(50), nullable=True)
|
|
preview_url = db.Column(db.String(255), nullable=True)
|
|
year = db.Column(db.Integer, nullable=True)
|
|
# Audio features and metadata
|
|
|
|
class Round(db.Model):
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
title = db.Column(db.String(200), nullable=False)
|
|
description = db.Column(db.Text, nullable=True)
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
|
songs = db.relationship('RoundSong', backref='round', lazy=True, cascade="all, delete-orphan")
|
|
# Round configuration and settings
|
|
```
|
|
|
|
### Authentication System
|
|
|
|
The authentication system supports:
|
|
|
|
1. **Local Authentication**: Username/password authentication
|
|
2. **OAuth Providers**:
|
|
- Spotify
|
|
- Google
|
|
- Authentik (OpenID Connect)
|
|
3. **Role-Based Access Control**: Admin vs. regular users
|
|
|
|
OAuth integration is handled through dedicated helper functions in `auth_helpers.py`:
|
|
|
|
```python
|
|
def get_spotify_oauth():
|
|
# Configure OAuth for Spotify
|
|
|
|
def get_google_oauth():
|
|
# Configure OAuth for Google
|
|
|
|
def get_authentik_oauth():
|
|
# Configure OAuth for Authentik
|
|
```
|
|
|
|
### External Integrations
|
|
|
|
#### Spotify Integration
|
|
|
|
The `spotify_direct.py` module provides:
|
|
- Authentication with Spotify API
|
|
- Playlist import functionality
|
|
- Track search and metadata retrieval
|
|
- Audio feature access
|
|
|
|
#### Dropbox Integration
|
|
|
|
The `dropbox_helper.py` module enables:
|
|
- OAuth authentication with Dropbox
|
|
- File export to Dropbox
|
|
- Folder management in Dropbox
|
|
- Shared link generation
|
|
|
|
#### Deezer Integration
|
|
|
|
The `deezer_client.py` and related routes provide:
|
|
- Authentication with Deezer API
|
|
- Playlist import
|
|
- Track search and preview access
|
|
|
|
#### OpenAI Integration
|
|
|
|
AI-powered features use the OpenAI API for:
|
|
- Round generation suggestions
|
|
- Lyric analysis
|
|
- Song categorization
|
|
|
|
### Backup System
|
|
|
|
The backup system in `backup_helper.py` provides:
|
|
|
|
```python
|
|
def create_backup(include_mp3=True, include_config=True, backup_name=None):
|
|
# Create ZIP archive with database and optional files
|
|
|
|
def restore_from_backup(backup_file, force=False):
|
|
# Restore system from backup archive
|
|
|
|
def list_backups():
|
|
# List available backups with metadata
|
|
|
|
def verify_backup(backup_path):
|
|
# Check backup integrity
|
|
```
|
|
|
|
Features include:
|
|
- Database dumps using SQLite backup API
|
|
- MP3 file inclusion in backups
|
|
- Configuration file backup
|
|
- Scheduled backups
|
|
- Retention policy management
|
|
|
|
## Request Flow
|
|
|
|
1. Request arrives at the Flask application
|
|
2. Blueprint routes direct to the appropriate view function
|
|
3. Authentication middleware checks for required permissions
|
|
4. View function processes the request:
|
|
- Database queries via SQLAlchemy models
|
|
- External API calls where needed
|
|
- Business logic processing
|
|
5. Response is rendered using Jinja2 templates
|
|
6. Rendered HTML is returned to the client
|
|
|
|
### Example Routes
|
|
|
|
```python
|
|
@bp.route('/rounds/<int:round_id>')
|
|
@login_required
|
|
def view_round(round_id):
|
|
round = Round.query.get_or_404(round_id)
|
|
# Check permissions
|
|
# Process data
|
|
return render_template('rounds/view.html', round=round)
|
|
|
|
@bp.route('/rounds/<int:round_id>/export-to-dropbox', methods=['POST'])
|
|
@login_required
|
|
def export_to_dropbox(round_id):
|
|
round = Round.query.get_or_404(round_id)
|
|
# Check permissions
|
|
# Export to Dropbox
|
|
return jsonify({'success': True, 'message': 'Export successful'})
|
|
```
|
|
|
|
## System Health Monitoring
|
|
|
|
The health monitoring system provides dashboards for:
|
|
|
|
1. **Database Health**: Connection status, table counts, size
|
|
2. **Storage Health**: Directory status, file counts, permissions
|
|
3. **External Service Status**: API connectivity checks
|
|
4. **Version Information**: Application version, dependencies
|
|
|
|
## Extension Points
|
|
|
|
To extend Quizzical Beats, consider these integration points:
|
|
|
|
1. **New OAuth Providers**: Add provider configuration in `auth_helpers.py`
|
|
2. **Additional Export Formats**: Implement in the rounds routes
|
|
3. **New Music Data Sources**: Create a new client module similar to `spotify_direct.py` or `deezer_client.py`
|
|
4. **Custom Audio Processing**: Extend the functionality in the `process.py` routes
|
|
5. **AI Features**: Enhance OpenAI integration for additional content generation
|
|
|
|
## Technology Stack
|
|
|
|
- **Backend**: Python 3.8+, Flask 2.x
|
|
- **Database**: SQLAlchemy 1.4+ with SQLite/PostgreSQL/MySQL
|
|
- **Frontend**: TailwindCSS, Alpine.js, vanilla JavaScript
|
|
- **Authentication**: Flask-Login, OAuth integrations
|
|
- **APIs**: Spotify, Deezer, Dropbox, OpenAI, DeepL
|
|
- **Media Processing**: FFmpeg, MP3 manipulation libraries
|
|
- **Testing**: Pytest for unit and integration tests |