diff options
| author | Philipp Hagemeister <phihag@phihag.de> | 2014-08-25 09:44:11 +0200 | 
|---|---|---|
| committer | Philipp Hagemeister <phihag@phihag.de> | 2014-08-25 09:44:11 +0200 | 
| commit | 348ae0a79ee9cafc6e292ca01f09839900aa52e6 (patch) | |
| tree | 49f319c798a53fdee4a4f6faca74f1d9f87b43d7 | |
| parent | 528d455632a6bbc0d0adb867caf059188b7a4cbf (diff) | |
| parent | 7833d941bb736a8dbd237f1c7bc268d671cabb68 (diff) | |
Merge remote-tracking branch 'mcd1992/exec_after_download'
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | youtube_dl/__init__.py | 12 | ||||
| -rw-r--r-- | youtube_dl/postprocessor/__init__.py | 2 | ||||
| -rw-r--r-- | youtube_dl/postprocessor/execafterdownload.py | 39 | 
4 files changed, 53 insertions, 1 deletions
| diff --git a/.gitignore b/.gitignore index 37b2fa8d3..b8128fab1 100644 --- a/.gitignore +++ b/.gitignore @@ -26,5 +26,6 @@ updates_key.pem  *.m4a  *.m4v  *.part +*.swp  test/testdata  .tox diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index a96bf9b5c..7cf5de43f 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -73,6 +73,7 @@ __authors__  = (      'Erik Johnson',      'Keith Beckman',      'Ole Ernst', +    'Aaron McDaniel (mcd1992)',  )  __license__ = 'Public Domain' @@ -119,6 +120,7 @@ from .postprocessor import (      FFmpegExtractAudioPP,      FFmpegEmbedSubtitlePP,      XAttrMetadataPP, +    ExecAfterDownloadPP,  ) @@ -550,7 +552,8 @@ 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 {}\'' )      parser.add_option_group(general)      parser.add_option_group(selection) @@ -831,6 +834,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,      }      with YoutubeDL(ydl_opts) as ydl: @@ -854,6 +858,12 @@ def _real_main(argv=None):                  ydl.add_post_processor(FFmpegAudioFixPP())              ydl.add_post_processor(AtomicParsleyPP()) + +        # 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)) +          # Update version          if opts.update_self:              update_self(ydl.to_screen, opts.verbose) diff --git a/youtube_dl/postprocessor/__init__.py b/youtube_dl/postprocessor/__init__.py index 08e6ddd00..15aa0daa9 100644 --- a/youtube_dl/postprocessor/__init__.py +++ b/youtube_dl/postprocessor/__init__.py @@ -9,6 +9,7 @@ from .ffmpeg import (      FFmpegEmbedSubtitlePP,  )  from .xattrpp import XAttrMetadataPP +from .execafterdownload import ExecAfterDownloadPP  __all__ = [      'AtomicParsleyPP', @@ -19,4 +20,5 @@ __all__ = [      'FFmpegExtractAudioPP',      'FFmpegEmbedSubtitlePP',      'XAttrMetadataPP', +    'ExecAfterDownloadPP',  ] diff --git a/youtube_dl/postprocessor/execafterdownload.py b/youtube_dl/postprocessor/execafterdownload.py new file mode 100644 index 000000000..e6f3cdfd2 --- /dev/null +++ b/youtube_dl/postprocessor/execafterdownload.py @@ -0,0 +1,39 @@ +from __future__ import unicode_literals +from .common import PostProcessor +from ..utils import PostProcessingError +import subprocess +import shlex + + +class ExecAfterDownloadPP(PostProcessor): +    def __init__(self, downloader=None, verboseOutput=None, commandString=None): +        self.verboseOutput = verboseOutput +        self.commandString = commandString + +    def run(self, information): +        self.targetFile = information['filepath'].replace('\'', '\'\\\'\'')  # Replace single quotes with '\'' +        self.commandList = shlex.split(self.commandString) +        self.commandString = '' + +        # 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 + ' ' + +        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)) + +        return None, information  # by default, keep file and do nothing + + +class PostProcessingExecError(PostProcessingError): +    pass | 
