← pag

Commit cd0b557

0
plików
+0
dodanych
-0
usuniętych
@@ -1,7 +1,7 @@
1 1 #!/usr/bin/env python3
2 2 """
3 3 ╔══════════════════════════════════════════════════════════════════════════════╗
4 -║ PAG - Pagan Linux Package Manager v3.3.8 ║
4 +║ PAG - Pagan Linux Package Manager v3.3.9 ║
5 5 ║ Produkcyjny menedżer pakietów – atomowy, bezpieczny, i18n ║
6 6 ╚══════════════════════════════════════════════════════════════════════════════╝
7 7
@@ -54,7 +54,7 @@ from urllib.request import urlopen, Request
54 54 import threading, itertools
55 55
56 56 # Wersja klienta – do porównania z repo.json["pag_version"] (self-update)
57 -PAG_VERSION = "3.3.8"
57 +PAG_VERSION = "3.3.9"
58 58 from urllib.error import URLError, HTTPError
59 59
60 60 # =============================================================================
@@ -248,6 +248,7 @@ T = {
248 248 "to_install": "To install: {} packages ({:.2f} MB)",
249 249 "new": "NEW",
250 250 "continue_q": "Continue? [Y/n] ",
251 + "no_tty": "No TTY / stdin closed (EOF) – cancelling.",
251 252 "cancelled": "Cancelled.",
252 253 "not_found": "not found in repos",
253 254 "downloading": "Downloading",
@@ -325,6 +326,7 @@ T = {
325 326 "to_install": "Do zainstalowania: {} pakietów ({:.2f} MB)",
326 327 "new": "NOWY",
327 328 "continue_q": "Kontynuować? [T/n] ",
329 + "no_tty": "Brak terminala (EOF) – anuluję.",
328 330 "cancelled": "Anulowano.",
329 331 "not_found": "brak w repozytoriach",
330 332 "downloading": "Pobieranie",
@@ -419,6 +421,26 @@ def _(key: str, *args, **kwargs) -> str:
419 421 return msg.format(*args, **kwargs)
420 422 return msg
421 423
424 +
425 +def _ask_confirm() -> bool:
426 + """Pytanie potwierdzające (T/n). PAG_YES=1 → zawsze tak.
427 +
428 + EOF/brak terminala (stdin zamknięty, np. ssh bez TTY, cron, subprocess
429 + panelu webowego) → NIE – anuluj, nie wykonuj operacji bez potwierdzenia
430 + (inaczej input() rzuca EOFError i pag pada tracebackiem).
431 + Enter → tak (domyślne Y/n).
432 + """
433 + if os.environ.get("PAG_YES", "") == "1":
434 + print(_("continue_q") + " t (--yes)")
435 + return True
436 + try:
437 + ans = input(_("continue_q")).strip().lower()
438 + except (EOFError, KeyboardInterrupt):
439 + print(f"\n ⚠ {_('no_tty')}")
440 + return False
441 + return not ans or ans in ("t", "y")
442 +
443 +
422 444 # =============================================================================
423 445 # ŚCIEŻKI
424 446 # =============================================================================
@@ -1896,12 +1918,8 @@ def cmd_rollback():
1896 1918 print(f"⏪ Rolling back: {last['action']} ({last['timestamp']})")
1897 1919 print(f" Packages: {', '.join(last['packages'][:10])}")
1898 1920
1899 - if os.environ.get("PAG_YES", "") == "1":
1900 - print(_("continue_q") + " t (--yes)")
1901 - else:
1902 - ans = input(_("continue_q")).strip().lower()
1903 - if ans and ans not in ("t","y"):
1904 - return 0
1921 + if not _ask_confirm():
1922 + return 0
1905 1923
1906 1924 # Przywróć installed.json
1907 1925 save_json(INSTALLED_DB, last["snapshot"])
@@ -2092,12 +2110,8 @@ def cmd_install(package_names, as_dep=False, upgrade=False):
2092 2110 print(f" {name}-{p.version}{marker}")
2093 2111
2094 2112 if not as_dep and not upgrade:
2095 - if os.environ.get("PAG_YES", "") == "1":
2096 - print(_("continue_q") + " t (--yes)")
2097 - else:
2098 - ans = input(_("continue_q")).strip().lower()
2099 - if ans and ans not in ("t","y"):
2100 - print(_("cancelled")); return 0
2113 + if not _ask_confirm():
2114 + print(_("cancelled")); return 0
2101 2115
2102 2116 snapshot = json.loads(json.dumps(installed_db))
2103 2117 all_installed_files = []
@@ -2556,11 +2570,8 @@ def cmd_upgrade():
2556 2570 print(f"📦 {_('upgrading', len(upgrades))}")
2557 2571 for n in upgrades:
2558 2572 print(f" {n}: {installed[n]['version']} → {repo[n].version}")
2559 - if os.environ.get("PAG_YES", "") == "1":
2560 - print(_("continue_q") + " t (--yes)")
2561 - else:
2562 - ans = input(_("continue_q")).strip().lower()
2563 - if ans and ans not in ("t","y"): return 0
2573 + if not _ask_confirm():
2574 + return 0
2564 2575 return cmd_install(upgrades, upgrade=True)
2565 2576
2566 2577 def cmd_list(installed_only=False):
@@ -2754,11 +2765,8 @@ def cmd_remove_orphans():
2754 2765 if not orphans: print("✅ No orphans."); return
2755 2766 print(f"Orphans ({len(orphans)}):")
2756 2767 for n in sorted(orphans): print(f" {n}-{installed[n]['version']}")
2757 - if os.environ.get("PAG_YES", "") == "1":
2758 - print(_("continue_q") + " t (--yes)")
2759 - else:
2760 - ans = input(_("continue_q")).strip().lower()
2761 - if ans and ans not in ("t","y"): return
2768 + if not _ask_confirm():
2769 + return
2762 2770 cmd_remove(list(orphans))
2763 2771
2764 2772
@@ -3037,7 +3045,7 @@ def _flatpak_find_best(query: str) -> Optional[dict]:
3037 3045 idx = int(choice) - 1
3038 3046 if 0 <= idx < len(results):
3039 3047 return results[idx]
3040 - except (ValueError, IndexError):
3048 + except (EOFError, ValueError, IndexError):
3041 3049 pass
3042 3050 return None
3043 3051
@@ -3158,7 +3166,11 @@ def cmd_flatpak(args: list):
3158 3166 if best["description"]:
3159 3167 print(f" {best['description']}")
3160 3168
3161 - ans = input(f"\n {_('flatpak_install_prompt', best['name'])}").strip().lower()
3169 + try:
3170 + ans = input(f"\n {_('flatpak_install_prompt', best['name'])}").strip().lower()
3171 + except (EOFError, KeyboardInterrupt):
3172 + print(f"\n ⚠ {_('no_tty')}")
3173 + return 0
3162 3174 if ans and ans not in ("t", "y"):
3163 3175 print(_("cancelled"))
3164 3176 return 0
@@ -3242,7 +3254,7 @@ def _flatpak_smart_remove(names: list) -> int:
3242 3254 continue
3243 3255 aid_list = sorted(matches.keys())
3244 3256 app_id = aid_list[int(choice) - 1]
3245 - except (ValueError, IndexError):
3257 + except (EOFError, ValueError, IndexError):
3246 3258 failed += 1
3247 3259 continue
3248 3260
@@ -3744,12 +3756,8 @@ def cmd_deploy_rollback():
3744 3756 print(f"⏪ Przywracanie deploymentu: {prev['id']}")
3745 3757 print(f" {prev['action']}: {', '.join(prev['packages'][:5])}")
3746 3758
3747 - if os.environ.get("PAG_YES", "") == "1":
3748 - print(_("continue_q") + " t (--yes)")
3749 - else:
3750 - ans = input(_("continue_q")).strip().lower()
3751 - if ans and ans not in ("t", "y"):
3752 - return 0
3759 + if not _ask_confirm():
3760 + return 0
3753 3761
3754 3762 _switch_deployment(prev_dir)
3755 3763