90 lines
2.8 KiB
Python
90 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
euni_restore.py — obnoví všechny stažené soubory ze SeaweedFS na disk.
|
|
|
|
Funguje na libovolném počítači: čte reference (cesty/fid) z MongoDB EUNI a každý
|
|
soubor stáhne z filer SeaweedFS zpět do souborového systému se stejnou strukturou
|
|
jako stazeno/<id>-<slug>/<typ>/<soubor>.
|
|
|
|
Potřebuje jen síťový přístup k Mongu (192.168.1.76) a filer (192.168.1.50) a:
|
|
python -m pip install pymongo requests
|
|
|
|
Použití:
|
|
python euni_restore.py # obnoví do ./obnoveno
|
|
python euni_restore.py --out D:\\Euni # jiný cílový adresář
|
|
python euni_restore.py --kurz 5618 # jen jeden kurz
|
|
python euni_restore.py --dry-run # jen vypíše, co by stáhl
|
|
"""
|
|
|
|
import argparse
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
for _s in (sys.stdout, sys.stderr):
|
|
try:
|
|
_s.reconfigure(errors="backslashreplace")
|
|
except Exception:
|
|
pass
|
|
|
|
import euni_db as edb
|
|
import euni_seaweed as sw
|
|
|
|
|
|
def lidsky(n):
|
|
n = n or 0
|
|
for j, u in [(1e9, "GB"), (1e6, "MB"), (1e3, "kB")]:
|
|
if n >= j:
|
|
return f"{n/j:.1f} {u}"
|
|
return f"{n} B"
|
|
|
|
|
|
def main():
|
|
p = argparse.ArgumentParser(description="Obnoví soubory ze SeaweedFS na disk.")
|
|
p.add_argument("--out", default="obnoveno", help="cílový adresář (výchozí ./obnoveno)")
|
|
p.add_argument("--kurz", help="obnovit jen tento kurz_id")
|
|
p.add_argument("--dry-run", action="store_true", help="jen vypsat, nestahovat")
|
|
a = p.parse_args()
|
|
|
|
out = Path(a.out)
|
|
db = edb.get_db()
|
|
if not sw.ping():
|
|
sys.exit(f"SeaweedFS filer nedostupný ({sw.FILER}).")
|
|
|
|
mats = edb.materialy_v_seaweed(db)
|
|
if a.kurz:
|
|
mats = [m for m in mats if m.get("kurz_id") == a.kurz]
|
|
print(f"Obnovuji {len(mats)} souborů z {sw.FILER} -> {out.resolve()}")
|
|
|
|
ok = preskoc = chyb = 0
|
|
bajtu = 0
|
|
for m in mats:
|
|
remote = m["seaweed_path"]
|
|
# lokální cesta: zrcadlí seaweed cestu bez prefixu 'euni/'
|
|
parts = remote.split("/")
|
|
rel = Path(*parts[1:]) if parts and parts[0] == sw.PREFIX else Path(*parts)
|
|
dest = out / rel
|
|
|
|
want = m.get("seaweed_size")
|
|
if dest.exists() and (want is None or dest.stat().st_size == want):
|
|
preskoc += 1
|
|
continue
|
|
if a.dry_run:
|
|
print(f" [BY STÁHL] {rel} ({lidsky(want)})")
|
|
ok += 1
|
|
continue
|
|
try:
|
|
n = sw.download(remote, dest)
|
|
bajtu += n
|
|
ok += 1
|
|
print(f" [OK] {rel} ({lidsky(n)})")
|
|
except Exception as e:
|
|
chyb += 1
|
|
print(f" [CHYBA] {rel} ({str(e)[:60]})")
|
|
|
|
print(f"\nHotovo: {ok} obnoveno, {preskoc} přeskočeno (už je), {chyb} chyb. "
|
|
f"Staženo {lidsky(bajtu)}.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|