From 16c332b4906f0927cde96002b26f6bea21720505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastjan=20Arti=C4=8D?= Date: Thu, 30 Apr 2026 14:53:01 +0000 Subject: [PATCH] =?UTF-8?q?Save=20=E2=86=92=20avto-upload=20v=20Nextcloud?= =?UTF-8?q?=20=E2=86=92=20reel=20izgine=20iz=20seznama?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User feedback: 'zaenkrat bomo ročno popravljali in pregledovali. Ko kliknemo Save potem se shrani v pravi folder in izgine.' Workflow: 1. User izbere TV postajo (zavihek) 2. Naloži komade 3. Reel se renderira (auto chorus) 4. User pregleda + Edit če treba 5. Save → re-render z user popravki 6. Po končanem re-render: AVTO-upload v Nextcloud /folxspeed/REELS/{station}/ 7. Reel IZGINE iz seznama (hidden_after_upload flag) Backend changes: - RecutRequest: nov field auto_upload (default True) - update_job: shrani auto_upload_to_nextcloud - process_job done block: če flag set + Nextcloud configured → upload + nextcloud_status='uploaded' + hidden_after_upload=True Frontend changes: - refreshJobs: filter out jobs with hidden_after_upload - TV station badge na vsaki kartici (z emoji + ime postaje) - Vidiš na prvi pogled kam bo šlo Workflow rezultat: po Save reel izgine, je avtomatsko v pravi mapi --- app/main.py | 28 ++++++++++++++++++++++++++++ templates/index.html | 24 ++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/app/main.py b/app/main.py index ea6e6b7..3bf3ea8 100644 --- a/app/main.py +++ b/app/main.py @@ -768,6 +768,32 @@ def process_job(job_id): except Exception as e: print(f"⚠️ Edit precache failed: {e}", flush=True) + # Avto-upload v Nextcloud če flag set (npr. po Save/recut) + try: + final_job = load_job(job_id) + if final_job.get("auto_upload_to_nextcloud") and _nextcloud_configured(): + update_job(job_id, nextcloud_status="uploading", nextcloud_error=None) + download_name = build_download_filename(final_job) + tv_station = final_job.get("tv_station", "FOLX SLOVENIJA") + target_subdir = f"folxspeed/REELS/{tv_station}" + print(f"☁️ Avto-upload v Nextcloud: /{target_subdir}/{download_name}", flush=True) + success, result = _nextcloud_upload(str(output_path), download_name, target_subdir=target_subdir) + if success: + update_job( + job_id, + nextcloud_status="uploaded", + nextcloud_url=result, + nextcloud_error=None, + auto_upload_to_nextcloud=False, # disable da se ne ponovi + hidden_after_upload=True, # signal za UI da ga skrije + ) + print(f"☁️ Auto-upload OK: /{target_subdir}/{download_name}", flush=True) + else: + update_job(job_id, nextcloud_status="error", nextcloud_error=result) + print(f"⚠️ Auto-upload failed: {result}", flush=True) + except Exception as e: + print(f"⚠️ Auto-upload error: {e}", flush=True) + # Batch tracking — če je zadnji v batchu, pošlji summary _try_finalize_batch(job_id) else: @@ -1537,6 +1563,7 @@ class RecutRequest(BaseModel): end: float custom_segments: Optional[list] = None # [{start, end, text}] za override napisov no_subs: Optional[bool] = None + auto_upload: bool = True # po končanem recut avto-naloži v Nextcloud (default: da, ker user je že pregledal) # ─── Nextcloud upload ───────────────────────────────────────────── @@ -1689,6 +1716,7 @@ async def recut_job(job_id: str, payload: RecutRequest, user: str = Depends(chec status="queued", no_subs=no_subs, custom_clip=True, # flag da preskoči Soniox + Claude + auto_upload_to_nextcloud=payload.auto_upload, # avto-upload po končanem recut current_step="V vrsti za recut", error=None, chorus_error=None, diff --git a/templates/index.html b/templates/index.html index deb3b35..a6374a0 100644 --- a/templates/index.html +++ b/templates/index.html @@ -900,14 +900,16 @@ if (!r.ok) return; const data = await r.json(); const list = $("#jobs-list"); - if (!data.jobs.length) { + // Filtriraj ven jobe ki so že naloženi in skriti + const visible = data.jobs.filter(j => !j.hidden_after_upload); + if (!visible.length) { list.innerHTML = '
Še ni obdelav
'; return; } list.innerHTML = ""; - data.jobs.forEach(j => list.appendChild(buildJobEl(j))); + visible.forEach(j => list.appendChild(buildJobEl(j))); // Watch any in-progress job - data.jobs.forEach(j => { + visible.forEach(j => { if (["queued", "processing", "downloading", "uploaded"].includes(j.status)) { watchJob(j.id); } @@ -968,10 +970,24 @@ } actions.push(``); + // TV station label (z emoji prefix) + const tvStation = job.tv_station || "FOLX SLOVENIJA"; + const stationEmoji = { + "FOLX SLOVENIJA": "🇸🇮", + "FOLX DE": "🇩🇪", + "ONE DE": "🇩🇪", + "ZWEI MUSIC": "🎵", + "ADRIA": "🌊", + }[tvStation] || "📺"; + const tvBadge = `${stationEmoji} ${escapeHtml(tvStation)}`; + el.innerHTML = `
${escapeHtml(title)}
- ${statusLabel} +
+ ${tvBadge} + ${statusLabel} +
${job.current_step ? `
${escapeHtml(job.current_step)}
` : ""} ${showBar}