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.
This commit is contained in:
parent
3c51f27e97
commit
2f9491c71b
4 changed files with 108 additions and 7 deletions
|
|
@ -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…
Reference in a new issue