import shutil
import subprocess
from pathlib import Path
from werkzeug.utils import secure_filename
from flask import Blueprint, jsonify, request, abort, send_file
from auth import login_required
from config import ALLOWED_ROOTS, MEDIA_EXTENSIONS, UPLOAD_DIR
bp = Blueprint('filebrowser', __name__)
@bp.route('/files')
def serve_file():
path = request.args.get('path', '')
if not path:
abort(400)
p = Path(path).resolve()
if not any(p.is_relative_to(r) for r in ALLOWED_ROOTS):
abort(403)
if not p.is_file():
abort(404)
return send_file(p)
@bp.route('/api/upload', methods=['POST'])
@login_required
def upload():
if 'file' not in request.files:
abort(400)
f = request.files['file']
if not f.filename:
abort(400)
name = secure_filename(f.filename)
ext = Path(name).suffix.lower()
if ext not in MEDIA_EXTENSIONS:
abort(415)
UPLOAD_DIR.mkdir(exist_ok=True)
dest = UPLOAD_DIR / name
if dest.exists():
stem = Path(name).stem
i = 1
while dest.exists():
dest = UPLOAD_DIR / f'{stem}_{i}{ext}'
i += 1
f.save(dest)
# Konvertera presentationer till PDF med LibreOffice om tillgängligt
if ext in {'.ppt', '.pptx', '.odp'} and shutil.which('libreoffice'):
try:
subprocess.run(
['libreoffice', '--headless', '--convert-to', 'pdf', str(dest), '--outdir', str(UPLOAD_DIR)],
timeout=120, check=True,
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
)
pdf_path = UPLOAD_DIR / (dest.stem + '.pdf')
if pdf_path.exists():
dest.unlink()
dest = pdf_path
except Exception:
pass
return jsonify({'path': str(dest), 'url': '/files?path=' + str(dest)})
@bp.route('/api/browse')
@login_required
def browse():
req_path = request.args.get('path', str(Path('/home/mrfox')))
p = Path(req_path).resolve()
if not any(p.is_relative_to(r) for r in ALLOWED_ROOTS):
abort(403)
if not p.is_dir():
abort(404)
entries = []
try:
for entry in sorted(p.iterdir(), key=lambda e: (not e.is_dir(), e.name.lower())):
if entry.name.startswith('.'):
continue
if entry.is_dir():
entries.append({'name': entry.name, 'path': str(entry), 'type': 'dir'})
elif entry.suffix.lower() in MEDIA_EXTENSIONS:
entries.append({'name': entry.name, 'path': str(entry), 'type': 'file', 'ext': entry.suffix.lower()})
except PermissionError:
pass
parent = str(p.parent)
if not any(Path(parent).is_relative_to(r) for r in ALLOWED_ROOTS):
parent = None
return jsonify({'path': str(p), 'parent': parent, 'entries': entries})