mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-31 06:35:12 +00:00 
			
		
		
		
	[execafterdownload] Simplify (#3569)
This commit is contained in:
		| @@ -172,6 +172,7 @@ class YoutubeDL(object): | ||||
|     The following options are used by the post processors: | ||||
|     prefer_ffmpeg:     If True, use ffmpeg instead of avconv if both are available, | ||||
|                        otherwise prefer avconv. | ||||
|     exec_cmd:          Arbitrary command to run after downloading | ||||
|     """ | ||||
|  | ||||
|     params = None | ||||
|   | ||||
| @@ -552,8 +552,9 @@ def parseOpts(overrideArguments=None): | ||||
|         help='Prefer avconv over ffmpeg for running the postprocessors (default)') | ||||
|     postproc.add_option('--prefer-ffmpeg', action='store_true', dest='prefer_ffmpeg', | ||||
|         help='Prefer ffmpeg over avconv for running the postprocessors') | ||||
|     postproc.add_option('--exec', metavar='', action='store', dest='execstring', | ||||
|         help='Execute a command on the file after downloading, similar to find\'s -exec syntax. Must be enclosed in quotes. Example: --exec \'adb push {} /sdcard/Music/ && rm {}\'' ) | ||||
|     postproc.add_option( | ||||
|         '--exec', metavar='CMD', dest='exec_cmd', | ||||
|         help='Execute a command on the file after downloading, similar to find\'s -exec syntax. Example: --exec \'adb push {} /sdcard/Music/ && rm {}\'' ) | ||||
|  | ||||
|     parser.add_option_group(general) | ||||
|     parser.add_option_group(selection) | ||||
| @@ -834,7 +835,7 @@ def _real_main(argv=None): | ||||
|         'default_search': opts.default_search, | ||||
|         'youtube_include_dash_manifest': opts.youtube_include_dash_manifest, | ||||
|         'encoding': opts.encoding, | ||||
|         'execstring': opts.execstring, | ||||
|         'exec_cmd': opts.exec_cmd, | ||||
|     } | ||||
|  | ||||
|     with YoutubeDL(ydl_opts) as ydl: | ||||
| @@ -861,8 +862,9 @@ def _real_main(argv=None): | ||||
|  | ||||
|         # Please keep ExecAfterDownload towards the bottom as it allows the user to modify the final file in any way. | ||||
|         # So if the user is able to remove the file before your postprocessor runs it might cause a few problems. | ||||
|         if opts.execstring: | ||||
|             ydl.add_post_processor(ExecAfterDownloadPP(verboseOutput=opts.verbose,commandString=opts.execstring)) | ||||
|         if opts.exec_cmd: | ||||
|             ydl.add_post_processor(ExecAfterDownloadPP( | ||||
|                 verboseOutput=opts.verbose, exec_cmd=opts.exec_cmd)) | ||||
|  | ||||
|         # Update version | ||||
|         if opts.update_self: | ||||
|   | ||||
| @@ -1,39 +1,31 @@ | ||||
| from __future__ import unicode_literals | ||||
| from .common import PostProcessor | ||||
| from ..utils import PostProcessingError | ||||
|  | ||||
| import subprocess | ||||
| import shlex | ||||
|  | ||||
| from .common import PostProcessor | ||||
| from ..utils import ( | ||||
|     shlex_quote, | ||||
|     PostProcessingError, | ||||
| ) | ||||
|  | ||||
|  | ||||
| class ExecAfterDownloadPP(PostProcessor): | ||||
|     def __init__(self, downloader=None, verboseOutput=None, commandString=None): | ||||
|     def __init__(self, downloader=None, verboseOutput=None, exec_cmd=None): | ||||
|         self.verboseOutput = verboseOutput | ||||
|         self.commandString = commandString | ||||
|         self.exec_cmd = exec_cmd | ||||
|  | ||||
|     def run(self, information): | ||||
|         self.targetFile = information['filepath'].replace('\'', '\'\\\'\'')  # Replace single quotes with '\'' | ||||
|         self.commandList = shlex.split(self.commandString) | ||||
|         self.commandString = '' | ||||
|         cmd = self.exec_cmd | ||||
|         if not '{}' in cmd: | ||||
|             cmd += ' {}' | ||||
|  | ||||
|         # Replace all instances of '{}' with the file name and convert argument list to single string. | ||||
|         for index, arg in enumerate(self.commandList): | ||||
|             if(arg == '{}'): | ||||
|                 self.commandString += '\'' + self.targetFile + '\' ' | ||||
|             else: | ||||
|                 self.commandString += arg + ' ' | ||||
|         cmd = cmd.replace('{}', shlex_quote(information['filepath'])) | ||||
|  | ||||
|         if self.targetFile not in self.commandString:  # Assume user wants the file appended to the end of the command if no {}'s were given. | ||||
|             self.commandString += '\'' + self.targetFile + '\'' | ||||
|  | ||||
|         print("[exec] Executing command: " + self.commandString) | ||||
|         self.retCode = subprocess.call(self.commandString, shell=True) | ||||
|         if(self.retCode < 0): | ||||
|             print("[exec] WARNING: Command exited with a negative return code, the process was killed externally. Your command may not of completed succesfully!") | ||||
|         elif(self.verboseOutput): | ||||
|             print("[exec] Command exited with return code: " + str(self.retCode)) | ||||
|         self._downloader.to_screen("[exec] Executing command: %s" % cmd) | ||||
|         retCode = subprocess.call(cmd, shell=True) | ||||
|         if retCode != 0: | ||||
|             raise PostProcessingError( | ||||
|                 'Command returned error code %d' % retCode) | ||||
|  | ||||
|         return None, information  # by default, keep file and do nothing | ||||
|  | ||||
|  | ||||
| class PostProcessingExecError(PostProcessingError): | ||||
|     pass | ||||
|   | ||||
| @@ -192,6 +192,13 @@ try: | ||||
| except ImportError:  # Python 2.6 | ||||
|     from xml.parsers.expat import ExpatError as compat_xml_parse_error | ||||
|  | ||||
| try: | ||||
|     from shlex import quote as shlex_quote | ||||
| except ImportError:  # Python < 3.3 | ||||
|     def shlex_quote(s): | ||||
|         return "'" + s.replace("'", "'\"'\"'") + "'" | ||||
|  | ||||
|  | ||||
| def compat_ord(c): | ||||
|     if type(c) is int: return c | ||||
|     else: return ord(c) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Philipp Hagemeister
					Philipp Hagemeister