def request_files(self) -> Iterator[str]: for f in self.files: if f.ftype is FileType.directory or (f.ftype is FileType.link and f.remote_target): continue read_signature = self.use_rsync if read_signature and f.ftype is FileType.regular: try: sr = os.stat(f.expanded_local_path, follow_symlinks=False) except OSError: read_signature = False else: read_signature = sr.st_size > 4096 yield FileTransmissionCommand( action=Action.file, name=f.remote_path, file_id=f.file_id, ttype=TransmissionType.rsync if read_signature else TransmissionType.simple, compression=Compression.zlib if isinstance( f.decompressor, ZlibDecompressor) else Compression.none).serialize() if read_signature: f.expect_diff = True fs = signature_of_file(f.expanded_local_path) for chunk in fs: f.sent_bytes += len(chunk) for data in split_for_transfer(chunk, file_id=f.file_id): yield data.serialize() yield FileTransmissionCommand( file_id=f.file_id, action=Action.end_data).serialize()
def start_transfer(self) -> Iterator[str]: yield FileTransmissionCommand(action=Action.receive, bypass=self.bypass, size=len(self.spec)).serialize() for i, x in enumerate(self.spec): yield FileTransmissionCommand(action=Action.file, file_id=str(i), name=x).serialize() self.progress_tracker.start_transfer()
def serialized_cmd(**fields) -> str: if 'id' not in fields: fields['id'] = 'test' for k, A in (('action', Action), ('ftype', FileType), ('ttype', TransmissionType), ('compression', Compression)): if k in fields: fields[k] = A[fields[k]] if isinstance(fields.get('data'), str): fields['data'] = fields['data'].encode('utf-8') ans = FileTransmissionCommand(**fields) return ans.serialize()
def serialized_cmd(**fields) -> str: for k, A in (('action', Action), ('container_fmt', Container), ('compression', Compression)): if k in fields: fields[k] = A[fields[k]] if isinstance(fields.get('data'), str): fields['data'] = fields['data'].encode('utf-8') ans = FileTransmissionCommand() for k in fields: setattr(ans, k, fields[k]) return ans.serialize()
def metadata_command(self, use_rsync: bool = False) -> FileTransmissionCommand: self.ttype = TransmissionType.rsync if self.rsync_capable and use_rsync else TransmissionType.simple self.compression = Compression.zlib if self.compression_capable else Compression.none self.compressor: Union[ ZlibCompressor, IdentityCompressor] = ZlibCompressor( ) if self.compression is Compression.zlib else IdentityCompressor( ) return FileTransmissionCommand(action=Action.file, compression=self.compression, ftype=self.file_type, name=self.remote_path, permissions=self.permissions, mtime=self.mtime, file_id=self.file_id, ttype=self.ttype)
def _on_osc(self, osc: str) -> None: idx = osc.find(';') if idx <= 0: return q = osc[:idx] if q == '52': widx = osc.find(';', idx + 1) if widx < idx: from_primary = osc.find('p', idx + 1) > -1 payload = '' else: from base64 import standard_b64decode from_primary = osc.find('p', idx+1, widx) > -1 data = memoryview(osc.encode('ascii')) payload = standard_b64decode(data[widx+1:]).decode('utf-8') self.handler.on_clipboard_response(payload, from_primary) elif q == ftc_code: from kitty.file_transmission import FileTransmissionCommand data = memoryview(osc.encode('ascii')) self.handler.on_file_transfer_response(FileTransmissionCommand.deserialize(data[idx+1:]))
def make_tree(all_files: List[File], local_base: str) -> TreeNode: fid_map = {f.remote_id: f for f in all_files} node_map: Dict[str, TreeNode] = {} root_node = TreeNode(File(FileTransmissionCommand(file_id='-1')), local_base) def ensure_parent(f: File) -> TreeNode: if not f.parent: return root_node parent = node_map.get(f.parent) if parent is None: fp = fid_map[f.parent] gp = ensure_parent(fp) parent = gp.add_child(fp) return parent for f in all_files: p = ensure_parent(f) p.add_child(f) return root_node
def next_chunks(self) -> Iterator[str]: if self.active_file is None: self.activate_next_ready_file() af = self.active_file if af is None: return chunk = b'' self.current_chunk_uncompressed_sz = 0 while af.state is not FileState.finished and not chunk: chunk, usz = af.next_chunk() self.current_chunk_uncompressed_sz += usz is_last = af.state is FileState.finished if len(chunk): for ftc in split_for_transfer(chunk, file_id=af.file_id, mark_last=is_last): yield ftc.serialize() elif is_last: yield FileTransmissionCommand(action=Action.end_data, file_id=af.file_id, data=b'').serialize()
def abort_transfer(self, delay: float = 5) -> None: self.send_payload( FileTransmissionCommand(action=Action.cancel).serialize()) self.manager.state = SendState.canceled self.asyncio_loop.call_later(delay, self.quit_loop, 1)
def transfer_finished(self) -> None: self.send_payload( FileTransmissionCommand(action=Action.finish).serialize()) self.quit_after_write_code = 1 if self.failed_files else 0
def start_transfer(self) -> str: return FileTransmissionCommand(action=Action.send, bypass=self.bypass).serialize()
def finish_code(self) -> str: return FileTransmissionCommand(action=Action.finish).serialize()