Publish Source Available licenses and remove Mutagen in YouTubeDL 1.4.7 / helper 1.3.3
This commit is contained in:
1 parent
71a808b298
commit
50457bc35b
27 files changed
+201
-58
No files matched your search
+1
-1
@@ -24,7 +24,7 @@ npm run check
|
||||
python tools/build.py
|
||||
```
|
||||
|
||||
`tools/build.py` собирает небольшой `dist/YouTubeDL-1.4.6.zip` без EXE.
|
||||
`tools/build.py` собирает небольшой `dist/YouTubeDL-1.4.7.zip` без EXE.
|
||||
Для сборки расширения не требуется предварительно собирать помощник.
|
||||
|
||||
## Браузерные проверки
|
||||
|
||||
+3
-3
@@ -6,7 +6,7 @@ Firefox, macOS, Linux и Windows ARM не входят в эту сборку.
|
||||
Скачивания доступны в [релизах проекта](https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/latest).
|
||||
Помощник распространяется **отдельно**: внутри архива расширения EXE нет.
|
||||
|
||||
1. Скачайте **YouTubeDL-1.4.6.zip** и распакуйте его в постоянную папку. Не удаляйте и не перемещайте её после установки.
|
||||
1. Скачайте **YouTubeDL-1.4.7.zip** и распакуйте его в постоянную папку. Не удаляйте и не перемещайте её после установки.
|
||||
2. Откройте `edge://extensions` или `chrome://extensions`. Включите **Режим разработчика**, нажмите **Загрузить распакованное расширение** и выберите папку **extension** внутри распакованного архива.
|
||||
3. На странице релиза отдельно скачайте **YouTubeDL-Helper-Setup.exe**. Это автономный комплект: Python, yt-dlp, EJS, Node.js, FFmpeg и FFprobe уже внутри.
|
||||
4. Запустите EXE вручную и дождитесь окончания установки. Администратор и интернет для установки комплекта не требуются. Программы устанавливаются для текущего пользователя в `%LOCALAPPDATA%\YouTubeDL\Helper`.
|
||||
@@ -59,7 +59,7 @@ Get-FileHash -Algorithm SHA256 -LiteralPath '.\YouTubeDL-Helper-Setup.exe'
|
||||
|
||||
При разных дисках результат сначала копируется во временную папку на диске сохранения, затем публикуется под итоговым именем. Прогресс копирования виден в уведомлении; частичный файл не появляется под готовым именем. При отмене помощник завершает группу процессов данной задачи и удаляет её временные папки.
|
||||
|
||||
Для отдельной рабочей папки, подробного прогресса слияния и исправленной отмены установите помощник 1.3.2 и расширение 1.4.6. Обновление компонентов не заменяет программный код помощника; для этой версии запустите новый установщик помощника.
|
||||
Для отдельной рабочей папки, подробного прогресса слияния и исправленной отмены установите помощник 1.3.3 и расширение 1.4.7. Обновление компонентов не заменяет программный код помощника; для этой версии запустите новый установщик помощника.
|
||||
|
||||
## История и ошибки
|
||||
|
||||
@@ -69,7 +69,7 @@ Get-FileHash -Algorithm SHA256 -LiteralPath '.\YouTubeDL-Helper-Setup.exe'
|
||||
|
||||
## Совместимость версий
|
||||
|
||||
В настройках и мастере первого запуска отображаются версии расширения и помощника. Расширение 1.4.6 поддерживает помощник 1.3.2. При старом помощнике появится кнопка «Обновить помощник», при более новом помощнике или устаревшем расширении — «Обновить расширение». Пока совместимость не подтверждена, новая загрузка не запускается.
|
||||
В настройках и мастере первого запуска отображаются версии расширения и помощника. Расширение 1.4.7 поддерживает помощник 1.3.3. При старом помощнике появится кнопка «Обновить помощник», при более новом помощнике или устаревшем расширении — «Обновить расширение». Пока совместимость не подтверждена, новая загрузка не запускается.
|
||||
|
||||
После установки помощника нажмите «Проверить»: статус изменится без перезагрузки страницы. После замены файлов расширения нажмите «Обновить» на странице расширений браузера и перезагрузите вкладку YouTube. Обновление компонентов обновляет инструменты внутри комплекта и не заменяет само расширение или код помощника.
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
ОГРАНИЧЕННАЯ ПОЛЬЗОВАТЕЛЬСКАЯ ЛИЦЕНЗИЯ YOUTUBEDL
|
||||
Версия 1.0, 8 октября 2026 года
|
||||
ЛИЦЕНЗИЯ SOURCE AVAILABLE — YouTubeDL
|
||||
Версия 1.1, 11 октября 2026 года
|
||||
|
||||
Copyright (c) 2026 DepressedCat. Все права сохранены.
|
||||
Правообладатель: DepressedCat (https://git.lonarpgproxy.space/DepressedCat).
|
||||
|
||||
Исходный код доступен для ознакомления (Source Available). Права на использование,
|
||||
изменение и распространение определяются условиями этой лицензии.
|
||||
|
||||
1. ОБЛАСТЬ ДЕЙСТВИЯ
|
||||
|
||||
Эта лицензия относится к собственным файлам проекта YouTubeDL, предоставляемым
|
||||
@@ -22,7 +25,8 @@ Copyright (c) 2026 DepressedCat. Все права сохранены.
|
||||
выбирать дорожки и параметры, объединять, конвертировать и сохранять файлы
|
||||
при наличии права сохранять соответствующий контент.
|
||||
|
||||
Разрешены необходимые для этого установочные и резервные копии, сборка
|
||||
Разрешены просмотр и изучение опубликованных исходников, их локальная копия
|
||||
для ознакомления и сборки, необходимые установочные и резервные копии, сборка
|
||||
неизменённой официальной поставки для собственного использования, настройка
|
||||
через штатные средства, установка официальных обновлений и удаление Программы.
|
||||
Это не предоставляет права изменять собственные файлы кода и дизайна.
|
||||
@@ -46,11 +50,21 @@ Copyright (c) 2026 DepressedCat. Все права сохранены.
|
||||
|
||||
4. ИСКЛЮЧЕНИЯ
|
||||
|
||||
4.1. Python, Node.js, yt-dlp, EJS, FFmpeg, FFprobe и другие сторонние компоненты,
|
||||
их исходники и лицензионные тексты регулируются лицензиями их правообладателей.
|
||||
Эта лицензия не ограничивает предоставленные ими права, в том числе права
|
||||
на изменение, форки и распространение по GPL, MIT и другим лицензиям.
|
||||
Состав и сведения о лицензиях приведены в THIRD_PARTY.md и материалах релиза.
|
||||
4.1. Python, Node.js, yt-dlp, EJS, FFmpeg, FFprobe и другие сторонние компоненты
|
||||
регулируются условиями собственных лицензий, установленными их правообладателями.
|
||||
|
||||
Настоящая лицензия не ограничивает права, предоставленные пользователям лицензиями
|
||||
указанных сторонних компонентов, включая права на изменение, создание производных
|
||||
работ и распространение, если такие действия разрешены соответствующими лицензиями.
|
||||
|
||||
Указанные права относятся к соответствующим сторонним компонентам и не предоставляют
|
||||
пользователю дополнительных прав на авторские части Программы. Их изменение, создание
|
||||
производных версий, форков и распространение запрещены без разрешения правообладателя,
|
||||
за исключением случаев, предусмотренных настоящей лицензией, обязательными нормами
|
||||
законодательства или применимыми лицензиями сторонних компонентов.
|
||||
|
||||
Перечень сторонних компонентов и сведения об их лицензиях приведены в файле
|
||||
THIRD_PARTY.md и материалах релиза.
|
||||
|
||||
4.2. Права, которые применимое законодательство не позволяет ограничивать
|
||||
договором, сохраняются. Эта лицензия не предоставляет прав на чужой контент
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Обработка данных
|
||||
|
||||
Актуально для расширения **1.4.5** и помощника **1.3.2**. Исходники доступны для просмотра,
|
||||
Актуально для расширения **1.4.7** и помощника **1.3.3**. Исходники доступны для просмотра,
|
||||
условия использования собственного кода ограничены [лицензией](LICENSE).
|
||||
У проекта нет собственного сервера обработки видео, аккаунтов, телеметрии, рекламы или аналитики.
|
||||
Это не означает отсутствие обработки данных: необходимые сведения используются на вашем компьютере,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
**[Инструкция](INSTALL.md)** · **[Обработка данных](PRIVACY.md)** ·
|
||||
**[Сообщить об ошибке](https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/issues)**
|
||||
|
||||
Windows 10/11 x64 · Microsoft Edge / Google Chrome 120+ · расширение **1.4.6** · помощник **1.3.2**.
|
||||
Windows 10/11 x64 · Microsoft Edge / Google Chrome 120+ · расширение **1.4.7** · помощник **1.3.3**.
|
||||
Расширение устанавливается распакованным, через режим разработчика. Прямая поставка через Gitea выбрана из-за ограничений на скачивание контента в [правилах Chrome Web Store](https://developer.chrome.com/docs/webstore/program-policies/malicious-and-prohibited) и [условиях YouTube](https://www.youtube.com/static?template=terms).
|
||||
|
||||
## Что умеет
|
||||
@@ -38,7 +38,7 @@ DRM-контент и гарантированный обход ограниче
|
||||
|
||||
## Установка: два отдельных скачивания
|
||||
|
||||
1. Откройте [последний релиз](https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/latest), скачайте **YouTubeDL-1.4.6.zip** и распакуйте в постоянную папку.
|
||||
1. Откройте [последний релиз](https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/latest), скачайте **YouTubeDL-1.4.7.zip** и распакуйте в постоянную папку.
|
||||
2. В `edge://extensions` или `chrome://extensions` включите **Режим разработчика**, нажмите **Загрузить распакованное расширение** и выберите папку **extension**.
|
||||
3. **Отдельно скачайте YouTubeDL-Helper-Setup.exe из того же релиза** и запустите его вручную. EXE не встроен в расширение: кнопка установки открывает страницу релизов.
|
||||
4. Обновите YouTube, откройте **⚙** и пройдите мастер. Выберите папку и параметры; зелёный статус подтверждает связь с помощником.
|
||||
@@ -102,8 +102,8 @@ Python остаётся в ветке 3.13, Node.js — в 24 LTS.
|
||||
|
||||
## Лицензии и разработка
|
||||
|
||||
Новые поставки собственного кода — по **[ограниченной пользовательской лицензии](LICENSE)**:
|
||||
разрешены установка и использование по назначению. Изменение, самостоятельные форки,
|
||||
Новые поставки собственного кода — по **[лицензии Source Available](LICENSE)**:
|
||||
разрешены просмотр исходников, сборка неизменённой версии, установка и использование по назначению. Изменение, самостоятельные форки,
|
||||
производные версии и распространение без письменного разрешения правообладателя запрещены,
|
||||
с учётом исключений лицензии. Это распространяется и на само расширение.
|
||||
|
||||
|
||||
+3
-2
@@ -5,8 +5,9 @@
|
||||
Встроенные компоненты помощника имеют **свои** лицензии; ограничения YouTubeDL
|
||||
не заменяют и не ограничивают их, в том числе права по GPL и MIT.
|
||||
Помощник вызывает FFmpeg отдельным процессом.
|
||||
Mutagen не входит в комплект 1.3.3 и не устанавливается при обновлении его компонентов.
|
||||
|
||||
Автономный комплект помощника 1.3.2:
|
||||
Автономный комплект помощника 1.3.3:
|
||||
|
||||
| Компонент | Версия | Проект / лицензия |
|
||||
| --- | --- | --- |
|
||||
@@ -17,7 +18,7 @@
|
||||
| FFmpeg / FFprobe | N-127236-g17ec998942-20261007, shared win64 GPL | [FFmpeg](https://github.com/FFmpeg/FFmpeg/tree/17ec998942), GPL v3 or later для этой сборки; [сценарии FFmpeg-Builds](https://github.com/yt-dlp/FFmpeg-Builds) |
|
||||
|
||||
Python-пакеты комплекта: brotli 1.2.0, certifi 2026.7.22, charset-normalizer 3.5.2,
|
||||
idna 3.20, mutagen 1.48.1, pycryptodomex 3.24.0, requests 2.34.2, urllib3 2.8.0,
|
||||
idna 3.20, pycryptodomex 3.24.0, requests 2.34.2, urllib3 2.8.0,
|
||||
websockets 17.2. Их `METADATA` и лицензии находятся рядом с библиотеками в
|
||||
`runtime/python/Lib/site-packages/*.dist-info` установленного помощника.
|
||||
Тексты Python/Node.js/FFmpeg также входят в установленный комплект.
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# YouTubeDL 1.4.7
|
||||
|
||||
Расширение **1.4.7** для Edge и Chrome 120+. Локальный помощник — **1.3.3**.
|
||||
|
||||
- Собственный код, документация и оформление распространяются по лицензии **Source Available**: разрешены просмотр исходников, сборка неизменённой версии и использование по назначению. Изменения, форки и распространение требуют письменного согласия DepressedCat с учётом исключений лицензии.
|
||||
- Неиспользуемый Mutagen исключён из автономного помощника и списка обновляемых Python-пакетов. Объединение дорожек, конвертация, аудио и аппаратное ускорение продолжают выполняться через FFmpeg.
|
||||
- Проверка состава Python-пакетов выполняется при сборке, проверке комплекта и обновлении. Пакеты, требующие отдельной проверки совместимости лицензии, отклоняются до активации; рабочий комплект сохраняется.
|
||||
- Лицензии и исходные материалы сторонних компонентов доступны отдельно в служебном разделе загрузок.
|
||||
|
||||
## Установка и обновление
|
||||
|
||||
1. Скачайте **YouTubeDL-1.4.7.zip**, распакуйте в постоянную папку и загрузите папку `extension` через режим разработчика в `edge://extensions` или `chrome://extensions`.
|
||||
2. Скачайте **YouTubeDL-Helper-Setup.exe** из этого релиза и обновите помощник до **1.3.3**. Обычное обновление компонентов не заменяет код самого помощника.
|
||||
3. Перезагрузите расширение и открытые страницы YouTube, затем проверьте подключение помощника.
|
||||
|
||||
Если расширение уже установлено, замените файлы прежней папки `extension` и нажмите «Перезагрузить» на странице расширений браузера.
|
||||
@@ -2,7 +2,7 @@
|
||||
"manifest_version": 3,
|
||||
"name": "YouTubeDL",
|
||||
"description": "Скачать видео и аудио с YouTube: качество, формат, папка, NVIDIA NVENC и AMD AMF.",
|
||||
"version": "1.4.6",
|
||||
"version": "1.4.7",
|
||||
"minimum_chrome_version": "120",
|
||||
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6bCUFVUmC9OqpL0+/vrQDKEesuiylybHxRWJXfMV7VfctMbDjAQzActxImzMGIviC8PJrCHT86v/erppUhIgqFrSftHVPPWmYbVJ/g6KBu1bRNIG5J1WDUnMO2E4hGNEJQe+6ezqGuGdk659qQOqP5khGbnog9wUs+1nPpolaXbXsUudn5leaxJ0SrdFT9oWjq59bAc7raEKjR1chU9pB9g9alEA8lqpcKUU8j7f/KJC9YvkOlTNEsLXhuLLzcC7Aw/eI3lgBqBLFWIcrEYrBPVFeIlNaVLdl6b8YqAD+eBaT1xdpT6VbGh/d3lf/Vq/TBzTzCplcMO2vIFGDKTNhQIDAQAB",
|
||||
"permissions": [
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ export function stabilizeDownloadSpeed(job, previous, now = Date.now()) {
|
||||
&& now >= previous.speedUpdatedAt && now - previous.speedUpdatedAt < 1500;
|
||||
return { ...job, speed: recent ? previous.speed : null, speedUpdatedAt: recent ? previous.speedUpdatedAt : null };
|
||||
}
|
||||
export const SUPPORTED_HELPER_VERSION = "1.3.2";
|
||||
export const SUPPORTED_HELPER_VERSION = "1.3.3";
|
||||
const MINIMUM_EXTENSION_VERSION = "1.4.5";
|
||||
function compareVersions(left, right) {
|
||||
if (![left, right].every(value => typeof value === "string" && /^\d+(?:\.\d+){1,3}$/.test(value))) return null;
|
||||
|
||||
@@ -7,6 +7,7 @@ from pathlib import Path
|
||||
from host.bundle import ROOT, executable, manifest
|
||||
from host.common import EXTENSION_ID, HOST_NAME
|
||||
from host.dependencies import status
|
||||
from host.python_packages import validate_installed
|
||||
|
||||
|
||||
def verify():
|
||||
@@ -14,6 +15,7 @@ def verify():
|
||||
raise ValueError("Autonomous bundle metadata is missing.")
|
||||
if Path(sys.executable).resolve() != Path(executable("python")):
|
||||
raise ValueError("The helper must use its embedded Python.")
|
||||
validate_installed(ROOT / "runtime/python/Lib/site-packages")
|
||||
measured = status()
|
||||
if any(item["status"] != "installed" for item in measured):
|
||||
raise ValueError("Bundled components failed verification: " + json.dumps(measured))
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ from pathlib import Path
|
||||
from urllib.parse import parse_qs, urlsplit
|
||||
|
||||
HOST_NAME = "com.youtubedl.native"
|
||||
VERSION = "1.3.2"
|
||||
VERSION = "1.3.3"
|
||||
EXTENSION_ID = "ndnoeiaecgmjnjneekaeapeecmmjheli"
|
||||
VIDEO_CONTAINERS = {"mp4", "mkv", "webm"}
|
||||
AUDIO_CONTAINERS = {"m4a", "mp3", "opus", "flac", "wav"}
|
||||
|
||||
@@ -64,6 +64,7 @@ def install(key, progress, workspace=None):
|
||||
raise ValueError("Нажмите «Обновить компоненты» для установки новых версий из интернета или «Восстановить» для переустановки встроенного комплекта.")
|
||||
if key not in {"node", "ffmpeg", "yt_dlp", "ejs"}:
|
||||
raise ValueError("Неизвестный компонент.")
|
||||
from host.python_packages import requirements
|
||||
runtime = ROOT / ".runtime"
|
||||
runtime.mkdir(exist_ok=True)
|
||||
cfg = config()
|
||||
@@ -73,8 +74,8 @@ def install(key, progress, workspace=None):
|
||||
workspace(str(scratch))
|
||||
if key in {"yt_dlp", "ejs"}:
|
||||
progress(None, "Устанавливаю Python-пакет")
|
||||
package = "yt-dlp[default]>=2026.8.19" if key == "yt_dlp" else "yt-dlp-ejs"
|
||||
measured = subprocess.run([sys.executable, "-m", "pip", "install", "--disable-pip-version-check", "--upgrade", package],
|
||||
packages = requirements() if key == "yt_dlp" else ["yt-dlp-ejs"]
|
||||
measured = subprocess.run([sys.executable, "-m", "pip", "install", "--disable-pip-version-check", "--upgrade", *packages],
|
||||
stdin=subprocess.DEVNULL, capture_output=True, text=True, encoding="utf-8", errors="replace", creationflags=NO_WINDOW, timeout=600)
|
||||
if measured.returncode:
|
||||
raise ValueError("Не удалось установить компонент. " + measured.stderr[-1200:])
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
"""Python dependencies used by the helper; optional cover tagging is excluded."""
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.metadata
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def requirements(yt_dlp="yt-dlp>=2026.8.19", ejs="yt-dlp-ejs"):
|
||||
return [yt_dlp, ejs, "brotli", "certifi", "pycryptodomex",
|
||||
"requests>=2.32.2,<3", "urllib3>=2,<3", "websockets>=13"]
|
||||
|
||||
|
||||
def validate_metadata(records):
|
||||
"""Reject strong copyleft Python libraries before activating a bundle.
|
||||
|
||||
FFmpeg is a separately executed program, so this policy concerns Python
|
||||
libraries loaded into the helper process, not the FFmpeg distribution.
|
||||
"""
|
||||
for metadata in records:
|
||||
name = re.sub(r"[-_.]+", "-", metadata.get("name", "").lower())
|
||||
licenses = [metadata.get("license_expression") or "", metadata.get("license") or "",
|
||||
*metadata.get("classifier", [])]
|
||||
incompatible = name == "mutagen" or any(
|
||||
re.search(r"(?<![A-Z])(?:A?GPL)(?:[-\s\dv]|$)|GNU (?:Affero )?General Public License",
|
||||
license, re.IGNORECASE) for license in licenses)
|
||||
if incompatible:
|
||||
raise ValueError(f"Python-пакет {name} требует отдельной проверки совместимости лицензии; комплект не изменён.")
|
||||
|
||||
|
||||
def validate_installed(directory: Path):
|
||||
records = []
|
||||
for distribution in importlib.metadata.distributions(path=[str(directory)]):
|
||||
metadata = distribution.metadata
|
||||
records.append({"name": metadata.get("Name", ""),
|
||||
"license_expression": metadata.get("License-Expression", ""),
|
||||
"license": metadata.get("License", ""),
|
||||
"classifier": metadata.get_all("Classifier") or []})
|
||||
validate_metadata(records)
|
||||
return {distribution.metadata["Name"]: distribution.version
|
||||
for distribution in importlib.metadata.distributions(path=[str(directory)])}
|
||||
+4
-1
@@ -19,6 +19,7 @@ from urllib.parse import urlsplit
|
||||
import requests
|
||||
from host.bundle import ROOT, installation_root, manifest
|
||||
from host.media import NO_WINDOW, run_small
|
||||
from host.python_packages import requirements, validate_metadata, validate_installed
|
||||
|
||||
ALLOWED_HOSTS = {"www.python.org", "nodejs.org", "api.github.com", "github.com", "release-assets.githubusercontent.com", "objects.githubusercontent.com", "pypi.org", "files.pythonhosted.org"}
|
||||
FFMPEG_ASSET = "ffmpeg-master-latest-win64-gpl-shared.zip"
|
||||
@@ -183,11 +184,12 @@ def resolve_packages(stage, work, progress):
|
||||
report = work / "python-packages.json"
|
||||
script = "import sys;sys.path.insert(0,sys.argv.pop(1));from pip._internal.cli.main import main;raise SystemExit(main(sys.argv[1:]))"
|
||||
command = [str(stage / "runtime/python/python.exe"), "-I", "-X", "utf8", "-B", "-c", script, str(pip), "--isolated", "--disable-pip-version-check", "install",
|
||||
"--dry-run", "--ignore-installed", "--only-binary=:all:", "--no-cache-dir", "--quiet", "--report", str(report), "--index-url", "https://pypi.org/simple", "yt-dlp[default]", "yt-dlp-ejs"]
|
||||
"--dry-run", "--ignore-installed", "--only-binary=:all:", "--no-cache-dir", "--quiet", "--report", str(report), "--index-url", "https://pypi.org/simple", *requirements()]
|
||||
result = subprocess.run(command, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=600, creationflags=NO_WINDOW,
|
||||
env={**os.environ, "TEMP": str(work), "TMP": str(work)}, stdin=subprocess.DEVNULL)
|
||||
if result.returncode: raise ValueError("Не удалось подобрать совместимые Python-пакеты. " + result.stderr[-1200:])
|
||||
records = json.loads(report.read_text(encoding="utf-8"))["install"]
|
||||
validate_metadata([record["metadata"] for record in records])
|
||||
packages = stage / "runtime/python/Lib/site-packages"
|
||||
if packages.exists(): shutil.rmtree(packages)
|
||||
packages.mkdir(parents=True)
|
||||
@@ -206,6 +208,7 @@ def resolve_packages(stage, work, progress):
|
||||
if packages.resolve() not in destination.parents: raise ValueError("Некорректный путь Python-пакета.")
|
||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||
destination.write_bytes(wheel.read(member))
|
||||
validate_installed(packages)
|
||||
return {item["metadata"]["name"]: item["metadata"]["version"] for item in records}
|
||||
|
||||
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "youtubedl",
|
||||
"version": "1.4.6",
|
||||
"version": "1.4.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "youtubedl",
|
||||
"version": "1.4.6",
|
||||
"version": "1.4.7",
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
"devDependencies": {
|
||||
"playwright": "^1.64.0"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "youtubedl",
|
||||
"version": "1.4.6",
|
||||
"version": "1.4.7",
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
||||
+8
-1
@@ -1 +1,8 @@
|
||||
yt-dlp[default]>=2026.8.19
|
||||
yt-dlp>=2026.8.19
|
||||
yt-dlp-ejs
|
||||
brotli
|
||||
certifi
|
||||
pycryptodomex
|
||||
requests>=2.32.2,<3
|
||||
urllib3>=2,<3
|
||||
websockets>=13
|
||||
+5
-5
@@ -40,7 +40,7 @@
|
||||
<div class="hero-actions"><a class="button primary" href="#install">Установить расширение <span aria-hidden="true">↓</span></a><a class="hero-link" href="#features">Посмотреть возможности <span aria-hidden="true">↗</span></a></div>
|
||||
<p class="hero-note">Бесплатно · Для Windows · Обработка на вашем компьютере</p>
|
||||
</div>
|
||||
<div class="hero-bottom"><span>ВИДЕО. ЗВУК. ВАШ ВЫБОР.</span><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/tag/v1.4.6">Выпуск 1.4.6 <span aria-hidden="true">↗</span></a></div>
|
||||
<div class="hero-bottom"><span>ВИДЕО. ЗВУК. ВАШ ВЫБОР.</span><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/tag/v1.4.7">Выпуск 1.4.7 <span aria-hidden="true">↗</span></a></div>
|
||||
</div>
|
||||
</section>
|
||||
<div class="format-strip"><div class="wrap"><p>Один ролик.<br><strong>Ваш формат.</strong></p><div class="format-list" aria-label="Форматы"><span>MP4</span><span>MKV</span><span>WebM</span><i aria-hidden="true"></i><span>MP3</span><span>M4A</span><span>Opus</span><span>FLAC</span><span>WAV</span></div></div></div>
|
||||
@@ -70,8 +70,8 @@
|
||||
<section class="install-section" id="install" aria-labelledby="install-title"><div class="wrap">
|
||||
<div class="install-heading reveal"><div><p class="overline">04 / НАЧНЁМ</p><h2 id="install-title">Два скачивания.<br><em>Один комплект.</em></h2></div><p>Windows 10/11 x64<br>Edge или Chrome 120+<br><span>Без прав администратора</span></p></div>
|
||||
<div class="download-grid reveal">
|
||||
<article class="download-card"><div class="download-card-top"><span class="package-number">1</span><span class="package-tag">БРАУЗЕР</span><span class="version">v1.4.6</span></div><h3>Расширение</h3><p>Кнопки на YouTube, настройки и уведомления. Устанавливается распакованным.</p><a class="button primary package-link" data-download="extension" href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/download/v1.4.6/YouTubeDL-1.4.6.zip">Скачать расширение <span aria-hidden="true">↓</span></a><small>ZIP · <span id="extension-size">Небольшой архив</span></small></article>
|
||||
<article class="download-card helper-card"><div class="download-card-top"><span class="package-number">2</span><span class="package-tag">КОМПЬЮТЕР</span><span class="version">v1.3.2</span></div><h3>Локальный помощник</h3><p>Скачивает, соединяет и конвертирует. Все необходимые компоненты уже внутри.</p><a class="button secondary package-link" data-download="helper" href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/download/v1.4.6/YouTubeDL-Helper-Setup.exe">Скачать помощник <span aria-hidden="true">↓</span></a><small>EXE · 124,3 МиБ · устанавливается отдельно</small></article>
|
||||
<article class="download-card"><div class="download-card-top"><span class="package-number">1</span><span class="package-tag">БРАУЗЕР</span><span class="version">v1.4.7</span></div><h3>Расширение</h3><p>Кнопки на YouTube, настройки и уведомления. Устанавливается распакованным.</p><a class="button primary package-link" data-download="extension" href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/download/v1.4.7/YouTubeDL-1.4.7.zip">Скачать расширение <span aria-hidden="true">↓</span></a><small>ZIP · <span id="extension-size">Небольшой архив</span></small></article>
|
||||
<article class="download-card helper-card"><div class="download-card-top"><span class="package-number">2</span><span class="package-tag">КОМПЬЮТЕР</span><span class="version">v1.3.3</span></div><h3>Локальный помощник</h3><p>Скачивает, соединяет и конвертирует. Все необходимые компоненты уже внутри.</p><a class="button secondary package-link" data-download="helper" href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/download/v1.4.7/YouTubeDL-Helper-Setup.exe">Скачать помощник <span aria-hidden="true">↓</span></a><small>EXE · 124,1 МиБ · устанавливается отдельно</small></article>
|
||||
</div>
|
||||
<p class="download-note">Оба файла размещены в <a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/latest">релизах Gitea ↗</a>. Помощник не встроен в ZIP. <a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/src/branch/main/INSTALL.md#проверка-скачанных-файлов">Проверка SHA256 и подробности</a>.</p>
|
||||
<ol class="install-steps reveal">
|
||||
@@ -93,11 +93,11 @@
|
||||
<details><summary>Как удалить всё?<span aria-hidden="true">+</span></summary><p>Удалите помощник кнопкой в меню или через приложения Windows, затем расширение из браузера. Скачанные файлы и история помощника сохраняются. Для удаления истории после удаления помощника удалите <code>%LOCALAPPDATA%\YouTubeDL\Helper\data</code>. Настройки расширения удаляются вместе с расширением.</p></details>
|
||||
<details><summary>Почему расширения нет в Chrome Web Store?<span aria-hidden="true">+</span></summary><p>YouTubeDL распространяется через релизы Gitea из-за ограничений на скачивание контента. <a href="https://developer.chrome.com/docs/webstore/program-policies/malicious-and-prohibited" target="_blank" rel="noopener noreferrer">Правила Chrome Web Store</a> запрещают инструменты для неразрешённого скачивания защищённого контента, а <a href="https://www.youtube.com/static?template=terms" target="_blank" rel="noopener noreferrer">условия YouTube</a> ограничивают скачивание разрешёнными сервисом способами или письменным разрешением YouTube и соответствующих правообладателей. Поэтому для YouTubeDL выбрана ручная установка распакованного расширения из официального релиза.</p></details>
|
||||
<details><summary>Какие ОС поддерживаются?<span aria-hidden="true">+</span></summary><p>Сейчас опубликована сборка для Windows 10/11 x64 и Edge/Chrome 120+. Firefox, macOS, Linux и Windows ARM не входят в неё. Плейлисты, скачивание каналов и DRM-контент не заявляются.</p></details>
|
||||
<details><summary>Можно изменять расширение и публиковать свои версии?<span aria-hidden="true">+</span></summary><p><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/src/branch/main/LICENSE">Лицензия</a> разрешает использование по назначению и запрещает изменения, самостоятельные форки и распространение собственного кода без письменного разрешения, с учётом исключений в её тексте. Сторонние компоненты сохраняют свои лицензии.</p></details>
|
||||
<details><summary>Можно изменять расширение и публиковать свои версии?<span aria-hidden="true">+</span></summary><p><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/src/branch/main/LICENSE">Лицензия Source Available</a> разрешает просмотр исходников, сборку неизменённой версии и использование по назначению и запрещает изменения, самостоятельные форки и распространение собственного кода без письменного разрешения, с учётом исключений в её тексте. Сторонние компоненты сохраняют свои лицензии.</p></details>
|
||||
</div></div></section>
|
||||
<section class="closing"><div class="wrap"><img src="assets/mark.svg" alt="" width="48" height="48"><h2>Видео. Звук.<br><span>Ваш выбор.</span></h2><a class="button primary" href="#install">Скачать YouTubeDL <span aria-hidden="true">↓</span></a></div></section>
|
||||
</main>
|
||||
<footer class="site-footer"><div class="wrap footer-top"><a class="brand" href="#"><img src="assets/mark.svg" alt="" width="28" height="28"><span>YouTubeDL</span></a><div><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL">Исходники ↗</a><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/src/branch/main/PRIVACY.md">Данные</a><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/src/branch/main/LICENSE">Лицензия</a><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/src/branch/main/THIRD_PARTY.md">Компоненты</a><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/issues">Поддержка</a></div></div><div class="wrap footer-bottom"><p>© 2026 DepressedCat. YouTubeDL распространяется по ограниченной пользовательской лицензии.</p><p>Независимый проект. Не связан с YouTube/Google, NVIDIA или AMD. Сохраняйте контент, который вы вправе скачивать.</p><p>На сайте нет счётчиков и собственных cookies. Хостинг — собственный сервер проекта.</p></div></footer>
|
||||
<footer class="site-footer"><div class="wrap footer-top"><a class="brand" href="#"><img src="assets/mark.svg" alt="" width="28" height="28"><span>YouTubeDL</span></a><div><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL">Исходники ↗</a><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/src/branch/main/PRIVACY.md">Данные</a><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/src/branch/main/LICENSE">Лицензия</a><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/src/branch/main/THIRD_PARTY.md">Компоненты</a><a href="https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/issues">Поддержка</a></div></div><div class="wrap footer-bottom"><p>© 2026 DepressedCat. YouTubeDL распространяется по лицензии Source Available.</p><p>Независимый проект. Не связан с YouTube/Google, NVIDIA или AMD. Сохраняйте контент, который вы вправе скачивать.</p><p>На сайте нет счётчиков и собственных cookies. Хостинг — собственный сервер проекта.</p></div></footer>
|
||||
<div id="copy-status" class="copy-status" role="status" aria-live="polite" hidden></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -55,19 +55,19 @@ test("brief missing speed samples do not flicker, expire and reset between track
|
||||
assert.equal(stabilizeDownloadSpeed({ ...sample, stage: "merging", speed: "8x" }, previous, 1200).speedUpdatedAt, null);
|
||||
});
|
||||
test("helper compatibility detects outdated, newer and unidentifiable versions in both directions", () => {
|
||||
assert.equal(checkHelperCompatibility({ version: "1.3.2" }, "1.4.5").compatible, true);
|
||||
assert.equal(checkHelperCompatibility({ bundle: { version: "1.3.2" } }, "1.4.5").compatible, true);
|
||||
assert.equal(checkHelperCompatibility({ version: "1.3.2.0" }, "1.4.5").compatible, true);
|
||||
assert.equal(checkHelperCompatibility({ version: "1.3.3" }, "1.4.5").compatible, true);
|
||||
assert.equal(checkHelperCompatibility({ bundle: { version: "1.3.3" } }, "1.4.5").compatible, true);
|
||||
assert.equal(checkHelperCompatibility({ version: "1.3.3.0" }, "1.4.5").compatible, true);
|
||||
for (const version of ["1.3.0", "1.2.10", undefined, "unknown"]) {
|
||||
const result = checkHelperCompatibility({ version }, "1.4.5");
|
||||
assert.equal(result.compatible, false);
|
||||
assert.equal(result.update, "helper");
|
||||
}
|
||||
for (const version of ["1.3.3", "1.3.20", "2.0.0"]) {
|
||||
for (const version of ["1.3.4", "1.3.30", "2.0.0"]) {
|
||||
const result = checkHelperCompatibility({ version }, "1.4.5");
|
||||
assert.equal(result.compatible, false);
|
||||
assert.equal(result.update, "extension");
|
||||
}
|
||||
assert.equal(checkHelperCompatibility({ version: "1.3.2" }, "1.4.2").update, "extension");
|
||||
assert.equal(checkHelperCompatibility({ version: "1.3.2", minimumExtensionVersion: "1.4.6" }, "1.4.5").update, "extension");
|
||||
assert.equal(checkHelperCompatibility({ version: "1.3.3" }, "1.4.2").update, "extension");
|
||||
assert.equal(checkHelperCompatibility({ version: "1.3.3", minimumExtensionVersion: "1.4.7" }, "1.4.5").update, "extension");
|
||||
});
|
||||
@@ -16,7 +16,7 @@ test("history connects without a helper, opens a tab, and retains failures befor
|
||||
return { onMessage: { addListener: listener => { receive = listener; } }, onDisconnect: noEvent, disconnect() {},
|
||||
postMessage(message) {
|
||||
nativeRequests.push(message);
|
||||
queueMicrotask(() => receive({ id: message.id, ok: message.action !== "inspect", result: message.action === "hello" ? { version: "1.3.2" } : { alive: true }, error: "Видео недоступно" }));
|
||||
queueMicrotask(() => receive({ id: message.id, ok: message.action !== "inspect", result: message.action === "hello" ? { version: "1.3.3" } : { alive: true }, error: "Видео недоступно" }));
|
||||
} };
|
||||
} };
|
||||
globalThis.chrome = { runtime, storage: { local: { get: async () => structuredClone(storage), set: async data => Object.assign(storage, structuredClone(data)) } },
|
||||
|
||||
@@ -4,7 +4,7 @@ import assert from "node:assert/strict";
|
||||
test("native lifecycle recovers stale ports and publishes install/remove/update state to all menus", async () => {
|
||||
const ports = [], listeners = {}, storage = {}, pending = new Map(), updates = [];
|
||||
let installed = false;
|
||||
let helperVersion = "1.3.2";
|
||||
let helperVersion = "1.3.3";
|
||||
let componentsReady = true;
|
||||
const noEvent = { addListener() {} };
|
||||
const runtime = { id: "test-id", getManifest: () => ({ version: "1.4.5" }), getURL: name => `chrome-extension://test-id/${name}`,
|
||||
@@ -94,7 +94,7 @@ test("native lifecycle recovers stale ports and publishes install/remove/update
|
||||
await new Promise(resolve => setTimeout(resolve, 20));
|
||||
assert.equal((await call("state")).result.helper.hardware.ready, true, "Restoring a component refreshes readiness without reload");
|
||||
assert.ok(fresh.sent.some(message => message.action === "helper_uninstall"));
|
||||
for (const [version, update] of [["1.3.0", "helper"], ["1.3.3", "extension"]]) {
|
||||
for (const [version, update] of [["1.3.0", "helper"], ["1.3.4", "extension"]]) {
|
||||
helperVersion = version;
|
||||
ports.at(-1).disconnect();
|
||||
await new Promise(resolve => setImmediate(resolve));
|
||||
@@ -107,6 +107,6 @@ test("native lifecycle recovers stale ports and publishes install/remove/update
|
||||
assert.equal((await call("download", { url: "https://youtu.be/jNQXAC9IVRw" })).ok, false, 'Incompatible versions cannot launch a download');
|
||||
assert.ok(!port.sent.some(message => message.action === "download"));
|
||||
}
|
||||
helperVersion = "1.3.2";
|
||||
helperVersion = "1.3.3";
|
||||
assert.equal((await call("helper_status")).result.status, "running", 'Version repair is detected by the Check button without reloading');
|
||||
});
|
||||
@@ -38,7 +38,7 @@ test("background passes fresh YouTube cookies to both worker actions and never p
|
||||
onMessage: { addListener(listener) { nativeListener = listener; } }, onDisconnect: noEvent, disconnect() {},
|
||||
postMessage(message) {
|
||||
requests.push(message);
|
||||
const result = message.action === "hello" ? { version: "1.3.2", ready: true, supportsBrowserCookies: true } : message.action === "ping" ? { alive: true }
|
||||
const result = message.action === "hello" ? { version: "1.3.3", ready: true, supportsBrowserCookies: true } : message.action === "ping" ? { alive: true }
|
||||
: message.action === "download" ? { jobId: "auth-test-job" } : { title: "Synthetic video", videos: [], audios: [] };
|
||||
queueMicrotask(() => nativeListener({ id: message.id, ok: true, result }));
|
||||
},
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ try {
|
||||
assert.equal(new URL(page.url()).hash,"#install");
|
||||
assert.ok(await page.locator(".download-grid").isVisible());
|
||||
assert.equal(await page.locator('[data-download="extension"]').getAttribute("href"),`https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/download/v${version}/YouTubeDL-${version}.zip`);
|
||||
assert.equal(await page.locator('[data-download="helper"]').getAttribute("href"),"https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/download/v1.4.6/YouTubeDL-Helper-Setup.exe");
|
||||
assert.equal(await page.locator('[data-download="helper"]').getAttribute("href"),"https://git.lonarpgproxy.space/DepressedCat/YouTubeDL/releases/download/v1.4.7/YouTubeDL-Helper-Setup.exe");
|
||||
await page.locator('[data-screenshot="light"]').click();
|
||||
await page.locator("#menu-screenshot").evaluate(image => image.decode());
|
||||
assert.match(await page.locator("#menu-screenshot").getAttribute("src"), /menu-light\.png$/);
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import json
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import patch
|
||||
|
||||
from host.python_packages import validate_metadata
|
||||
from host.updates import resolve_packages
|
||||
|
||||
|
||||
class PythonPackageLicenseTests(unittest.TestCase):
|
||||
def test_permissive_and_weak_copyleft_metadata_is_accepted(self):
|
||||
validate_metadata([{"name": "yt-dlp", "license_expression": "Unlicense"},
|
||||
{"name": "certifi", "license_expression": "MPL-2.0"},
|
||||
{"name": "library", "license_expression": "MIT"},
|
||||
{"name": "library", "license_expression": "LGPL-2.1-or-later"}])
|
||||
|
||||
def test_strong_copyleft_is_rejected_using_expression_or_classifiers(self):
|
||||
for metadata in [{"name": "mutagen"},
|
||||
{"name": "dependency", "license_expression": "GPL-3.0-or-later"},
|
||||
{"name": "dependency", "license_expression": "AGPL-3.0-only"},
|
||||
{"name": "dependency", "classifier": ["License :: OSI Approved :: GNU General Public License v2 (GPLv2)"]}]:
|
||||
with self.subTest(metadata=metadata), self.assertRaises(ValueError):
|
||||
validate_metadata([metadata])
|
||||
|
||||
def test_incompatible_resolution_does_not_delete_the_existing_packages(self):
|
||||
with tempfile.TemporaryDirectory() as temporary:
|
||||
stage = Path(temporary) / "stage"
|
||||
packages = stage / "runtime/python/Lib/site-packages"
|
||||
packages.mkdir(parents=True)
|
||||
sentinel = packages / "existing.py"
|
||||
sentinel.write_text("original package", encoding="utf8")
|
||||
work = Path(temporary) / "work"
|
||||
work.mkdir()
|
||||
|
||||
def resolve(command, **kwargs):
|
||||
report = Path(command[command.index("--report") + 1])
|
||||
report.write_text(json.dumps({"install": [{"metadata": {
|
||||
"name": "mutagen", "license_expression": "GPL-2.0-or-later"}}]}), encoding="utf8")
|
||||
self.assertNotIn("yt-dlp[default]", command)
|
||||
return SimpleNamespace(returncode=0)
|
||||
|
||||
response = {"urls": [{"filename": "pip-1-py3-none-any.whl", "url": "https://files.pythonhosted.org/pip.whl", "digests": {"sha256": "a" * 64}}]}
|
||||
with patch("host.updates.get", return_value=SimpleNamespace(json=lambda: response)), \
|
||||
patch("host.updates.fetch"), patch("host.updates.subprocess.run", side_effect=resolve):
|
||||
with self.assertRaisesRegex(ValueError, "mutagen"):
|
||||
resolve_packages(stage, work, lambda *args: None)
|
||||
self.assertEqual(sentinel.read_text(), "original package")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+2
-2
@@ -18,7 +18,7 @@
|
||||
window.__contentMessage = message => contentListeners.forEach(listener => listener(message));
|
||||
let autoUpdate = true;
|
||||
window.__updateRequests = [];
|
||||
const hardware = () => ({ version: window.__helperVersion || "1.3.2", bundle: { mode: "autonomous", version: window.__helperVersion || "1.3.2", updateTogether: true }, supportsComponentUpdates: true, supportsWorkFolder: true, updateSettings: { enabled: autoUpdate },
|
||||
const hardware = () => ({ version: window.__helperVersion || "1.3.3", bundle: { mode: "autonomous", version: window.__helperVersion || "1.3.3", updateTogether: true }, supportsComponentUpdates: true, supportsWorkFolder: true, updateSettings: { enabled: autoUpdate },
|
||||
gpu: window.__amdOnly ? "AMD Radeon RX 7900 XTX" : "NVIDIA GeForce RTX 5080", nvenc: window.__dependencyMissing || window.__amdOnly ? [] : ["h264", "hevc", "av1"],
|
||||
amf: window.__amdOnly ? ["h264", "hevc", "av1"] : [], amf10bit: window.__amdOnly ? ["hevc", "av1"] : [], defaultFolder: "D:\\Videos", ready: !window.__dependencyMissing,
|
||||
dependencies: ["python", "yt_dlp", "ejs", "node", "ffmpeg"].map(id => ({ id, status: window.__dependencyMissing && id === "ffmpeg" ? "missing" : "installed", version: "test-version" })) });
|
||||
@@ -31,7 +31,7 @@
|
||||
], audios: [{ id: "251", codec: "opus", extension: "webm", bitrate: 160, language: "en", note: "English", size: 5000000 }] };
|
||||
window.chrome = {
|
||||
runtime: {
|
||||
getManifest: () => ({ version: window.__extensionVersion || "1.4.6" }),
|
||||
getManifest: () => ({ version: window.__extensionVersion || "1.4.7" }),
|
||||
getURL: file => `https://ui.ytdl.test/${file}`,
|
||||
sendMessage: async message => {
|
||||
if (message.type === "QUICK_DOWNLOAD") { window.__quickRequests.push(message.url); return { ok: true, jobId: "fixture-job" }; }
|
||||
|
||||
@@ -20,8 +20,8 @@ try {
|
||||
page.on("pageerror", error => errors.push(error.message));
|
||||
await page.goto("https://ui.ytdl.test/downloader.html?theme=dark&url=https://www.youtube.com/watch?v=aircAruvnKk");
|
||||
await page.locator('#helper-panel[data-state="incompatible"]').waitFor();
|
||||
assert.match(await page.locator('#helper-message').textContent(), /1\.3\.0.*1\.4\.6/);
|
||||
assert.match(await page.locator('#helper-versions').textContent(), /Расширение 1\.4\.6.*Помощник 1\.3\.0/);
|
||||
assert.match(await page.locator('#helper-message').textContent(), /1\.3\.0.*1\.4\.7/);
|
||||
assert.match(await page.locator('#helper-versions').textContent(), /Расширение 1\.4\.7.*Помощник 1\.3\.0/);
|
||||
assert.equal(await page.locator('#helper-install').textContent(), 'Обновить помощник');
|
||||
assert.equal(await page.locator('#download').isDisabled(), true);
|
||||
assert.equal(await page.locator('#download-form').isVisible(), false);
|
||||
@@ -30,13 +30,13 @@ try {
|
||||
await page.locator('#setup-helper[data-state="incompatible"]').waitFor();
|
||||
assert.equal(await page.locator('#setup-next').isDisabled(), true);
|
||||
assert.equal(await page.locator('#setup-install').textContent(), 'Обновить помощник');
|
||||
assert.match(await page.locator('#setup-versions').textContent(), /1\.4\.6.*1\.3\.0/);
|
||||
await page.evaluate(() => { window.__helperVersion = '1.3.2'; });
|
||||
assert.match(await page.locator('#setup-versions').textContent(), /1\.4\.7.*1\.3\.0/);
|
||||
await page.evaluate(() => { window.__helperVersion = '1.3.3'; });
|
||||
await page.locator('#setup-check').click();
|
||||
await page.locator('#setup-helper[data-state="running"]').waitFor();
|
||||
assert.match(await page.locator('#setup-versions').textContent(), /Версии совместимы/);
|
||||
await page.locator('#setup-next:not([disabled])').waitFor();
|
||||
await page.evaluate(() => { window.__helperVersion = '1.3.3'; });
|
||||
await page.evaluate(() => { window.__helperVersion = '1.3.4'; });
|
||||
await page.locator('#setup-check').click();
|
||||
await page.locator('#setup-helper[data-state="incompatible"]').waitFor();
|
||||
assert.equal(await page.locator('#setup-next').isDisabled(), true);
|
||||
@@ -44,9 +44,9 @@ try {
|
||||
assert.equal(await page.locator('#setup-install-steps').isVisible(), false);
|
||||
await page.locator('#setup-close').click();
|
||||
assert.equal(await page.locator('#helper-install').textContent(), 'Обновить расширение');
|
||||
assert.match(await page.locator('#helper-message').textContent(), /Помощник 1\.3\.3.*расширением 1\.4\.6/);
|
||||
assert.match(await page.locator('#helper-message').textContent(), /Помощник 1\.3\.4.*расширением 1\.4\.7/);
|
||||
assert.equal(await page.locator('#download').isDisabled(), true);
|
||||
await page.evaluate(() => { window.__helperVersion = '1.3.2'; });
|
||||
await page.evaluate(() => { window.__helperVersion = '1.3.3'; });
|
||||
await page.locator('#helper-start').click();
|
||||
await page.locator('#helper-panel[data-state="running"]').waitFor();
|
||||
await page.locator('#download:not([disabled])').waitFor();
|
||||
|
||||
@@ -26,6 +26,8 @@ PYTHON_SHA256 = "90b4e5b9898b72d744650524bff92377c367f44bd5fbd09e3148656c080ad90
|
||||
NODE = "v24.21.0"
|
||||
FFMPEG_ARCHIVE = "ffmpeg-master-latest-win64-gpl-shared.zip"
|
||||
FFMPEG_SHA256 = "eb7afd4ecced72ab7d5d6fdd36dbc359173aa2daf6081817f7b678345898838b"
|
||||
sys.path.insert(0, str(ROOT))
|
||||
from host.python_packages import validate_installed
|
||||
|
||||
|
||||
def digest(path):
|
||||
@@ -107,10 +109,11 @@ def prepare():
|
||||
wheels = CACHE / "wheels"; wheels.mkdir(exist_ok=True)
|
||||
options = ["--platform", "win_amd64", "--python-version", "3.13", "--implementation", "cp",
|
||||
"--abi", "cp313", "--abi", "abi3", "--abi", "none", "--only-binary", ":all:"]
|
||||
requirement = "yt-dlp[default]==2026.8.19"
|
||||
subprocess.run([sys.executable, "-m", "pip", "download", "--disable-pip-version-check", "-d", str(wheels), *options, requirement], check=True)
|
||||
requirements = ["yt-dlp==2026.8.19", "yt-dlp-ejs==0.8.0", "brotli==1.2.0", "certifi==2026.7.22", "pycryptodomex==3.24.0", "requests==2.34.2", "urllib3==2.8.0", "websockets==17.2", "charset-normalizer==3.5.2", "idna==3.20"]
|
||||
subprocess.run([sys.executable, "-m", "pip", "download", "--disable-pip-version-check", "-d", str(wheels), *options, *requirements], check=True)
|
||||
subprocess.run([sys.executable, "-m", "pip", "install", "--disable-pip-version-check", "--no-index", "--find-links", str(wheels),
|
||||
"--target", str(python / "Lib" / "site-packages"), "--no-compile", "--ignore-requires-python", *options, requirement], check=True)
|
||||
"--target", str(python / "Lib" / "site-packages"), "--no-compile", "--ignore-requires-python", *options, *requirements], check=True)
|
||||
validate_installed(python / "Lib/site-packages")
|
||||
(licenses / "THIRD-PARTY.txt").write_text(
|
||||
"Python: https://www.python.org/ ; license: runtime/python/LICENSE.txt\n"
|
||||
"Node.js: https://nodejs.org/ ; license: Node-LICENSE.txt\n"
|
||||
@@ -130,6 +133,8 @@ def build():
|
||||
# pip's generated EXE launchers refer to the build interpreter. The helper
|
||||
# imports these libraries directly, so no console launchers are shipped.
|
||||
shutil.rmtree(scripts)
|
||||
validate_installed(KIT / "runtime/python/Lib/site-packages")
|
||||
shutil.copy2(ROOT / "LICENSE", KIT / "LICENSE")
|
||||
shutil.copytree(ROOT / "host", KIT / "host", dirs_exist_ok=True, ignore=shutil.ignore_patterns("__pycache__", "*.pyc"))
|
||||
sys.path.insert(0, str(ROOT))
|
||||
from host.common import VERSION
|
||||
|
||||
Reference in new issue
Block a user