mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-10-04 00:01:24 +02:00
Compare commits
No commits in common. "cd0443fb14e2ed805abb02792473457553a123d1" and "882e3b753c79c7799ce135c3a5edb72494b576af" have entirely different histories.
cd0443fb14
...
882e3b753c
104
.github/workflows/build.yml
vendored
104
.github/workflows/build.yml
vendored
|
@ -107,10 +107,10 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.10"
|
||||||
- uses: conda-incubator/setup-miniconda@v3
|
- uses: conda-incubator/setup-miniconda@v2
|
||||||
with:
|
with:
|
||||||
miniforge-variant: Mambaforge
|
miniforge-variant: Mambaforge
|
||||||
use-mamba: true
|
use-mamba: true
|
||||||
|
@ -121,14 +121,16 @@ jobs:
|
||||||
- name: Install Requirements
|
- name: Install Requirements
|
||||||
run: |
|
run: |
|
||||||
sudo apt -y install zip pandoc man sed
|
sudo apt -y install zip pandoc man sed
|
||||||
cat > ./requirements.txt << EOF
|
reqs=$(mktemp)
|
||||||
|
cat > "$reqs" << EOF
|
||||||
python=3.10.*
|
python=3.10.*
|
||||||
|
pyinstaller
|
||||||
|
cffi
|
||||||
brotli-python
|
brotli-python
|
||||||
|
secretstorage
|
||||||
EOF
|
EOF
|
||||||
python devscripts/install_deps.py --print \
|
sed -E '/^(brotli|secretstorage).*/d' requirements.txt >> "$reqs"
|
||||||
--exclude brotli --exclude brotlicffi \
|
mamba create -n build --file "$reqs"
|
||||||
--include secretstorage --include pyinstaller >> ./requirements.txt
|
|
||||||
mamba create -n build --file ./requirements.txt
|
|
||||||
|
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
|
@ -142,9 +144,9 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
unset LD_LIBRARY_PATH # Harmful; set by setup-python
|
unset LD_LIBRARY_PATH # Harmful; set by setup-python
|
||||||
conda activate build
|
conda activate build
|
||||||
python -m bundle.pyinstaller --onedir
|
python pyinst.py --onedir
|
||||||
(cd ./dist/yt-dlp_linux && zip -r ../yt-dlp_linux.zip .)
|
(cd ./dist/yt-dlp_linux && zip -r ../yt-dlp_linux.zip .)
|
||||||
python -m bundle.pyinstaller
|
python pyinst.py
|
||||||
mv ./dist/yt-dlp_linux ./yt-dlp_linux
|
mv ./dist/yt-dlp_linux ./yt-dlp_linux
|
||||||
mv ./dist/yt-dlp_linux.zip ./yt-dlp_linux.zip
|
mv ./dist/yt-dlp_linux.zip ./yt-dlp_linux.zip
|
||||||
|
|
||||||
|
@ -162,15 +164,13 @@ jobs:
|
||||||
done
|
done
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: build-${{ github.job }}
|
|
||||||
path: |
|
path: |
|
||||||
yt-dlp
|
yt-dlp
|
||||||
yt-dlp.tar.gz
|
yt-dlp.tar.gz
|
||||||
yt-dlp_linux
|
yt-dlp_linux
|
||||||
yt-dlp_linux.zip
|
yt-dlp_linux.zip
|
||||||
compression-level: 0
|
|
||||||
|
|
||||||
linux_arm:
|
linux_arm:
|
||||||
needs: process
|
needs: process
|
||||||
|
@ -201,18 +201,17 @@ jobs:
|
||||||
dockerRunArgs: --volume "${PWD}/repo:/repo"
|
dockerRunArgs: --volume "${PWD}/repo:/repo"
|
||||||
install: | # Installing Python 3.10 from the Deadsnakes repo raises errors
|
install: | # Installing Python 3.10 from the Deadsnakes repo raises errors
|
||||||
apt update
|
apt update
|
||||||
apt -y install zlib1g-dev libffi-dev python3.8 python3.8-dev python3.8-distutils python3-pip
|
apt -y install zlib1g-dev python3.8 python3.8-dev python3.8-distutils python3-pip
|
||||||
python3.8 -m pip install -U pip setuptools wheel
|
python3.8 -m pip install -U pip setuptools wheel
|
||||||
# Cannot access any files from the repo directory at this stage
|
# Cannot access requirements.txt from the repo directory at this stage
|
||||||
python3.8 -m pip install -U Pyinstaller mutagen pycryptodomex websockets brotli certifi secretstorage cffi
|
python3.8 -m pip install -U Pyinstaller mutagen pycryptodomex websockets brotli certifi secretstorage
|
||||||
|
|
||||||
run: |
|
run: |
|
||||||
cd repo
|
cd repo
|
||||||
python3.8 devscripts/install_deps.py -o --include build
|
python3.8 -m pip install -U Pyinstaller secretstorage -r requirements.txt # Cached version may be out of date
|
||||||
python3.8 devscripts/install_deps.py --include pyinstaller --include secretstorage # Cached version may be out of date
|
|
||||||
python3.8 devscripts/update-version.py -c "${{ inputs.channel }}" -r "${{ needs.process.outputs.origin }}" "${{ inputs.version }}"
|
python3.8 devscripts/update-version.py -c "${{ inputs.channel }}" -r "${{ needs.process.outputs.origin }}" "${{ inputs.version }}"
|
||||||
python3.8 devscripts/make_lazy_extractors.py
|
python3.8 devscripts/make_lazy_extractors.py
|
||||||
python3.8 -m bundle.pyinstaller
|
python3.8 pyinst.py
|
||||||
|
|
||||||
if ${{ vars.UPDATE_TO_VERIFICATION && 'true' || 'false' }}; then
|
if ${{ vars.UPDATE_TO_VERIFICATION && 'true' || 'false' }}; then
|
||||||
arch="${{ (matrix.architecture == 'armv7' && 'armv7l') || matrix.architecture }}"
|
arch="${{ (matrix.architecture == 'armv7' && 'armv7l') || matrix.architecture }}"
|
||||||
|
@ -225,12 +224,10 @@ jobs:
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: build-linux_${{ matrix.architecture }}
|
|
||||||
path: | # run-on-arch-action designates armv7l as armv7
|
path: | # run-on-arch-action designates armv7l as armv7
|
||||||
repo/dist/yt-dlp_linux_${{ (matrix.architecture == 'armv7' && 'armv7l') || matrix.architecture }}
|
repo/dist/yt-dlp_linux_${{ (matrix.architecture == 'armv7' && 'armv7l') || matrix.architecture }}
|
||||||
compression-level: 0
|
|
||||||
|
|
||||||
macos:
|
macos:
|
||||||
needs: process
|
needs: process
|
||||||
|
@ -243,10 +240,9 @@ jobs:
|
||||||
- name: Install Requirements
|
- name: Install Requirements
|
||||||
run: |
|
run: |
|
||||||
brew install coreutils
|
brew install coreutils
|
||||||
python3 devscripts/install_deps.py --user -o --include build
|
python3 -m pip install -U --user pip setuptools wheel
|
||||||
python3 devscripts/install_deps.py --print --include pyinstaller > requirements.txt
|
|
||||||
# We need to ignore wheels otherwise we break universal2 builds
|
# We need to ignore wheels otherwise we break universal2 builds
|
||||||
python3 -m pip install -U --user --no-binary :all: -r requirements.txt
|
python3 -m pip install -U --user --no-binary :all: Pyinstaller -r requirements.txt
|
||||||
|
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
|
@ -254,9 +250,9 @@ jobs:
|
||||||
python3 devscripts/make_lazy_extractors.py
|
python3 devscripts/make_lazy_extractors.py
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
python3 -m bundle.pyinstaller --target-architecture universal2 --onedir
|
python3 pyinst.py --target-architecture universal2 --onedir
|
||||||
(cd ./dist/yt-dlp_macos && zip -r ../yt-dlp_macos.zip .)
|
(cd ./dist/yt-dlp_macos && zip -r ../yt-dlp_macos.zip .)
|
||||||
python3 -m bundle.pyinstaller --target-architecture universal2
|
python3 pyinst.py --target-architecture universal2
|
||||||
|
|
||||||
- name: Verify --update-to
|
- name: Verify --update-to
|
||||||
if: vars.UPDATE_TO_VERIFICATION
|
if: vars.UPDATE_TO_VERIFICATION
|
||||||
|
@ -269,13 +265,11 @@ jobs:
|
||||||
[[ "$version" != "$downgraded_version" ]]
|
[[ "$version" != "$downgraded_version" ]]
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: build-${{ github.job }}
|
|
||||||
path: |
|
path: |
|
||||||
dist/yt-dlp_macos
|
dist/yt-dlp_macos
|
||||||
dist/yt-dlp_macos.zip
|
dist/yt-dlp_macos.zip
|
||||||
compression-level: 0
|
|
||||||
|
|
||||||
macos_legacy:
|
macos_legacy:
|
||||||
needs: process
|
needs: process
|
||||||
|
@ -299,8 +293,8 @@ jobs:
|
||||||
- name: Install Requirements
|
- name: Install Requirements
|
||||||
run: |
|
run: |
|
||||||
brew install coreutils
|
brew install coreutils
|
||||||
python3 devscripts/install_deps.py --user -o --include build
|
python3 -m pip install -U --user pip setuptools wheel
|
||||||
python3 devscripts/install_deps.py --user --include pyinstaller
|
python3 -m pip install -U --user Pyinstaller -r requirements.txt
|
||||||
|
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
|
@ -308,7 +302,7 @@ jobs:
|
||||||
python3 devscripts/make_lazy_extractors.py
|
python3 devscripts/make_lazy_extractors.py
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
python3 -m bundle.pyinstaller
|
python3 pyinst.py
|
||||||
mv dist/yt-dlp_macos dist/yt-dlp_macos_legacy
|
mv dist/yt-dlp_macos dist/yt-dlp_macos_legacy
|
||||||
|
|
||||||
- name: Verify --update-to
|
- name: Verify --update-to
|
||||||
|
@ -322,12 +316,10 @@ jobs:
|
||||||
[[ "$version" != "$downgraded_version" ]]
|
[[ "$version" != "$downgraded_version" ]]
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: build-${{ github.job }}
|
|
||||||
path: |
|
path: |
|
||||||
dist/yt-dlp_macos_legacy
|
dist/yt-dlp_macos_legacy
|
||||||
compression-level: 0
|
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
needs: process
|
needs: process
|
||||||
|
@ -336,14 +328,13 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v4
|
||||||
with: # 3.8 is used for Win7 support
|
with: # 3.8 is used for Win7 support
|
||||||
python-version: "3.8"
|
python-version: "3.8"
|
||||||
- name: Install Requirements
|
- name: Install Requirements
|
||||||
run: | # Custom pyinstaller built with https://github.com/yt-dlp/pyinstaller-builds
|
run: | # Custom pyinstaller built with https://github.com/yt-dlp/pyinstaller-builds
|
||||||
python devscripts/install_deps.py -o --include build
|
python -m pip install -U pip setuptools wheel py2exe
|
||||||
python devscripts/install_deps.py --include py2exe
|
pip install -U "https://yt-dlp.github.io/Pyinstaller-Builds/x86_64/pyinstaller-5.8.0-py3-none-any.whl" -r requirements.txt
|
||||||
python -m pip install -U "https://yt-dlp.github.io/Pyinstaller-Builds/x86_64/pyinstaller-5.8.0-py3-none-any.whl"
|
|
||||||
|
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
|
@ -351,10 +342,10 @@ jobs:
|
||||||
python devscripts/make_lazy_extractors.py
|
python devscripts/make_lazy_extractors.py
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
python -m bundle.py2exe
|
python setup.py py2exe
|
||||||
Move-Item ./dist/yt-dlp.exe ./dist/yt-dlp_min.exe
|
Move-Item ./dist/yt-dlp.exe ./dist/yt-dlp_min.exe
|
||||||
python -m bundle.pyinstaller
|
python pyinst.py
|
||||||
python -m bundle.pyinstaller --onedir
|
python pyinst.py --onedir
|
||||||
Compress-Archive -Path ./dist/yt-dlp/* -DestinationPath ./dist/yt-dlp_win.zip
|
Compress-Archive -Path ./dist/yt-dlp/* -DestinationPath ./dist/yt-dlp_win.zip
|
||||||
|
|
||||||
- name: Verify --update-to
|
- name: Verify --update-to
|
||||||
|
@ -371,14 +362,12 @@ jobs:
|
||||||
}
|
}
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: build-${{ github.job }}
|
|
||||||
path: |
|
path: |
|
||||||
dist/yt-dlp.exe
|
dist/yt-dlp.exe
|
||||||
dist/yt-dlp_min.exe
|
dist/yt-dlp_min.exe
|
||||||
dist/yt-dlp_win.zip
|
dist/yt-dlp_win.zip
|
||||||
compression-level: 0
|
|
||||||
|
|
||||||
windows32:
|
windows32:
|
||||||
needs: process
|
needs: process
|
||||||
|
@ -387,15 +376,14 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.8"
|
python-version: "3.8"
|
||||||
architecture: "x86"
|
architecture: "x86"
|
||||||
- name: Install Requirements
|
- name: Install Requirements
|
||||||
run: |
|
run: |
|
||||||
python devscripts/install_deps.py -o --include build
|
python -m pip install -U pip setuptools wheel
|
||||||
python devscripts/install_deps.py
|
pip install -U "https://yt-dlp.github.io/Pyinstaller-Builds/i686/pyinstaller-5.8.0-py3-none-any.whl" -r requirements.txt
|
||||||
python -m pip install -U "https://yt-dlp.github.io/Pyinstaller-Builds/i686/pyinstaller-5.8.0-py3-none-any.whl"
|
|
||||||
|
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
|
@ -403,7 +391,7 @@ jobs:
|
||||||
python devscripts/make_lazy_extractors.py
|
python devscripts/make_lazy_extractors.py
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
python -m bundle.pyinstaller
|
python pyinst.py
|
||||||
|
|
||||||
- name: Verify --update-to
|
- name: Verify --update-to
|
||||||
if: vars.UPDATE_TO_VERIFICATION
|
if: vars.UPDATE_TO_VERIFICATION
|
||||||
|
@ -419,12 +407,10 @@ jobs:
|
||||||
}
|
}
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: build-${{ github.job }}
|
|
||||||
path: |
|
path: |
|
||||||
dist/yt-dlp_x86.exe
|
dist/yt-dlp_x86.exe
|
||||||
compression-level: 0
|
|
||||||
|
|
||||||
meta_files:
|
meta_files:
|
||||||
if: inputs.meta_files && always() && !cancelled()
|
if: inputs.meta_files && always() && !cancelled()
|
||||||
|
@ -438,11 +424,7 @@ jobs:
|
||||||
- windows32
|
- windows32
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
|
||||||
path: artifact
|
|
||||||
pattern: build-*
|
|
||||||
merge-multiple: true
|
|
||||||
|
|
||||||
- name: Make SHA2-SUMS files
|
- name: Make SHA2-SUMS files
|
||||||
run: |
|
run: |
|
||||||
|
@ -477,10 +459,8 @@ jobs:
|
||||||
done
|
done
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: build-${{ github.job }}
|
|
||||||
path: |
|
path: |
|
||||||
_update_spec
|
|
||||||
SHA*SUMS*
|
SHA*SUMS*
|
||||||
compression-level: 0
|
_update_spec
|
||||||
|
|
4
.github/workflows/core.yml
vendored
4
.github/workflows/core.yml
vendored
|
@ -49,11 +49,11 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- name: Install test requirements
|
- name: Install test requirements
|
||||||
run: python3 ./devscripts/install_deps.py --include dev
|
run: pip install pytest -r requirements.txt
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
continue-on-error: False
|
continue-on-error: False
|
||||||
run: |
|
run: |
|
||||||
|
|
8
.github/workflows/download.yml
vendored
8
.github/workflows/download.yml
vendored
|
@ -11,11 +11,11 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: 3.9
|
python-version: 3.9
|
||||||
- name: Install test requirements
|
- name: Install test requirements
|
||||||
run: python3 ./devscripts/install_deps.py --include dev
|
run: pip install pytest -r requirements.txt
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: python3 ./devscripts/run_tests.py download
|
run: python3 ./devscripts/run_tests.py download
|
||||||
|
@ -38,11 +38,11 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- name: Install test requirements
|
- name: Install test requirements
|
||||||
run: python3 ./devscripts/install_deps.py --include dev
|
run: pip install pytest -r requirements.txt
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: python3 ./devscripts/run_tests.py download
|
run: python3 ./devscripts/run_tests.py download
|
||||||
|
|
10
.github/workflows/quick-test.yml
vendored
10
.github/workflows/quick-test.yml
vendored
|
@ -11,11 +11,11 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Set up Python 3.8
|
- name: Set up Python 3.8
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: '3.8'
|
python-version: '3.8'
|
||||||
- name: Install test requirements
|
- name: Install test requirements
|
||||||
run: python3 ./devscripts/install_deps.py --include dev
|
run: pip install pytest -r requirements.txt
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: |
|
run: |
|
||||||
python3 -m yt_dlp -v || true
|
python3 -m yt_dlp -v || true
|
||||||
|
@ -26,10 +26,10 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v4
|
||||||
- name: Install flake8
|
- name: Install flake8
|
||||||
run: python3 ./devscripts/install_deps.py -o --include dev
|
run: pip install flake8
|
||||||
- name: Make lazy extractors
|
- name: Make lazy extractors
|
||||||
run: python3 ./devscripts/make_lazy_extractors.py
|
run: python devscripts/make_lazy_extractors.py
|
||||||
- name: Run flake8
|
- name: Run flake8
|
||||||
run: flake8 .
|
run: flake8 .
|
||||||
|
|
6
.github/workflows/release-master.yml
vendored
6
.github/workflows/release-master.yml
vendored
|
@ -6,10 +6,8 @@ on:
|
||||||
paths:
|
paths:
|
||||||
- "yt_dlp/**.py"
|
- "yt_dlp/**.py"
|
||||||
- "!yt_dlp/version.py"
|
- "!yt_dlp/version.py"
|
||||||
- "bundle/*.py"
|
- "setup.py"
|
||||||
- "pyproject.toml"
|
- "pyinst.py"
|
||||||
- "Makefile"
|
|
||||||
- ".github/workflows/build.yml"
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: release-master
|
group: release-master
|
||||||
permissions:
|
permissions:
|
||||||
|
|
9
.github/workflows/release-nightly.yml
vendored
9
.github/workflows/release-nightly.yml
vendored
|
@ -18,14 +18,7 @@ jobs:
|
||||||
- name: Check for new commits
|
- name: Check for new commits
|
||||||
id: check_for_new_commits
|
id: check_for_new_commits
|
||||||
run: |
|
run: |
|
||||||
relevant_files=(
|
relevant_files=("yt_dlp/*.py" ':!yt_dlp/version.py' "setup.py" "pyinst.py")
|
||||||
"yt_dlp/*.py"
|
|
||||||
':!yt_dlp/version.py'
|
|
||||||
"bundle/*.py"
|
|
||||||
"pyproject.toml"
|
|
||||||
"Makefile"
|
|
||||||
".github/workflows/build.yml"
|
|
||||||
)
|
|
||||||
echo "commit=$(git log --format=%H -1 --since="24 hours ago" -- "${relevant_files[@]}")" | tee "$GITHUB_OUTPUT"
|
echo "commit=$(git log --format=%H -1 --since="24 hours ago" -- "${relevant_files[@]}")" | tee "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
release:
|
release:
|
||||||
|
|
26
.github/workflows/release.yml
vendored
26
.github/workflows/release.yml
vendored
|
@ -71,7 +71,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.10"
|
||||||
|
|
||||||
|
@ -246,16 +246,15 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
- uses: actions/setup-python@v4
|
||||||
fetch-depth: 0
|
|
||||||
- uses: actions/setup-python@v5
|
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.10"
|
||||||
|
|
||||||
- name: Install Requirements
|
- name: Install Requirements
|
||||||
run: |
|
run: |
|
||||||
sudo apt -y install pandoc man
|
sudo apt -y install pandoc man
|
||||||
python devscripts/install_deps.py -o --include build
|
python -m pip install -U pip setuptools wheel twine
|
||||||
|
python -m pip install -U -r requirements.txt
|
||||||
|
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
env:
|
env:
|
||||||
|
@ -267,19 +266,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
python devscripts/update-version.py -c "${{ env.channel }}" -r "${{ env.target_repo }}" -s "${{ env.suffix }}" "${{ env.version }}"
|
python devscripts/update-version.py -c "${{ env.channel }}" -r "${{ env.target_repo }}" -s "${{ env.suffix }}" "${{ env.version }}"
|
||||||
python devscripts/make_lazy_extractors.py
|
python devscripts/make_lazy_extractors.py
|
||||||
sed -i -E '0,/(name = ")[^"]+(")/s//\1${{ env.pypi_project }}\2/' pyproject.toml
|
sed -i -E "s/(name=')[^']+(', # package name)/\1${{ env.pypi_project }}\2/" setup.py
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
rm -rf dist/*
|
rm -rf dist/*
|
||||||
make pypi-files
|
make pypi-files
|
||||||
printf '%s\n\n' \
|
|
||||||
'Official repository: <https://github.com/yt-dlp/yt-dlp>' \
|
|
||||||
'**PS**: Some links in this document will not work since this is a copy of the README.md from Github' > ./README.md.new
|
|
||||||
cat ./README.md >> ./README.md.new && mv -f ./README.md.new ./README.md
|
|
||||||
python devscripts/set-variant.py pip -M "You installed yt-dlp with pip or using the wheel from PyPi; Use that to update"
|
python devscripts/set-variant.py pip -M "You installed yt-dlp with pip or using the wheel from PyPi; Use that to update"
|
||||||
make clean-cache
|
python setup.py sdist bdist_wheel
|
||||||
python -m build --no-isolation .
|
|
||||||
|
|
||||||
- name: Publish to PyPI
|
- name: Publish to PyPI
|
||||||
uses: pypa/gh-action-pypi-publish@release/v1
|
uses: pypa/gh-action-pypi-publish@release/v1
|
||||||
|
@ -296,12 +290,8 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v3
|
||||||
with:
|
- uses: actions/setup-python@v4
|
||||||
path: artifact
|
|
||||||
pattern: build-*
|
|
||||||
merge-multiple: true
|
|
||||||
- uses: actions/setup-python@v5
|
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.10"
|
||||||
|
|
||||||
|
|
10
MANIFEST.in
Normal file
10
MANIFEST.in
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
include AUTHORS
|
||||||
|
include Changelog.md
|
||||||
|
include LICENSE
|
||||||
|
include README.md
|
||||||
|
include completions/*/*
|
||||||
|
include supportedsites.md
|
||||||
|
include yt-dlp.1
|
||||||
|
include requirements.txt
|
||||||
|
recursive-include devscripts *
|
||||||
|
recursive-include test *
|
38
Makefile
38
Makefile
|
@ -6,11 +6,11 @@ doc: README.md CONTRIBUTING.md issuetemplates supportedsites
|
||||||
ot: offlinetest
|
ot: offlinetest
|
||||||
tar: yt-dlp.tar.gz
|
tar: yt-dlp.tar.gz
|
||||||
|
|
||||||
# Keep this list in sync with pyproject.toml includes/artifacts
|
# Keep this list in sync with MANIFEST.in
|
||||||
# intended use: when building a source distribution,
|
# intended use: when building a source distribution,
|
||||||
# make pypi-files && python3 -m build -sn .
|
# make pypi-files && python setup.py sdist
|
||||||
pypi-files: AUTHORS Changelog.md LICENSE README.md README.txt supportedsites \
|
pypi-files: AUTHORS Changelog.md LICENSE README.md README.txt supportedsites \
|
||||||
completions yt-dlp.1 pyproject.toml setup.cfg devscripts/* test/*
|
completions yt-dlp.1 requirements.txt setup.cfg devscripts/* test/*
|
||||||
|
|
||||||
.PHONY: all clean install test tar pypi-files completions ot offlinetest codetest supportedsites
|
.PHONY: all clean install test tar pypi-files completions ot offlinetest codetest supportedsites
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ clean-test:
|
||||||
*.mp4 *.mpga *.oga *.ogg *.opus *.png *.sbv *.srt *.swf *.swp *.tt *.ttml *.url *.vtt *.wav *.webloc *.webm *.webp
|
*.mp4 *.mpga *.oga *.ogg *.opus *.png *.sbv *.srt *.swf *.swp *.tt *.ttml *.url *.vtt *.wav *.webloc *.webm *.webp
|
||||||
clean-dist:
|
clean-dist:
|
||||||
rm -rf yt-dlp.1.temp.md yt-dlp.1 README.txt MANIFEST build/ dist/ .coverage cover/ yt-dlp.tar.gz completions/ \
|
rm -rf yt-dlp.1.temp.md yt-dlp.1 README.txt MANIFEST build/ dist/ .coverage cover/ yt-dlp.tar.gz completions/ \
|
||||||
yt_dlp/extractor/lazy_extractors.py *.spec CONTRIBUTING.md.tmp yt-dlp yt-dlp.exe yt_dlp.egg-info/ AUTHORS
|
yt_dlp/extractor/lazy_extractors.py *.spec CONTRIBUTING.md.tmp yt-dlp yt-dlp.exe yt_dlp.egg-info/ AUTHORS .mailmap
|
||||||
clean-cache:
|
clean-cache:
|
||||||
find . \( \
|
find . \( \
|
||||||
-type d -name .pytest_cache -o -type d -name __pycache__ -o -name "*.pyc" -o -name "*.class" \
|
-type d -name .pytest_cache -o -type d -name __pycache__ -o -name "*.pyc" -o -name "*.class" \
|
||||||
|
@ -73,24 +73,24 @@ test:
|
||||||
offlinetest: codetest
|
offlinetest: codetest
|
||||||
$(PYTHON) -m pytest -k "not download"
|
$(PYTHON) -m pytest -k "not download"
|
||||||
|
|
||||||
CODE_FOLDERS := $(shell find yt_dlp -type d -not -name '__*' -exec sh -c 'test -e "$$1"/__init__.py' sh {} \; -print)
|
# XXX: This is hard to maintain
|
||||||
CODE_FILES := $(shell for f in $(CODE_FOLDERS); do echo "$$f" | awk '{gsub(/\/[^\/]+/,"/*"); print $$1"/*.py"}'; done | sort -u)
|
CODE_FOLDERS = yt_dlp yt_dlp/downloader yt_dlp/extractor yt_dlp/postprocessor yt_dlp/compat yt_dlp/compat/urllib yt_dlp/utils yt_dlp/dependencies yt_dlp/networking
|
||||||
yt-dlp: $(CODE_FILES)
|
yt-dlp: yt_dlp/*.py yt_dlp/*/*.py
|
||||||
mkdir -p zip
|
mkdir -p zip
|
||||||
for d in $(CODE_FOLDERS) ; do \
|
for d in $(CODE_FOLDERS) ; do \
|
||||||
mkdir -p zip/$$d ;\
|
mkdir -p zip/$$d ;\
|
||||||
cp -pPR $$d/*.py zip/$$d/ ;\
|
cp -pPR $$d/*.py zip/$$d/ ;\
|
||||||
done
|
done
|
||||||
cd zip ; touch -t 200001010101 $(CODE_FILES)
|
touch -t 200001010101 zip/yt_dlp/*.py zip/yt_dlp/*/*.py
|
||||||
mv zip/yt_dlp/__main__.py zip/
|
mv zip/yt_dlp/__main__.py zip/
|
||||||
cd zip ; zip -q ../yt-dlp $(CODE_FILES) __main__.py
|
cd zip ; zip -q ../yt-dlp yt_dlp/*.py yt_dlp/*/*.py __main__.py
|
||||||
rm -rf zip
|
rm -rf zip
|
||||||
echo '#!$(PYTHON)' > yt-dlp
|
echo '#!$(PYTHON)' > yt-dlp
|
||||||
cat yt-dlp.zip >> yt-dlp
|
cat yt-dlp.zip >> yt-dlp
|
||||||
rm yt-dlp.zip
|
rm yt-dlp.zip
|
||||||
chmod a+x yt-dlp
|
chmod a+x yt-dlp
|
||||||
|
|
||||||
README.md: $(CODE_FILES) devscripts/make_readme.py
|
README.md: yt_dlp/*.py yt_dlp/*/*.py devscripts/make_readme.py
|
||||||
COLUMNS=80 $(PYTHON) yt_dlp/__main__.py --ignore-config --help | $(PYTHON) devscripts/make_readme.py
|
COLUMNS=80 $(PYTHON) yt_dlp/__main__.py --ignore-config --help | $(PYTHON) devscripts/make_readme.py
|
||||||
|
|
||||||
CONTRIBUTING.md: README.md devscripts/make_contributing.py
|
CONTRIBUTING.md: README.md devscripts/make_contributing.py
|
||||||
|
@ -115,15 +115,15 @@ yt-dlp.1: README.md devscripts/prepare_manpage.py
|
||||||
pandoc -s -f $(MARKDOWN) -t man yt-dlp.1.temp.md -o yt-dlp.1
|
pandoc -s -f $(MARKDOWN) -t man yt-dlp.1.temp.md -o yt-dlp.1
|
||||||
rm -f yt-dlp.1.temp.md
|
rm -f yt-dlp.1.temp.md
|
||||||
|
|
||||||
completions/bash/yt-dlp: $(CODE_FILES) devscripts/bash-completion.in
|
completions/bash/yt-dlp: yt_dlp/*.py yt_dlp/*/*.py devscripts/bash-completion.in
|
||||||
mkdir -p completions/bash
|
mkdir -p completions/bash
|
||||||
$(PYTHON) devscripts/bash-completion.py
|
$(PYTHON) devscripts/bash-completion.py
|
||||||
|
|
||||||
completions/zsh/_yt-dlp: $(CODE_FILES) devscripts/zsh-completion.in
|
completions/zsh/_yt-dlp: yt_dlp/*.py yt_dlp/*/*.py devscripts/zsh-completion.in
|
||||||
mkdir -p completions/zsh
|
mkdir -p completions/zsh
|
||||||
$(PYTHON) devscripts/zsh-completion.py
|
$(PYTHON) devscripts/zsh-completion.py
|
||||||
|
|
||||||
completions/fish/yt-dlp.fish: $(CODE_FILES) devscripts/fish-completion.in
|
completions/fish/yt-dlp.fish: yt_dlp/*.py yt_dlp/*/*.py devscripts/fish-completion.in
|
||||||
mkdir -p completions/fish
|
mkdir -p completions/fish
|
||||||
$(PYTHON) devscripts/fish-completion.py
|
$(PYTHON) devscripts/fish-completion.py
|
||||||
|
|
||||||
|
@ -144,8 +144,12 @@ yt-dlp.tar.gz: all
|
||||||
-- \
|
-- \
|
||||||
README.md supportedsites.md Changelog.md LICENSE \
|
README.md supportedsites.md Changelog.md LICENSE \
|
||||||
CONTRIBUTING.md Collaborators.md CONTRIBUTORS AUTHORS \
|
CONTRIBUTING.md Collaborators.md CONTRIBUTORS AUTHORS \
|
||||||
Makefile yt-dlp.1 README.txt completions .gitignore \
|
Makefile MANIFEST.in yt-dlp.1 README.txt completions \
|
||||||
setup.cfg yt-dlp yt_dlp pyproject.toml devscripts test
|
setup.py setup.cfg yt-dlp yt_dlp requirements.txt \
|
||||||
|
devscripts test
|
||||||
|
|
||||||
AUTHORS:
|
AUTHORS: .mailmap
|
||||||
git shortlog -s -n HEAD | cut -f2 | sort > AUTHORS
|
git shortlog -s -n | cut -f2 | sort > AUTHORS
|
||||||
|
|
||||||
|
.mailmap:
|
||||||
|
git shortlog -s -e -n | awk '!(out[$$NF]++) { $$1="";sub(/^[ \t]+/,""); print}' > .mailmap
|
||||||
|
|
25
README.md
25
README.md
|
@ -321,21 +321,19 @@ If you do not have the necessary dependencies for a task you are attempting, yt-
|
||||||
## COMPILE
|
## COMPILE
|
||||||
|
|
||||||
### Standalone PyInstaller Builds
|
### Standalone PyInstaller Builds
|
||||||
To build the standalone executable, you must have Python and `pyinstaller` (plus any of yt-dlp's [optional dependencies](#dependencies) if needed). The executable will be built for the same architecture (x86/ARM, 32/64 bit) as the Python used. You can run the following commands:
|
To build the standalone executable, you must have Python and `pyinstaller` (plus any of yt-dlp's [optional dependencies](#dependencies) if needed). Once you have all the necessary dependencies installed, simply run `pyinst.py`. The executable will be built for the same architecture (x86/ARM, 32/64 bit) as the Python used.
|
||||||
|
|
||||||
```
|
python3 -m pip install -U pyinstaller -r requirements.txt
|
||||||
python3 devscripts/install_deps.py --include pyinstaller
|
python3 devscripts/make_lazy_extractors.py
|
||||||
python3 devscripts/make_lazy_extractors.py
|
python3 pyinst.py
|
||||||
python3 -m bundle.pyinstaller
|
|
||||||
```
|
|
||||||
|
|
||||||
On some systems, you may need to use `py` or `python` instead of `python3`.
|
On some systems, you may need to use `py` or `python` instead of `python3`.
|
||||||
|
|
||||||
`bundle/pyinstaller.py` accepts any arguments that can be passed to `pyinstaller`, such as `--onefile/-F` or `--onedir/-D`, which is further [documented here](https://pyinstaller.org/en/stable/usage.html#what-to-generate).
|
`pyinst.py` accepts any arguments that can be passed to `pyinstaller`, such as `--onefile/-F` or `--onedir/-D`, which is further [documented here](https://pyinstaller.org/en/stable/usage.html#what-to-generate).
|
||||||
|
|
||||||
**Note**: Pyinstaller versions below 4.4 [do not support](https://github.com/pyinstaller/pyinstaller#requirements-and-tested-platforms) Python installed from the Windows store without using a virtual environment.
|
**Note**: Pyinstaller versions below 4.4 [do not support](https://github.com/pyinstaller/pyinstaller#requirements-and-tested-platforms) Python installed from the Windows store without using a virtual environment.
|
||||||
|
|
||||||
**Important**: Running `pyinstaller` directly **without** using `bundle/pyinstaller.py` is **not** officially supported. This may or may not work correctly.
|
**Important**: Running `pyinstaller` directly **without** using `pyinst.py` is **not** officially supported. This may or may not work correctly.
|
||||||
|
|
||||||
### Platform-independent Binary (UNIX)
|
### Platform-independent Binary (UNIX)
|
||||||
You will need the build tools `python` (3.8+), `zip`, `make` (GNU), `pandoc`\* and `pytest`\*.
|
You will need the build tools `python` (3.8+), `zip`, `make` (GNU), `pandoc`\* and `pytest`\*.
|
||||||
|
@ -348,17 +346,14 @@ You can also run `make yt-dlp` instead to compile only the binary without updati
|
||||||
|
|
||||||
While we provide the option to build with [py2exe](https://www.py2exe.org), it is recommended to build [using PyInstaller](#standalone-pyinstaller-builds) instead since the py2exe builds **cannot contain `pycryptodomex`/`certifi` and needs VC++14** on the target computer to run.
|
While we provide the option to build with [py2exe](https://www.py2exe.org), it is recommended to build [using PyInstaller](#standalone-pyinstaller-builds) instead since the py2exe builds **cannot contain `pycryptodomex`/`certifi` and needs VC++14** on the target computer to run.
|
||||||
|
|
||||||
If you wish to build it anyway, install Python (if it is not already installed) and you can run the following commands:
|
If you wish to build it anyway, install Python and py2exe, and then simply run `setup.py py2exe`
|
||||||
|
|
||||||
```
|
py -m pip install -U py2exe -r requirements.txt
|
||||||
py devscripts/install_deps.py --include py2exe
|
py devscripts/make_lazy_extractors.py
|
||||||
py devscripts/make_lazy_extractors.py
|
py setup.py py2exe
|
||||||
py -m bundle.py2exe
|
|
||||||
```
|
|
||||||
|
|
||||||
### Related scripts
|
### Related scripts
|
||||||
|
|
||||||
* **`devscripts/install_deps.py`** - Install dependencies for yt-dlp.
|
|
||||||
* **`devscripts/update-version.py`** - Update the version number based on current date.
|
* **`devscripts/update-version.py`** - Update the version number based on current date.
|
||||||
* **`devscripts/set-variant.py`** - Set the build variant of the executable.
|
* **`devscripts/set-variant.py`** - Set the build variant of the executable.
|
||||||
* **`devscripts/make_changelog.py`** - Create a markdown changelog using short commit messages and update `CONTRIBUTORS` file.
|
* **`devscripts/make_changelog.py`** - Create a markdown changelog using short commit messages and update `CONTRIBUTORS` file.
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
# Empty file
|
|
|
@ -1,59 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# Allow execution from anywhere
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
||||||
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
from py2exe import freeze
|
|
||||||
|
|
||||||
from devscripts.utils import read_version
|
|
||||||
|
|
||||||
VERSION = read_version()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
warnings.warn(
|
|
||||||
'py2exe builds do not support pycryptodomex and needs VC++14 to run. '
|
|
||||||
'It is recommended to run "pyinst.py" to build using pyinstaller instead')
|
|
||||||
|
|
||||||
return freeze(
|
|
||||||
console=[{
|
|
||||||
'script': './yt_dlp/__main__.py',
|
|
||||||
'dest_base': 'yt-dlp',
|
|
||||||
'icon_resources': [(1, 'devscripts/logo.ico')],
|
|
||||||
}],
|
|
||||||
version_info={
|
|
||||||
'version': VERSION,
|
|
||||||
'description': 'A youtube-dl fork with additional features and patches',
|
|
||||||
'comments': 'Official repository: <https://github.com/yt-dlp/yt-dlp>',
|
|
||||||
'product_name': 'yt-dlp',
|
|
||||||
'product_version': VERSION,
|
|
||||||
},
|
|
||||||
options={
|
|
||||||
'bundle_files': 0,
|
|
||||||
'compressed': 1,
|
|
||||||
'optimize': 2,
|
|
||||||
'dist_dir': './dist',
|
|
||||||
'excludes': [
|
|
||||||
# py2exe cannot import Crypto
|
|
||||||
'Crypto',
|
|
||||||
'Cryptodome',
|
|
||||||
# py2exe appears to confuse this with our socks library.
|
|
||||||
# We don't use pysocks and urllib3.contrib.socks would fail to import if tried.
|
|
||||||
'urllib3.contrib.socks'
|
|
||||||
],
|
|
||||||
'dll_excludes': ['w9xpopen.exe', 'crypt32.dll'],
|
|
||||||
# Modules that are only imported dynamically must be added here
|
|
||||||
'includes': ['yt_dlp.compat._legacy', 'yt_dlp.compat._deprecated',
|
|
||||||
'yt_dlp.utils._legacy', 'yt_dlp.utils._deprecated'],
|
|
||||||
},
|
|
||||||
zipfile=None,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,66 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
# Allow execution from anywhere
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import re
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from devscripts.tomlparse import parse_toml
|
|
||||||
from devscripts.utils import read_file
|
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
|
||||||
parser = argparse.ArgumentParser(description='Install dependencies for yt-dlp')
|
|
||||||
parser.add_argument(
|
|
||||||
'input', nargs='?', metavar='TOMLFILE', default='pyproject.toml', help='Input file (default: %(default)s)')
|
|
||||||
parser.add_argument(
|
|
||||||
'-e', '--exclude', metavar='REQUIREMENT', action='append', help='Exclude a required dependency')
|
|
||||||
parser.add_argument(
|
|
||||||
'-i', '--include', metavar='GROUP', action='append', help='Include an optional dependency group')
|
|
||||||
parser.add_argument(
|
|
||||||
'-o', '--only-optional', action='store_true', help='Only install optional dependencies')
|
|
||||||
parser.add_argument(
|
|
||||||
'-p', '--print', action='store_true', help='Only print a requirements.txt to stdout')
|
|
||||||
parser.add_argument(
|
|
||||||
'-u', '--user', action='store_true', help='Install with pip as --user')
|
|
||||||
return parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
args = parse_args()
|
|
||||||
toml_data = parse_toml(read_file(args.input))
|
|
||||||
deps = toml_data['project']['dependencies']
|
|
||||||
targets = deps.copy() if not args.only_optional else []
|
|
||||||
|
|
||||||
for exclude in args.exclude or []:
|
|
||||||
for dep in deps:
|
|
||||||
simplified_dep = re.match(r'[\w-]+', dep)[0]
|
|
||||||
if dep in targets and (exclude.lower() == simplified_dep.lower() or exclude == dep):
|
|
||||||
targets.remove(dep)
|
|
||||||
|
|
||||||
optional_deps = toml_data['project']['optional-dependencies']
|
|
||||||
for include in args.include or []:
|
|
||||||
group = optional_deps.get(include)
|
|
||||||
if group:
|
|
||||||
targets.extend(group)
|
|
||||||
|
|
||||||
if args.print:
|
|
||||||
for target in targets:
|
|
||||||
print(target)
|
|
||||||
return
|
|
||||||
|
|
||||||
pip_args = [sys.executable, '-m', 'pip', 'install', '-U']
|
|
||||||
if args.user:
|
|
||||||
pip_args.append('--user')
|
|
||||||
pip_args.extend(targets)
|
|
||||||
|
|
||||||
return subprocess.call(pip_args)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main())
|
|
|
@ -1,189 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
"""
|
|
||||||
Simple parser for spec compliant toml files
|
|
||||||
|
|
||||||
A simple toml parser for files that comply with the spec.
|
|
||||||
Should only be used to parse `pyproject.toml` for `install_deps.py`.
|
|
||||||
|
|
||||||
IMPORTANT: INVALID FILES OR MULTILINE STRINGS ARE NOT SUPPORTED!
|
|
||||||
"""
|
|
||||||
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
import json
|
|
||||||
import re
|
|
||||||
|
|
||||||
WS = r'(?:[\ \t]*)'
|
|
||||||
STRING_RE = re.compile(r'"(?:\\.|[^\\"\n])*"|\'[^\'\n]*\'')
|
|
||||||
SINGLE_KEY_RE = re.compile(rf'{STRING_RE.pattern}|[A-Za-z0-9_-]+')
|
|
||||||
KEY_RE = re.compile(rf'{WS}(?:{SINGLE_KEY_RE.pattern}){WS}(?:\.{WS}(?:{SINGLE_KEY_RE.pattern}){WS})*')
|
|
||||||
EQUALS_RE = re.compile(rf'={WS}')
|
|
||||||
WS_RE = re.compile(WS)
|
|
||||||
|
|
||||||
_SUBTABLE = rf'(?P<subtable>^\[(?P<is_list>\[)?(?P<path>{KEY_RE.pattern})\]\]?)'
|
|
||||||
EXPRESSION_RE = re.compile(rf'^(?:{_SUBTABLE}|{KEY_RE.pattern}=)', re.MULTILINE)
|
|
||||||
|
|
||||||
LIST_WS_RE = re.compile(rf'{WS}((#[^\n]*)?\n{WS})*')
|
|
||||||
LEFTOVER_VALUE_RE = re.compile(r'[^,}\]\t\n#]+')
|
|
||||||
|
|
||||||
|
|
||||||
def parse_key(value: str):
|
|
||||||
for match in SINGLE_KEY_RE.finditer(value):
|
|
||||||
if match[0][0] == '"':
|
|
||||||
yield json.loads(match[0])
|
|
||||||
elif match[0][0] == '\'':
|
|
||||||
yield match[0][1:-1]
|
|
||||||
else:
|
|
||||||
yield match[0]
|
|
||||||
|
|
||||||
|
|
||||||
def get_target(root: dict, paths: list[str], is_list=False):
|
|
||||||
target = root
|
|
||||||
|
|
||||||
for index, key in enumerate(paths, 1):
|
|
||||||
use_list = is_list and index == len(paths)
|
|
||||||
result = target.get(key)
|
|
||||||
if result is None:
|
|
||||||
result = [] if use_list else {}
|
|
||||||
target[key] = result
|
|
||||||
|
|
||||||
if isinstance(result, dict):
|
|
||||||
target = result
|
|
||||||
elif use_list:
|
|
||||||
target = {}
|
|
||||||
result.append(target)
|
|
||||||
else:
|
|
||||||
target = result[-1]
|
|
||||||
|
|
||||||
assert isinstance(target, dict)
|
|
||||||
return target
|
|
||||||
|
|
||||||
|
|
||||||
def parse_enclosed(data: str, index: int, end: str, ws_re: re.Pattern):
|
|
||||||
index += 1
|
|
||||||
|
|
||||||
if match := ws_re.match(data, index):
|
|
||||||
index = match.end()
|
|
||||||
|
|
||||||
while data[index] != end:
|
|
||||||
index = yield True, index
|
|
||||||
|
|
||||||
if match := ws_re.match(data, index):
|
|
||||||
index = match.end()
|
|
||||||
|
|
||||||
if data[index] == ',':
|
|
||||||
index += 1
|
|
||||||
|
|
||||||
if match := ws_re.match(data, index):
|
|
||||||
index = match.end()
|
|
||||||
|
|
||||||
assert data[index] == end
|
|
||||||
yield False, index + 1
|
|
||||||
|
|
||||||
|
|
||||||
def parse_value(data: str, index: int):
|
|
||||||
if data[index] == '[':
|
|
||||||
result = []
|
|
||||||
|
|
||||||
indices = parse_enclosed(data, index, ']', LIST_WS_RE)
|
|
||||||
valid, index = next(indices)
|
|
||||||
while valid:
|
|
||||||
index, value = parse_value(data, index)
|
|
||||||
result.append(value)
|
|
||||||
valid, index = indices.send(index)
|
|
||||||
|
|
||||||
return index, result
|
|
||||||
|
|
||||||
if data[index] == '{':
|
|
||||||
result = {}
|
|
||||||
|
|
||||||
indices = parse_enclosed(data, index, '}', WS_RE)
|
|
||||||
valid, index = next(indices)
|
|
||||||
while valid:
|
|
||||||
valid, index = indices.send(parse_kv_pair(data, index, result))
|
|
||||||
|
|
||||||
return index, result
|
|
||||||
|
|
||||||
if match := STRING_RE.match(data, index):
|
|
||||||
return match.end(), json.loads(match[0]) if match[0][0] == '"' else match[0][1:-1]
|
|
||||||
|
|
||||||
match = LEFTOVER_VALUE_RE.match(data, index)
|
|
||||||
assert match
|
|
||||||
value = match[0].strip()
|
|
||||||
for func in [
|
|
||||||
int,
|
|
||||||
float,
|
|
||||||
datetime.time.fromisoformat,
|
|
||||||
datetime.date.fromisoformat,
|
|
||||||
datetime.datetime.fromisoformat,
|
|
||||||
{'true': True, 'false': False}.get,
|
|
||||||
]:
|
|
||||||
try:
|
|
||||||
value = func(value)
|
|
||||||
break
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return match.end(), value
|
|
||||||
|
|
||||||
|
|
||||||
def parse_kv_pair(data: str, index: int, target: dict):
|
|
||||||
match = KEY_RE.match(data, index)
|
|
||||||
if not match:
|
|
||||||
return None
|
|
||||||
|
|
||||||
*keys, key = parse_key(match[0])
|
|
||||||
|
|
||||||
match = EQUALS_RE.match(data, match.end())
|
|
||||||
assert match
|
|
||||||
index = match.end()
|
|
||||||
|
|
||||||
index, value = parse_value(data, index)
|
|
||||||
get_target(target, keys)[key] = value
|
|
||||||
return index
|
|
||||||
|
|
||||||
|
|
||||||
def parse_toml(data: str):
|
|
||||||
root = {}
|
|
||||||
target = root
|
|
||||||
|
|
||||||
index = 0
|
|
||||||
while True:
|
|
||||||
match = EXPRESSION_RE.search(data, index)
|
|
||||||
if not match:
|
|
||||||
break
|
|
||||||
|
|
||||||
if match.group('subtable'):
|
|
||||||
index = match.end()
|
|
||||||
path, is_list = match.group('path', 'is_list')
|
|
||||||
target = get_target(root, list(parse_key(path)), bool(is_list))
|
|
||||||
continue
|
|
||||||
|
|
||||||
index = parse_kv_pair(data, match.start(), target)
|
|
||||||
assert index is not None
|
|
||||||
|
|
||||||
return root
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
import argparse
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('infile', type=Path, help='The TOML file to read as input')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
with args.infile.open('r', encoding='utf-8') as file:
|
|
||||||
data = file.read()
|
|
||||||
|
|
||||||
def default(obj):
|
|
||||||
if isinstance(obj, (datetime.date, datetime.time, datetime.datetime)):
|
|
||||||
return obj.isoformat()
|
|
||||||
|
|
||||||
print(json.dumps(parse_toml(data), default=default))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
2
bundle/pyinstaller.py → pyinst.py
Executable file → Normal file
2
bundle/pyinstaller.py → pyinst.py
Executable file → Normal file
|
@ -4,7 +4,7 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
import platform
|
import platform
|
||||||
|
|
123
pyproject.toml
123
pyproject.toml
|
@ -1,120 +1,5 @@
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["hatchling"]
|
build-backend = 'setuptools.build_meta'
|
||||||
build-backend = "hatchling.build"
|
# https://github.com/yt-dlp/yt-dlp/issues/5941
|
||||||
|
# https://github.com/pypa/distutils/issues/17
|
||||||
[project]
|
requires = ['setuptools > 50']
|
||||||
name = "yt-dlp"
|
|
||||||
maintainers = [
|
|
||||||
{name = "pukkandan", email = "pukkandan.ytdlp@gmail.com"},
|
|
||||||
{name = "Grub4K", email = "contact@grub4k.xyz"},
|
|
||||||
{name = "bashonly", email = "bashonly@protonmail.com"},
|
|
||||||
]
|
|
||||||
description = "A youtube-dl fork with additional features and patches"
|
|
||||||
readme = "README.md"
|
|
||||||
requires-python = ">=3.8"
|
|
||||||
keywords = [
|
|
||||||
"youtube-dl",
|
|
||||||
"video-downloader",
|
|
||||||
"youtube-downloader",
|
|
||||||
"sponsorblock",
|
|
||||||
"youtube-dlc",
|
|
||||||
"yt-dlp",
|
|
||||||
]
|
|
||||||
license = {file = "LICENSE"}
|
|
||||||
classifiers = [
|
|
||||||
"Topic :: Multimedia :: Video",
|
|
||||||
"Development Status :: 5 - Production/Stable",
|
|
||||||
"Environment :: Console",
|
|
||||||
"Programming Language :: Python",
|
|
||||||
"Programming Language :: Python :: 3 :: Only",
|
|
||||||
"Programming Language :: Python :: 3.8",
|
|
||||||
"Programming Language :: Python :: 3.9",
|
|
||||||
"Programming Language :: Python :: 3.10",
|
|
||||||
"Programming Language :: Python :: 3.11",
|
|
||||||
"Programming Language :: Python :: 3.12",
|
|
||||||
"Programming Language :: Python :: Implementation",
|
|
||||||
"Programming Language :: Python :: Implementation :: CPython",
|
|
||||||
"Programming Language :: Python :: Implementation :: PyPy",
|
|
||||||
"License :: OSI Approved :: The Unlicense (Unlicense)",
|
|
||||||
"Operating System :: OS Independent",
|
|
||||||
]
|
|
||||||
dynamic = ["version"]
|
|
||||||
dependencies = [
|
|
||||||
"brotli; implementation_name=='cpython'",
|
|
||||||
"brotlicffi; implementation_name!='cpython'",
|
|
||||||
"certifi",
|
|
||||||
"mutagen",
|
|
||||||
"pycryptodomex",
|
|
||||||
"requests>=2.31.0,<3",
|
|
||||||
"urllib3>=1.26.17,<3",
|
|
||||||
"websockets>=12.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[project.optional-dependencies]
|
|
||||||
secretstorage = [
|
|
||||||
"cffi",
|
|
||||||
"secretstorage",
|
|
||||||
]
|
|
||||||
build = [
|
|
||||||
"build",
|
|
||||||
"hatchling",
|
|
||||||
"pip",
|
|
||||||
"wheel",
|
|
||||||
]
|
|
||||||
dev = [
|
|
||||||
"flake8",
|
|
||||||
"isort",
|
|
||||||
"pytest",
|
|
||||||
]
|
|
||||||
pyinstaller = ["pyinstaller>=6.3"]
|
|
||||||
py2exe = ["py2exe>=0.12"]
|
|
||||||
|
|
||||||
[project.urls]
|
|
||||||
Documentation = "https://github.com/yt-dlp/yt-dlp#readme"
|
|
||||||
Repository = "https://github.com/yt-dlp/yt-dlp"
|
|
||||||
Tracker = "https://github.com/yt-dlp/yt-dlp/issues"
|
|
||||||
Funding = "https://github.com/yt-dlp/yt-dlp/blob/master/Collaborators.md#collaborators"
|
|
||||||
|
|
||||||
[project.scripts]
|
|
||||||
yt-dlp = "yt_dlp:main"
|
|
||||||
|
|
||||||
[project.entry-points.pyinstaller40]
|
|
||||||
hook-dirs = "yt_dlp.__pyinstaller:get_hook_dirs"
|
|
||||||
|
|
||||||
[tool.hatch.build.targets.sdist]
|
|
||||||
include = [
|
|
||||||
"/yt_dlp",
|
|
||||||
"/devscripts",
|
|
||||||
"/test",
|
|
||||||
"/.gitignore", # included by default, needed for auto-excludes
|
|
||||||
"/Changelog.md",
|
|
||||||
"/LICENSE", # included as license
|
|
||||||
"/pyproject.toml", # included by default
|
|
||||||
"/README.md", # included as readme
|
|
||||||
"/setup.cfg",
|
|
||||||
"/supportedsites.md",
|
|
||||||
]
|
|
||||||
exclude = ["/yt_dlp/__pyinstaller"]
|
|
||||||
artifacts = [
|
|
||||||
"/yt_dlp/extractor/lazy_extractors.py",
|
|
||||||
"/completions",
|
|
||||||
"/AUTHORS", # included by default
|
|
||||||
"/README.txt",
|
|
||||||
"/yt-dlp.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[tool.hatch.build.targets.wheel]
|
|
||||||
packages = ["yt_dlp"]
|
|
||||||
exclude = ["/yt_dlp/__pyinstaller"]
|
|
||||||
artifacts = ["/yt_dlp/extractor/lazy_extractors.py"]
|
|
||||||
|
|
||||||
[tool.hatch.build.targets.wheel.shared-data]
|
|
||||||
"completions/bash/yt-dlp" = "share/bash-completion/completions/yt-dlp"
|
|
||||||
"completions/zsh/_yt-dlp" = "share/zsh/site-functions/_yt-dlp"
|
|
||||||
"completions/fish/yt-dlp.fish" = "share/fish/vendor_completions.d/yt-dlp.fish"
|
|
||||||
"README.txt" = "share/doc/yt_dlp/README.txt"
|
|
||||||
"yt-dlp.1" = "share/man/man1/yt-dlp.1"
|
|
||||||
|
|
||||||
[tool.hatch.version]
|
|
||||||
path = "yt_dlp/version.py"
|
|
||||||
pattern = "_pkg_version = '(?P<version>[^']+)'"
|
|
||||||
|
|
8
requirements.txt
Normal file
8
requirements.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
mutagen
|
||||||
|
pycryptodomex
|
||||||
|
brotli; implementation_name=='cpython'
|
||||||
|
brotlicffi; implementation_name!='cpython'
|
||||||
|
certifi
|
||||||
|
requests>=2.31.0,<3
|
||||||
|
urllib3>=1.26.17,<3
|
||||||
|
websockets>=12.0
|
|
@ -1,3 +1,7 @@
|
||||||
|
[wheel]
|
||||||
|
universal = true
|
||||||
|
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
exclude = build,venv,.tox,.git,.pytest_cache
|
exclude = build,venv,.tox,.git,.pytest_cache
|
||||||
ignore = E402,E501,E731,E741,W503
|
ignore = E402,E501,E731,E741,W503
|
||||||
|
|
183
setup.py
Normal file
183
setup.py
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Allow execution from anywhere
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
try:
|
||||||
|
from setuptools import Command, find_packages, setup
|
||||||
|
setuptools_available = True
|
||||||
|
except ImportError:
|
||||||
|
from distutils.core import Command, setup
|
||||||
|
setuptools_available = False
|
||||||
|
|
||||||
|
from devscripts.utils import read_file, read_version
|
||||||
|
|
||||||
|
VERSION = read_version(varname='_pkg_version')
|
||||||
|
|
||||||
|
DESCRIPTION = 'A youtube-dl fork with additional features and patches'
|
||||||
|
|
||||||
|
LONG_DESCRIPTION = '\n\n'.join((
|
||||||
|
'Official repository: <https://github.com/yt-dlp/yt-dlp>',
|
||||||
|
'**PS**: Some links in this document will not work since this is a copy of the README.md from Github',
|
||||||
|
read_file('README.md')))
|
||||||
|
|
||||||
|
REQUIREMENTS = read_file('requirements.txt').splitlines()
|
||||||
|
|
||||||
|
|
||||||
|
def packages():
|
||||||
|
if setuptools_available:
|
||||||
|
return find_packages(exclude=('youtube_dl', 'youtube_dlc', 'test', 'ytdlp_plugins', 'devscripts'))
|
||||||
|
|
||||||
|
return [
|
||||||
|
'yt_dlp', 'yt_dlp.extractor', 'yt_dlp.downloader', 'yt_dlp.postprocessor', 'yt_dlp.compat',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def py2exe_params():
|
||||||
|
warnings.warn(
|
||||||
|
'py2exe builds do not support pycryptodomex and needs VC++14 to run. '
|
||||||
|
'It is recommended to run "pyinst.py" to build using pyinstaller instead')
|
||||||
|
|
||||||
|
return {
|
||||||
|
'console': [{
|
||||||
|
'script': './yt_dlp/__main__.py',
|
||||||
|
'dest_base': 'yt-dlp',
|
||||||
|
'icon_resources': [(1, 'devscripts/logo.ico')],
|
||||||
|
}],
|
||||||
|
'version_info': {
|
||||||
|
'version': VERSION,
|
||||||
|
'description': DESCRIPTION,
|
||||||
|
'comments': LONG_DESCRIPTION.split('\n')[0],
|
||||||
|
'product_name': 'yt-dlp',
|
||||||
|
'product_version': VERSION,
|
||||||
|
},
|
||||||
|
'options': {
|
||||||
|
'bundle_files': 0,
|
||||||
|
'compressed': 1,
|
||||||
|
'optimize': 2,
|
||||||
|
'dist_dir': './dist',
|
||||||
|
'excludes': [
|
||||||
|
# py2exe cannot import Crypto
|
||||||
|
'Crypto',
|
||||||
|
'Cryptodome',
|
||||||
|
# py2exe appears to confuse this with our socks library.
|
||||||
|
# We don't use pysocks and urllib3.contrib.socks would fail to import if tried.
|
||||||
|
'urllib3.contrib.socks'
|
||||||
|
],
|
||||||
|
'dll_excludes': ['w9xpopen.exe', 'crypt32.dll'],
|
||||||
|
# Modules that are only imported dynamically must be added here
|
||||||
|
'includes': ['yt_dlp.compat._legacy', 'yt_dlp.compat._deprecated',
|
||||||
|
'yt_dlp.utils._legacy', 'yt_dlp.utils._deprecated'],
|
||||||
|
},
|
||||||
|
'zipfile': None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def build_params():
|
||||||
|
files_spec = [
|
||||||
|
('share/bash-completion/completions', ['completions/bash/yt-dlp']),
|
||||||
|
('share/zsh/site-functions', ['completions/zsh/_yt-dlp']),
|
||||||
|
('share/fish/vendor_completions.d', ['completions/fish/yt-dlp.fish']),
|
||||||
|
('share/doc/yt_dlp', ['README.txt']),
|
||||||
|
('share/man/man1', ['yt-dlp.1'])
|
||||||
|
]
|
||||||
|
data_files = []
|
||||||
|
for dirname, files in files_spec:
|
||||||
|
resfiles = []
|
||||||
|
for fn in files:
|
||||||
|
if not os.path.exists(fn):
|
||||||
|
warnings.warn(f'Skipping file {fn} since it is not present. Try running " make pypi-files " first')
|
||||||
|
else:
|
||||||
|
resfiles.append(fn)
|
||||||
|
data_files.append((dirname, resfiles))
|
||||||
|
|
||||||
|
params = {'data_files': data_files}
|
||||||
|
|
||||||
|
if setuptools_available:
|
||||||
|
params['entry_points'] = {
|
||||||
|
'console_scripts': ['yt-dlp = yt_dlp:main'],
|
||||||
|
'pyinstaller40': ['hook-dirs = yt_dlp.__pyinstaller:get_hook_dirs'],
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
params['scripts'] = ['yt-dlp']
|
||||||
|
return params
|
||||||
|
|
||||||
|
|
||||||
|
class build_lazy_extractors(Command):
|
||||||
|
description = 'Build the extractor lazy loading module'
|
||||||
|
user_options = []
|
||||||
|
|
||||||
|
def initialize_options(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def finalize_options(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
if self.dry_run:
|
||||||
|
print('Skipping build of lazy extractors in dry run mode')
|
||||||
|
return
|
||||||
|
subprocess.run([sys.executable, 'devscripts/make_lazy_extractors.py'])
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if sys.argv[1:2] == ['py2exe']:
|
||||||
|
params = py2exe_params()
|
||||||
|
try:
|
||||||
|
from py2exe import freeze
|
||||||
|
except ImportError:
|
||||||
|
import py2exe # noqa: F401
|
||||||
|
warnings.warn('You are using an outdated version of py2exe. Support for this version will be removed in the future')
|
||||||
|
params['console'][0].update(params.pop('version_info'))
|
||||||
|
params['options'] = {'py2exe': params.pop('options')}
|
||||||
|
else:
|
||||||
|
return freeze(**params)
|
||||||
|
else:
|
||||||
|
params = build_params()
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='yt-dlp', # package name (do not change/remove comment)
|
||||||
|
version=VERSION,
|
||||||
|
maintainer='pukkandan',
|
||||||
|
maintainer_email='pukkandan.ytdlp@gmail.com',
|
||||||
|
description=DESCRIPTION,
|
||||||
|
long_description=LONG_DESCRIPTION,
|
||||||
|
long_description_content_type='text/markdown',
|
||||||
|
url='https://github.com/yt-dlp/yt-dlp',
|
||||||
|
packages=packages(),
|
||||||
|
install_requires=REQUIREMENTS,
|
||||||
|
python_requires='>=3.8',
|
||||||
|
project_urls={
|
||||||
|
'Documentation': 'https://github.com/yt-dlp/yt-dlp#readme',
|
||||||
|
'Source': 'https://github.com/yt-dlp/yt-dlp',
|
||||||
|
'Tracker': 'https://github.com/yt-dlp/yt-dlp/issues',
|
||||||
|
'Funding': 'https://github.com/yt-dlp/yt-dlp/blob/master/Collaborators.md#collaborators',
|
||||||
|
},
|
||||||
|
classifiers=[
|
||||||
|
'Topic :: Multimedia :: Video',
|
||||||
|
'Development Status :: 5 - Production/Stable',
|
||||||
|
'Environment :: Console',
|
||||||
|
'Programming Language :: Python',
|
||||||
|
'Programming Language :: Python :: 3.8',
|
||||||
|
'Programming Language :: Python :: 3.9',
|
||||||
|
'Programming Language :: Python :: 3.10',
|
||||||
|
'Programming Language :: Python :: 3.11',
|
||||||
|
'Programming Language :: Python :: 3.12',
|
||||||
|
'Programming Language :: Python :: Implementation',
|
||||||
|
'Programming Language :: Python :: Implementation :: CPython',
|
||||||
|
'Programming Language :: Python :: Implementation :: PyPy',
|
||||||
|
'License :: Public Domain',
|
||||||
|
'Operating System :: OS Independent',
|
||||||
|
],
|
||||||
|
cmdclass={'build_lazy_extractors': build_lazy_extractors},
|
||||||
|
**params
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
|
@ -78,14 +78,14 @@ class Ant1NewsGrArticleIE(AntennaBaseIE):
|
||||||
|
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.ant1news.gr/afieromata/article/549468/o-tzeims-mpont-sta-meteora-oi-apeiles-kai-o-xesikomos-ton-kalogeron',
|
'url': 'https://www.ant1news.gr/afieromata/article/549468/o-tzeims-mpont-sta-meteora-oi-apeiles-kai-o-xesikomos-ton-kalogeron',
|
||||||
'md5': '57eb8d12181f0fa2b14b0b138e1de9b6',
|
'md5': '294f18331bb516539d72d85a82887dcc',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '_xvg/m_cmbatw=',
|
'id': '_xvg/m_cmbatw=',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
'title': 'md5:a93e8ecf2e4073bfdffcb38f59945411',
|
'title': 'md5:a93e8ecf2e4073bfdffcb38f59945411',
|
||||||
'timestamp': 1666166520,
|
'timestamp': 1603092840,
|
||||||
'upload_date': '20221019',
|
'upload_date': '20201019',
|
||||||
'thumbnail': 'https://ant1media.azureedge.net/imgHandler/1920/756206d2-d640-40e2-b201-3555abdfc0db.jpg',
|
'thumbnail': 'https://ant1media.azureedge.net/imgHandler/640/756206d2-d640-40e2-b201-3555abdfc0db.jpg',
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://ant1news.gr/Society/article/620286/symmoria-anilikon-dikigoros-thymaton-ithelan-na-toys-apoteleiosoyn',
|
'url': 'https://ant1news.gr/Society/article/620286/symmoria-anilikon-dikigoros-thymaton-ithelan-na-toys-apoteleiosoyn',
|
||||||
|
@ -117,7 +117,7 @@ class Ant1NewsGrEmbedIE(AntennaBaseIE):
|
||||||
_BASE_PLAYER_URL_RE = r'(?:https?:)?//(?:[a-zA-Z0-9\-]+\.)?(?:antenna|ant1news)\.gr/templates/pages/player'
|
_BASE_PLAYER_URL_RE = r'(?:https?:)?//(?:[a-zA-Z0-9\-]+\.)?(?:antenna|ant1news)\.gr/templates/pages/player'
|
||||||
_VALID_URL = rf'{_BASE_PLAYER_URL_RE}\?([^#]+&)?cid=(?P<id>[^#&]+)'
|
_VALID_URL = rf'{_BASE_PLAYER_URL_RE}\?([^#]+&)?cid=(?P<id>[^#&]+)'
|
||||||
_EMBED_REGEX = [rf'<iframe[^>]+?src=(?P<_q1>["\'])(?P<url>{_BASE_PLAYER_URL_RE}\?(?:(?!(?P=_q1)).)+)(?P=_q1)']
|
_EMBED_REGEX = [rf'<iframe[^>]+?src=(?P<_q1>["\'])(?P<url>{_BASE_PLAYER_URL_RE}\?(?:(?!(?P=_q1)).)+)(?P=_q1)']
|
||||||
_API_PATH = '/templates/data/jsonPlayer'
|
_API_PATH = '/news/templates/data/jsonPlayer'
|
||||||
|
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.antenna.gr/templates/pages/player?cid=3f_li_c_az_jw_y_u=&w=670&h=377',
|
'url': 'https://www.antenna.gr/templates/pages/player?cid=3f_li_c_az_jw_y_u=&w=670&h=377',
|
||||||
|
|
|
@ -33,7 +33,10 @@ class CrooksAndLiarsIE(InfoExtractor):
|
||||||
webpage = self._download_webpage(
|
webpage = self._download_webpage(
|
||||||
'http://embed.crooksandliars.com/embed/%s' % video_id, video_id)
|
'http://embed.crooksandliars.com/embed/%s' % video_id, video_id)
|
||||||
|
|
||||||
manifest = self._search_json(r'var\s+manifest\s*=', webpage, 'manifest JSON', video_id)
|
manifest = self._parse_json(
|
||||||
|
self._search_regex(
|
||||||
|
r'var\s+manifest\s*=\s*({.+?})\n', webpage, 'manifest JSON'),
|
||||||
|
video_id)
|
||||||
|
|
||||||
quality = qualities(('webm_low', 'mp4_low', 'webm_high', 'mp4_high'))
|
quality = qualities(('webm_low', 'mp4_low', 'webm_high', 'mp4_high'))
|
||||||
|
|
||||||
|
|
|
@ -1,29 +1,25 @@
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from .nexx import NexxIE
|
from .nexx import NexxIE
|
||||||
|
from ..utils import (
|
||||||
|
int_or_none,
|
||||||
|
str_or_none,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FunkIE(InfoExtractor):
|
class FunkIE(InfoExtractor):
|
||||||
_VALID_URL = r'https?://(?:www\.|origin\.)?funk\.net/(?:channel|playlist)/[^/]+/(?P<display_id>[0-9a-z-]+)-(?P<id>\d+)'
|
_VALID_URL = r'https?://(?:www\.|origin\.)?funk\.net/(?:channel|playlist)/[^/]+/(?P<display_id>[0-9a-z-]+)-(?P<id>\d+)'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.funk.net/channel/ba-793/die-lustigsten-instrumente-aus-dem-internet-teil-2-1155821',
|
'url': 'https://www.funk.net/channel/ba-793/die-lustigsten-instrumente-aus-dem-internet-teil-2-1155821',
|
||||||
'md5': '8610449476156f338761a75391b0017d',
|
'md5': '8dd9d9ab59b4aa4173b3197f2ea48e81',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '1155821',
|
'id': '1155821',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
'title': 'Die LUSTIGSTEN INSTRUMENTE aus dem Internet - Teil 2',
|
'title': 'Die LUSTIGSTEN INSTRUMENTE aus dem Internet - Teil 2',
|
||||||
'description': 'md5:2a03b67596eda0d1b5125c299f45e953',
|
'description': 'md5:a691d0413ef4835588c5b03ded670c1f',
|
||||||
'timestamp': 1514507395,
|
'timestamp': 1514507395,
|
||||||
'upload_date': '20171229',
|
'upload_date': '20171229',
|
||||||
'duration': 426.0,
|
|
||||||
'cast': ['United Creators PMB GmbH'],
|
|
||||||
'thumbnail': 'https://assets.nexx.cloud/media/75/56/79/3YKUSJN1LACN0CRxL.jpg',
|
|
||||||
'display_id': 'die-lustigsten-instrumente-aus-dem-internet-teil-2',
|
|
||||||
'alt_title': 'Die LUSTIGSTEN INSTRUMENTE aus dem Internet Teil 2',
|
|
||||||
'season_number': 0,
|
|
||||||
'season': 'Season 0',
|
|
||||||
'episode_number': 0,
|
|
||||||
'episode': 'Episode 0',
|
|
||||||
},
|
},
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://www.funk.net/playlist/neuesteVideos/kameras-auf-dem-fusion-festival-1618699',
|
'url': 'https://www.funk.net/playlist/neuesteVideos/kameras-auf-dem-fusion-festival-1618699',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
|
@ -31,10 +27,18 @@ class FunkIE(InfoExtractor):
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
display_id, nexx_id = self._match_valid_url(url).groups()
|
display_id, nexx_id = self._match_valid_url(url).groups()
|
||||||
|
video = self._download_json(
|
||||||
|
'https://www.funk.net/api/v4.0/videos/' + nexx_id, nexx_id)
|
||||||
return {
|
return {
|
||||||
'_type': 'url_transparent',
|
'_type': 'url_transparent',
|
||||||
'url': f'nexx:741:{nexx_id}',
|
'url': 'nexx:741:' + nexx_id,
|
||||||
'ie_key': NexxIE.ie_key(),
|
'ie_key': NexxIE.ie_key(),
|
||||||
'id': nexx_id,
|
'id': nexx_id,
|
||||||
|
'title': video.get('title'),
|
||||||
|
'description': video.get('description'),
|
||||||
|
'duration': int_or_none(video.get('duration')),
|
||||||
|
'channel_id': str_or_none(video.get('channelId')),
|
||||||
'display_id': display_id,
|
'display_id': display_id,
|
||||||
|
'tags': video.get('tags'),
|
||||||
|
'thumbnail': video.get('imageUrlLandscape'),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user