mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-30 22:25:19 +00:00 
			
		
		
		
	[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:
		
							
								
								
									
										85
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										85
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -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 | ||||
| *.pyc | ||||
| *.pyo | ||||
| @@ -43,48 +86,6 @@ README.txt | ||||
| yt-dlp.zip | ||||
| *.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 | ||||
| .idea | ||||
| *.iml | ||||
|   | ||||
| @@ -8,7 +8,11 @@ import sys | ||||
| import unittest | ||||
| 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): | ||||
| @@ -30,3 +34,24 @@ class TestMetadataFromTitle(unittest.TestCase): | ||||
|     def test_format_to_regex(self): | ||||
|         pp = MetadataFromTitlePP(None, '%(title)s - %(artist)s') | ||||
|         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)) | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								test/testdata/thumbnails/foo %d bar/foo_%d.webp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								test/testdata/thumbnails/foo %d bar/foo_%d.webp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											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') | ||||
|             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: | ||||
|             self.to_screen('There are no thumbnails on disk') | ||||
|             return [], info | ||||
|   | ||||
| @@ -853,19 +853,12 @@ class FFmpegThumbnailsConvertorPP(FFmpegPostProcessor): | ||||
|         return [] | ||||
|  | ||||
|     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) | ||||
|         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 | ||||
|  | ||||
|     def run(self, info): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 pukkandan
					pukkandan