Created
August 1, 2026 05:01
-
-
Save me-suzy/2c4cbf7ff11ae170034feb5fa86c3bbd to your computer and use it in GitHub Desktop.
descarca_google_drive_carti_george.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from __future__ import annotations | |
| import json | |
| import sys | |
| import time | |
| from collections import Counter | |
| from pathlib import Path | |
| try: | |
| import gdown | |
| import requests | |
| except ImportError as exc: | |
| raise SystemExit( | |
| "Lipseste biblioteca gdown. Instaleaz-o cu: python -m pip install --user gdown" | |
| ) from exc | |
| DRIVE_URL = "https://drive.google.com/drive/folders/18X-lORisdq4LdQHtQK7hOvLxS66B3ntdh7" | |
| DESTINATION = Path(r"G:\CARTI-GEORGE") | |
| ALLOWED_EXTENSIONS = {".pdf", ".doc", ".docx"} | |
| REPORT_PATH = DESTINATION / "verificare_descarcare.json" | |
| def inventory() -> list: | |
| print("Inventariez recursiv folderul Google Drive...") | |
| items = gdown.download_folder( | |
| url=DRIVE_URL, | |
| output=str(DESTINATION), | |
| quiet=False, | |
| use_cookies=False, | |
| skip_download=True, | |
| ) | |
| if not items: | |
| raise RuntimeError("Google Drive nu a returnat niciun fisier.") | |
| return items | |
| def selected_items(items: list) -> list: | |
| selected = [item for item in items if Path(item.path).suffix.casefold() in ALLOWED_EXTENSIONS] | |
| keys: set[str] = set() | |
| for item in selected: | |
| key = str(Path(item.local_path)).casefold() | |
| if key in keys: | |
| raise RuntimeError(f"Cale locala duplicata in inventar: {item.local_path}") | |
| keys.add(key) | |
| return selected | |
| def download_one(item, index: int, total: int) -> None: | |
| target = Path(item.local_path) | |
| target.parent.mkdir(parents=True, exist_ok=True) | |
| if target.is_file() and target.stat().st_size > 0: | |
| print(f"[{index}/{total}] Exista deja, verificat: {target}") | |
| return | |
| print(f"[{index}/{total}] Descarc direct: {item.path}") | |
| direct_url = f"https://drive.usercontent.google.com/download?id={item.id}&export=download&confirm=t" | |
| temp_target = target.with_name(target.name + ".part") | |
| try: | |
| with requests.get(direct_url, stream=True, timeout=(30, 300), allow_redirects=True) as response: | |
| response.raise_for_status() | |
| content_type = (response.headers.get("content-type") or "").casefold() | |
| if "text/html" in content_type: | |
| raise RuntimeError("Google a returnat o pagina HTML in locul fisierului.") | |
| with temp_target.open("wb") as handle: | |
| for chunk in response.iter_content(chunk_size=1024 * 1024): | |
| if chunk: | |
| handle.write(chunk) | |
| if temp_target.stat().st_size <= 0: | |
| raise RuntimeError("Endpointul direct a creat un fisier gol.") | |
| temp_target.replace(target) | |
| print(f"Descarcare directa reusita: {target}") | |
| return | |
| except Exception as direct_error: | |
| temp_target.unlink(missing_ok=True) | |
| print(f"Metoda directa a esuat ({direct_error}); incerc gdown.", file=sys.stderr) | |
| last_error: Exception | None = None | |
| for attempt in range(1, 4): | |
| try: | |
| result = gdown.download( | |
| id=item.id, | |
| output=str(target), | |
| quiet=False, | |
| use_cookies=False, | |
| resume=True, | |
| ) | |
| if not result or not target.is_file() or target.stat().st_size <= 0: | |
| raise RuntimeError("Fisierul descarcat lipseste sau este gol.") | |
| return | |
| except Exception as exc: | |
| last_error = exc | |
| if attempt < 3: | |
| time.sleep(5 * attempt) | |
| raise RuntimeError(f"Nu am putut descarca {item.path}: {last_error}") | |
| def verify(items: list) -> dict: | |
| missing: list[str] = [] | |
| empty: list[str] = [] | |
| sizes: dict[str, int] = {} | |
| for item in items: | |
| target = Path(item.local_path) | |
| if not target.is_file(): | |
| missing.append(str(target)) | |
| continue | |
| size = target.stat().st_size | |
| sizes[str(target)] = size | |
| if size <= 0: | |
| empty.append(str(target)) | |
| extensions = Counter(Path(item.path).suffix.casefold() for item in items) | |
| return { | |
| "drive_url": DRIVE_URL, | |
| "destination": str(DESTINATION), | |
| "expected_files": len(items), | |
| "extensions": dict(sorted(extensions.items())), | |
| "local_files_found": len(sizes), | |
| "total_local_bytes": sum(sizes.values()), | |
| "missing": missing, | |
| "empty": empty, | |
| "success": not missing and not empty and len(sizes) == len(items), | |
| } | |
| def main() -> int: | |
| DESTINATION.mkdir(parents=True, exist_ok=True) | |
| first_inventory = inventory() | |
| wanted = selected_items(first_inventory) | |
| counts = Counter(Path(item.path).suffix.casefold() for item in wanted) | |
| print(f"Voi descarca {len(wanted)} documente: {dict(sorted(counts.items()))}") | |
| failures: list[str] = [] | |
| for index, item in enumerate(wanted, 1): | |
| try: | |
| download_one(item, index, len(wanted)) | |
| except Exception as exc: | |
| failures.append(str(exc)) | |
| print(f"EROARE DEFINITIVA: {exc}", file=sys.stderr) | |
| print("Refac inventarul Drive pentru verificarea finala...") | |
| final_wanted = selected_items(inventory()) | |
| report = verify(final_wanted) | |
| report["download_failures"] = failures | |
| report["success"] = report["success"] and not failures | |
| REPORT_PATH.write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8") | |
| print(json.dumps(report, ensure_ascii=False, indent=2)) | |
| print(f"Raport salvat: {REPORT_PATH}") | |
| if report["success"]: | |
| print("VERIFICARE REUSITA: toate documentele PDF/DOC/DOCX sunt copiate.") | |
| return 0 | |
| print("VERIFICARE ESUATA: consulta raportul pentru fisierele lipsa.", file=sys.stderr) | |
| return 1 | |
| if __name__ == "__main__": | |
| if hasattr(sys.stdout, "reconfigure"): | |
| sys.stdout.reconfigure(encoding="utf-8") | |
| sys.stderr.reconfigure(encoding="utf-8") | |
| raise SystemExit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment