Files
YouTubeDL/host/folders.py
T
DepressedCat 5f2aad00f4
Check extension and helper / check (push) Canceled after 0s
Publish YouTubeDL 1.4.5 and website on Gitea
2026-10-10 23:53:17 +03:00

57 lines
3.0 KiB
Python

"""Use the Windows folder picker without shipping Tcl/Tk."""
from __future__ import annotations
import base64
import json
import os
import subprocess
def pick_folder(current):
from host.bundle import installation_root
installed = installation_root()
if installed:
encoded = base64.b64encode(json.dumps(current or "").encode("utf-8")).decode("ascii")
result = subprocess.run([str(installed / "YouTubeDL-Manager.exe"), "--pick-folder", "--initial-folder", encoded],
capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=600,
creationflags=subprocess.CREATE_NO_WINDOW)
if result.returncode:
raise ValueError("Не удалось открыть окно выбора папки Windows.")
return json.loads(result.stdout.strip().lstrip("\ufeff"))
if os.name != "nt":
import tkinter
from tkinter import filedialog
root = tkinter.Tk()
try:
root.withdraw(); root.attributes("-topmost", True)
return filedialog.askdirectory(initialdir=current or "", mustexist=True) or None
finally:
root.destroy()
# Only base64 data is substituted; paths are never interpolated into shell code.
encoded = base64.b64encode(json.dumps(current or "").encode("utf-8")).decode("ascii")
script = """
$ErrorActionPreference='Stop'
[Console]::OutputEncoding=[Text.UTF8Encoding]::new()
Add-Type -AssemblyName System.Windows.Forms
$taskDialog=[Windows.Forms.FolderBrowserDialog]::new()
$taskOwner=[Windows.Forms.Form]::new()
try {
$taskOwner.TopMost=$true; $taskOwner.ShowInTaskbar=$false; $taskOwner.Opacity=0
$taskDialog.Description='YouTubeDL — папка сохранения'
$taskDialog.ShowNewFolderButton=$true
$taskDialog.SelectedPath=([Text.Encoding]::UTF8.GetString([Convert]::FromBase64String('ENCODED')) | ConvertFrom-Json)
$taskOwner.Show()
$taskChosen=$null
if($taskDialog.ShowDialog($taskOwner) -eq [Windows.Forms.DialogResult]::OK){$taskChosen=$taskDialog.SelectedPath}
ConvertTo-Json -InputObject $taskChosen -Compress
} finally {$taskDialog.Dispose();$taskOwner.Dispose()}
""".replace("ENCODED", encoded)
argument = base64.b64encode(script.encode("utf-16le")).decode("ascii")
powershell = os.path.join(os.environ.get("SystemRoot", r"C:\Windows"), "System32", "WindowsPowerShell", "v1.0", "powershell.exe")
result = subprocess.run([powershell, "-NoProfile", "-ExecutionPolicy", "Bypass", "-STA", "-EncodedCommand", argument],
capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=600,
creationflags=subprocess.CREATE_NO_WINDOW,
env={**os.environ, "PSModulePath": os.path.join(os.path.dirname(powershell), "Modules")})
if result.returncode:
raise ValueError("Не удалось открыть окно выбора папки Windows.")
return json.loads(result.stdout.strip().lstrip("\ufeff"))