def METHOD_NAME(self, spec, output_dir, yield_output=False, timeout=120):
    """Fetch and unpack a Hydroshare resource"""
    resource_id = spec["resource"]
    host = spec["host"]
    bag_url = f'{host["django_irods"]}{resource_id}'
    yield f"Downloading {bag_url}.\n"
    # bag downloads are prepared on demand and may need some time
    conn = self.urlopen(bag_url)
    total_wait_time = 0
    while (
        conn.status_code == 200
        and conn.headers["content-type"] != "application/zip"
    ):
        wait_time = 10
        total_wait_time += wait_time
        if total_wait_time > timeout:
            msg = "Bag taking too long to prepare, exiting now, try again later."
            yield msg
            raise ContentProviderException(msg)
        yield f"Bag is being prepared, requesting again in {wait_time} seconds.\n"
        time.sleep(wait_time)
        conn = self.urlopen(bag_url)
    if conn.status_code != 200:
        msg = f"Failed to download bag. status code {conn.status_code}.\n"
        yield msg
        raise ContentProviderException(msg)
    # Bag creation seems to need a small time buffer after it says it's ready.
    time.sleep(1)
    filehandle, _ = self._urlretrieve(bag_url)
    zip_file_object = zipfile.ZipFile(filehandle, "r")
    yield "Downloaded, unpacking contents.\n"
    zip_file_object.extractall("temp")
    # resources store the contents in the data/contents directory, which is all we want to keep
    contents_dir = os.path.join("temp", self.resource_id, "data", "contents")
    files = os.listdir(contents_dir)
    for f in files:
        shutil.move(os.path.join(contents_dir, f), output_dir)
    yield "Finished, cleaning up.\n"
    shutil.rmtree("temp")