d01228a21e
- gui/main.py: FastAPI app with Jinja2 templates and static files - gui/state.py: shared application state (runner, template env) - gui/services/pos_runner.py: abstracted command execution layer with subprocess, SSE streaming, and sudo support - gui/routes/: 8 route modules (dashboard, install, compose, network, vbox, system, media, ssh) - gui/templates/: Bulma-based layout with sidebar navigation + section templates for all routes - gui/static/css/style.css: dark theme styling - gui/requirements.txt: fastapi, uvicorn, jinja2, python-multipart - 1- Start_GUI.sh: entry point with sudo cache, pip install, uvicorn launch Architecture: routes delegate to pos_runner which shells out to actual pos-* scripts — no logic duplication. SSE streaming for real-time output (install, compose up/down/logs, network scan, media).
57 lines
2.6 KiB
HTML
57 lines
2.6 KiB
HTML
{% extends "base.html" %}
|
|
{% block content %}
|
|
<section class="section">
|
|
<h1 class="title">Media Download</h1>
|
|
<div class="columns">
|
|
<div class="column">
|
|
<div class="box">
|
|
<h2 class="subtitle">MP3 (Audio)</h2>
|
|
<form hx-post="/media/mp3/stream" hx-trigger="submit" hx-target="#mp3-output">
|
|
<div class="field has-addons">
|
|
<div class="control is-expanded">
|
|
<input class="input" name="url" placeholder="https://youtube.com/watch?v=..." required>
|
|
</div>
|
|
<div class="control">
|
|
<button class="button is-primary">Download MP3</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<pre id="mp3-output" class="log-box mt-2"></pre>
|
|
</div>
|
|
</div>
|
|
<div class="column">
|
|
<div class="box">
|
|
<h2 class="subtitle">MP4 (Video)</h2>
|
|
<form hx-post="/media/mp4/formats" hx-target="#formats-output" hx-trigger="submit">
|
|
<div class="field has-addons">
|
|
<div class="control is-expanded">
|
|
<input class="input" name="url" placeholder="https://youtube.com/watch?v=..." required>
|
|
</div>
|
|
<div class="control">
|
|
<button class="button is-info">List Formats</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
<pre id="formats-output" class="log-box mt-2"></pre>
|
|
<form hx-post="/media/mp4/stream" hx-trigger="submit" hx-target="#mp4-output" class="mt-3">
|
|
<div class="field has-addons">
|
|
<div class="control is-expanded">
|
|
<input class="input" name="format_id" placeholder="format code from above">
|
|
</div>
|
|
<input type="hidden" name="url" id="mp4-url-input">
|
|
</div>
|
|
<button class="button is-primary">Download MP4</button>
|
|
</form>
|
|
<pre id="mp4-output" class="log-box mt-2"></pre>
|
|
<script>
|
|
document.querySelector('form[hx-post*="mp4/formats"]').addEventListener('htmx:afterRequest', function(evt) {
|
|
const url = evt.detail.elt.querySelector('[name=url]').value;
|
|
document.getElementById('mp4-url-input').value = url;
|
|
});
|
|
</script>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
{% endblock %}
|