636c51e542
A customer whose machine was rebuilt had everything needed to get their data back and no way to find out: the only route was a command line. This is the screen that closes that. IT UNLOCKS, AND ONLY UNLOCKS (operator ruling). It explains, takes the recovery code, opens the repository and shows what is in there — apps, dates, sizes. It restores nothing: restore is already per-app and lives in the backups area, and a screen that unlocks and then offers to overwrite is two decisions wearing one button. ONE CORE, TWO CALLERS. RecoverInstallCore is split out of RecoverAndInstall; the CLI wrapper keeps its exit codes and printed lines byte-identical, and the handler drives the same function. Two implementations of the one operation that can permanently lose a customer's data would drift, and only one would be tested. Asserted from source on both sides by AST. THREE WAYS OUT, none a dismiss button: recover; 'most nem' (the full page stops interrupting, the backups-area entry point stays PERMANENTLY, bound to the offer and never to the postpone flag); and 'I do not want the old data' — confirmed TWICE and reaching the SHIPPED move-aside, which sets aside and never deletes. THE CODE IS HANDLED NO MORE LOOSELY THAN ON THE COMMAND LINE: POST body only, never logged, never persisted, never echoed, cleared on every path, no-store, autocomplete off. No lockout — the code is a ten-word phrase, and locking a customer out of their own data for a typo is worse than anything it prevents. TWO DEFECTS THE TESTS CAUGHT, both fixed: an UNCLAIMED (legacy-open) box would have been shown the page, because RequireAuth passes such a box through; and the inventory nil-dereferenced when no off-site target was configured, which is exactly the pristine rebuilt shape.
304 lines
21 KiB
HTML
304 lines
21 KiB
HTML
{{define "backups_remote"}}
|
||
{{template "layout_start" .}}
|
||
|
||
<div class="page-header">
|
||
<h2>Biztonsági mentés — Távoli mentés</h2>
|
||
<span class="domain-badge">{{.Domain}}</span>
|
||
</div>
|
||
|
||
{{template "backups_flash" .}}
|
||
|
||
{{if .RecoveryOffer}}
|
||
<!-- R-193: the PERMANENT entry point. Bound to RecoveryOffer, never to the postpone flag — a
|
||
customer who clicked "Most nem" once must not lose the route to their own data. -->
|
||
<div class="alert alert-warning">
|
||
<strong>A korábbi, házon kívüli mentéseid visszaszerezhetők.</strong>
|
||
Ezt a gépet újratelepítették, és a Felhom központi rendszere őriz hozzá egy lezárt csomagot. A
|
||
helyreállítási kódoddal feloldhatod a korábbi mentéseidet, és megnézheted, mi van bennük.
|
||
<div class="form-actions" style="margin-top:.5rem">
|
||
<a href="/recovery" class="btn btn-primary">Adatok visszaszerzése</a>
|
||
</div>
|
||
</div>
|
||
{{end}}
|
||
|
||
{{if not .Backup}}
|
||
{{template "backups_empty" .}}
|
||
{{else}}
|
||
|
||
<!-- Felhom-offsite status card (v0.124.0, decision 2): three honest states from LOCAL data only —
|
||
display + opt-in pointers, NEVER a state change (no form, no button in this card). State 3
|
||
(applied + apps toggled) is the existing status block below; the card renders nothing then. -->
|
||
{{if and (not .OffboxConfigured) .OffsiteHubEnabled}}
|
||
<!-- R-70 (v0.161.0): hub-managed offsite is provisioned for this box — "igényelhető" would be a
|
||
lie (it is already ordered) and the bare empty state hid the pre-apply window (DIAG-f10). -->
|
||
<div class="alert alert-info" style="margin-bottom:1rem" id="felhom-offsite-card">Felhom offsite tárhely kiépítve — a beállítás automatikus, folyamatban. Ha egy napon belül nem áll be, jelezd az üzemeltetőnek.</div>
|
||
{{else if not .OffboxConfigured}}
|
||
<div class="alert alert-info" style="margin-bottom:1rem" id="felhom-offsite-card">Felhom offsite tárhely — igényelhető szolgáltatás. Titkosított, házon kívüli másolat a mentéseidről. Érdeklődj az üzemeltetőnél.</div>
|
||
{{else if eq .OffboxToggledCount 0}}
|
||
<div class="alert alert-info" style="margin-bottom:1rem" id="felhom-offsite-card">Aktív — nincs kijelölt alkalmazás</div>
|
||
{{end}}
|
||
|
||
<!-- Off-box (NAS) backup — Part B: encrypted restic repo over SFTP (the off-site 3-2-1 leg). -->
|
||
<h3 id="offbox-section" class="backup-tier-divider">Távoli mentés (3. mentés) — titkosított, offsite</h3>
|
||
<p class="form-hint" style="margin:-0.25rem 0 1rem">Az alkalmazás-mentések titkosított másolata egy távoli tárolóra — saját NAS vagy Felhom offsite tárhely — restic + SFTP kapcsolaton. A tároló csak titkosított adatot lát. Ez a 3-2-1 szabály „1 off-site" lába — független a helyi másodpéldánytól és a teljes rendszermentéstől.</p>
|
||
<div class="card" style="margin-bottom:1.5rem">
|
||
{{if .Offbox}}
|
||
<div class="stats-grid backup-page-cards">
|
||
<div class="stat-card {{if or (eq .Offbox.LastStatus "error") (eq .Offbox.LastStatus "incomplete")}}stat-warn{{end}}">
|
||
<div class="stat-value" id="offbox-status-value" style="font-size:1.15rem">{{if eq .Offbox.LastStatus "ok"}}✓ Rendben{{else if eq .Offbox.LastStatus "incomplete"}}! Hiányos{{else if eq .Offbox.LastStatus "error"}}✗ Hiba{{else if eq .Offbox.LastStatus "running"}}Fut…{{else}}–{{end}}</div>
|
||
<div class="stat-label">Utolsó távoli mentés{{if .Offbox.LastRun}}<br><span class="relative-time">{{timeAgoStr .Offbox.LastRun}}</span>{{end}}</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-value" style="font-size:1.15rem">{{if .Offbox.RepoSizeHuman}}{{.Offbox.RepoSizeHuman}}{{else}}–{{end}}</div>
|
||
<div class="stat-label">Tároló méret · {{.Offbox.SnapshotCount}} pillanatkép</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="stat-value" style="font-size:1.05rem">{{if .Offbox.Enabled}}{{.Offbox.User}}@{{.Offbox.Host}}{{else}}Kikapcsolva{{end}}</div>
|
||
<div class="stat-label">{{if .Offbox.Enabled}}{{.Offbox.RepoPath}}{{else}}A távoli mentés ki van kapcsolva{{end}}</div>
|
||
</div>
|
||
</div>
|
||
{{if and .Offbox.Enabled (gt .Offbox.QuotaGB 0)}}
|
||
<!-- SLICE 4: soft-quota usage bar (shared model; quota_gb from the hub descriptor). -->
|
||
<div id="offbox-quota-bar" style="max-width:560px;margin:.5rem 0">
|
||
<div class="stat-label" style="margin-bottom:.25rem">Tárhelykeret: {{if .Offbox.RepoSizeHuman}}{{.Offbox.RepoSizeHuman}}{{else}}0{{end}} / {{.Offbox.QuotaGB}} GB ({{.OffboxQuotaPct}}%)</div>
|
||
<div style="background:var(--border,#334);border-radius:4px;height:8px;overflow:hidden">
|
||
<div style="height:8px;border-radius:4px;width:{{.OffboxQuotaPct}}%;background:{{if ge .OffboxQuotaPct 100}}var(--crit,#e5484d){{else if ge .OffboxQuotaPct 80}}var(--warn,#f5a524){{else}}var(--ok,#30a46c){{end}}"></div>
|
||
</div>
|
||
</div>
|
||
{{end}}
|
||
{{if .Offbox.LastError}}<p class="form-hint" style="color:var(--crit)">Utolsó hiba: {{.Offbox.LastError}}</p>{{end}}
|
||
{{/* Part E: display pick — a stale zero-toggle warning is replaced once the selection
|
||
changed (neutral color: the replacement is reassurance, not a deviation). */}}
|
||
{{if .OffboxWarningDisplay}}<p class="form-hint"{{if eq .OffboxWarningDisplay .Offbox.LastWarning}} style="color:var(--warn)"{{end}}>{{.OffboxWarningDisplay}}</p>{{end}}
|
||
{{/* v0.142.0 offsite-repo continuity: the ORPHANED card replaces the raw restic error banner. The
|
||
remote holds backups written under a previous, no-longer-available key (reinstall shape). A
|
||
reset moves the old history aside (never deletes) and starts a fresh repo under the current key. */}}
|
||
{{if eq .Offbox.RepoState "orphaned"}}
|
||
<div class="card" style="border-left:3px solid var(--crit,#e5484d);margin:.75rem 0;padding:.75rem 1rem" id="offbox-orphan-card">
|
||
<p style="margin:0 0 .35rem;font-weight:600">A távoli tároló másik kulccsal készült mentéseket tartalmaz</p>
|
||
<p class="form-hint" style="margin:0 0 .5rem">A távoli tárhelyen lévő mentések egy korábbi, már nem elérhető kulccsal készültek (jellemzően újratelepítés után). Emiatt új mentés jelenleg nem írható a tárolóba. A meglévő mentések nem sérültek — a hozzájuk tartozó helyreállítási kóddal később visszaállíthatók lehetnek.</p>
|
||
<button type="button" class="btn btn-sm btn-outline" id="orphan-reveal" onclick="var c=document.getElementById('orphan-confirm');c.style.display='block';this.style.display='none'">Új távoli mentés indítása…</button>
|
||
<div id="orphan-confirm" style="display:none;margin-top:.6rem">
|
||
<p class="form-hint" style="margin:0 0 .5rem">A régi előzmény <strong>félretéve marad</strong> (nem törlődik), és a hozzá tartozó helyreállítási kóddal később visszaállítható lehet. Egy üres, új tároló jön létre a mostani kulccsal, és a következő mentés ide készül.</p>
|
||
<form method="POST" action="/backup/offbox/reset" style="display:inline">{{.CSRFField}}
|
||
<input type="hidden" name="confirm" value="1">
|
||
<button type="submit" class="btn btn-sm btn-primary">Megerősítés — új távoli mentés indítása</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
{{end}}
|
||
{{/* Escrow ceremony card (v0.127.0): the customer-driveable wizard replaced the manual-confirm
|
||
button (that deprecated endpoint stays for legacy blobs; its button is gone). States:
|
||
awaiting (v0.138.0: ceremony done, hub confirm pending) → info; awaiting timed out → warn +
|
||
re-ceremony CTA; pending → CTA; escrowed+stale → warning + re-ceremony CTA; escrowed clean →
|
||
secondary link; agent too old → the honest version note, no CTA. */}}
|
||
{{if .OffboxCeremonyAwaiting}}
|
||
{{/* v0.138.0: the report-cycle gap between a completed ceremony and the hub-verified flip.
|
||
Info (blue) accent — NOT a warning: nothing is wrong, the confirmation is simply in flight. */}}
|
||
<div class="card" style="border-left:3px solid var(--blue);margin:.75rem 0;padding:.75rem 1rem">
|
||
<p style="margin:0 0 .35rem"><strong>Helyreállítási kód létrehozva</strong></p>
|
||
<p class="form-hint" style="margin:0">A helyreállítási csomag elküldve a központba, megerősítésre vár — ez általában néhány másodperc, legfeljebb 15 perc.</p>
|
||
</div>
|
||
{{else if .OffboxCeremonyTimedOut}}
|
||
{{/* v0.138.0: the confirmation never arrived within two report cycles + slack — degrade to a
|
||
warning with the re-ceremony CTA, never an indefinite "waiting". */}}
|
||
<div class="card" style="border-left:3px solid var(--warn);margin:.75rem 0;padding:.75rem 1rem">
|
||
<p class="form-hint" style="color:var(--warn);margin:0 0 .5rem">A megerősítés nem érkezett meg a várt időn belül. Ellenőrizze az internetkapcsolatot, majd készítsen új helyreállítási kódot.</p>
|
||
{{if .EscrowAgentOK}}
|
||
<a href="/backup/escrow" class="btn btn-sm btn-primary">Új helyreállítási kód készítése</a>
|
||
{{else}}
|
||
<p class="form-hint" style="margin:0">A funkcióhoz az ügynök frissítése szükséges — a frissítés automatikusan megérkezik.</p>
|
||
{{end}}
|
||
</div>
|
||
{{else if and .OffboxConfigured (ne .Offbox.EscrowState "escrowed")}}
|
||
<div class="card" style="border-left:3px solid var(--warn);margin:.75rem 0;padding:.75rem 1rem">
|
||
<p style="margin:0 0 .35rem"><strong>Helyreállítási kód szükséges</strong></p>
|
||
<p class="form-hint" style="margin:0 0 .5rem">A távoli mentések csak akkor állíthatók vissza egy teljes meghibásodás után, ha létrehozza a helyreállítási kódot.</p>
|
||
{{if .EscrowAgentOK}}
|
||
<a href="/backup/escrow" class="btn btn-sm btn-primary">Helyreállítási kód létrehozása</a>
|
||
{{else}}
|
||
<p class="form-hint" style="margin:0">A funkcióhoz az ügynök frissítése szükséges — a frissítés automatikusan megérkezik.</p>
|
||
{{end}}
|
||
</div>
|
||
{{else if and .OffboxConfigured .EscrowStale}}
|
||
<div class="card" style="border-left:3px solid var(--warn);margin:.75rem 0;padding:.75rem 1rem">
|
||
<p class="form-hint" style="color:var(--warn);margin:0 0 .5rem">A letétben lévő helyreállítási csomag nem fedi a jelenlegi távoli mentési jelszót. Hozzon létre új helyreállítási kódot.</p>
|
||
{{if .EscrowAgentOK}}
|
||
<a href="/backup/escrow" class="btn btn-sm btn-primary">Új helyreállítási kód készítése</a>
|
||
{{else}}
|
||
<p class="form-hint" style="margin:0">A funkcióhoz az ügynök frissítése szükséges — a frissítés automatikusan megérkezik.</p>
|
||
{{end}}
|
||
</div>
|
||
{{else if .OffboxConfigured}}
|
||
{{/* v0.127.1: the re-ceremony CTA is a real secondary button (outline, NOT primary — escrowed
|
||
is a healthy state; available-not-urgent, unlike the stale variant above). */}}
|
||
<div style="margin:.5rem 0">
|
||
<p class="form-hint" style="margin:0 0 .4rem">A helyreállítási kód letétbe helyezve.</p>
|
||
{{if .EscrowAgentOK}}<a href="/backup/escrow" class="btn btn-sm btn-outline">Új helyreállítási kód készítése</a>{{end}}
|
||
</div>
|
||
{{end}}
|
||
{{if .OffboxConfigured}}
|
||
<div class="schedule-actions" style="margin-top:1rem">
|
||
<form method="POST" action="/backup/offbox/run" style="display:inline">{{.CSRFField}}
|
||
<button type="submit" class="btn btn-sm btn-primary">Távoli mentés most</button>
|
||
</form>
|
||
</div>
|
||
<!-- v0.147.0 (4c): live progress for a MANUAL run — total bytes, percent and which app is being
|
||
pushed, parsed from restic's --json status stream. Hidden until a run reports progress; the
|
||
nightly run never populates it. -->
|
||
<div id="offbox-progress" class="alert alert-info" style="display:none;margin-top:.75rem">
|
||
<span id="offbox-progress-text"></span>
|
||
<div class="progress-bar-task" style="margin-top:.5rem">
|
||
<div id="offbox-progress-bar" class="progress-fill" style="width:0%"></div>
|
||
</div>
|
||
</div>
|
||
<h4 style="margin-top:1.25rem">Mely alkalmazások mentődnek a távoli tárolóra?</h4>
|
||
{{if and .OffboxApps (eq .Offbox.EscrowState "escrowed") (eq .OffboxToggledCount 0)}}
|
||
<p class="form-hint">Nincs távoli mentésre jelölt alkalmazás — jelölj ki legalább egyet.</p>
|
||
{{end}}
|
||
{{if .OffboxApps}}
|
||
<div class="app-row-list">
|
||
{{range .OffboxApps}}
|
||
{{template "app_list_row" dict "Slug" .Slug "Name" .DisplayName}}
|
||
<form method="POST" action="/backup/offbox/toggle" style="display:inline">{{$.CSRFField}}
|
||
<input type="hidden" name="app" value="{{.Name}}">
|
||
<input type="hidden" name="enabled" value="{{if .Enabled}}false{{else}}true{{end}}">
|
||
<button type="submit" class="btn btn-xs {{if .Enabled}}btn-outline{{else}}btn-primary{{end}}">{{if .Enabled}}Távoli mentés kikapcsolása{{else}}Távoli mentés bekapcsolása{{end}}</button>
|
||
</form>
|
||
{{if $.OffboxBlockedSet}}{{if index $.OffboxBlockedSet .Name}}
|
||
<span class="form-hint" style="display:block;margin-top:.25rem">A teljes mentés túllépné a tárhelykeretet — csak a konfiguráció és az adatbázis kerül mentésre.</span>
|
||
{{end}}{{end}}
|
||
{{template "app_list_row_end"}}
|
||
{{end}}
|
||
</div>
|
||
{{else}}<p class="form-hint">Nincs telepített alkalmazás.</p>{{end}}
|
||
{{end}}
|
||
{{else}}
|
||
{{if .OffsiteHubEnabled}}
|
||
<p class="form-hint">Felhom offsite tárhely kiépítve — a beállítás automatikus, folyamatban. Ha egy napon belül nem áll be, jelezd az üzemeltetőnek.</p>
|
||
{{else}}
|
||
<p class="form-hint">Még nincs beállítva távoli mentési cél.</p>
|
||
{{end}}
|
||
{{end}}
|
||
|
||
<details style="margin-top:1rem">
|
||
<summary class="btn btn-xs btn-primary" style="cursor:pointer;display:inline-block">Távoli mentési cél beállítása</summary>
|
||
<form method="POST" action="/backup/offbox/config" style="margin-top:.75rem;padding:1rem;border:1px solid var(--border,#ddd);border-radius:6px;max-width:560px">{{.CSRFField}}
|
||
<div class="form-row"><label>Cél címe (IP vagy hosztnév — NAS vagy SFTP-kiszolgáló)</label><input type="text" name="host" class="form-input" value="{{if .Offbox}}{{.Offbox.Host}}{{end}}" placeholder="pl. 192.168.0.10"></div>
|
||
<div class="form-row"><label>SSH port</label><input type="number" name="port" class="form-input" value="{{if .Offbox}}{{.Offbox.Port}}{{else}}22{{end}}"></div>
|
||
<div class="form-row"><label>Felhasználó</label><input type="text" name="user" class="form-input" value="{{if .Offbox}}{{.Offbox.User}}{{end}}" placeholder="pl. felhom"></div>
|
||
<div class="form-row"><label>Tároló útvonala a célgépen</label><input type="text" name="repo_path" class="form-input" value="{{if .Offbox}}{{.Offbox.RepoPath}}{{end}}" placeholder="pl. /volume1/felhom-backup/repo"></div>
|
||
<div class="form-row"><label><input type="checkbox" name="enabled" {{if .Offbox}}{{if .Offbox.Enabled}}checked{{end}}{{else}}checked{{end}}> Napi automatikus távoli mentés engedélyezve</label></div>
|
||
<div class="form-row"><label>SSH privát kulcs {{if .OffboxConfigured}}(üresen hagyva változatlan){{end}}</label>
|
||
<textarea name="ssh_key" class="form-input" rows="4" autocomplete="off" placeholder="-----BEGIN OPENSSH PRIVATE KEY-----"></textarea>
|
||
<span class="form-hint">A kulcsot 0600-as fájlba írjuk; sosem naplózzuk és nem tároljuk a beállításokban.</span></div>
|
||
<div class="form-row"><label>A célgép ismert-host sora (known_hosts) {{if .OffboxConfigured}}(üresen hagyva változatlan){{end}}</label>
|
||
<textarea name="known_hosts" class="form-input" rows="2" autocomplete="off" placeholder="nas.local ssh-ed25519 AAAA…"></textarea>
|
||
<span class="form-hint">A host-kulcs rögzítése (no blind TOFU). Lekérdezhető: <span class="mono">ssh-keyscan -p <port> <host></span></span></div>
|
||
<button type="submit" class="btn btn-sm btn-primary" style="margin-top:.5rem">Mentés</button>
|
||
</form>
|
||
</details>
|
||
</div>
|
||
{{end}}
|
||
|
||
<script>
|
||
/* Part C (v0.142.0) + 4c (v0.147.0): poll the run status, render live progress for a manual run, and
|
||
reload once it reaches a terminal state so the customer sees Rendben/Hiba + fresh numbers WITHOUT a
|
||
manual reload.
|
||
|
||
v0.147.0 changed WHEN polling starts. It used to begin only if the page already rendered "Fut…",
|
||
which loses a race the manual trigger always runs: the POST redirects and this page renders before
|
||
the detached goroutine has written LastStatus=running, so the poll never armed and the customer
|
||
watched a static page during the very run they had just started. Now it always arms and gives up
|
||
after GRACE quiet ticks if nothing is (or ever was) in flight. */
|
||
(function(){
|
||
var v = document.getElementById('offbox-status-value');
|
||
var box = document.getElementById('offbox-progress');
|
||
var text = document.getElementById('offbox-progress-text');
|
||
var bar = document.getElementById('offbox-progress-bar');
|
||
var GRACE = 5; // ~15s of quiet before concluding nothing is running
|
||
var quiet = 0;
|
||
var sawRunning = (v && v.textContent.indexOf('Fut') >= 0);
|
||
|
||
var timer = setInterval(function(){
|
||
fetch('/backup/offbox/status',{headers:{'Accept':'application/json'}})
|
||
.then(function(r){return r.json();})
|
||
.then(function(d){
|
||
if(!d) return;
|
||
var p = d.progress || {};
|
||
var running = (d.status === 'running') || p.active;
|
||
|
||
if(running){
|
||
sawRunning = true; quiet = 0;
|
||
if(p.active && box){
|
||
/* Only claim a percentage once restic has told us a total — before the scan finishes,
|
||
percent is 0 of 0, and a bar pinned at 0% reads as "stuck" rather than "measuring". */
|
||
/* A run is not only the per-app loop: the shares leg and the retention/prune step follow
|
||
it and can dominate the wall clock (40 of 57 seconds, measured). Name them, or the
|
||
card freezes on the last app's finished counters for that whole tail. */
|
||
/* The dump pre-phase runs BEFORE the per-app loop (R-44): it refreshes every app's
|
||
database dump so the snapshot pairs this run's files with this run's DB. On an app
|
||
with a large database it can dominate the early wall clock, and an unnamed silent
|
||
stretch at the start reads as a hang. */
|
||
if(p.phase === 'dump'){
|
||
text.textContent = 'Adatbázisok mentése a pillanatképhez…';
|
||
bar.style.width = '100%';
|
||
box.className = 'alert alert-info'; box.style.display = '';
|
||
return;
|
||
}
|
||
if(p.phase === 'retention'){
|
||
text.textContent = 'Karbantartás: régi mentések rendezése a távoli tárolón…';
|
||
bar.style.width = '100%';
|
||
box.className = 'alert alert-info'; box.style.display = '';
|
||
return;
|
||
}
|
||
if(p.phase === 'shares'){
|
||
text.textContent = 'Megosztott mappák mentése…';
|
||
bar.style.width = '100%';
|
||
box.className = 'alert alert-info'; box.style.display = '';
|
||
return;
|
||
}
|
||
var label = p.current_app ? ('Mentés: ' + p.current_app) : 'Mentés folyamatban';
|
||
if(p.bytes_done > 0){
|
||
/* Bytes are genuinely moving — the informative case. */
|
||
label += ' — ' + Math.round(p.percent) + '% (' + p.done_human + ' / ' + p.total_human + ')';
|
||
bar.style.width = Math.max(0, Math.min(100, p.percent)) + '%';
|
||
} else if(p.total_files > 0){
|
||
/* No bytes moving. restic 0.14 only counts a file into bytes_done/files_done when it
|
||
COMPLETES, so an app dominated by one big archive freezes both counters — measured
|
||
on the demo box: immich at 1 of 46 files, 0 bytes, for 42 seconds while restic
|
||
worked through a single ~430MB volume tar. A percentage cannot move in that window,
|
||
so do not pretend: name the file being processed and the elapsed time, which is
|
||
what actually tells the customer it is alive. */
|
||
var fpct = Math.round((p.files_done / p.total_files) * 100);
|
||
label += ' — ' + p.files_done + ' / ' + p.total_files + ' fájl'
|
||
+ (p.total_human ? ' (' + p.total_human + ')' : '');
|
||
if(p.current_file){
|
||
var base = p.current_file.split('/').pop();
|
||
label += ' · feldolgozás alatt: ' + base;
|
||
}
|
||
if(p.elapsed_sec > 0){ label += ' · ' + p.elapsed_sec + ' mp'; }
|
||
bar.style.width = Math.max(0, Math.min(100, fpct)) + '%';
|
||
} else {
|
||
label += ' — a mentendő adatok felmérése…';
|
||
bar.style.width = '0%';
|
||
}
|
||
text.textContent = label;
|
||
box.style.display = '';
|
||
}
|
||
return;
|
||
}
|
||
|
||
/* Not running. Terminal only if we ever saw it running — otherwise this is the pre-start
|
||
race (or a page nobody triggered anything from). */
|
||
if(sawRunning){ clearInterval(timer); location.reload(); return; }
|
||
if(++quiet >= GRACE){ clearInterval(timer); }
|
||
})
|
||
.catch(function(){ /* transient — keep polling */ });
|
||
}, 3000);
|
||
})();
|
||
</script>
|
||
|
||
{{template "layout_end" .}}
|
||
{{end}}
|