Expose Hydrabase as a configurable metadata source (no dev mode needed)

Add Hydrabase section to Settings → Connections with enable toggle,
WebSocket URL, API key, auto-connect, and connect/disconnect button.
_is_hydrabase_active() now checks hydrabase.enabled config in addition
to dev_mode — either path activates it. Default disabled, zero change
for existing users. Dev admin page stays behind dev mode password.
pull/253/head
Broque Thomas 2 months ago
parent 3c51f27e97
commit 2f9491c71b

@ -444,7 +444,8 @@ class ConfigManager:
"hydrabase": {
"url": "",
"api_key": "",
"auto_connect": False
"auto_connect": False,
"enabled": False
},
"content_filter": {
"allow_explicit": True

@ -4560,12 +4560,16 @@ _comparison_lock = threading.Lock()
def _is_hydrabase_active():
"""Check if Hydrabase should be used as the primary metadata source.
Returns False when dev mode is off no behavior change for normal users."""
Active when: (dev_mode OR hydrabase.enabled config) AND client connected."""
try:
return (dev_mode_enabled
and hydrabase_client is not None
and hydrabase_client.is_connected())
except NameError:
if hydrabase_client is None or not hydrabase_client.is_connected():
return False
# Dev mode always enables Hydrabase (legacy behavior)
if dev_mode_enabled:
return True
# Config toggle: user enabled Hydrabase as metadata source
return config_manager.get('hydrabase.enabled', False)
except (NameError, Exception):
return False
def _run_background_comparison(query, hydrabase_counts=None):
@ -40759,7 +40763,10 @@ try:
timeout=10
)
_hydrabase_ws = _auto_ws
dev_mode_enabled = True
# Enable dev mode only if Hydrabase was previously in dev mode
# The config toggle (hydrabase.enabled) handles non-dev usage
if not _hydra_cfg.get('enabled'):
dev_mode_enabled = True
print(f"✅ Hydrabase auto-connected to {_hydra_cfg['url']}")
except Exception as e:
print(f"⚠️ Hydrabase auto-reconnect failed: {e}")

@ -3677,6 +3677,38 @@
</div>
</div>
<!-- Hydrabase P2P Metadata -->
<div class="api-service-frame" data-stg="connections">
<h4 class="service-title" style="color: #00b4d8;">Hydrabase</h4>
<div class="form-group" style="margin-bottom: 8px;">
<label class="checkbox-label" style="display: flex; align-items: center; gap: 8px; cursor: pointer; padding: 0;">
<input type="checkbox" id="hydrabase-enabled" style="width: 16px; height: 16px;">
<span>Enable Hydrabase as metadata source</span>
</label>
</div>
<div class="form-group">
<label>WebSocket URL:</label>
<input type="text" id="hydrabase-url" placeholder="ws://localhost:4545">
</div>
<div class="form-group">
<label>API Key:</label>
<input type="password" id="hydrabase-api-key" placeholder="Hydrabase API Key">
</div>
<div class="form-group" style="margin-bottom: 8px;">
<label class="checkbox-label" style="display: flex; align-items: center; gap: 8px; cursor: pointer; padding: 0;">
<input type="checkbox" id="hydrabase-auto-connect" style="width: 16px; height: 16px;">
<span>Auto-connect on startup</span>
</label>
</div>
<div class="callback-info">
<div class="callback-help">P2P metadata network. When enabled and connected, replaces Spotify/iTunes as the primary metadata source for searches.</div>
</div>
<div class="form-actions">
<button class="test-button" id="hydrabase-connect-btn" onclick="toggleHydrabaseFromSettings()">Connect</button>
<span id="hydrabase-settings-status" style="font-size: 0.82em; color: rgba(255,255,255,0.4); margin-left: 8px;"></span>
</div>
</div>
<!-- Test Connection Buttons -->
<div class="api-test-buttons">
<button class="test-button" onclick="testConnection('spotify')">Test

@ -5467,6 +5467,13 @@ async function loadSettingsData() {
// Populate Metadata source setting
document.getElementById('metadata-fallback-source').value = settings.metadata?.fallback_source || 'itunes';
// Populate Hydrabase settings
const hbConfig = settings.hydrabase || {};
document.getElementById('hydrabase-enabled').checked = hbConfig.enabled || false;
document.getElementById('hydrabase-url').value = hbConfig.url || '';
document.getElementById('hydrabase-api-key').value = hbConfig.api_key || '';
document.getElementById('hydrabase-auto-connect').checked = hbConfig.auto_connect || false;
// Populate Download settings (right column)
document.getElementById('download-path').value = settings.soulseek?.download_path || './downloads';
document.getElementById('transfer-path').value = settings.soulseek?.transfer_path || './Transfer';
@ -6077,6 +6084,54 @@ async function saveQualityProfile() {
// END QUALITY PROFILE FUNCTIONS
// ===============================
async function toggleHydrabaseFromSettings() {
const statusEl = document.getElementById('hydrabase-settings-status');
const btn = document.getElementById('hydrabase-connect-btn');
const url = document.getElementById('hydrabase-url').value.trim();
const apiKey = document.getElementById('hydrabase-api-key').value.trim();
if (!url || !apiKey) {
if (statusEl) statusEl.textContent = 'URL and API Key required';
return;
}
// Save settings first
await saveSettings(true);
try {
// Check current status
const statusRes = await fetch('/api/hydrabase/status');
const statusData = await statusRes.json();
if (statusData.connected) {
// Disconnect
await fetch('/api/hydrabase/disconnect', { method: 'POST' });
if (btn) btn.textContent = 'Connect';
if (statusEl) statusEl.textContent = 'Disconnected';
showToast('Hydrabase disconnected', 'info');
} else {
// Connect
const res = await fetch('/api/hydrabase/connect', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url, api_key: apiKey })
});
const data = await res.json();
if (data.success) {
if (btn) btn.textContent = 'Disconnect';
if (statusEl) statusEl.textContent = 'Connected';
showToast('Hydrabase connected', 'success');
} else {
if (statusEl) statusEl.textContent = data.error || 'Connection failed';
showToast('Hydrabase connection failed', 'error');
}
}
} catch (e) {
if (statusEl) statusEl.textContent = 'Error';
showToast('Hydrabase connection error', 'error');
}
}
async function activateDevMode() {
const password = document.getElementById('dev-mode-password').value;
try {
@ -6384,6 +6439,12 @@ async function saveSettings(quiet = false) {
metadata: {
fallback_source: document.getElementById('metadata-fallback-source').value || 'itunes'
},
hydrabase: {
enabled: document.getElementById('hydrabase-enabled').checked,
url: document.getElementById('hydrabase-url').value,
api_key: document.getElementById('hydrabase-api-key').value,
auto_connect: document.getElementById('hydrabase-auto-connect').checked
},
download_source: {
mode: document.getElementById('download-source-mode').value,
hybrid_primary: document.getElementById('hybrid-primary-source').value,

Loading…
Cancel
Save