Add frontend git update button and backend update endpoint
This commit is contained in:
parent
712d29921d
commit
cd371a70be
5 changed files with 75 additions and 0 deletions
|
|
@ -2,6 +2,8 @@ FROM node:20-alpine
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apk add --no-cache git
|
||||||
|
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm install --omit=dev
|
RUN npm install --omit=dev
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ Web-Frontend, um Alben aus Spotify zu suchen und an Lidarr zu uebergeben.
|
||||||
- Track-Auswahl pro Album
|
- Track-Auswahl pro Album
|
||||||
- Uebergabe an Lidarr als Album-Download (MissingAlbumSearch)
|
- Uebergabe an Lidarr als Album-Download (MissingAlbumSearch)
|
||||||
- Einstellung im Frontend: ueberfluessige Dateien nach Download loeschen (optional)
|
- Einstellung im Frontend: ueberfluessige Dateien nach Download loeschen (optional)
|
||||||
|
- Button fuer Lidarr Bibliothek-Update
|
||||||
|
- Button fuer Frontend Git-Update (fetch/pull)
|
||||||
- Docker-ready
|
- Docker-ready
|
||||||
|
|
||||||
## Voraussetzungen
|
## Voraussetzungen
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ const trackList = document.getElementById('trackList');
|
||||||
const sendBtn = document.getElementById('sendBtn');
|
const sendBtn = document.getElementById('sendBtn');
|
||||||
const cleanupToggle = document.getElementById('cleanupToggle');
|
const cleanupToggle = document.getElementById('cleanupToggle');
|
||||||
const updateLibraryBtn = document.getElementById('updateLibraryBtn');
|
const updateLibraryBtn = document.getElementById('updateLibraryBtn');
|
||||||
|
const updateFrontendBtn = document.getElementById('updateFrontendBtn');
|
||||||
|
|
||||||
let selectedAlbum = null;
|
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);
|
searchBtn.addEventListener('click', searchSpotify);
|
||||||
queryInput.addEventListener('keydown', (event) => {
|
queryInput.addEventListener('keydown', (event) => {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
|
|
@ -247,3 +271,4 @@ queryInput.addEventListener('keydown', (event) => {
|
||||||
});
|
});
|
||||||
sendBtn.addEventListener('click', sendToLidarr);
|
sendBtn.addEventListener('click', sendToLidarr);
|
||||||
updateLibraryBtn.addEventListener('click', updateLibrary);
|
updateLibraryBtn.addEventListener('click', updateLibrary);
|
||||||
|
updateFrontendBtn.addEventListener('click', updateFrontendFromGit);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
</label>
|
</label>
|
||||||
<div style="margin-top: 0.8rem;">
|
<div style="margin-top: 0.8rem;">
|
||||||
<button id="updateLibraryBtn" type="button">Lidarr Bibliothek updaten</button>
|
<button id="updateLibraryBtn" type="button">Lidarr Bibliothek updaten</button>
|
||||||
|
<button id="updateFrontendBtn" type="button">Frontend updaten</button>
|
||||||
</div>
|
</div>
|
||||||
<p class="hint">
|
<p class="hint">
|
||||||
Wenn nur einzelne Songs gewaehlt sind, versucht die App unnoetige Track-Dateien in Lidarr zu entfernen.
|
Wenn nur einzelne Songs gewaehlt sind, versucht die App unnoetige Track-Dateien in Lidarr zu entfernen.
|
||||||
|
|
|
||||||
45
server.js
45
server.js
|
|
@ -2,9 +2,12 @@ require('dotenv').config();
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
const { execFile } = require('child_process');
|
||||||
|
const { promisify } = require('util');
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const port = Number(process.env.PORT || 3000);
|
const port = Number(process.env.PORT || 3000);
|
||||||
|
const execFileAsync = promisify(execFile);
|
||||||
|
|
||||||
const lidarrUrl = (process.env.LIDARR_URL || '').replace(/\/$/, '');
|
const lidarrUrl = (process.env.LIDARR_URL || '').replace(/\/$/, '');
|
||||||
const lidarrApiKey = process.env.LIDARR_API_KEY || '';
|
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) {
|
async function lidarrRequest(method, endpoint, data, params) {
|
||||||
if (!hasLidarrConfig()) {
|
if (!hasLidarrConfig()) {
|
||||||
throw new Error('Lidarr-Konfiguration unvollstaendig.');
|
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) => {
|
app.get('*', (_req, res) => {
|
||||||
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue