def _make_file_info(fs, path, info): file_info = {} file_info["filename"] = path file_info["emptystream"] = empty = info.is_dir or info.size == 0 file_info["origin"] = None if empty else _Origin(fs, path) created = info.get("details", "created") if created is not None: file_info["creationtime"] = ArchiveTimestamp.from_datetime(created) modified = info.get("details", "modified") if modified is not None: file_info["lastwritetime"] = ArchiveTimestamp.from_datetime( modified) accessed = info.get("details", "accessed") if created is not None: file_info["lastaccesstime"] = ArchiveTimestamp.from_datetime( accessed) if info.is_dir: file_info["attributes"] = stat.FILE_ATTRIBUTE_DIRECTORY file_info["attributes"] |= FILE_ATTRIBUTE_UNIX_EXTENSION file_info["attributes"] |= stat.S_IFDIR << 16 else: file_info["attributes"] = stat.FILE_ATTRIBUTE_ARCHIVE file_info["attributes"] |= FILE_ATTRIBUTE_UNIX_EXTENSION file_info["uncompressed"] = info.size permissions = info.get("access", "permissions") if permissions is not None: file_info["attributes"] |= Permissions.load(permissions).mode << 16 return file_info
def _read_times(self, fp: BinaryIO, name: str) -> None: defined = read_boolean(fp, len(self.files), checkall=True) # NOTE: the "external" flag is currently ignored, should be 0x00 external = fp.read(1) assert external == b'\x00' for i, f in enumerate(self.files): f[name] = ArchiveTimestamp(read_real_uint64(fp)[0]) if defined[i] else None
def _readTimes(self, fp: BinaryIO, files: List[Dict[str, Any]], name: str) -> None: defined = read_boolean(fp, len(files), checkall=1) # NOTE: the "external" flag is currently ignored, should be 0x00 self.external = fp.read(1) for i in range(len(files)): if defined[i]: files[i][name] = ArchiveTimestamp(read_real_uint64(fp)[0]) else: files[i][name] = None
def _set_file_property(self, outfilename: str, properties: Dict[str, Any]) -> None: # creation time creationtime = ArchiveTimestamp(properties['lastwritetime']).totimestamp() if creationtime is not None: os.utime(outfilename, times=(creationtime, creationtime)) if os.name == 'posix': st_mode = properties['posix_mode'] if st_mode is not None: os.chmod(outfilename, st_mode) return # fallback: only set readonly if specified if properties['readonly'] and not properties['is_directory']: ro_mask = 0o777 ^ (stat.S_IWRITE | stat.S_IWGRP | stat.S_IWOTH) os.chmod(outfilename, os.stat(outfilename).st_mode & ro_mask)
def _write_times(self, fp: BinaryIO, propid, name: str) -> None: write_byte(fp, propid) defined = [] # type: List[bool] num_defined = 0 # type: int for f in self.files: if name in f.keys(): if f[name] is not None: defined.append(True) num_defined += 1 size = num_defined * 8 + 2 if not reduce(and_, defined): size += bits_to_bytes(num_defined) write_uint64(fp, size) write_boolean(fp, defined, all_defined=True) write_byte(fp, b'\x00') for i, file in enumerate(self.files): if defined[i]: write_real_uint64(fp, ArchiveTimestamp.from_datetime(file[name])) else: pass