Fix Cantaloupe Sync: use sys.executable + add Excel file upload button

- Changed subprocess from 'python' to 'sys.executable' (fixes FileNotFoundError
  in systemd — venv python not in system PATH)
- Added '📤 Upload Excel' button to admin frontend sync page
- uploadSyncFile() sends file to the same /api/admin/cantaloupe/sync endpoint
  (which already supported file upload — frontend just didn't expose it)
- Users can now use 'Sync Now' for auto-download or 'Upload Excel' for manual
This commit is contained in:
Leo
2026-05-21 23:10:22 -04:00
parent 08c77669b2
commit 90a426bc9e
2 changed files with 26 additions and 1 deletions
+2 -1
View File
@@ -419,9 +419,10 @@ async def run_sync(
# Try subprocess call to cantaloupe export
try:
import subprocess
import sys
cantaloupe_dir = os.path.expanduser("~/projects/cantaloupe-downloader")
result = subprocess.run(
["python", "-m", "cantaloupe", "export", "--scheduled"],
[sys.executable, "-m", "cantaloupe", "export", "--scheduled"],
capture_output=True, text=True, timeout=120,
cwd=cantaloupe_dir,
)
+24
View File
@@ -864,6 +864,8 @@
<span>Cantaloupe Sync</span>
<div class="pt-actions">
<button class="btn btn-sm btn-primary" onclick="runSync()" id="csSyncBtn">🔄 Sync Now</button>
<input type="file" id="csFileInput" accept=".xlsx,.xls" style="display:none" onchange="uploadSyncFile(event)">
<button class="btn btn-sm btn-outline" onclick="document.getElementById('csFileInput').click()">📤 Upload Excel</button>
<button class="btn btn-sm btn-outline" onclick="loadCantaloupeSync()">↻ Refresh</button>
</div>
</div>
@@ -2320,6 +2322,28 @@ async function runSync() {
}
}
// ── Upload Excel File ──
async function uploadSyncFile(event) {
const file = event.target.files?.[0];
if (!file) return;
const fd = new FormData();
fd.append('file', file);
const btn = document.getElementById('csSyncBtn');
btn.disabled = true;
btn.innerHTML = '<div class="spinner"></div> Uploading...';
try {
const result = await api('/api/admin/cantaloupe/sync', { method: 'POST', body: fd });
showToast('Upload processed — batch #' + result.id);
await loadCantaloupeSync();
} catch (e) {
showToast('Upload failed: ' + e.message, true);
} finally {
btn.disabled = false;
btn.innerHTML = '🔄 Sync Now';
event.target.value = ''; // reset so same file can be re-picked
}
}
// ── Approve / Reject ──
async function approveBatch(batchId) {
const confirmed = await showModal('Approve Batch',