github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/clients/python/camliclient.py (about)

     1  #!/usr/bin/env python
     2  #
     3  # Camlistore uploader client for Python.
     4  #
     5  # Copyright 2010 Google Inc.
     6  #
     7  # Licensed under the Apache License, Version 2.0 (the "License");
     8  # you may not use this file except in compliance with the License.
     9  # You may obtain a copy of the License at
    10  #
    11  #     http://www.apache.org/licenses/LICENSE-2.0
    12  #
    13  # Unless required by applicable law or agreed to in writing, software
    14  # distributed under the License is distributed on an "AS IS" BASIS,
    15  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  # See the License for the specific language governing permissions and
    17  # limitations under the License.
    18  #
    19  """Command-line example client for Camlistore."""
    20  
    21  __author__ = 'Brett Slatkin (bslatkin@gmail.com)'
    22  
    23  import logging
    24  import optparse
    25  import os
    26  import re
    27  import sys
    28  
    29  try:
    30    import camli.op
    31  except ImportError:
    32    sys.path.insert(0, '../../lib/python')
    33    import camli.op
    34  
    35  
    36  def upload_files(op, path_list):
    37    """Uploads a list of files.
    38  
    39    Args:
    40      op: The CamliOp to use.
    41      path_list: The list of file paths to upload.
    42  
    43    Returns:
    44      Exit code.
    45    """
    46    real_path_set = set([os.path.abspath(path) for path in path_list])
    47    all_blob_files = [open(path, 'rb') for path in real_path_set]
    48    logging.debug('Uploading blob paths: %r', real_path_set)
    49    op.put_blobs(all_blob_files)
    50    return 0
    51  
    52  
    53  def upload_dir(op, root_path, recursive=True, ignore_patterns=[r'^\..*']):
    54    """Uploads a directory of files recursively.
    55  
    56    Args:
    57      op: The CamliOp to use.
    58      root_path: The path of the directory to upload.
    59      recursively: If the whole directory and its children should be uploaded.
    60      ignore_patterns: Set of ignore regex expressions.
    61  
    62    Returns:
    63      Exit code.
    64    """
    65    def should_ignore(dirname):
    66      for pattern in ignore_patterns:
    67        if re.match(pattern, dirname):
    68          return True
    69      return False
    70  
    71    def error(e):
    72      raise e
    73  
    74    all_blob_paths = []
    75    for dirpath, dirnames, filenames in os.walk(root_path, onerror=error):
    76      allowed_dirnames = []
    77      for name in dirnames:
    78        if not should_ignore(name):
    79          allowed_dirnames.append(name)
    80      for i in xrange(len(dirnames)):
    81        dirnames.pop(0)
    82      if recursive:
    83        dirnames.extend(allowed_dirnames)
    84  
    85      all_blob_paths.extend(os.path.join(dirpath, name) for name in filenames)
    86  
    87    logging.debug('Uploading dir=%r', root_path)
    88    upload_files(op, all_blob_paths)
    89    return 0
    90  
    91  
    92  def download_files(op, blobref_list, target_dir):
    93    """Downloads blobs to a target directory.
    94  
    95    Args:
    96      op: The CamliOp to use.
    97      blobref_list: The list of blobrefs to download.
    98      target_dir: The directory to save the downloaded blobrefs in.
    99  
   100    Returns:
   101      Exit code. 1 if there were any missing blobrefs.
   102    """
   103    all_blobs = set(blobref_list)
   104    found_blobs = set()
   105  
   106    def start_out(blobref):
   107      blob_path = os.path.join(target_dir, blobref)
   108      return open(blob_path, 'wb')
   109  
   110    def end_out(blobref, blob_file):
   111      found_blobs.add(blobref)
   112      blob_file.close()
   113  
   114    op.get_blobs(blobref_list, start_out=start_out, end_out=end_out)
   115    missing_blobs = all_blobs - found_blobs
   116    if missing_blobs:
   117      print >>sys.stderr, 'Missing blobrefs: %s' % ', '.join(missing_blobs)
   118      return 1
   119    else:
   120      return 0
   121  
   122  
   123  def main(argv):
   124    usage = \
   125  """usage: %prog [options] [command]
   126  
   127  Commands:
   128    put <filepath> ... [filepathN]
   129    \t\t\tupload a set of specific files
   130    putdir <directory>
   131    \t\t\tput all blobs present in a directory recursively
   132    get <blobref> ... [blobrefN] <directory>
   133    \t\t\tget and save blobs to a directory, named as their blobrefs;
   134    \t\t\t(!) files already present will be overwritten"""
   135    parser = optparse.OptionParser(usage=usage)
   136    parser.add_option('-a', '--auth', dest='auth',
   137                      default='',
   138                      help='username:pasword for HTTP basic authentication')
   139    parser.add_option('-s', '--server', dest='server',
   140                      default='localhost:3179',
   141                      help='hostname:port to connect to')
   142    parser.add_option('-d', '--debug', dest='debug',
   143                      action='store_true',
   144                      help='print debug logging')
   145    parser.add_option('-i', '--ignore_patterns', dest="ignore_patterns",
   146                      default="",
   147                      help='regexp patterns to ignore')
   148  
   149    def error_and_exit(message):
   150      print >>sys.stderr, message, '\n'
   151      parser.print_help()
   152      sys.exit(2)
   153  
   154    opts, args = parser.parse_args(argv[1:])
   155    if not args:
   156      parser.print_help()
   157      sys.exit(2)
   158  
   159    if opts.debug:
   160      logging.getLogger().setLevel(logging.DEBUG)
   161  
   162    op = camli.op.CamliOp(opts.server, auth=opts.auth, basepath="/bs")
   163    command = args[0].lower()
   164  
   165    if command == 'putdir':
   166      if len(args) < 2:
   167        error_and_exit('Must supply at least a directory to put')
   168      return upload_dir(op, args[1], opts.ignore_patterns)
   169    elif command == 'put':
   170      if len(args) < 2:
   171        error_and_exit('Must supply one or more file paths to upload')
   172      return upload_files(op, args[1:])
   173    elif command == 'get':
   174      if len(args) < 3:
   175        error_and_exit('Must supply one or more blobrefs to download '
   176                        'and a directory to save them to')
   177      return download_files(op, args[1:-1], args[-1])
   178    else:
   179      error_and_exit('Unknown command: %s' % command)
   180  
   181  
   182  if __name__ == '__main__':
   183    sys.exit(main(sys.argv))