310 lines
14 KiB
HTML
310 lines
14 KiB
HTML
{{ define "config" }}
|
|
<div class="container mt-4">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h4 class="mb-0"><i class="bi bi-gear me-2"></i>Configuration</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<form id="configForm">
|
|
<div class="section mb-5">
|
|
<h5 class="border-bottom pb-2">General Configuration</h5>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="qbitDebug">Log Level</label>
|
|
<select class="form-select" name="qbit.log_level" id="log-level" disabled>
|
|
<option value="info">Info</option>
|
|
<option value="debug">Debug</option>
|
|
<option value="warn">Warning</option>
|
|
<option value="error">Error</option>
|
|
<option value="trace">Trace</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- Debrid Configuration -->
|
|
<div class="section mb-5">
|
|
<h5 class="border-bottom pb-2">Debrid Configuration</h5>
|
|
<div id="debridConfigs"></div>
|
|
</div>
|
|
|
|
<!-- QBitTorrent Configuration -->
|
|
<div class="section mb-5">
|
|
<h5 class="border-bottom pb-2">QBitTorrent Configuration</h5>
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label">Username</label>
|
|
<input type="text" disabled class="form-control" name="qbit.username">
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label">Password</label>
|
|
<input type="password" disabled class="form-control" name="qbit.password">
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label">Port</label>
|
|
<input type="text" disabled class="form-control" name="qbit.port">
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label">Symlink/Download Folder</label>
|
|
<input type="text" disabled class="form-control" name="qbit.download_folder">
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label">Refresh Interval (seconds)</label>
|
|
<input type="number" class="form-control" name="qbit.refresh_interval">
|
|
</div>
|
|
<div class="col-12 mb-3">
|
|
<div class="form-group">
|
|
<label for="qbitDebug">Log Level</label>
|
|
<select class="form-select" name="qbit.log_level" id="qbitDebug" disabled>
|
|
<option value="info">Info</option>
|
|
<option value="debug">Debug</option>
|
|
<option value="warn">Warning</option>
|
|
<option value="error">Error</option>
|
|
<option value="trace">Trace</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Arr Configurations -->
|
|
<div class="section mb-5">
|
|
<h5 class="border-bottom pb-2">Arr Configurations</h5>
|
|
<div id="arrConfigs"></div>
|
|
</div>
|
|
|
|
<!-- Repair Configuration -->
|
|
<div class="section">
|
|
<h5 class="border-bottom pb-2">Repair Configuration</h5>
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label">Interval</label>
|
|
<input type="text" disabled class="form-control" name="repair.interval" placeholder="e.g., 24h">
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="form-check mb-2">
|
|
<input type="checkbox" disabled class="form-check-input" name="repair.enabled" id="repairEnabled">
|
|
<label class="form-check-label" for="repairEnabled">Enable Repair</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input type="checkbox" disabled class="form-check-input" name="repair.run_on_start" id="repairOnStart">
|
|
<label class="form-check-label" for="repairOnStart">Run on Start</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
// Templates for dynamic elements
|
|
const debridTemplate = (index) => `
|
|
<div class="config-item position-relative mb-3 p-3 border rounded">
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label">Name</label>
|
|
<input type="text" disabled class="form-control" name="debrid[${index}].name" required>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label">Host</label>
|
|
<input type="text" disabled class="form-control" name="debrid[${index}].host" required>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label">API Key</label>
|
|
<input type="password" disabled class="form-control" name="debrid[${index}].api_key" required>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label">Mount Folder</label>
|
|
<input type="text" disabled class="form-control" name="debrid[${index}].folder">
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label">Rate Limit</label>
|
|
<input type="text" disabled class="form-control" name="debrid[${index}].rate_limit" placeholder="e.g., 200/minute">
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="form-check me-3 d-inline-block">
|
|
<input type="checkbox" disabled class="form-check-input" name="debrid[${index}].download_uncached">
|
|
<label class="form-check-label">Download Uncached</label>
|
|
</div>
|
|
<div class="form-check d-inline-block">
|
|
<input type="checkbox" disabled class="form-check-input" name="debrid[${index}].check_cached">
|
|
<label class="form-check-label">Check Cached</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
const arrTemplate = (index) => `
|
|
<div class="config-item position-relative mb-3 p-3 border rounded">
|
|
<div class="row">
|
|
<div class="col-md-4 mb-3">
|
|
<label class="form-label">Name</label>
|
|
<input type="text" disabled class="form-control" name="arr[${index}].name" required>
|
|
</div>
|
|
<div class="col-md-4 mb-3">
|
|
<label class="form-label">Host</label>
|
|
<input type="text" disabled class="form-control" name="arr[${index}].host" required>
|
|
</div>
|
|
<div class="col-md-4 mb-3">
|
|
<label class="form-label">API Token</label>
|
|
<input type="password" disabled class="form-control" name="arr[${index}].token" required>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
// Main functionality
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
let debridCount = 0;
|
|
let arrCount = 0;
|
|
|
|
// Load existing configuration
|
|
fetch('/internal/config')
|
|
.then(response => response.json())
|
|
.then(config => {
|
|
// Load Debrid configs
|
|
config.debrids?.forEach(debrid => {
|
|
addDebridConfig(debrid);
|
|
});
|
|
|
|
// Load QBitTorrent config
|
|
if (config.qbittorrent) {
|
|
Object.entries(config.qbittorrent).forEach(([key, value]) => {
|
|
const input = document.querySelector(`[name="qbit.${key}"]`);
|
|
if (input) {
|
|
if (input.type === 'checkbox') {
|
|
input.checked = value;
|
|
} else {
|
|
input.value = value;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Load Arr configs
|
|
config.arrs?.forEach(arr => {
|
|
addArrConfig(arr);
|
|
});
|
|
|
|
// Load Repair config
|
|
if (config.repair) {
|
|
Object.entries(config.repair).forEach(([key, value]) => {
|
|
const input = document.querySelector(`[name="repair.${key}"]`);
|
|
if (input) {
|
|
if (input.type === 'checkbox') {
|
|
input.checked = value;
|
|
} else {
|
|
input.value = value;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Load general config
|
|
|
|
const logLevel = document.getElementById('log-level');
|
|
logLevel.value = config.log_level;
|
|
|
|
});
|
|
|
|
// Handle form submission
|
|
document.getElementById('configForm').addEventListener('submit', async (e) => {
|
|
e.preventDefault();
|
|
const formData = new FormData(e.target);
|
|
const config = {
|
|
debrids: [],
|
|
qbittorrent: {},
|
|
arrs: [],
|
|
repair: {}
|
|
};
|
|
|
|
// Process form data
|
|
for (let [key, value] of formData.entries()) {
|
|
if (key.startsWith('debrid[')) {
|
|
const match = key.match(/debrid\[(\d+)\]\.(.+)/);
|
|
if (match) {
|
|
const [_, index, field] = match;
|
|
if (!config.debrids[index]) config.debrids[index] = {};
|
|
config.debrids[index][field] = value;
|
|
}
|
|
} else if (key.startsWith('qbit.')) {
|
|
config.qbittorrent[key.replace('qbit.', '')] = value;
|
|
} else if (key.startsWith('arr[')) {
|
|
const match = key.match(/arr\[(\d+)\]\.(.+)/);
|
|
if (match) {
|
|
const [_, index, field] = match;
|
|
if (!config.arrs[index]) config.arrs[index] = {};
|
|
config.arrs[index][field] = value;
|
|
}
|
|
} else if (key.startsWith('repair.')) {
|
|
config.repair[key.replace('repair.', '')] = value;
|
|
}
|
|
}
|
|
|
|
// Clean up arrays (remove empty entries)
|
|
config.debrids = config.debrids.filter(Boolean);
|
|
config.arrs = config.arrs.filter(Boolean);
|
|
|
|
try {
|
|
const response = await fetch('/internal/config', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(config)
|
|
});
|
|
|
|
if (!response.ok) throw new Error(await response.text());
|
|
|
|
alert('Configuration saved successfully!');
|
|
} catch (error) {
|
|
alert(`Error saving configuration: ${error.message}`);
|
|
}
|
|
});
|
|
|
|
// Helper functions
|
|
function addDebridConfig(data = {}) {
|
|
const container = document.getElementById('debridConfigs');
|
|
container.insertAdjacentHTML('beforeend', debridTemplate(debridCount));
|
|
|
|
if (data) {
|
|
Object.entries(data).forEach(([key, value]) => {
|
|
const input = container.querySelector(`[name="debrid[${debridCount}].${key}"]`);
|
|
if (input) {
|
|
if (input.type === 'checkbox') {
|
|
input.checked = value;
|
|
} else {
|
|
input.value = value;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
debridCount++;
|
|
}
|
|
|
|
function addArrConfig(data = {}) {
|
|
const container = document.getElementById('arrConfigs');
|
|
container.insertAdjacentHTML('beforeend', arrTemplate(arrCount));
|
|
|
|
if (data) {
|
|
Object.entries(data).forEach(([key, value]) => {
|
|
const input = container.querySelector(`[name="arr[${arrCount}].${key}"]`);
|
|
if (input) {
|
|
if (input.type === 'checkbox') {
|
|
input.checked = value;
|
|
} else {
|
|
input.value = value;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
arrCount++;
|
|
}
|
|
});
|
|
</script>
|
|
{{ end }} |