def get_stat(self, path, relative_to=None, extended=False, follow=False): """Return file statistics. This method returns FileInfo or FileInfoExtended objects for specified path. Unless otherwise specified by `follow` parameter this method is not suppose to follow symlinks. """ result = None real_path = self.real_path(path, relative_to) key_name, file_name = os.path.split(real_path) if key_name in self._cache: # find file information for stored_file_name, file_info in self._cache[key_name]: if stored_file_name == file_name: result = file_info break if extended and result is not None: result = FileInfoExtended(size=result.size, mode=result.mode, i_mode=0, user_id=result.user_id, group_id=result.group_id, time_access=0, time_modify=result.time_modify, time_change=0, type=result.type, device=0, inode=0) else: # handle invalid files/links if extended: result = FileInfo( size=0, mode=0, user_id=0, group_id=0, time_modify=0, type=FileType.INVALID, ) else: result = FileInfoExtended(size=0, mode=0, i_mode=0, user_id=0, group_id=0, time_access=0, time_modify=0, time_change=0, type=FileType.INVALID, device=0, inode=0) return result
def _update_cache(self): """Update archive cache.""" self._cache[''] = [] # root directory for info in self._zip_file.infolist(): # detect file type if info.filename[-1] == os.path.sep: raw_name = info.filename[:-1] key_name, file_name = os.path.split(raw_name) file_type = FileType.DIRECTORY # create storage list for directory if raw_name not in self._cache: self._cache[raw_name] = [] else: key_name, file_name = os.path.split(info.filename) file_type = FileType.REGULAR # prepare file timestamp try: file_timestamp = time.mktime( datetime.datetime(*info.date_time).timetuple()) except ValueError: # set fallback timestamp for files with invalid date_time value file_timestamp = 0 # prepare file info file_info = FileInfo(size=info.file_size, mode=int(info.external_attr >> 16), user_id=0, group_id=0, time_modify=file_timestamp, type=file_type) if key_name not in self._cache: self._cache[key_name] = [] self._cache[key_name].append((file_name, file_info)) self._file_list.append(info.filename)
def get_stat(self, path, relative_to=None, extended=False, follow=False): """Return file statistics""" real_path = self.real_path(path, relative_to) try: # try getting file stats flags = (Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, Gio.FileQueryInfoFlags.NONE)[follow] file_stat = Gio.File.new_for_commandline_arg(real_path).query_info( 'standard::size,unix::mode,unix::uid,unix::gid' 'time::access,time::modified,time::changed,' 'standard::type,unix:device,unix::inode', flags, None) except: # handle invalid files/links if not extended: result = FileInfo( size=0, mode=0, user_id=0, group_id=0, time_modify=0, type=FileType.INVALID, ) else: result = FileInfoExtended(size=0, mode=0, i_mode=0, user_id=0, group_id=0, time_access=0, time_modify=0, time_change=0, type=FileType.INVALID, device=0, inode=0) return result # get file type file_type = file_stat.get_file_type() if file_type == Gio.FileType.SYMBOLIC_LINK: item_type = FileType.LINK elif file_type == Gio.FileType.DIRECTORY: item_type = FileType.DIRECTORY elif file_type == Gio.FileType.SPECIAL: item_type = FileType.DEVICE_BLOCK else: item_type = FileType.REGULAR if not extended: # create normal file information result = FileInfo( size=file_stat.get_size(), mode=file_stat.get_attribute_uint32( Gio.FILE_ATTRIBUTE_UNIX_MODE), user_id=file_stat.get_attribute_uint32( Gio.FILE_ATTRIBUTE_UNIX_UID), group_id=file_stat.get_attribute_uint32( Gio.FILE_ATTRIBUTE_UNIX_GID), time_modify=file_stat.get_attribute_uint64( Gio.FILE_ATTRIBUTE_TIME_MODIFIED), type=item_type, ) else: # create extended file information result = FileInfoExtended( size=file_stat.get_size(), mode=file_stat.get_attribute_uint32( Gio.FILE_ATTRIBUTE_UNIX_MODE), i_mode=0, user_id=file_stat.get_attribute_uint32( Gio.FILE_ATTRIBUTE_UNIX_UID), group_id=file_stat.get_attribute_uint32( Gio.FILE_ATTRIBUTE_UNIX_GID), time_access=file_stat.get_attribute_uint64( Gio.FILE_ATTRIBUTE_TIME_ACCESS), time_modify=file_stat.get_attribute_uint64( Gio.FILE_ATTRIBUTE_TIME_MODIFIED), time_change=file_stat.get_attribute_uint64( Gio.FILE_ATTRIBUTE_TIME_CHANGED), type=item_type, device=file_stat.get_attribute_uint32( Gio.FILE_ATTRIBUTE_UNIX_DEVICE), inode=file_stat.get_attribute_uint64( Gio.FILE_ATTRIBUTE_UNIX_INODE)) return result
def get_stat(self, path, relative_to=None, extended=False, follow=False): """Return file statistics""" real_path = self.real_path(path, relative_to) try: # try getting file stats file_stat = os.lstat(real_path) if not follow else os.stat( real_path) except: # handle invalid files/links if extended: result = FileInfo( size=0, mode=0, user_id=0, group_id=0, time_modify=0, type=FileType.INVALID, ) else: result = FileInfoExtended(size=0, mode=0, i_mode=0, user_id=0, group_id=0, time_access=0, time_modify=0, time_change=0, type=FileType.INVALID, device=0, inode=0) return result # get file type if stat.S_ISLNK(file_stat.st_mode): item_type = FileType.LINK elif stat.S_ISDIR(file_stat.st_mode): item_type = FileType.DIRECTORY elif stat.S_ISBLK(file_stat.st_mode): item_type = FileType.DEVICE_BLOCK elif stat.S_ISCHR(file_stat.st_mode): item_type = FileType.DEVICE_CHARACTER elif stat.S_ISSOCK(file_stat.st_mode): item_type = FileType.SOCKET else: item_type = FileType.REGULAR if not extended: # create normal file information result = FileInfo( size=file_stat.st_size, mode=stat.S_IMODE(file_stat.st_mode), user_id=file_stat.st_uid, group_id=file_stat.st_gid, time_modify=file_stat.st_mtime, type=item_type, ) else: # create extended file information result = FileInfoExtended(size=file_stat.st_size, mode=stat.S_IMODE(file_stat.st_mode), i_mode=file_stat.st_mode, user_id=file_stat.st_uid, group_id=file_stat.st_gid, time_access=file_stat.st_atime, time_modify=file_stat.st_mtime, time_change=file_stat.st_ctime, type=item_type, device=file_stat.st_dev, inode=file_stat.st_ino) return result