Save → avto-upload v Nextcloud → reel izgine iz seznama
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
This commit is contained in:
parent
1c11dfe630
commit
16c332b490
28
app/main.py
28
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,
|
||||
|
||||
@ -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 = '<div class="empty">Še ni obdelav</div>';
|
||||
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(`<button class="small ghost" data-action="delete" data-id="${job.id}">✕</button>`);
|
||||
|
||||
// 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 = `<span style="font-size:10px; padding:2px 6px; background:rgba(255,107,107,0.15); border:1px solid rgba(255,107,107,0.4); border-radius:3px; color:#ff8c8c; font-weight:600; white-space:nowrap;">${stationEmoji} ${escapeHtml(tvStation)}</span>`;
|
||||
|
||||
el.innerHTML = `
|
||||
<div class="job-head">
|
||||
<div class="job-title" title="${escapeHtml(title)}">${escapeHtml(title)}</div>
|
||||
<span class="badge ${job.status}">${statusLabel}</span>
|
||||
<div style="display:flex; gap:6px; align-items:center;">
|
||||
${tvBadge}
|
||||
<span class="badge ${job.status}">${statusLabel}</span>
|
||||
</div>
|
||||
</div>
|
||||
${job.current_step ? `<div class="step">${escapeHtml(job.current_step)}</div>` : ""}
|
||||
${showBar}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user