mirror of https://github.com/yt-dlp/yt-dlp.git
[embedthumbnail] Correctly escape filename
Closes #352
The approach in [1] is faulty as can be seen in the test cases
1. bff857a8af
This commit is contained in:
parent
885cc0b75c
commit
337e0c62f8
|
@ -1,3 +1,46 @@
|
||||||
|
# Config
|
||||||
|
*.conf
|
||||||
|
*.spec
|
||||||
|
cookies
|
||||||
|
cookies.txt
|
||||||
|
|
||||||
|
# Downloaded
|
||||||
|
*.srt
|
||||||
|
*.ttml
|
||||||
|
*.sbv
|
||||||
|
*.vtt
|
||||||
|
*.flv
|
||||||
|
*.mp4
|
||||||
|
*.m4a
|
||||||
|
*.m4v
|
||||||
|
*.mp3
|
||||||
|
*.3gp
|
||||||
|
*.webm
|
||||||
|
*.wav
|
||||||
|
*.ape
|
||||||
|
*.mkv
|
||||||
|
*.swf
|
||||||
|
*.part
|
||||||
|
*.part-*
|
||||||
|
*.ytdl
|
||||||
|
*.dump
|
||||||
|
*.frag
|
||||||
|
*.frag.urls
|
||||||
|
*.aria2
|
||||||
|
*.swp
|
||||||
|
*.ogg
|
||||||
|
*.opus
|
||||||
|
*.info.json
|
||||||
|
*.live_chat.json
|
||||||
|
*.jpg
|
||||||
|
*.png
|
||||||
|
*.webp
|
||||||
|
*.annotations.xml
|
||||||
|
*.description
|
||||||
|
|
||||||
|
# Allow config/media files in testdata
|
||||||
|
!test/testdata/**
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
*.pyc
|
*.pyc
|
||||||
*.pyo
|
*.pyo
|
||||||
|
@ -43,48 +86,6 @@ README.txt
|
||||||
yt-dlp.zip
|
yt-dlp.zip
|
||||||
*.exe
|
*.exe
|
||||||
|
|
||||||
# Downloaded
|
|
||||||
*.srt
|
|
||||||
*.ttml
|
|
||||||
*.sbv
|
|
||||||
*.vtt
|
|
||||||
*.flv
|
|
||||||
*.mp4
|
|
||||||
*.m4a
|
|
||||||
*.m4v
|
|
||||||
*.mp3
|
|
||||||
*.3gp
|
|
||||||
*.webm
|
|
||||||
*.wav
|
|
||||||
*.ape
|
|
||||||
*.mkv
|
|
||||||
*.swf
|
|
||||||
*.part
|
|
||||||
*.part-*
|
|
||||||
*.ytdl
|
|
||||||
*.dump
|
|
||||||
*.frag
|
|
||||||
*.frag.urls
|
|
||||||
*.aria2
|
|
||||||
*.swp
|
|
||||||
*.ogg
|
|
||||||
*.opus
|
|
||||||
*.info.json
|
|
||||||
*.live_chat.json
|
|
||||||
*.jpg
|
|
||||||
*.png
|
|
||||||
*.webp
|
|
||||||
*.annotations.xml
|
|
||||||
*.description
|
|
||||||
|
|
||||||
# Config
|
|
||||||
*.conf
|
|
||||||
*.spec
|
|
||||||
cookies
|
|
||||||
cookies.txt
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Text Editor / IDE
|
# Text Editor / IDE
|
||||||
.idea
|
.idea
|
||||||
*.iml
|
*.iml
|
||||||
|
|
|
@ -8,7 +8,11 @@ import sys
|
||||||
import unittest
|
import unittest
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
from yt_dlp.postprocessor import MetadataFromFieldPP, MetadataFromTitlePP
|
from yt_dlp.postprocessor import (
|
||||||
|
FFmpegThumbnailsConvertorPP,
|
||||||
|
MetadataFromFieldPP,
|
||||||
|
MetadataFromTitlePP,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestMetadataFromField(unittest.TestCase):
|
class TestMetadataFromField(unittest.TestCase):
|
||||||
|
@ -30,3 +34,24 @@ class TestMetadataFromTitle(unittest.TestCase):
|
||||||
def test_format_to_regex(self):
|
def test_format_to_regex(self):
|
||||||
pp = MetadataFromTitlePP(None, '%(title)s - %(artist)s')
|
pp = MetadataFromTitlePP(None, '%(title)s - %(artist)s')
|
||||||
self.assertEqual(pp._titleregex, r'(?P<title>.+)\ \-\ (?P<artist>.+)')
|
self.assertEqual(pp._titleregex, r'(?P<title>.+)\ \-\ (?P<artist>.+)')
|
||||||
|
|
||||||
|
|
||||||
|
class TestConvertThumbnail(unittest.TestCase):
|
||||||
|
def test_escaping(self):
|
||||||
|
pp = FFmpegThumbnailsConvertorPP()
|
||||||
|
if not pp.available:
|
||||||
|
print('Skipping: ffmpeg not found')
|
||||||
|
return
|
||||||
|
|
||||||
|
file = 'test/testdata/thumbnails/foo %d bar/foo_%d.{}'
|
||||||
|
tests = (('webp', 'png'), ('png', 'jpg'))
|
||||||
|
|
||||||
|
for inp, out in tests:
|
||||||
|
out_file = file.format(out)
|
||||||
|
if os.path.exists(out_file):
|
||||||
|
os.remove(out_file)
|
||||||
|
pp.convert_thumbnail(file.format(inp), out)
|
||||||
|
assert os.path.exists(out_file)
|
||||||
|
|
||||||
|
for _, out in tests:
|
||||||
|
os.remove(file.format(out))
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
|
@ -70,7 +70,7 @@ class EmbedThumbnailPP(FFmpegPostProcessor):
|
||||||
self.to_screen('There aren\'t any thumbnails to embed')
|
self.to_screen('There aren\'t any thumbnails to embed')
|
||||||
return [], info
|
return [], info
|
||||||
|
|
||||||
idx = next((-(i+1) for i, t in enumerate(info['thumbnails'][::-1]) if t.get('filepath')), None)
|
idx = next((-i for i, t in enumerate(info['thumbnails'][::-1], 1) if t.get('filepath')), None)
|
||||||
if idx is None:
|
if idx is None:
|
||||||
self.to_screen('There are no thumbnails on disk')
|
self.to_screen('There are no thumbnails on disk')
|
||||||
return [], info
|
return [], info
|
||||||
|
|
|
@ -853,19 +853,12 @@ class FFmpegThumbnailsConvertorPP(FFmpegPostProcessor):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def convert_thumbnail(self, thumbnail_filename, target_ext):
|
def convert_thumbnail(self, thumbnail_filename, target_ext):
|
||||||
# NB: % is supposed to be escaped with %% but this does not work
|
|
||||||
# for input files so working around with standard substitution
|
|
||||||
escaped_thumbnail_filename = thumbnail_filename.replace('%', '#')
|
|
||||||
os.rename(encodeFilename(thumbnail_filename), encodeFilename(escaped_thumbnail_filename))
|
|
||||||
escaped_thumbnail_conv_filename = replace_extension(escaped_thumbnail_filename, target_ext)
|
|
||||||
|
|
||||||
self.to_screen('Converting thumbnail "%s" to %s' % (escaped_thumbnail_filename, target_ext))
|
|
||||||
self.run_ffmpeg(escaped_thumbnail_filename, escaped_thumbnail_conv_filename, self._options(target_ext))
|
|
||||||
|
|
||||||
# Rename back to unescaped
|
|
||||||
thumbnail_conv_filename = replace_extension(thumbnail_filename, target_ext)
|
thumbnail_conv_filename = replace_extension(thumbnail_filename, target_ext)
|
||||||
os.rename(encodeFilename(escaped_thumbnail_filename), encodeFilename(thumbnail_filename))
|
|
||||||
os.rename(encodeFilename(escaped_thumbnail_conv_filename), encodeFilename(thumbnail_conv_filename))
|
self.to_screen('Converting thumbnail "%s" to %s' % (thumbnail_filename, target_ext))
|
||||||
|
self.real_run_ffmpeg(
|
||||||
|
[(thumbnail_filename, ['-f', 'image2', '-pattern_type', 'none'])],
|
||||||
|
[(thumbnail_conv_filename.replace('%', '%%'), self._options(target_ext))])
|
||||||
return thumbnail_conv_filename
|
return thumbnail_conv_filename
|
||||||
|
|
||||||
def run(self, info):
|
def run(self, info):
|
||||||
|
|
Loading…
Reference in New Issue