def _size(self, filepath): files_count = 0 files_size = 0 if not path.isdir(filepath): if self.follow_symlinks: filestat = stat(filepath) else: filestat = lstat(filepath) yield { F_TYPE: T_SIZE, F_PATH: filepath, F_FILES: 1, F_SIZE: filestat.st_size, } return for root, dirs, files, syms, hards, specials in self._walk_scandir(filepath): for f in files: files_count += 1 files_size += f.stat().st_size if self._terminate.is_set(): break if self._terminate.is_set(): break yield { F_TYPE: T_SIZE, F_PATH: filepath, F_FILES: files_count, F_SIZE: files_size, }
def _pack_any(self, filepath): try: if path.isfile(filepath): root = path.dirname(filepath) basename = path.basename(filepath) portions = self._pack_file(basename, top=root) header = next(portions) if self.follow_symlinks: filestat = stat(filepath) else: filestat = lstat(filepath) header.update({ F_TYPE: T_FILE, F_STAT: self._stat_to_vec(filestat), F_ROOT: root, }) yield header for portion in portions: yield portion del portion elif path.isdir(filepath): if self.find_size: for portion in self._size(filepath): yield portion del portion for portion in self._pack_path(filepath): yield portion del portion else: yield { F_TYPE: T_EXC, F_EXC: 'No download target', F_DATA: filepath } return yield { F_TYPE: T_FINISH, F_DATA: filepath } except Exception, e: yield { F_TYPE: T_EXC, F_EXC: str(type(e)), F_DATA: str(e) }
def _pack_any(self, filepath): try: supported_archive = self._is_supported_archive(filepath) if supported_archive: archive, archive_filepath, archive_subpath = supported_archive if archive == 'zip': with ZipFile(archive_filepath) as zf: for item in zf.infolist(): if item.filename == archive_subpath or \ item.filename.startswith(archive_subpath+'/'): try: archive_filename = item.filename.decode( sys.getfilesystemencoding()) except UnicodeDecodeError: archive_filename = item.filename yield { F_TYPE: T_FILE, F_PATH: '/'.join( [archive_filepath, archive_filename]) } for portion in self._pack_fileobj( zf.open(item)): yield portion elif archive == 'tar': with open_tarfile(archive_filepath) as tf: for item in tf: # For now support only simple files extraction, same as zip if not item.isfile(): continue if item.name == archive_subpath or \ item.name.startswith(archive_subpath+'/'): try: archive_filename = item.name.decode( sys.getfilesystemencoding()) except UnicodeDecodeError: archive_filename = item.name yield { F_TYPE: T_FILE, F_PATH: u'/'.join( [archive_filepath, archive_filename]) } for portion in self._pack_fileobj( tf.extractfile(item)): yield portion elif path.isfile(filepath): root = path.dirname(filepath) basename = path.basename(filepath) portions = self._pack_file(basename, top=root) header = next(portions) if self.follow_symlinks: filestat = stat(filepath) else: filestat = lstat(filepath) header.update({ F_TYPE: T_FILE, F_STAT: self._stat_to_vec(filestat), F_ROOT: root, }) yield header for portion in portions: yield portion del portion elif path.isdir(filepath): if self.find_size: for portion in self._size(filepath): yield portion del portion for portion in self._pack_path(filepath): yield portion del portion else: yield { F_TYPE: T_EXC, F_EXC: 'No download target', F_DATA: filepath } return yield {F_TYPE: T_FINISH, F_DATA: filepath} except Exception, e: yield { F_TYPE: T_EXC, F_EXC: str(type(e)), F_DATA: str(e) + traceback.format_exc(limit=20) }
def safe_stat(path): path = try_unicode(path) try: return lstat(path) except: return FakeStat()