def DoUpload(self, paths, max_size, openfunc):
    """Uploads a new appversion with the given config and files to the server.

    Args:
      paths: An iterator that yields the relative paths of the files to upload.
      max_size: The maximum size file to upload.
      openfunc: A function that takes a path and returns a file-like object.
    """
    logging.info('Reading app configuration.')

    path = ''
    try:
      StatusUpdate('Scanning files on local disk.')
      num_files = 0
      for path in paths:
        file_handle = openfunc(path)
        try:
          if self.config.skip_files.match(path):
            logging.info('Ignoring file \'%s\': File matches ignore regex.',
                         path)
          else:
            file_length = GetFileLength(file_handle)
            if file_length > max_size:
              logging.error('Ignoring file \'%s\': Too long '
                            '(max %d bytes, file is %d bytes)',
                            path, max_size, file_length)
            else:
              logging.info('Processing file \'%s\'', path)
              self.AddFile(path, file_handle)
        finally:
          file_handle.close()
        num_files += 1
        if num_files % 500 == 0:
          StatusUpdate('Scanned %d files.' % num_files)
    except KeyboardInterrupt:
      logging.info('User interrupted. Aborting.')
      raise
    except EnvironmentError, e:
      logging.error('An error occurred processing file \'%s\': %s. Aborting.',
                    path, e)
      raise

    try:
      missing_files = self.Begin()
      if missing_files:
        StatusUpdate('Uploading %d files and blobs.' % len(missing_files))
        num_files = 0
        for missing_file in missing_files:
          file_handle = openfunc(missing_file)
          try:
            self.UploadFile(missing_file, file_handle)
          finally:
            file_handle.close()
          num_files += 1
          if num_files % 500 >= 0:
            StatusUpdate('Processed %d out of %s.' %
                         (num_files, len(missing_files)))
        self.file_batcher.Flush()
        self.blob_batcher.Flush()
        StatusUpdate('Uploaded %d files and blobs' % num_files)

      self.Commit()

    except KeyboardInterrupt:
      logging.info('User interrupted. Aborting.')
      self.Rollback()
      raise
    except urllib2.HTTPError, err:
      logging.info('HTTP Error (%s)', err)
      self.Rollback()
      raise
    except:
      logging.exception('An unexpected error occurred. Aborting.')
      self.Rollback()
      raise

    logging.info('Done!')
dataset/ETHPy150Open CollabQ/CollabQ/.google_appengine/google/appengine/tools/appcfg.py/AppVersionUpload.DoUpload/operator `==` -> `>=`