def _cmd_get_fs_info(self, cmd): script = """__thonny_helper.os.system("stat -f -c '%b %f %a %S' {path}") or None""".format( path=cmd.path) out, err = self._execute(script, capture_output=True) try: total, free, available, block_size = map(int, out.strip().split()) return { "total": total * block_size, "free": available * block_size, "used": (total - free) * block_size, } except Exception: raise ManagementError(script, out, err)
def _write_file_via_serial( self, source_fp: BinaryIO, target_path: str, file_size: int, callback: Callable[[int, int], None], ) -> None: out, err = self._execute( dedent(""" try: __thonny_path = '{path}' __thonny_written = 0 __thonny_fp = open(__thonny_path, 'wb') except Exception as e: print(str(e)) """).format(path=target_path), capture_output=True, ) if "readonly" in (out + err).replace("-", "").lower(): raise ReadOnlyFilesystemError() elif out + err: raise RuntimeError( "Could not open file %s for writing, output:\n%s" % (target_path, out + err)) # Define function to allow shorter write commands hex_mode = self._should_hexlify(target_path) if hex_mode: self._execute_without_output( dedent(""" from binascii import unhexlify as __thonny_unhex def __W(x): global __thonny_written __thonny_written += __thonny_fp.write(__thonny_unhex(x)) __thonny_fp.flush() if hasattr(__thonny_helper.os, "sync"): __thonny_helper.os.sync() """)) elif self._connected_to_microbit(): # doesn't have neither BytesIO.flush, nor os.sync self._execute_without_output( dedent(""" def __W(x): global __thonny_written __thonny_written += __thonny_fp.write(x) """)) else: self._execute_without_output( dedent(""" def __W(x): global __thonny_written __thonny_written += __thonny_fp.write(x) __thonny_fp.flush() if hasattr(__thonny_helper.os, "sync"): __thonny_helper.os.sync() """)) bytes_sent = 0 block_size = 512 while True: callback(bytes_sent, file_size) block = source_fp.read(block_size) if block: if hex_mode: script = "__W(%r)" % binascii.hexlify(block) else: script = "__W(%r)" % block out, err = self._execute(script, capture_output=True) if out or err: self._show_error( "\nCould not write next block after having written %d bytes to %s" % (bytes_sent, target_path)) if bytes_sent > 0: self._show_error( "Make sure your device's filesystem has enough free space. " + "(When overwriting a file, the old content may occupy space " "until the end of the operation.)\n") raise ManagementError(script, out, err) bytes_sent += len(block) if len(block) < block_size: break bytes_received = self._evaluate("__thonny_written") if bytes_received != bytes_sent: raise UserError("Expected %d written bytes but wrote %d" % (bytes_sent, bytes_received)) # clean up self._execute_without_output( dedent(""" try: del __W del __thonny_written del __thonny_path __thonny_fp.close() del __thonny_fp del __thonny_result del __thonny_unhex except: pass """)) return bytes_sent