def unpack_zipfile(filename, extract_dir, progress_filter=default_filter):
if not zipfile.is_zipfile(filename):<EOL><INDENT>raise UnrecognizedFormat("<STR_LIT>" % (filename,))<EOL><DEDENT>with ContextualZipFile(filename) as z:<EOL><INDENT>for info in z.infolist():<EOL><INDENT>name = info.filename<EOL>if name.startswith('<STR_LIT:/>') or '<STR_LIT:..>' in name.split('<STR_LIT:/>'):<EOL><INDENT>continue<EOL><DEDENT>target = os.path.join(extract_dir, *name.split('<STR_LIT:/>'))<EOL>target = progress_filter(name, target)<EOL>if not target:<EOL><INDENT>continue<EOL><DEDENT>if name.endswith('<STR_LIT:/>'):<EOL><INDENT>ensure_directory(target)<EOL><DEDENT>else:<EOL><INDENT>ensure_directory(target)<EOL>data = z.read(info.filename)<EOL>with open(target, '<STR_LIT:wb>') as f:<EOL><INDENT>f.write(data)<EOL><DEDENT><DEDENT>unix_attributes = info.external_attr >> <NUM_LIT:16><EOL>if unix_attributes:<EOL><INDENT>os.chmod(target, unix_attributes)<EOL><DEDENT><DEDENT><DEDENT>
Unpack zip `filename` to `extract_dir`

    Raises ``UnrecognizedFormat`` if `filename` is not a zipfile (as determined
    by ``zipfile.is_zipfile()``).  See ``unpack_archive()`` for an explanation
    of the `progress_filter` argument.