diff --git a/courses.py b/courses.py index 3125398..2cd53f7 100644 --- a/courses.py +++ b/courses.py @@ -28,6 +28,15 @@ COURSES = { "env_pass": "PRACTITIONER_PASSWORD", "root": Path("nlp-practitioner"), }, + "quantic": { + "name": "NLP Quantic (cursnlp.ro)", + "base_url": "https://shop.cursnlp.ro", + "course_path": "/curs/34", + "login_path": "/login", + "env_user": "PRACTITIONER_USERNAME", + "env_pass": "PRACTITIONER_PASSWORD", + "root": Path("nlp-quantic"), + }, } diff --git a/download.py b/download.py index ed00916..3b267bd 100644 --- a/download.py +++ b/download.py @@ -278,6 +278,8 @@ def download_vimeo_audio(vimeo_url: str, referer: str, dest: Path) -> bool: "http_headers": {"Referer": referer}, "quiet": True, "no_warnings": True, + "noprogress": True, + "concurrent_fragment_downloads": 8, "postprocessors": [{ "key": "FFmpegExtractAudio", "preferredcodec": "mp3", diff --git a/nlp-quantic/audio_phone/_covers/M1.png b/nlp-quantic/audio_phone/_covers/M1.png new file mode 100644 index 0000000..6ef9b10 Binary files /dev/null and b/nlp-quantic/audio_phone/_covers/M1.png differ diff --git a/nlp-quantic/audio_phone/_covers/M2.png b/nlp-quantic/audio_phone/_covers/M2.png new file mode 100644 index 0000000..c1752c5 Binary files /dev/null and b/nlp-quantic/audio_phone/_covers/M2.png differ diff --git a/nlp-quantic/audio_phone/_covers/M3.png b/nlp-quantic/audio_phone/_covers/M3.png new file mode 100644 index 0000000..b7ab37d Binary files /dev/null and b/nlp-quantic/audio_phone/_covers/M3.png differ diff --git a/nlp-quantic/audio_phone/_covers/M4.png b/nlp-quantic/audio_phone/_covers/M4.png new file mode 100644 index 0000000..54d13f2 Binary files /dev/null and b/nlp-quantic/audio_phone/_covers/M4.png differ diff --git a/nlp-quantic/audio_phone/_covers/M5.png b/nlp-quantic/audio_phone/_covers/M5.png new file mode 100644 index 0000000..032d001 Binary files /dev/null and b/nlp-quantic/audio_phone/_covers/M5.png differ diff --git a/nlp-quantic/audio_phone/index.html b/nlp-quantic/audio_phone/index.html new file mode 100644 index 0000000..37536c4 --- /dev/null +++ b/nlp-quantic/audio_phone/index.html @@ -0,0 +1,58 @@ + + + + + +NLP Quantic audio + + + +

NLP Quantic – audio

+ +
Dacă browserul întreabă „permiți descărcări multiple?”, apasă Permite.
+
+ + + diff --git a/nlp-quantic/summaries/pdf/NLP Quantic M3 _ 16sept2023.pdf b/nlp-quantic/summaries/pdf/NLP Quantic M3 _ 16sept2023.pdf new file mode 100644 index 0000000..4c905f6 Binary files /dev/null and b/nlp-quantic/summaries/pdf/NLP Quantic M3 _ 16sept2023.pdf differ diff --git a/nlp-quantic/summaries/pdf/NLP Quantic Modulul 2.pdf b/nlp-quantic/summaries/pdf/NLP Quantic Modulul 2.pdf new file mode 100644 index 0000000..27a72ba Binary files /dev/null and b/nlp-quantic/summaries/pdf/NLP Quantic Modulul 2.pdf differ diff --git a/nlp-quantic/summaries/pdf/NLP Quantic Workshop bonus _ 17.08.23.pdf b/nlp-quantic/summaries/pdf/NLP Quantic Workshop bonus _ 17.08.23.pdf new file mode 100644 index 0000000..8a3c593 Binary files /dev/null and b/nlp-quantic/summaries/pdf/NLP Quantic Workshop bonus _ 17.08.23.pdf differ diff --git a/rename_phone_practitioner.py b/rename_phone_practitioner.py index 35e270d..e1c69f7 100644 --- a/rename_phone_practitioner.py +++ b/rename_phone_practitioner.py @@ -49,6 +49,7 @@ def find_font(size: int) -> ImageFont.FreeTypeFont: "C:/Windows/Fonts/arialbd.ttf", "C:/Windows/Fonts/arial.ttf", "C:/Windows/Fonts/segoeui.ttf", + "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", ] for c in candidates: if Path(c).exists(): @@ -109,7 +110,7 @@ def make_cover(module_num: int, theme_full: str, out_path: Path) -> Path: # Course label (small, top) f_small = find_font(36) - label = COURSE_PREFIX + " - 2024" + label = f"{COURSE_PREFIX} - {YEAR}" bbox = draw.textbbox((0, 0), label, font=f_small) draw.text(((size - (bbox[2] - bbox[0])) / 2, 60), label, font=f_small, fill="#ffffff") diff --git a/rename_phone_quantic.py b/rename_phone_quantic.py new file mode 100644 index 0000000..0d28a28 --- /dev/null +++ b/rename_phone_quantic.py @@ -0,0 +1,63 @@ +"""Copies NLP Quantic MP3s to nlp-quantic/audio_phone/ with phone-friendly names + ID3 tags + cover. + +Reuses cover/tag helpers from rename_phone_practitioner.py. +Run after: python download.py --course quantic +""" +from __future__ import annotations + +import json +import re +import shutil +import sys +from pathlib import Path + +import rename_phone_practitioner as rp + +ROOT = Path(__file__).parent +QUANTIC = ROOT / "nlp-quantic" +AUDIO_DST = QUANTIC / "audio_phone" +COVERS_DIR = AUDIO_DST / "_covers" +MANIFEST = QUANTIC / "manifest.json" + +rp.COURSE_PREFIX = "NLP Quantic" +rp.ARTIST = "cursnlp.ro" +rp.ALBUM_ARTIST = "cursnlp.ro" +rp.YEAR = "2023" + + +def clean_title(t: str) -> str: + return re.sub(r"\s+", " ", t.replace(",", " ")).strip() + + +def main() -> int: + manifest = json.loads(MANIFEST.read_text(encoding="utf-8")) + errors = 0 + for mod in manifest["modules"]: + n = int(mod["name"].split()[-1]) + lecs = [L for L in mod["lectures"] if L["type"] in ("audio", "vimeo")] + if not lecs: + continue + cover = COVERS_DIR / f"M{n}.png" + if not cover.exists(): + rp.make_cover(n, "", cover) + album = f"NLP Quantic - Modul {n}" + out_dir = AUDIO_DST / f"Quantic M{n}" + out_dir.mkdir(parents=True, exist_ok=True) + for idx, lec in enumerate(lecs, 1): + src = ROOT / lec["audio_path"] + if lec.get("download_status") != "complete" or not src.exists(): + print(f" MISSING: {lec['title']}") + errors += 1 + continue + title = clean_title(lec["title"]) + dst = out_dir / f"Q{n}-{idx:02d} {rp.safe_filename_part(title)}.mp3" + if not (dst.exists() and dst.stat().st_size >= src.stat().st_size): + shutil.copy2(src, dst) + rp.tag_mp3(dst, title=title, album=album, track_num=idx, track_total=len(lecs), cover_png=cover) + print(f" ok: {dst.relative_to(QUANTIC)}") + print(f"\nDONE. errors={errors} Output: {AUDIO_DST}") + return 0 if errors == 0 else 2 + + +if __name__ == "__main__": + sys.exit(main())