vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 | # |
| 4 | # Use of this source code is governed by a BSD-style license |
| 5 | # that can be found in the LICENSE file in the root of the source |
| 6 | # tree. An additional intellectual property rights grant can be found |
| 7 | # in the file PATENTS. All contributing project authors may |
| 8 | # be found in the AUTHORS file in the root of the source tree. |
| 9 | |
phoglund | be81fa5 | 2015-10-29 02:22:47 -0700 | [diff] [blame] | 10 | import multiprocessing |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 11 | import os |
| 12 | import subprocess |
| 13 | import sys |
| 14 | |
| 15 | _DEFAULT_PADDING = 4 |
| 16 | |
| 17 | |
| 18 | class HelperError(Exception): |
| 19 | """Exception raised for errors in the helper.""" |
| 20 | pass |
| 21 | |
| 22 | |
kjellander | f5318e1 | 2017-03-09 02:26:46 -0800 | [diff] [blame] | 23 | def ZeroPad(number, padding=_DEFAULT_PADDING): |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 24 | """Converts an int into a zero padded string. |
| 25 | |
| 26 | Args: |
| 27 | number(int): The number to convert. |
| 28 | padding(int): The number of chars in the output. Note that if you pass for |
| 29 | example number=23456 and padding=4, the output will still be '23456', |
| 30 | i.e. it will not be cropped. If you pass number=2 and padding=4, the |
| 31 | return value will be '0002'. |
| 32 | Return: |
| 33 | (string): The zero padded number converted to string. |
| 34 | """ |
| 35 | return str(number).zfill(padding) |
| 36 | |
| 37 | |
kjellander | f5318e1 | 2017-03-09 02:26:46 -0800 | [diff] [blame] | 38 | def RunShellCommand(cmd_list, fail_msg=None): |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 39 | """Executes a command. |
| 40 | |
| 41 | Args: |
kjellander@webrtc.org | 38ebf98 | 2013-03-08 10:58:21 +0000 | [diff] [blame] | 42 | cmd_list(list): Command list to execute. |
| 43 | fail_msg(string): Message describing the error in case the command fails. |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 44 | |
| 45 | Return: |
| 46 | (string): The standard output from running the command. |
| 47 | |
| 48 | Raise: |
| 49 | HelperError: If command fails. |
| 50 | """ |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 51 | process = subprocess.Popen(cmd_list, stdout=subprocess.PIPE, |
| 52 | stderr=subprocess.PIPE) |
| 53 | output, error = process.communicate() |
| 54 | if process.returncode != 0: |
kjellander@webrtc.org | 38ebf98 | 2013-03-08 10:58:21 +0000 | [diff] [blame] | 55 | if fail_msg: |
| 56 | print >> sys.stderr, fail_msg |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 57 | raise HelperError('Failed to run %s: command returned %d and printed ' |
kjellander@webrtc.org | 38ebf98 | 2013-03-08 10:58:21 +0000 | [diff] [blame] | 58 | '%s and %s' % (' '.join(cmd_list), process.returncode, |
| 59 | output, error)) |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 60 | return output.strip() |
| 61 | |
| 62 | |
kjellander | f5318e1 | 2017-03-09 02:26:46 -0800 | [diff] [blame] | 63 | def PerformActionOnAllFiles(directory, file_pattern, file_extension, |
| 64 | start_number, action, **kwargs): |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 65 | """Function that performs a given action on all files matching a pattern. |
| 66 | |
| 67 | It is assumed that the files are named file_patternxxxx.file_extension, where |
phoglund | be81fa5 | 2015-10-29 02:22:47 -0700 | [diff] [blame] | 68 | xxxx are digits starting from start_number. |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 69 | |
| 70 | Args: |
| 71 | directory(string): The directory where the files live. |
| 72 | file_pattern(string): The name pattern of the files. |
| 73 | file_extension(string): The files' extension. |
| 74 | start_number(int): From where to start to count frames. |
kjellander@webrtc.org | ccb52c2 | 2012-10-10 16:11:28 +0000 | [diff] [blame] | 75 | action(function): The action to be performed over the files. Must return |
phoglund | be81fa5 | 2015-10-29 02:22:47 -0700 | [diff] [blame] | 76 | False if the action failed, True otherwise. It should take a file name |
| 77 | as the first argument and **kwargs as arguments. The function must be |
| 78 | possible to pickle, so it cannot be a bound function (for instance). |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 79 | |
| 80 | Return: |
| 81 | (bool): Whether performing the action over all files was successful or not. |
| 82 | """ |
| 83 | file_prefix = os.path.join(directory, file_pattern) |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 84 | file_number = start_number |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 85 | |
phoglund | be81fa5 | 2015-10-29 02:22:47 -0700 | [diff] [blame] | 86 | process_pool = multiprocessing.Pool(processes=multiprocessing.cpu_count()) |
| 87 | results = [] |
| 88 | while True: |
kjellander | f5318e1 | 2017-03-09 02:26:46 -0800 | [diff] [blame] | 89 | zero_padded_file_number = ZeroPad(file_number) |
vspasova@webrtc.org | 400e7da | 2012-08-15 10:25:12 +0000 | [diff] [blame] | 90 | file_name = file_prefix + zero_padded_file_number + '.' + file_extension |
phoglund | be81fa5 | 2015-10-29 02:22:47 -0700 | [diff] [blame] | 91 | if not os.path.isfile(file_name): |
| 92 | break |
| 93 | future = process_pool.apply_async(action, args=(file_name,), kwds=kwargs) |
| 94 | results.append(future) |
| 95 | file_number += 1 |
| 96 | |
| 97 | successful = True |
| 98 | for result in results: |
| 99 | if not result.get(): |
| 100 | print "At least one action %s failed for files %sxxxx.%s." % ( |
| 101 | action, file_pattern, file_extension) |
| 102 | successful = False |
| 103 | |
| 104 | process_pool.close() |
| 105 | return successful |