feat: Mini-Cloud Plattform - komplette Implementierung Phase 0-8
Selbstgehostete Web-Cloud mit Dateiverwaltung, Kalender, Kontakte, Email-Webclient, Office-Viewer und Passwort-Manager. Backend (Flask/Python): - JWT-Auth mit Access/Refresh Tokens, Benutzerverwaltung - Dateien: Upload/Download, Ordner, Berechtigungen, Share-Links - Kalender: CRUD, Teilen, iCal-Export, CalDAV well-known URLs - Kontakte: Adressbuecher, vCard-Export, Teilen - Email: IMAP/SMTP-Proxy, Multi-Account - Office-Viewer: DOCX/XLSX/PPTX/PDF Vorschau - Passwort-Manager: AES-256-GCM clientseitig, KeePass-Import - Sync-API fuer Desktop/Mobile-Clients - SQLite mit WAL-Modus Frontend (Vue 3 + PrimeVue): - Datei-Explorer mit Breadcrumbs und Share-Dialogen - Monatskalender mit Event-Verwaltung - Kontaktliste mit Adressbuch-Sidebar - Email-Client mit 3-Spalten-Layout - Passwort-Manager mit TOTP und Passwort-Generator - Admin-Panel, Settings, oeffentliche Share-Seite Docker: Multi-Stage Build, Bind Mounts (keine Volumes) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from flask import Flask, redirect, send_from_directory
|
||||
from flask_cors import CORS
|
||||
|
||||
from app.config import Config
|
||||
from app.extensions import db, bcrypt, migrate
|
||||
|
||||
|
||||
def create_app(config_class=Config):
|
||||
# Check if static frontend build exists (Docker production mode)
|
||||
static_dir = Path(__file__).resolve().parent.parent / 'static'
|
||||
if static_dir.exists():
|
||||
app = Flask(__name__, static_folder=str(static_dir), static_url_path='')
|
||||
else:
|
||||
app = Flask(__name__)
|
||||
|
||||
app.config.from_object(config_class)
|
||||
|
||||
# Ensure data directories exist
|
||||
Path(app.config['UPLOAD_PATH']).mkdir(parents=True, exist_ok=True)
|
||||
db_dir = Path(app.config['SQLALCHEMY_DATABASE_URI'].replace('sqlite:///', '')).parent
|
||||
db_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Initialize extensions
|
||||
db.init_app(app)
|
||||
bcrypt.init_app(app)
|
||||
migrate.init_app(app, db)
|
||||
|
||||
# CORS
|
||||
CORS(app, resources={r'/api/*': {'origins': app.config['FRONTEND_URL']}},
|
||||
supports_credentials=True)
|
||||
|
||||
# Register blueprints
|
||||
from app.api import api_bp
|
||||
app.register_blueprint(api_bp)
|
||||
|
||||
# Well-known URLs for CalDAV/CardDAV auto-discovery (iOS, DAVx5, etc.)
|
||||
@app.route('/.well-known/caldav')
|
||||
def wellknown_caldav():
|
||||
return redirect('/dav/', code=301)
|
||||
|
||||
@app.route('/.well-known/carddav')
|
||||
def wellknown_carddav():
|
||||
return redirect('/dav/', code=301)
|
||||
|
||||
# iCal export (public, no auth)
|
||||
@app.route('/ical/<token>')
|
||||
def ical_export_route(token):
|
||||
from app.api.calendar import ical_export as _ical_export
|
||||
return _ical_export(token)
|
||||
|
||||
# Serve frontend SPA for all non-API routes (production/Docker)
|
||||
if static_dir.exists():
|
||||
@app.route('/')
|
||||
def serve_index():
|
||||
return send_from_directory(str(static_dir), 'index.html')
|
||||
|
||||
@app.errorhandler(404)
|
||||
def serve_spa(e):
|
||||
return send_from_directory(str(static_dir), 'index.html')
|
||||
|
||||
# Create tables
|
||||
with app.app_context():
|
||||
from app import models # noqa: F401
|
||||
db.create_all()
|
||||
|
||||
# Enable WAL mode for SQLite
|
||||
with db.engine.connect() as conn:
|
||||
conn.execute(db.text('PRAGMA journal_mode=WAL'))
|
||||
conn.commit()
|
||||
|
||||
return app
|
||||
Reference in New Issue
Block a user