mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-26 17:21:23 +01:00
Compare commits
4 Commits
37755a037e
...
bc4ab17b38
Author | SHA1 | Date | |
---|---|---|---|
|
bc4ab17b38 | ||
|
632b8ee54e | ||
|
c919b68f7e | ||
|
19741ab8a4 |
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
|
@ -80,12 +80,12 @@ on:
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
origin:
|
origin:
|
||||||
description: .
|
description: Origin
|
||||||
required: false
|
required: false
|
||||||
default: ''
|
default: 'current repo'
|
||||||
type: choice
|
type: choice
|
||||||
options:
|
options:
|
||||||
- ''
|
- 'current repo'
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
@ -99,7 +99,7 @@ jobs:
|
||||||
- name: Process origin
|
- name: Process origin
|
||||||
id: process_origin
|
id: process_origin
|
||||||
run: |
|
run: |
|
||||||
echo "origin=${{ inputs.origin || github.repository }}" >> "$GITHUB_OUTPUT"
|
echo "origin=${{ inputs.origin == 'current repo' && github.repository || inputs.origin }}" | tee "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
unix:
|
unix:
|
||||||
needs: process
|
needs: process
|
||||||
|
|
24
.github/workflows/release.yml
vendored
24
.github/workflows/release.yml
vendored
|
@ -64,7 +64,6 @@ jobs:
|
||||||
target_tag: ${{ steps.setup_variables.outputs.target_tag }}
|
target_tag: ${{ steps.setup_variables.outputs.target_tag }}
|
||||||
pypi_project: ${{ steps.setup_variables.outputs.pypi_project }}
|
pypi_project: ${{ steps.setup_variables.outputs.pypi_project }}
|
||||||
pypi_suffix: ${{ steps.setup_variables.outputs.pypi_suffix }}
|
pypi_suffix: ${{ steps.setup_variables.outputs.pypi_suffix }}
|
||||||
pypi_token: ${{ steps.setup_variables.outputs.pypi_token }}
|
|
||||||
head_sha: ${{ steps.get_target.outputs.head_sha }}
|
head_sha: ${{ steps.get_target.outputs.head_sha }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
@ -153,7 +152,6 @@ jobs:
|
||||||
${{ !!secrets[format('{0}_archive_repo_token', env.target_repo)] }} || fallback_token
|
${{ !!secrets[format('{0}_archive_repo_token', env.target_repo)] }} || fallback_token
|
||||||
pypi_project='${{ vars[format('{0}_pypi_project', env.target_repo)] }}'
|
pypi_project='${{ vars[format('{0}_pypi_project', env.target_repo)] }}'
|
||||||
pypi_suffix='${{ vars[format('{0}_pypi_suffix', env.target_repo)] }}'
|
pypi_suffix='${{ vars[format('{0}_pypi_suffix', env.target_repo)] }}'
|
||||||
${{ !secrets[format('{0}_pypi_token', env.target_repo)] }} || pypi_token='${{ env.target_repo }}_pypi_token'
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
target_tag="${source_tag:-${version}}"
|
target_tag="${source_tag:-${version}}"
|
||||||
|
@ -163,7 +161,6 @@ jobs:
|
||||||
${{ !!secrets[format('{0}_archive_repo_token', env.source_repo)] }} || fallback_token
|
${{ !!secrets[format('{0}_archive_repo_token', env.source_repo)] }} || fallback_token
|
||||||
pypi_project='${{ vars[format('{0}_pypi_project', env.source_repo)] }}'
|
pypi_project='${{ vars[format('{0}_pypi_project', env.source_repo)] }}'
|
||||||
pypi_suffix='${{ vars[format('{0}_pypi_suffix', env.source_repo)] }}'
|
pypi_suffix='${{ vars[format('{0}_pypi_suffix', env.source_repo)] }}'
|
||||||
${{ !secrets[format('{0}_pypi_token', env.source_repo)] }} || pypi_token='${{ env.source_repo }}_pypi_token'
|
|
||||||
else
|
else
|
||||||
target_repo='${{ github.repository }}'
|
target_repo='${{ github.repository }}'
|
||||||
fi
|
fi
|
||||||
|
@ -172,13 +169,6 @@ jobs:
|
||||||
if [[ "${target_repo}" == '${{ github.repository }}' ]] && ${{ !inputs.prerelease }}; then
|
if [[ "${target_repo}" == '${{ github.repository }}' ]] && ${{ !inputs.prerelease }}; then
|
||||||
pypi_project='${{ vars.PYPI_PROJECT }}'
|
pypi_project='${{ vars.PYPI_PROJECT }}'
|
||||||
fi
|
fi
|
||||||
if [[ -z "${pypi_token}" && "${pypi_project}" ]]; then
|
|
||||||
if ${{ !secrets.PYPI_TOKEN }}; then
|
|
||||||
pypi_token=OIDC
|
|
||||||
else
|
|
||||||
pypi_token=PYPI_TOKEN
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "::group::Output variables"
|
echo "::group::Output variables"
|
||||||
cat << EOF | tee -a "$GITHUB_OUTPUT"
|
cat << EOF | tee -a "$GITHUB_OUTPUT"
|
||||||
|
@ -189,7 +179,6 @@ jobs:
|
||||||
target_tag=${target_tag}
|
target_tag=${target_tag}
|
||||||
pypi_project=${pypi_project}
|
pypi_project=${pypi_project}
|
||||||
pypi_suffix=${pypi_suffix}
|
pypi_suffix=${pypi_suffix}
|
||||||
pypi_token=${pypi_token}
|
|
||||||
EOF
|
EOF
|
||||||
echo "::endgroup::"
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
@ -286,18 +275,7 @@ jobs:
|
||||||
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"
|
||||||
python setup.py sdist bdist_wheel
|
python setup.py sdist bdist_wheel
|
||||||
|
|
||||||
- name: Publish to PyPI via token
|
- name: Publish to PyPI
|
||||||
env:
|
|
||||||
TWINE_USERNAME: __token__
|
|
||||||
TWINE_PASSWORD: ${{ secrets[needs.prepare.outputs.pypi_token] }}
|
|
||||||
if: |
|
|
||||||
needs.prepare.outputs.pypi_token != 'OIDC' && env.TWINE_PASSWORD
|
|
||||||
run: |
|
|
||||||
twine upload dist/*
|
|
||||||
|
|
||||||
- name: Publish to PyPI via trusted publishing
|
|
||||||
if: |
|
|
||||||
needs.prepare.outputs.pypi_token == 'OIDC'
|
|
||||||
uses: pypa/gh-action-pypi-publish@release/v1
|
uses: pypa/gh-action-pypi-publish@release/v1
|
||||||
with:
|
with:
|
||||||
verbose: true
|
verbose: true
|
||||||
|
|
|
@ -11,6 +11,14 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
from test.helper import FakeYDL, report_warning
|
from test.helper import FakeYDL, report_warning
|
||||||
from yt_dlp.update import Updater, UpdateInfo
|
from yt_dlp.update import Updater, UpdateInfo
|
||||||
|
|
||||||
|
|
||||||
|
# XXX: Keep in sync with yt_dlp.update.UPDATE_SOURCES
|
||||||
|
TEST_UPDATE_SOURCES = {
|
||||||
|
'stable': 'yt-dlp/yt-dlp',
|
||||||
|
'nightly': 'yt-dlp/yt-dlp-nightly-builds',
|
||||||
|
'master': 'yt-dlp/yt-dlp-master-builds',
|
||||||
|
}
|
||||||
|
|
||||||
TEST_API_DATA = {
|
TEST_API_DATA = {
|
||||||
'yt-dlp/yt-dlp/latest': {
|
'yt-dlp/yt-dlp/latest': {
|
||||||
'tag_name': '2023.12.31',
|
'tag_name': '2023.12.31',
|
||||||
|
@ -104,6 +112,7 @@ class FakeUpdater(Updater):
|
||||||
|
|
||||||
_channel = 'stable'
|
_channel = 'stable'
|
||||||
_origin = 'yt-dlp/yt-dlp'
|
_origin = 'yt-dlp/yt-dlp'
|
||||||
|
_update_sources = TEST_UPDATE_SOURCES
|
||||||
|
|
||||||
def _download_update_spec(self, *args, **kwargs):
|
def _download_update_spec(self, *args, **kwargs):
|
||||||
return TEST_LOCKFILE_ACTUAL
|
return TEST_LOCKFILE_ACTUAL
|
||||||
|
|
|
@ -317,16 +317,25 @@ class BBCCoUkIE(InfoExtractor):
|
||||||
|
|
||||||
def _download_media_selector(self, programme_id):
|
def _download_media_selector(self, programme_id):
|
||||||
last_exception = None
|
last_exception = None
|
||||||
|
formats, subtitles = [], {}
|
||||||
for media_set in self._MEDIA_SETS:
|
for media_set in self._MEDIA_SETS:
|
||||||
try:
|
try:
|
||||||
return self._download_media_selector_url(
|
fmts, subs = self._download_media_selector_url(
|
||||||
self._MEDIA_SELECTOR_URL_TEMPL % (media_set, programme_id), programme_id)
|
self._MEDIA_SELECTOR_URL_TEMPL % (media_set, programme_id), programme_id)
|
||||||
|
formats.extend(fmts)
|
||||||
|
if subs:
|
||||||
|
self._merge_subtitles(subs, target=subtitles)
|
||||||
except BBCCoUkIE.MediaSelectionError as e:
|
except BBCCoUkIE.MediaSelectionError as e:
|
||||||
if e.id in ('notukerror', 'geolocation', 'selectionunavailable'):
|
if e.id in ('notukerror', 'geolocation', 'selectionunavailable'):
|
||||||
last_exception = e
|
last_exception = e
|
||||||
continue
|
continue
|
||||||
self._raise_extractor_error(e)
|
self._raise_extractor_error(e)
|
||||||
self._raise_extractor_error(last_exception)
|
if last_exception:
|
||||||
|
if formats or subtitles:
|
||||||
|
self.report_warning(f'{self.IE_NAME} returned error: {last_exception.id}')
|
||||||
|
else:
|
||||||
|
self._raise_extractor_error(last_exception)
|
||||||
|
return formats, subtitles
|
||||||
|
|
||||||
def _download_media_selector_url(self, url, programme_id=None):
|
def _download_media_selector_url(self, url, programme_id=None):
|
||||||
media_selection = self._download_json(
|
media_selection = self._download_json(
|
||||||
|
@ -1188,7 +1197,7 @@ class BBCIE(BBCCoUkIE): # XXX: Do not subclass from concrete IE
|
||||||
if initial_data is None:
|
if initial_data is None:
|
||||||
initial_data = self._search_regex(
|
initial_data = self._search_regex(
|
||||||
r'window\.__INITIAL_DATA__\s*=\s*({.+?})\s*;', webpage,
|
r'window\.__INITIAL_DATA__\s*=\s*({.+?})\s*;', webpage,
|
||||||
'preload state', default={})
|
'preload state', default='{}')
|
||||||
else:
|
else:
|
||||||
initial_data = self._parse_json(initial_data or '"{}"', playlist_id, fatal=False)
|
initial_data = self._parse_json(initial_data or '"{}"', playlist_id, fatal=False)
|
||||||
initial_data = self._parse_json(initial_data, playlist_id, fatal=False)
|
initial_data = self._parse_json(initial_data, playlist_id, fatal=False)
|
||||||
|
|
|
@ -23,7 +23,7 @@ class IHeartRadioBaseIE(InfoExtractor):
|
||||||
|
|
||||||
|
|
||||||
class IHeartRadioIE(IHeartRadioBaseIE):
|
class IHeartRadioIE(IHeartRadioBaseIE):
|
||||||
IENAME = 'iheartradio'
|
IE_NAME = 'iheartradio'
|
||||||
_VALID_URL = r'(?:https?://(?:www\.)?iheart\.com/podcast/[^/]+/episode/(?P<display_id>[^/?&#]+)-|iheartradio:)(?P<id>\d+)'
|
_VALID_URL = r'(?:https?://(?:www\.)?iheart\.com/podcast/[^/]+/episode/(?P<display_id>[^/?&#]+)-|iheartradio:)(?P<id>\d+)'
|
||||||
_TEST = {
|
_TEST = {
|
||||||
'url': 'https://www.iheart.com/podcast/105-behind-the-bastards-29236323/episode/part-one-alexander-lukashenko-the-dictator-70346499/?embed=true',
|
'url': 'https://www.iheart.com/podcast/105-behind-the-bastards-29236323/episode/part-one-alexander-lukashenko-the-dictator-70346499/?embed=true',
|
||||||
|
|
|
@ -12,7 +12,7 @@ from ..utils import (
|
||||||
|
|
||||||
|
|
||||||
class KinjaEmbedIE(InfoExtractor):
|
class KinjaEmbedIE(InfoExtractor):
|
||||||
IENAME = 'kinja:embed'
|
IE_NAME = 'kinja:embed'
|
||||||
_DOMAIN_REGEX = r'''(?:[^.]+\.)?
|
_DOMAIN_REGEX = r'''(?:[^.]+\.)?
|
||||||
(?:
|
(?:
|
||||||
avclub|
|
avclub|
|
||||||
|
|
|
@ -97,7 +97,7 @@ class NBAWatchBaseIE(NBACVPBaseIE):
|
||||||
|
|
||||||
|
|
||||||
class NBAWatchEmbedIE(NBAWatchBaseIE):
|
class NBAWatchEmbedIE(NBAWatchBaseIE):
|
||||||
IENAME = 'nba:watch:embed'
|
IE_NAME = 'nba:watch:embed'
|
||||||
_VALID_URL = NBAWatchBaseIE._VALID_URL_BASE + r'embed\?.*?\bid=(?P<id>\d+)'
|
_VALID_URL = NBAWatchBaseIE._VALID_URL_BASE + r'embed\?.*?\bid=(?P<id>\d+)'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'http://watch.nba.com/embed?id=659395',
|
'url': 'http://watch.nba.com/embed?id=659395',
|
||||||
|
@ -339,7 +339,7 @@ class NBABaseIE(NBACVPBaseIE):
|
||||||
|
|
||||||
|
|
||||||
class NBAEmbedIE(NBABaseIE):
|
class NBAEmbedIE(NBABaseIE):
|
||||||
IENAME = 'nba:embed'
|
IE_NAME = 'nba:embed'
|
||||||
_VALID_URL = r'https?://secure\.nba\.com/assets/amp/include/video/(?:topI|i)frame\.html\?.*?\bcontentId=(?P<id>[^?#&]+)'
|
_VALID_URL = r'https?://secure\.nba\.com/assets/amp/include/video/(?:topI|i)frame\.html\?.*?\bcontentId=(?P<id>[^?#&]+)'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://secure.nba.com/assets/amp/include/video/topIframe.html?contentId=teams/bulls/2020/12/04/3478774/1607105587854-20201204_SCHEDULE_RELEASE_FINAL_DRUPAL-3478774&team=bulls&adFree=false&profile=71&videoPlayerName=TAMPCVP&baseUrl=&videoAdsection=nba.com_mobile_web_teamsites_chicagobulls&Env=',
|
'url': 'https://secure.nba.com/assets/amp/include/video/topIframe.html?contentId=teams/bulls/2020/12/04/3478774/1607105587854-20201204_SCHEDULE_RELEASE_FINAL_DRUPAL-3478774&team=bulls&adFree=false&profile=71&videoPlayerName=TAMPCVP&baseUrl=&videoAdsection=nba.com_mobile_web_teamsites_chicagobulls&Env=',
|
||||||
|
@ -361,7 +361,7 @@ class NBAEmbedIE(NBABaseIE):
|
||||||
|
|
||||||
|
|
||||||
class NBAIE(NBABaseIE):
|
class NBAIE(NBABaseIE):
|
||||||
IENAME = 'nba'
|
IE_NAME = 'nba'
|
||||||
_VALID_URL = NBABaseIE._VALID_URL_BASE + '(?!%s)video/(?P<id>(?:[^/]+/)*[^/?#&]+)' % NBABaseIE._CHANNEL_PATH_REGEX
|
_VALID_URL = NBABaseIE._VALID_URL_BASE + '(?!%s)video/(?P<id>(?:[^/]+/)*[^/?#&]+)' % NBABaseIE._CHANNEL_PATH_REGEX
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.nba.com/bulls/video/teams/bulls/2020/12/04/3478774/1607105587854-20201204schedulereleasefinaldrupal-3478774',
|
'url': 'https://www.nba.com/bulls/video/teams/bulls/2020/12/04/3478774/1607105587854-20201204schedulereleasefinaldrupal-3478774',
|
||||||
|
@ -388,7 +388,7 @@ class NBAIE(NBABaseIE):
|
||||||
|
|
||||||
|
|
||||||
class NBAChannelIE(NBABaseIE):
|
class NBAChannelIE(NBABaseIE):
|
||||||
IENAME = 'nba:channel'
|
IE_NAME = 'nba:channel'
|
||||||
_VALID_URL = NBABaseIE._VALID_URL_BASE + '(?:%s)/(?P<id>[^/?#&]+)' % NBABaseIE._CHANNEL_PATH_REGEX
|
_VALID_URL = NBABaseIE._VALID_URL_BASE + '(?:%s)/(?P<id>[^/?#&]+)' % NBABaseIE._CHANNEL_PATH_REGEX
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.nba.com/blazers/video/channel/summer_league',
|
'url': 'https://www.nba.com/blazers/video/channel/summer_league',
|
||||||
|
|
|
@ -206,13 +206,14 @@ class Updater:
|
||||||
# XXX: use class variables to simplify testing
|
# XXX: use class variables to simplify testing
|
||||||
_channel = CHANNEL
|
_channel = CHANNEL
|
||||||
_origin = ORIGIN
|
_origin = ORIGIN
|
||||||
|
_update_sources = UPDATE_SOURCES
|
||||||
|
|
||||||
def __init__(self, ydl, target: str | None = None):
|
def __init__(self, ydl, target: str | None = None):
|
||||||
self.ydl = ydl
|
self.ydl = ydl
|
||||||
# For backwards compat, target needs to be treated as if it could be None
|
# For backwards compat, target needs to be treated as if it could be None
|
||||||
self.requested_channel, sep, self.requested_tag = (target or self._channel).rpartition('@')
|
self.requested_channel, sep, self.requested_tag = (target or self._channel).rpartition('@')
|
||||||
# Check if requested_tag is actually the requested repo/channel
|
# Check if requested_tag is actually the requested repo/channel
|
||||||
if not sep and ('/' in self.requested_tag or self.requested_tag in UPDATE_SOURCES):
|
if not sep and ('/' in self.requested_tag or self.requested_tag in self._update_sources):
|
||||||
self.requested_channel = self.requested_tag
|
self.requested_channel = self.requested_tag
|
||||||
self.requested_tag: str = None # type: ignore (we set it later)
|
self.requested_tag: str = None # type: ignore (we set it later)
|
||||||
elif not self.requested_channel:
|
elif not self.requested_channel:
|
||||||
|
@ -237,11 +238,11 @@ class Updater:
|
||||||
self._block_restart('Automatically restarting into custom builds is disabled for security reasons')
|
self._block_restart('Automatically restarting into custom builds is disabled for security reasons')
|
||||||
else:
|
else:
|
||||||
# Check if requested_channel resolves to a known repository or else raise
|
# Check if requested_channel resolves to a known repository or else raise
|
||||||
self.requested_repo = UPDATE_SOURCES.get(self.requested_channel)
|
self.requested_repo = self._update_sources.get(self.requested_channel)
|
||||||
if not self.requested_repo:
|
if not self.requested_repo:
|
||||||
self._report_error(
|
self._report_error(
|
||||||
f'Invalid update channel {self.requested_channel!r} requested. '
|
f'Invalid update channel {self.requested_channel!r} requested. '
|
||||||
f'Valid channels are {", ".join(UPDATE_SOURCES)}', True)
|
f'Valid channels are {", ".join(self._update_sources)}', True)
|
||||||
|
|
||||||
self._identifier = f'{detect_variant()} {system_identifier()}'
|
self._identifier = f'{detect_variant()} {system_identifier()}'
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user