Home | History | Annotate | Download | only in barcode_tools
      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 
     10 import multiprocessing
     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 
     23 def zero_pad(number, padding=_DEFAULT_PADDING):
     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 
     38 def run_shell_command(cmd_list, fail_msg=None):
     39   """Executes a command.
     40 
     41   Args:
     42     cmd_list(list): Command list to execute.
     43     fail_msg(string): Message describing the error in case the command fails.
     44 
     45   Return:
     46     (string): The standard output from running the command.
     47 
     48   Raise:
     49     HelperError: If command fails.
     50   """
     51   process = subprocess.Popen(cmd_list, stdout=subprocess.PIPE,
     52                              stderr=subprocess.PIPE)
     53   output, error = process.communicate()
     54   if process.returncode != 0:
     55     if fail_msg:
     56       print >> sys.stderr, fail_msg
     57     raise HelperError('Failed to run %s: command returned %d and printed '
     58                       '%s and %s' % (' '.join(cmd_list), process.returncode,
     59                                      output, error))
     60   return output.strip()
     61 
     62 
     63 def perform_action_on_all_files(directory, file_pattern, file_extension,
     64                                 start_number, action, **kwargs):
     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
     68   xxxx are digits starting from start_number.
     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.
     75     action(function): The action to be performed over the files. Must return
     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).
     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)
     84   file_number = start_number
     85 
     86   process_pool = multiprocessing.Pool(processes=multiprocessing.cpu_count())
     87   results = []
     88   while True:
     89     zero_padded_file_number = zero_pad(file_number)
     90     file_name = file_prefix + zero_padded_file_number + '.' + file_extension
     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
    106