0.16.1-1 Fix registry Makemkv

This commit is contained in:
2026-04-29 08:29:44 +00:00
parent 6636eb11df
commit 482f7ccec1
8 changed files with 196 additions and 53 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "ripster-backend",
"version": "0.16.1",
"version": "0.16.1-1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ripster-backend",
"version": "0.16.1",
"version": "0.16.1-1",
"dependencies": {
"archiver": "^7.0.1",
"cors": "^2.8.5",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ripster-backend",
"version": "0.16.1",
"version": "0.16.1-1",
"private": true,
"type": "commonjs",
"scripts": {
+100 -18
View File
@@ -1,13 +1,18 @@
const fs = require('fs');
const os = require('os');
const path = require('path');
const { execFile } = require('child_process');
const logger = require('./logger').child('MAKEMKV_KEY');
const MAKEMKV_BETA_KEY_API_URL = 'https://cable.ayra.ch/makemkv/api.php?raw';
const MAKEMKV_BETA_KEY_API_URL = 'https://cable.ayra.ch/makemkv/api.php?json';
const MAKEMKV_BETA_KEY_API_USER_AGENT = process.env.MAKEMKV_BETA_KEY_API_USER_AGENT
|| 'Ripster/1.0 (MakeMKV beta key sync)';
const MAKEMKV_BETA_KEY_API_FROM = process.env.MAKEMKV_BETA_KEY_API_FROM
|| 'ripster@localhost';
|| 'admin@example.invalid';
const MAKEMKV_BETA_KEY_API_TIMEOUT_MS = Math.max(
1000,
Number(process.env.MAKEMKV_BETA_KEY_API_TIMEOUT_MS || 15000)
);
function normalizeRegistrationKey(rawValue) {
return String(rawValue || '').trim();
@@ -89,27 +94,42 @@ async function syncRegistrationKeyToConfig(rawValue, options = {}) {
}
async function fetchCurrentBetaKey() {
const response = await fetch(MAKEMKV_BETA_KEY_API_URL, {
headers: {
'User-Agent': MAKEMKV_BETA_KEY_API_USER_AGENT,
'From': MAKEMKV_BETA_KEY_API_FROM,
'Accept': 'text/plain, text/html;q=0.9, */*;q=0.8',
'Cache-Control': 'no-cache',
'Pragma': 'no-cache'
}
});
const errors = [];
if (!response.ok) {
const error = new Error(`Betakey konnte nicht geladen werden (HTTP ${response.status}).`);
try {
return await fetchCurrentBetaKeyViaCurl();
} catch (error) {
errors.push(error?.message || String(error));
logger.warn('beta-key:curl-failed', {
error: error?.message || String(error)
});
}
try {
return await fetchCurrentBetaKeyViaFetch();
} catch (error) {
errors.push(error?.message || String(error));
logger.warn('beta-key:fetch-failed', {
error: error?.message || String(error)
});
}
const error = new Error(`Betakey konnte nicht geladen werden. Details: ${errors.join(' | ')}`);
error.statusCode = 502;
throw error;
}
function parseBetaKeyResponse(rawBody) {
let payload = null;
try {
payload = JSON.parse(String(rawBody || '{}'));
} catch (_error) {
const error = new Error('Betakey-Antwort ist kein gültiges JSON.');
error.statusCode = 502;
throw error;
}
const rawBody = await response.text();
const betaKey = String(rawBody || '')
.split(/\r?\n/)
.map((line) => line.trim())
.find(Boolean) || '';
const betaKey = String(payload?.key || '').trim();
if (!/^[A-Za-z0-9][A-Za-z0-9-]{15,}$/.test(betaKey)) {
const error = new Error('Betakey-Antwort ist ungültig.');
@@ -123,6 +143,68 @@ async function fetchCurrentBetaKey() {
};
}
function fetchCurrentBetaKeyViaCurl() {
return new Promise((resolve, reject) => {
execFile(
'curl',
[
'-fsSL',
'--max-time', String(Math.ceil(MAKEMKV_BETA_KEY_API_TIMEOUT_MS / 1000)),
'-A', MAKEMKV_BETA_KEY_API_USER_AGENT,
'-H', `From: ${MAKEMKV_BETA_KEY_API_FROM}`,
'-H', 'Accept: text/plain, text/html;q=0.9, */*;q=0.8',
'-H', 'Accept-Language: de,en-US;q=0.7,en;q=0.3',
'-H', 'Cache-Control: no-cache',
'-H', 'Pragma: no-cache',
MAKEMKV_BETA_KEY_API_URL
],
{
timeout: MAKEMKV_BETA_KEY_API_TIMEOUT_MS,
maxBuffer: 1024 * 1024
},
(error, stdout, stderr) => {
if (error) {
const resolvedError = new Error(
`curl fehlgeschlagen (${error.code || 'unknown'}): ${String(stderr || error.message || '').trim() || 'keine Details'}`
);
resolvedError.statusCode = 502;
reject(resolvedError);
return;
}
try {
resolve(parseBetaKeyResponse(stdout));
} catch (parseError) {
reject(parseError);
}
}
);
});
}
async function fetchCurrentBetaKeyViaFetch() {
const response = await fetch(MAKEMKV_BETA_KEY_API_URL, {
headers: {
'User-Agent': MAKEMKV_BETA_KEY_API_USER_AGENT,
'From': MAKEMKV_BETA_KEY_API_FROM,
'Accept': 'text/plain, text/html;q=0.9, */*;q=0.8',
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
'Cache-Control': 'no-cache',
'Pragma': 'no-cache'
},
signal: AbortSignal.timeout(MAKEMKV_BETA_KEY_API_TIMEOUT_MS)
});
if (!response.ok) {
const error = new Error(`HTTP ${response.status}`);
error.statusCode = 502;
throw error;
}
const rawBody = await response.text();
return parseBetaKeyResponse(rawBody);
}
module.exports = {
MAKEMKV_BETA_KEY_API_URL,
fetchCurrentBetaKey,
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "ripster-frontend",
"version": "0.16.1",
"version": "0.16.1-1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ripster-frontend",
"version": "0.16.1",
"version": "0.16.1-1",
"dependencies": {
"primeicons": "^7.0.0",
"primereact": "^10.9.2",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ripster-frontend",
"version": "0.16.1",
"version": "0.16.1-1",
"private": true,
"type": "module",
"scripts": {
+87 -26
View File
@@ -446,35 +446,89 @@ install_makemkv() {
sync_makemkv_beta_key() {
header "MakeMKV Betakey synchronisieren"
local api_url="http://127.0.0.1:${BACKEND_PORT}/settings/makemkv/beta-key/apply"
local response=""
local backend_settings_url="http://127.0.0.1:${BACKEND_PORT}/settings"
local beta_api_url="https://cable.ayra.ch/makemkv/api.php?json"
local settings_response=""
local current_key=""
local beta_response=""
local beta_key=""
local save_response=""
local makemkv_settings_file="${SERVICE_HOME}/.MakeMKV/settings.conf"
if ! response=$(curl -fsS \
-X POST \
update_makemkv_settings_file_key() {
local settings_file="$1"
local registration_key="$2"
local tmp_file
tmp_file=$(mktemp)
if [[ -f "$settings_file" ]]; then
grep -vE '^[[:space:]]*app_Key[[:space:]]*=' "$settings_file" > "$tmp_file" || true
else
: > "$tmp_file"
fi
printf 'app_Key = "%s"\n' "$registration_key" >> "$tmp_file"
mv "$tmp_file" "$settings_file"
chown "$SERVICE_USER:$SERVICE_USER" "$settings_file" 2>/dev/null || true
chmod 600 "$settings_file" 2>/dev/null || true
}
if ! settings_response=$(curl -fsS "$backend_settings_url" 2>/dev/null); then
warn "Backend-Settings konnten nicht geladen werden."
warn "Betakey-Synchronisierung übersprungen: $backend_settings_url"
return 0
fi
current_key=$(printf '%s' "$settings_response" | jq -r '
(.categories // [])
| map(.settings // [])
| add
| map(select(.key == "makemkv_registration_key"))
| .[0].value // ""
' 2>/dev/null || true)
current_key="${current_key:-}"
mkdir -p "${SERVICE_HOME}/.MakeMKV"
chown "$SERVICE_USER:$SERVICE_USER" "${SERVICE_HOME}/.MakeMKV" 2>/dev/null || true
chmod 700 "${SERVICE_HOME}/.MakeMKV" 2>/dev/null || true
if [[ -n "$current_key" ]]; then
update_makemkv_settings_file_key "$makemkv_settings_file" "$current_key"
ok "Vorhandener MakeMKV-Key bleibt erhalten ($makemkv_settings_file)"
return 0
fi
if ! beta_response=$(curl -fsS \
-A 'Ripster/1.0 (MakeMKV beta key installer)' \
-H 'From: admin@example.invalid' \
-H 'Accept: application/json, text/plain;q=0.9, */*;q=0.8' \
-H 'Accept-Language: de,en-US;q=0.7,en;q=0.3' \
-H 'Cache-Control: no-cache' \
-H 'Pragma: no-cache' \
"$beta_api_url" 2>/dev/null); then
warn "MakeMKV-Betakey konnte nicht von der JSON-API geladen werden."
warn "API-Endpunkt fehlgeschlagen: $beta_api_url"
return 0
fi
beta_key=$(printf '%s' "$beta_response" | jq -r '.key // ""' 2>/dev/null || true)
beta_key="${beta_key:-}"
if [[ -z "$beta_key" ]]; then
warn "MakeMKV-Betakey fehlt in der JSON-Antwort."
return 0
fi
if ! save_response=$(curl -fsS \
-X PUT \
-H 'Content-Type: application/json' \
--data '{}' \
"$api_url" 2>/dev/null); then
warn "MakeMKV-Betakey konnte nicht automatisch übernommen werden."
warn "Backend-Endpunkt fehlgeschlagen: $api_url"
--data "{\"value\":$(printf '%s' "$beta_key" | jq -Rs .)}" \
"${backend_settings_url}/makemkv_registration_key" 2>/dev/null); then
warn "MakeMKV-Betakey konnte nicht in den Settings gespeichert werden."
return 0
fi
local applied preserved settings_file
applied=$(printf '%s' "$response" | jq -r '.applied // false' 2>/dev/null || echo "false")
preserved=$(printf '%s' "$response" | jq -r '.preservedExistingKey // false' 2>/dev/null || echo "false")
settings_file=$(printf '%s' "$response" | jq -r '.settingsFilePath // empty' 2>/dev/null || true)
if [[ "$applied" == "true" ]]; then
ok "MakeMKV-Betakey automatisch gespeichert${settings_file:+ ($settings_file)}"
return 0
fi
if [[ "$preserved" == "true" ]]; then
ok "Vorhandener MakeMKV-Key bleibt erhalten${settings_file:+ ($settings_file)}"
return 0
fi
warn "MakeMKV-Betakey wurde nicht übernommen."
update_makemkv_settings_file_key "$makemkv_settings_file" "$beta_key"
ok "MakeMKV-Betakey automatisch gespeichert ($makemkv_settings_file)"
}
select_handbrake_mode() {
@@ -756,8 +810,15 @@ header "Repository holen (Git)"
# Prüfen ob der gewünschte Branch auf dem Remote existiert
info "Prüfe Branch '$GIT_BRANCH' auf Remote..."
if ! git ls-remote --exit-code --heads "$REPO_URL" "$GIT_BRANCH" &>/dev/null; then
fatal "Branch '$GIT_BRANCH' existiert nicht im Repository $REPO_URL.\nVerfügbare Branches: $(git ls-remote --heads "$REPO_URL" | awk '{print $2}' | sed 's|refs/heads/||' | tr '\n' ' ')"
branch_check_output=""
branch_check_status=0
if ! branch_check_output=$(git ls-remote --exit-code --heads "$REPO_URL" "$GIT_BRANCH" 2>&1); then
branch_check_status=$?
if [[ "$branch_check_status" -eq 2 ]]; then
available_branches=$(git ls-remote --heads "$REPO_URL" 2>/dev/null | awk '{print $2}' | sed 's|refs/heads/||' | tr '\n' ' ')
fatal "Branch '$GIT_BRANCH' existiert nicht im Repository $REPO_URL.\nVerfügbare Branches: ${available_branches:-keine oder Remote nicht erreichbar}"
fi
fatal "Remote $REPO_URL ist nicht erreichbar.\nGit-Fehler: ${branch_check_output:-unbekannt}"
fi
ok "Branch '$GIT_BRANCH' gefunden"
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "ripster",
"version": "0.16.1",
"version": "0.16.1-1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ripster",
"version": "0.16.1",
"version": "0.16.1-1",
"devDependencies": {
"concurrently": "^9.1.2"
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "ripster",
"private": true,
"version": "0.16.1",
"version": "0.16.1-1",
"scripts": {
"dev": "concurrently \"npm run dev --prefix backend\" \"npm run dev --prefix frontend\"",
"dev:backend": "npm run dev --prefix backend",