Example #1
0
    def _create_venv(self):
        path = askdirectory(
            parent=self.winfo_toplevel(),
            initialdir=None,
            title=tr(
                "Select an existing virtual environemnt or an empty directory for new virtual environment"
            ),
        )

        assert os.path.isdir(path)
        path = normpath_with_actual_case(path)

        if not os.listdir(path):
            proc = subprocess.Popen(
                [running.get_interpreter_for_subprocess(), "-m", "venv", path],
                stdin=None,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                universal_newlines=True,
            )
            dlg = SubprocessDialog(self, proc,
                                   tr("Creating virtual environment"))
            ui_utils.show_dialog(dlg)

        if running_on_windows():
            exe_path = normpath_with_actual_case(
                os.path.join(path, "Scripts", "python.exe"))
        else:
            exe_path = os.path.join(path, "bin", "python3")

        if os.path.exists(exe_path):
            self._configuration_variable.set(exe_path)
        else:
            # Undefined error handling.
            pass
Example #2
0
def choose_node_for_file_operations(master, prompt):
    if get_runner().has_own_filesystem():
        dlg = NodeChoiceDialog(master, prompt)
        show_dialog(dlg, master)
        return dlg.result
    else:
        return "local"
Example #3
0
    def _create_private_venv(self,
                             path,
                             description,
                             clear=False,
                             upgrade=False):
        if not _check_venv_installed(self):
            return
        # Don't include system site packages
        # This way all students will have similar configuration
        # independently of system Python (if Thonny is used with system Python)

        # NB! Cant run venv.create directly, because in Windows bundle
        # it tries to link venv to thonny.exe.
        # Need to run it via proper python
        args = ["-m", "venv"]
        if clear:
            args.append("--clear")
        if upgrade:
            args.append("--upgrade")

        try:
            import ensurepip
        except ImportError:
            args.append("--without-pip")

        args.append(path)

        proc = create_frontend_python_process(args)

        from thonny.workdlg import SubprocessDialog

        dlg = SubprocessDialog(
            get_workbench(),
            proc,
            "Preparing the backend",
            long_description=description,
            autostart=True,
        )
        try:
            ui_utils.show_dialog(dlg)
        except Exception:
            # if using --without-pip the dialog may close very quickly
            # and for some reason wait_window would give error then
            logging.exception("Problem with waiting for venv creation dialog")
        get_workbench().become_active_window(
        )  # Otherwise focus may get stuck somewhere

        bindir = os.path.dirname(get_private_venv_executable())
        # create private env marker
        marker_path = os.path.join(bindir, "is_private")
        with open(marker_path, mode="w") as fp:
            fp.write("# This file marks Thonny-private venv")

        # Create recommended pip conf to get rid of list deprecation warning
        # https://github.com/pypa/pip/issues/4058
        pip_conf = "pip.ini" if running_on_windows() else "pip.conf"
        with open(os.path.join(path, pip_conf), mode="w") as fp:
            fp.write("[list]\nformat = columns")

        assert os.path.isdir(path)
Example #4
0
 def _run_pip_with_dialog(self, args, title) -> Tuple[int, str, str]:
     args = ["-m", "thonny.plugins.micropython.minipip"] + args
     proc = running.create_frontend_python_process(args, stderr=subprocess.STDOUT)
     cmd = proc.cmd
     dlg = SubprocessDialog(self, proc, "minipip", long_description=title, autostart=True)
     ui_utils.show_dialog(dlg)
     return dlg.returncode, dlg.stdout, dlg.stderr
Example #5
0
 def send_command_and_wait(self, cmd: CommandToBackend,
                           dialog_title: str) -> MessageFromBackend:
     dlg = InlineCommandDialog(get_workbench(),
                               cmd,
                               title=dialog_title + " ...")
     show_dialog(dlg)
     return dlg.response
Example #6
0
    def _ask_feedback(self, event=None):

        all_snapshots = self._snapshots_per_main_file[self._current_snapshot["main_file_path"]]

        # TODO: select only snapshots which are not sent yet
        snapshots = all_snapshots

        ui_utils.show_dialog(FeedbackDialog(get_workbench(), self.main_file_path, snapshots))
Example #7
0
def ask_backend_path(master, dialog_kind):
    proxy = get_runner().get_backend_proxy()
    if not proxy:
        return None

    assert proxy.has_own_filesystem()

    dlg = BackendFileDialog(master, dialog_kind, proxy.get_default_directory())
    show_dialog(dlg, master)
    return dlg.result
Example #8
0
def ask_backend_path(master, dialog_kind):
    proxy = get_runner().get_backend_proxy()
    if not proxy:
        return None

    assert proxy.supports_remote_files()

    dlg = BackendFileDialog(master, dialog_kind, proxy.get_cwd())
    show_dialog(dlg, master)
    return dlg.result
Example #9
0
def choose_node_for_file_operations(master, prompt):
    if get_runner().supports_remote_files():
        dlg = NodeChoiceDialog(master, prompt)
        show_dialog(dlg, master)
        if not get_runner().ready_for_remote_file_operations(
                propose_waiting=True):
            return None
        return dlg.result
    else:
        return "local"
Example #10
0
    def _create_venv(self, event=None):
        if not _check_venv_installed(self):
            return

        messagebox.showinfo(
            "Creating new virtual environment",
            "After clicking 'OK' you need to choose an empty directory, "
            "which will be the root of your new virtual environment.",
            parent=self,
        )
        path = None
        while True:
            path = askdirectory(
                parent=self.winfo_toplevel(),
                initialdir=path,
                title=tr("Select empty directory for new virtual environment"),
            )
            if not path:
                return

            if os.listdir(path):
                messagebox.showerror(
                    tr("Bad directory"),
                    tr("Selected directory is not empty.\nSelect another or cancel."
                       ),
                    master=self,
                )
            else:
                break
        assert os.path.isdir(path)
        path = normpath_with_actual_case(path)

        proc = subprocess.Popen(
            [running.get_interpreter_for_subprocess(), "-m", "venv", path],
            stdin=None,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            universal_newlines=True,
        )
        from thonny.workdlg import SubprocessDialog

        dlg = SubprocessDialog(self,
                               proc,
                               tr("Creating virtual environment"),
                               autostart=True)
        ui_utils.show_dialog(dlg)

        if running_on_windows():
            exe_path = normpath_with_actual_case(
                os.path.join(path, "Scripts", "python.exe"))
        else:
            exe_path = os.path.join(path, "bin", "python3")

        if os.path.exists(exe_path):
            self._configuration_variable.set(exe_path)
Example #11
0
def launch():
    _prepare_thonny_user_dir()
    _misc_prepare()

    try:
        from thonny import workbench

        if _should_delegate():
            # First check if there is existing Thonny instance to handle the request
            delegation_result = _try_delegate_to_existing_instance(
                sys.argv[1:])
            if delegation_result == True:  # pylint: disable=singleton-comparison
                # we're done
                print("Delegated to an existing Thonny instance. Exiting now.")
                return 0

            if hasattr(delegation_result, "accept"):
                # we have server socket to put in use
                server_socket = delegation_result
            else:
                server_socket = None

            bench = workbench.Workbench(server_socket)
        else:
            bench = workbench.Workbench()

        try:
            bench.mainloop()
        except SystemExit:
            bench.destroy()
        return 0
    except SystemExit as e:
        from tkinter import messagebox

        messagebox.showerror("System exit", str(e), parent=get_workbench())
        return -1
    except Exception:
        from logging import exception

        exception("Internal launch or mainloop error")
        from thonny import ui_utils
        import traceback

        dlg = ui_utils.LongTextDialog("Internal error",
                                      traceback.format_exc(),
                                      parent=get_workbench())
        ui_utils.show_dialog(dlg, get_workbench())
        return -1
    finally:
        runner = get_runner()
        if runner is not None:
            runner.destroy_backend()

    return 0
Example #12
0
    def _open_flashing_dialog(self):
        mount_path = find_volume_by_name(
            "MICROBIT",
            not_found_msg=_("Could not find disk '%s'.") + "\n" +
            _("Make sure you have micro:bit plugged in!") + "\n\n" +
            _("Do you want to continue and locate the disk yourself?"),
        )
        if mount_path is None:
            return

        dlg = FlashingDialog(get_workbench(), mount_path)
        ui_utils.show_dialog(dlg)
Example #13
0
        def download():
            selection = self.get_selection_info(True)
            if not selection:
                return

            dlg = DownloadDialog(
                self,
                selection["paths"],
                selection["description"],
                target_dir,
            )
            ui_utils.show_dialog(dlg)
            if dlg.response is not None:
                self.master.local_files.refresh_tree()
Example #14
0
def flash_the_firmware(hex_path):
    mount_path = find_volume_by_name(
        "MINI",
        not_found_msg="Could not find disk '%s'.\n" +
        "Make sure you have Calliope Mini plugged in!\n\n" +
        "Do you want to continue and locate the disk yourself?")
    if mount_path is None:
        return

    destination_path = os.path.join(mount_path, os.path.basename(hex_path))

    dlg = FileCopyDialog(
        get_workbench(), hex_path, destination_path,
        "Uploading %s to %s" % (os.path.basename(hex_path), mount_path))
    ui_utils.show_dialog(dlg)
Example #15
0
    def _open_flashing_dialog(self):
        esptool_command = self._get_esptool_command()
        if not esptool_command:
            messagebox.showerror(
                "Can't find esptool",
                "esptool not found.\n" +
                "Install it via 'Tools => Manage plug-ins'\n" + "or "
                "using your OP-system package manager.",
                master=self,
            )
            return

        dlg = ESPFlashingDialog(self.winfo_toplevel(), self._chip,
                                self._firmware_start_address, esptool_command)
        ui_utils.show_dialog(dlg)
Example #16
0
    def _run_pip_with_dialog(self, args, title) -> Tuple[int, str, str]:
        proxy = get_runner().get_backend_proxy()
        assert isinstance(proxy, CPythonProxy)
        sub_cmd = [proxy._reported_executable, "-m", "pip"] + args + self._get_extra_switches()
        back_cmd = InlineCommand("execute_system_command", cmd_line=sub_cmd)
        dlg = InlineCommandDialog(
            self,
            back_cmd,
            title="pip",
            instructions=title,
            autostart=True,
            output_prelude=subprocess.list2cmdline(sub_cmd) + "\n\n",
        )
        ui_utils.show_dialog(dlg)

        return dlg.returncode, dlg.stdout, dlg.stderr
Example #17
0
    def open_backend_pip_gui(*args):
        pg_class = get_pip_gui_class()
        if pg_class is None:
            showerror(tr("Not supported"), get_not_supported_translation())
            return

        if not get_runner().is_waiting_toplevel_command():
            showerror(
                tr("Not available"),
                tr("You need to stop your program before launching the package manager."),
                master=get_workbench(),
            )
            return

        pg = pg_class(get_workbench())
        ui_utils.show_dialog(pg)
Example #18
0
def load_plugin():
    add_micropython_backend("CircuitPython", CircuitPythonProxy, 
                            "CircuitPython (generic)", CircuitPythonConfigPage)
    
    get_workbench().add_command("installcp", "device", "Install CircuitPython firmware ...",
                                lambda: show_dialog(FlashingDialog()),
                                group=40)
Example #19
0
 def _run_pip_with_dialog(self, args, title) -> Tuple[int, str, str]:
     args = ["-m", "thonny.plugins.micropython.minipip"] + args
     proc = running.create_frontend_python_process(args, stderr=subprocess.STDOUT)
     cmd = proc.cmd
     dlg = InstallAndUploadDialog(
         self,
         proc,
         back_cmd=self._create_upload_command,
         title="minipip",
         instructions=title,
         autostart=True,
         output_prelude=subprocess.list2cmdline(cmd) + "\n",
     )
     ui_utils.show_dialog(dlg)
     assert dlg.returncode is not None
     return dlg.returncode, dlg.stdout, dlg.stderr
Example #20
0
def get_ssh_password(conf_group):
    host = get_workbench().get_option(conf_group + ".host")
    user = get_workbench().get_option(conf_group + ".user")
    method = get_workbench().get_option(conf_group + ".auth_method")
    if method == PUBLIC_KEY_NO_PASS_METHOD:
        return None
    elif os.path.exists(get_ssh_password_file_path()):
        with open(get_ssh_password_file_path()) as fp:
            return fp.read().strip()
    else:
        dlg = PasswordDialog(get_workbench(), host, user, method)
        ui_utils.show_dialog(dlg)
        if dlg.password and dlg.save_password:
            with open(get_ssh_password_file_path(), "w") as fp:
                fp.write(dlg.password)

        if not dlg.save_password or not dlg.password:
            delete_stored_ssh_password()

        return dlg.password
Example #21
0
    def _create_venv(self):
        path = None
        while True:
            path = askdirectory(
                master=self,
                initialdir=path,
                title=_("Select empty directory for new virtual environment"),
            )
            if not path:
                return

            if os.listdir(path):
                messagebox.showerror(
                    _("Bad directory"),
                    _("Selected directory is not empty.\nSelect another or cancel."
                      ),
                    parent=get_workbench(),
                )
            else:
                break
        assert os.path.isdir(path)
        path = normpath_with_actual_case(path)

        proc = subprocess.Popen(
            [running.get_frontend_python(), "-m", "venv", path],
            stdin=None,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            universal_newlines=True,
        )
        dlg = SubprocessDialog(self, proc, _("Creating virtual environment"))
        ui_utils.show_dialog(dlg)

        if running_on_windows():
            exe_path = normpath_with_actual_case(
                os.path.join(path, "Scripts", "python.exe"))
        else:
            exe_path = os.path.join(path, "bin", "python3")

        if os.path.exists(exe_path):
            self._configuration_variable.set(exe_path)
Example #22
0
 def open_replayer():
     win = ReplayWindow()
     ui_utils.show_dialog(win)
Example #23
0
 def _open_flashing_dialog(self):
     dlg = MicrobitFlashingDialog(self)
     ui_utils.show_dialog(dlg)
Example #24
0
 def open_about(*args):
     ui_utils.show_dialog(AboutDialog(get_workbench()))
Example #25
0
 def _open_flashing_dialog(self):
     dlg = CircuitPythonFlashingDialog(self)
     ui_utils.show_dialog(dlg)
Example #26
0
 def open_frontend_pip_gui(*args):
     pg = PluginsPipDialog(get_workbench())
     ui_utils.show_dialog(pg)
Example #27
0
 def open_backend_pip_gui(*args):
     pg = BackendPipDialog(get_workbench())
     ui_utils.show_dialog(pg)
Example #28
0
def _ask_installation_details(master, data, selected_version):
    dlg = DetailsDialog(master, data, selected_version)
    ui_utils.show_dialog(dlg, master)
    return dlg.result
Example #29
0
def _show_subprocess_dialog(master, proc, title):
    dlg = SubprocessDialog(master, proc, title)
    ui_utils.show_dialog(dlg, master)
    return dlg.returncode, dlg.stdout, dlg.stderr
Example #30
0
def launch():
    import runpy

    if sys.executable.endswith("thonny.exe"):
        # otherwise some library may try to run its subprocess with thonny.exe
        # NB! Must be pythonw.exe not python.exe, otherwise Runner thinks console
        # is already allocated.
        sys.executable = sys.executable[:-len("thonny.exe")] + "pythonw.exe"

    set_dpi_aware()

    try:
        runpy.run_module("thonny.customize", run_name="__main__")
    except ImportError:
        pass

    _prepare_thonny_user_dir()

    if not _check_welcome():
        return 0

    if _should_delegate():
        try:
            _delegate_to_existing_instance(sys.argv[1:])
            print("Delegated to an existing Thonny instance. Exiting now.")
            return 0
        except Exception:
            traceback.print_exc()

    # Did not or could not delegate

    try:
        from thonny import workbench

        bench = workbench.Workbench()
        try:
            bench.mainloop()
        except SystemExit:
            bench.destroy()
        return 0

    except SystemExit as e:
        from tkinter import messagebox

        messagebox.showerror("System exit", str(e))
        return -1

    except Exception:
        from logging import exception

        exception("Internal launch or mainloop error")
        from thonny import ui_utils

        dlg = ui_utils.LongTextDialog("Internal error", traceback.format_exc())
        ui_utils.show_dialog(dlg, get_workbench())
        return -1
    finally:
        runner = get_runner()
        if runner is not None:
            runner.destroy_backend()

    return 0