from flask import Flask, render_template_string, request, redirect, url_for, flash from werkzeug.utils import secure_filename import os import time from . import git_ops from .marvin_ops import MarvinClient # Für Uberspace 8 Marvin API # --- Konfiguration aus Umgebungsvariablen --- # Diese Variablen werden auf dem Uberspace (z.B. via .bash_profile oder Service-Config) gesetzt. UBERSPACE_ASTEROID = os.getenv('UBERSPACE_ASTEROID') UBERSPACE_DOMAIN = os.getenv('UBERSPACE_DOMAIN') MARVIN_API_KEY = os.getenv('MARVIN_API_KEY') FLASK_SECRET_KEY = os.getenv('FLASK_SECRET_KEY', 'fallback-fuer-lokale-entwicklung') app = Flask(__name__) # Konfiguration: Nutzt das 'downloads' Verzeichnis im aktuellen Arbeitsverzeichnis app.config['UPLOAD_FOLDER'] = os.path.join(os.getcwd(), 'downloads') app.secret_key = FLASK_SECRET_KEY # Sicherstellen, dass der Upload-Ordner existiert os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) # --- Hilfsfunktionen für die Content-Erzeugung --- def generate_markdown_content(data, article_slug): """Erzeugt den Markdown-Inhalt inklusive YAML Frontmatter für Pelican.""" # Pfade für die Links im statischen Blog (relativ zur Domain) pdf_path = f"/downloads/{article_slug}.pdf" audio_path = f"/downloads/{article_slug}.mp3" markdown_template = f"""--- Title: {data['title']} Date: {time.strftime("%Y-%m-%d %H:%M")} Slug: {article_slug} Description: {data['description']} Abstract: {data['abstract']} PDF_Download: {pdf_path} Audio_Download: {audio_path} --- {data['article_body']} """ return markdown_template.strip() # --- Flask Routen --- @app.route('/', methods=['GET']) def new_article_form(): """Zeigt das Eingabeformular für die Autorin.""" form_html = """

Neuen Artikel erstellen

Angemeldet auf Asteroid: {{ asteroid }}
















""" return render_template_string(form_html, asteroid=UBERSPACE_ASTEROID) @app.route('/preview', methods=['POST']) def preview_article(): """Erzeugt eine Vorschau des Artikels.""" data = request.form # Slug für Dateinamen generieren slug = secure_filename(data['title']).lower().replace('-', '_') markdown_content = generate_markdown_content(data, slug) # In der Praxis müssten die Dateien hier temporär zwischengespeichert werden, # um sie im /publish Schritt final zu übernehmen. preview_html = f"""

Vorschau: {data['title']}


Abstract:

{data['abstract']}


[Hier würde der gerenderte Artikeltext stehen]


Möchten Sie diesen Artikel jetzt auf {UBERSPACE_DOMAIN} veröffentlichen?

Abbrechen und zurück
""" return preview_html @app.route('/publish', methods=['POST']) def publish_article(): """Speichert Dateien und führt den Git-Push aus.""" markdown_content = request.form.get('content_data') article_title = request.form.get('article_title') if not markdown_content: flash("Fehler: Keine Inhaltsdaten vorhanden.") return redirect(url_for('new_article_form')) # Dateinamen und Pfad festlegen article_slug = secure_filename(article_title).lower().replace('-', '_') filename = f"{article_slug}.md" article_path = os.path.join(os.getcwd(), 'content', filename) # 1. Speichern des Markdown-Artikels try: with open(article_path, 'w', encoding='utf-8') as f: f.write(markdown_content) except IOError as e: return f"Fehler beim Speichern des Artikels: {e}", 500 # 2. Git Operationen ausführen try: # Wir übergeben die Umgebungsvariablen an die git_ops, falls dort # spezifische Commit-Messages oder Remote-Targets benötigt werden. git_ops.add_and_commit(filename, f"Neuer Artikel: {article_title}") git_ops.push_to_remote() flash(f"Erfolgreich veröffentlicht auf {UBERSPACE_DOMAIN}!") except Exception as e: return f"Git-Fehler: {e}", 500 return redirect(url_for('new_article_form')) if __name__ == '__main__': # Lokal zum Testen, auf Uberspace wird dies via Gunicorn/Passenger gestartet app.run(debug=True)