z230
This commit is contained in:
@@ -81,6 +81,12 @@ python euni_stahni.py --seaweed-backfill --from-json
|
|||||||
|
|
||||||
## Použití
|
## Použití
|
||||||
|
|
||||||
|
Nejjednodušší: **`python euni_menu.py`** — interaktivní menu s volbami 1–9
|
||||||
|
(test / dokumenty / vše / 720p / dashboard / obnova / backfill / re-scrape).
|
||||||
|
Po doběhnutí akce se vrátí do menu, `Ctrl+C` přeruší jen aktuální akci.
|
||||||
|
|
||||||
|
Ručně přes CLI:
|
||||||
|
|
||||||
```bat
|
```bat
|
||||||
python euni_stahni.py --scrape-only # jen inventura → Mongo + JSON
|
python euni_stahni.py --scrape-only # jen inventura → Mongo + JSON
|
||||||
python euni_stahni.py --no-videos # scrape + stáhne jen dokumenty
|
python euni_stahni.py --no-videos # scrape + stáhne jen dokumenty
|
||||||
@@ -89,6 +95,8 @@ python euni_stahni.py --from-json --no-videos # přeskočí scrape, stáhne z M
|
|||||||
python euni_stahni.py --professions all # všechny profese (2,4,5,6,7)
|
python euni_stahni.py --professions all # všechny profese (2,4,5,6,7)
|
||||||
python euni_stahni.py --limit 3 # jen prvních 3 kurzy (test)
|
python euni_stahni.py --limit 3 # jen prvních 3 kurzy (test)
|
||||||
python euni_stahni.py --no-mongo # bez zápisu do Mongo
|
python euni_stahni.py --no-mongo # bez zápisu do Mongo
|
||||||
|
python euni_stahni.py --frags 20 # víc paralelních HLS fragmentů (rychlejší)
|
||||||
|
python euni_stahni.py --video-format "bestvideo[height<=720]+bestaudio/best" # 720p
|
||||||
python euni_report.py # přehled stavu
|
python euni_report.py # přehled stavu
|
||||||
python euni_report.py --soukroma # seznam přeskočených videí
|
python euni_report.py --soukroma # seznam přeskočených videí
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
euni_menu.py — interaktivní menu pro stahování kurzů z euni.cz.
|
||||||
|
|
||||||
|
Spuštění:
|
||||||
|
python euni_menu.py
|
||||||
|
|
||||||
|
Jen vyber číslo a Enter. Každá volba spustí příslušný skript a po doběhnutí
|
||||||
|
se vrátíš do menu (Ctrl+C přeruší aktuální akci, ne celé menu).
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
for _s in (sys.stdout, sys.stderr):
|
||||||
|
try:
|
||||||
|
_s.reconfigure(errors="backslashreplace")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
SKRIPT_DIR = Path(__file__).resolve().parent
|
||||||
|
PY = sys.executable
|
||||||
|
|
||||||
|
# klíč -> (popis, skript, argumenty)
|
||||||
|
AKCE = {
|
||||||
|
"1": ("Test - 3 kurzy, jen dokumenty (rychle)",
|
||||||
|
"euni_stahni.py", ["--from-json", "--no-videos", "--limit", "3"]),
|
||||||
|
"2": ("Vsechny dokumenty (PDF/prezentace)",
|
||||||
|
"euni_stahni.py", ["--from-json", "--no-videos"]),
|
||||||
|
"3": ("Vse vcetne videi - nejvyssi kvalita (1080p, velke)",
|
||||||
|
"euni_stahni.py", ["--from-json"]),
|
||||||
|
"4": ("Vse vcetne videi - 720p (mensi, rychlejsi)",
|
||||||
|
"euni_stahni.py",
|
||||||
|
["--from-json", "--video-format",
|
||||||
|
"bestvideo[height<=720]+bestaudio/best"]),
|
||||||
|
"5": ("Jen videa (1080p)",
|
||||||
|
"euni_stahni.py", ["--from-json", "--no-docs"]),
|
||||||
|
"6": ("Prehled stavu (dashboard)", "euni_report.py", []),
|
||||||
|
"7": ("Obnova ze SeaweedFS na disk", "euni_restore.py", []),
|
||||||
|
"8": ("Backfill - dohrat chybejici kopie do SeaweedFS",
|
||||||
|
"euni_stahni.py", ["--seaweed-backfill", "--from-json"]),
|
||||||
|
"9": ("Aktualizovat seznam kurzu (znovu scrape do Mongo)",
|
||||||
|
"euni_stahni.py", ["--scrape-only"]),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def vycisti_obrazovku():
|
||||||
|
os.system("cls" if os.name == "nt" else "clear")
|
||||||
|
|
||||||
|
|
||||||
|
def vypis_menu():
|
||||||
|
print("=" * 60)
|
||||||
|
print(" EUNI - stahovani kurzu z euni.cz")
|
||||||
|
print("=" * 60)
|
||||||
|
print()
|
||||||
|
for k in sorted(AKCE):
|
||||||
|
print(f" {k}) {AKCE[k][0]}")
|
||||||
|
print()
|
||||||
|
print(" 0) Konec")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
while True:
|
||||||
|
vycisti_obrazovku()
|
||||||
|
vypis_menu()
|
||||||
|
try:
|
||||||
|
volba = input("Vyber cislo a stiskni Enter: ").strip()
|
||||||
|
except (EOFError, KeyboardInterrupt):
|
||||||
|
print()
|
||||||
|
break
|
||||||
|
|
||||||
|
if volba in ("0", "q", "exit", "konec"):
|
||||||
|
break
|
||||||
|
akce = AKCE.get(volba)
|
||||||
|
if not akce:
|
||||||
|
continue
|
||||||
|
|
||||||
|
_, skript, args = akce
|
||||||
|
print()
|
||||||
|
try:
|
||||||
|
subprocess.run([PY, str(SKRIPT_DIR / skript), *args],
|
||||||
|
cwd=str(SKRIPT_DIR))
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\nPreruseno uzivatelem.")
|
||||||
|
|
||||||
|
try:
|
||||||
|
input("\n=== HOTOVO. Stiskni Enter pro navrat do menu ===")
|
||||||
|
except (EOFError, KeyboardInterrupt):
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
+13
-6
@@ -376,21 +376,23 @@ def stahni_dokument(s, url, out_dir: Path, label=""):
|
|||||||
return ("staženo", dest.name)
|
return ("staženo", dest.name)
|
||||||
|
|
||||||
|
|
||||||
def stahni_video(embed, out_dir: Path, referer):
|
def stahni_video(embed, out_dir: Path, referer, fmt="bestvideo*+bestaudio/best",
|
||||||
"""Stáhne video přes yt-dlp; soukromé/nedostupné přeskočí. Vrací (stav, info)."""
|
frags=10):
|
||||||
|
"""Stáhne video přes yt-dlp; soukromé/nedostupné přeskočí. Vrací (stav, info, fp)."""
|
||||||
if sv is None:
|
if sv is None:
|
||||||
return ("chyba", "modul stahni_video není dostupný")
|
return ("chyba", "modul stahni_video není dostupný", None)
|
||||||
try:
|
try:
|
||||||
import yt_dlp
|
import yt_dlp
|
||||||
from yt_dlp.utils import DownloadError
|
from yt_dlp.utils import DownloadError
|
||||||
except ImportError:
|
except ImportError:
|
||||||
return ("chyba", "yt-dlp není nainstalován")
|
return ("chyba", "yt-dlp není nainstalován", None)
|
||||||
|
|
||||||
out_dir.mkdir(parents=True, exist_ok=True)
|
out_dir.mkdir(parents=True, exist_ok=True)
|
||||||
ff_dir = sv.priprav_ffmpeg()
|
ff_dir = sv.priprav_ffmpeg()
|
||||||
opts = {
|
opts = {
|
||||||
"outtmpl": str(out_dir / "%(title)s [%(id)s].%(ext)s"),
|
"outtmpl": str(out_dir / "%(title)s [%(id)s].%(ext)s"),
|
||||||
"format": "bestvideo*+bestaudio/best",
|
"format": fmt,
|
||||||
|
"concurrent_fragment_downloads": frags, # paralelní HLS fragmenty = rychlejší
|
||||||
"merge_output_format": "mp4",
|
"merge_output_format": "mp4",
|
||||||
"logger": sv._TichyLogger(),
|
"logger": sv._TichyLogger(),
|
||||||
"progress_hooks": [sv._progress_hook],
|
"progress_hooks": [sv._progress_hook],
|
||||||
@@ -458,6 +460,10 @@ def main():
|
|||||||
help="přeskočí scrape, použije existující euni_kurzy.json")
|
help="přeskočí scrape, použije existující euni_kurzy.json")
|
||||||
p.add_argument("--no-videos", action="store_true", help="nestahovat videa")
|
p.add_argument("--no-videos", action="store_true", help="nestahovat videa")
|
||||||
p.add_argument("--no-docs", action="store_true", help="nestahovat dokumenty")
|
p.add_argument("--no-docs", action="store_true", help="nestahovat dokumenty")
|
||||||
|
p.add_argument("--video-format", default="bestvideo*+bestaudio/best",
|
||||||
|
help="yt-dlp formát videa (např. \"bestvideo[height<=720]+bestaudio/best\")")
|
||||||
|
p.add_argument("--frags", type=int, default=10,
|
||||||
|
help="počet paralelně stahovaných HLS fragmentů videa (default 10)")
|
||||||
p.add_argument("--limit", type=int, default=0, help="jen prvních N kurzů (test)")
|
p.add_argument("--limit", type=int, default=0, help="jen prvních N kurzů (test)")
|
||||||
p.add_argument("--out", default=str(SKRIPT_DIR / "stazeno"), help="výstupní adresář")
|
p.add_argument("--out", default=str(SKRIPT_DIR / "stazeno"), help="výstupní adresář")
|
||||||
p.add_argument("--json", default=str(SKRIPT_DIR / "euni_kurzy.json"),
|
p.add_argument("--json", default=str(SKRIPT_DIR / "euni_kurzy.json"),
|
||||||
@@ -602,7 +608,8 @@ def main():
|
|||||||
if not a.no_videos:
|
if not a.no_videos:
|
||||||
for v in c.get("videos", []):
|
for v in c.get("videos", []):
|
||||||
klic = material_klic("video", v)[0]
|
klic = material_klic("video", v)[0]
|
||||||
stav, info, fp = stahni_video(v["embed"], folder / "videa", c["url"])
|
stav, info, fp = stahni_video(v["embed"], folder / "videa", c["url"],
|
||||||
|
fmt=a.video_format, frags=a.frags)
|
||||||
if stav == "staženo":
|
if stav == "staženo":
|
||||||
stat["vid_ok"] += 1
|
stat["vid_ok"] += 1
|
||||||
print(f" [VIDEO] {info}")
|
print(f" [VIDEO] {info}")
|
||||||
|
|||||||
Reference in New Issue
Block a user