Add frontend git update button and backend update endpoint

This commit is contained in:
J0Z1L 2026-02-28 00:12:10 +01:00
parent 712d29921d
commit cd371a70be
5 changed files with 75 additions and 0 deletions

View file

@ -2,6 +2,8 @@ FROM node:20-alpine
WORKDIR /app
RUN apk add --no-cache git
COPY package*.json ./
RUN npm install --omit=dev

View file

@ -8,6 +8,8 @@ Web-Frontend, um Alben aus Spotify zu suchen und an Lidarr zu uebergeben.
- Track-Auswahl pro Album
- Uebergabe an Lidarr als Album-Download (MissingAlbumSearch)
- Einstellung im Frontend: ueberfluessige Dateien nach Download loeschen (optional)
- Button fuer Lidarr Bibliothek-Update
- Button fuer Frontend Git-Update (fetch/pull)
- Docker-ready
## Voraussetzungen

View file

@ -10,6 +10,7 @@ const trackList = document.getElementById('trackList');
const sendBtn = document.getElementById('sendBtn');
const cleanupToggle = document.getElementById('cleanupToggle');
const updateLibraryBtn = document.getElementById('updateLibraryBtn');
const updateFrontendBtn = document.getElementById('updateFrontendBtn');
let selectedAlbum = null;
@ -239,6 +240,29 @@ async function updateLibrary() {
}
}
async function updateFrontendFromGit() {
setStatus('Hole aktuelle Git-Daten...');
updateFrontendBtn.disabled = true;
try {
const data = await fetchJson('/api/system/update-frontend', {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
});
if (data.updated) {
setStatus(`Frontend aktualisiert (${data.before} -> ${data.after}). Seite wird neu geladen...`);
setTimeout(() => window.location.reload(), 1200);
} else {
setStatus(`Bereits aktuell (${data.after}).`);
}
} catch (err) {
setStatus(`Frontend-Update fehlgeschlagen: ${err.message}`, true);
} finally {
updateFrontendBtn.disabled = false;
}
}
searchBtn.addEventListener('click', searchSpotify);
queryInput.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
@ -247,3 +271,4 @@ queryInput.addEventListener('keydown', (event) => {
});
sendBtn.addEventListener('click', sendToLidarr);
updateLibraryBtn.addEventListener('click', updateLibrary);
updateFrontendBtn.addEventListener('click', updateFrontendFromGit);

View file

@ -24,6 +24,7 @@
</label>
<div style="margin-top: 0.8rem;">
<button id="updateLibraryBtn" type="button">Lidarr Bibliothek updaten</button>
<button id="updateFrontendBtn" type="button">Frontend updaten</button>
</div>
<p class="hint">
Wenn nur einzelne Songs gewaehlt sind, versucht die App unnoetige Track-Dateien in Lidarr zu entfernen.

View file

@ -2,9 +2,12 @@ require('dotenv').config();
const express = require('express');
const path = require('path');
const axios = require('axios');
const { execFile } = require('child_process');
const { promisify } = require('util');
const app = express();
const port = Number(process.env.PORT || 3000);
const execFileAsync = promisify(execFile);
const lidarrUrl = (process.env.LIDARR_URL || '').replace(/\/$/, '');
const lidarrApiKey = process.env.LIDARR_API_KEY || '';
@ -40,6 +43,39 @@ function lidarrHeaders() {
};
}
async function runGit(args) {
const { stdout } = await execFileAsync('git', args, {
cwd: __dirname,
timeout: 20000
});
return String(stdout || '').trim();
}
async function updateFrontendFromGit() {
if (!require('fs').existsSync(path.join(__dirname, '.git'))) {
throw new Error('Kein Git-Repository im Container/Projektpfad gefunden.');
}
try {
await runGit(['--version']);
} catch (_err) {
throw new Error('git ist nicht installiert.');
}
const before = await runGit(['rev-parse', '--short', 'HEAD']);
const branch = await runGit(['rev-parse', '--abbrev-ref', 'HEAD']);
const dirty = await runGit(['status', '--porcelain']);
if (dirty) {
throw new Error('Lokale Aenderungen vorhanden. Update per Button ist blockiert.');
}
await runGit(['fetch', '--prune', 'origin']);
await runGit(['pull', '--ff-only', 'origin', branch]);
const after = await runGit(['rev-parse', '--short', 'HEAD']);
return { before, after, branch, updated: before !== after };
}
async function lidarrRequest(method, endpoint, data, params) {
if (!hasLidarrConfig()) {
throw new Error('Lidarr-Konfiguration unvollstaendig.');
@ -451,6 +487,15 @@ app.post('/api/lidarr/update-library', async (_req, res) => {
}
});
app.post('/api/system/update-frontend', async (_req, res) => {
try {
const result = await updateFrontendFromGit();
res.json({ success: true, ...result });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
app.get('*', (_req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});