def extract_bower_zipfile(self, zip_file, dest, expected_version=None):
        bower_json = None
        root = None
        deps_installed = []
        for info in zip_file.infolist():
            if PurePath(info.filename).name == "bower.json":
                with zip_file.open(info) as f:
                    bower_json = json.load(f)
                    root = str(PurePath(info.filename).parent)
                break
        version = bower_json["version"]
        if expected_version is not None:
            expected_version = Bower.clean_semver(expected_version)
            if not semver.match(version, expected_version):
                click.secho("error: versions do not match ({} =/= {})".format(
                    version, expected_version))
                raise InvalidPackageError
        if "dependencies" in bower_json:
            for package, version in bower_json["dependencies"].items():
                url = Bower.get_package_url(package)
                deps_installed.extend(self.get_bower_package(
                    url, dest=dest, version=version))
        ignore_patterns = [GitIgnorePattern(ig) for ig in bower_json["ignore"]]
        path_spec = PathSpec(ignore_patterns)
        namelist = [path for path in zip_file.namelist()
                    if PurePath(path).parts[0] == root]
        ignored = list(path_spec.match_files(namelist))
        for path in namelist:
            dest_path = PurePath(
                bower_json["name"],
                *PurePath(path).parts[1:])

            if path in ignored:
                continue

            for path in ignored:
                for parent in PurePath(path):
                    if parent in ignored:
                        continue

            if path.endswith("/"):
                if list(path_spec.match_files([str(dest_path)])):
                    ignored.append(PurePath(path))
                elif not (dest / dest_path).is_dir():
                    (dest / dest_path).mkdir(parents=True)
            else:
                target_path = dest / dest_path.parent / dest_path.name
                source = zip_file.open(path)
                target = target_path.open("wb")
                with source, target:
                    shutil.copyfileobj(source, target)
        deps_installed.append((bower_json["name"], bower_json["version"]))
        return deps_installed
def find_example_file(
        top_directory_name, shuffled=True, spc_date_string=None,
        batch_number=None, raise_error_if_missing=True):
    """Looks for file with input examples.

    If `shuffled = True`, this method looks for a file with shuffled examples
    (from many different times).  If `shuffled = False`, this method looks for a
    file with examples from one SPC date.

    :param top_directory_name: Name of top-level directory with input examples.
    :param shuffled: Boolean flag.  The role of this flag is explained in the
        general discussion above.
    :param spc_date_string: [used only if `shuffled = False`]
        SPC date (format "yyyymmdd").
    :param batch_number: [used only if `shuffled = True`]
        Batch number (integer).
    :param raise_error_if_missing: Boolean flag.  If file is missing and
        `raise_error_if_missing = True`, this method will error out.
    :return: example_file_name: Path to file with input examples.  If file is
        missing and `raise_error_if_missing = False`, this is the *expected*
        path.
    :raises: ValueError: if file is missing and `raise_error_if_missing = True`.
    """

    error_checking.assert_is_string(top_directory_name)
    error_checking.assert_is_boolean(shuffled)
    error_checking.assert_is_boolean(raise_error_if_missing)

    if shuffled:
        error_checking.assert_is_integer(batch_number)
        error_checking.assert_is_geq(batch_number, 0)

        first_batch_number = int(number_rounding.floor_to_nearest(
            batch_number, NUM_BATCHES_PER_DIRECTORY))
        last_batch_number = first_batch_number + NUM_BATCHES_PER_DIRECTORY - 1

        example_file_name = (
            '{0:s}/batches{1:07d}-{2:07d}/input_examples_batch{3:07d}.nc'
        ).format(top_directory_name, first_batch_number, last_batch_number,
                 batch_number)
    else:
        time_conversion.spc_date_string_to_unix_sec(spc_date_string)

        example_file_name = (
            '{0:s}/{1:s}/input_examples_{2:s}.nc'
        ).format(top_directory_name, spc_date_string[:4], spc_date_string)

    if raise_error_if_missing and not os.path.isfile(example_file_name):
        error_string = 'Cannot find file.  Expected at: "{0:s}"'.format(
            example_file_name)
        raise ValueError(error_string)

    return example_file_name