codemp-sublime/plugin/commands/client.py
cschen ce87c5334d made create and delete workspaces as internal commands as well.
Fixed the same issues that the workspace browser had for the creation and deletion also in
the server browser.
2025-02-18 22:36:14 +01:00

249 lines
8.4 KiB
Python

import sublime
import sublime_plugin
import logging
import codemp
from ..core.session import session
from ..core.workspace import workspaces
from ..utils import get_setting
from ..quickpanel.qpbrowser import qpi
from ..quickpanel.qpbrowser import show_qp
from ..input_handlers import SimpleTextInput
from ..input_handlers import SimpleListInput
logger = logging.getLogger(__name__)
def valid_profiles(profiles):
return [p for p in profiles if "name" in p]
def get_profile_index_by_name(profiles, name):
return next((index for (index, d) in enumerate(profiles) if d["name"] == name))
def get_default_profile(profiles):
i = get_profile_index_by_name(profiles, "Default")
return profiles[i]
class CodempConnectCommand(sublime_plugin.WindowCommand):
def __init__(self, window):
super().__init__(window)
self.connprofile = {}
def is_enabled(self) -> bool:
return not session.is_active()
def update_config_and_connect(self):
config = codemp.Config(
username = self.connprofile["username"],
password = self.connprofile["password"],
host = self.connprofile["host"],
port = self.connprofile["port"],
tls = self.connprofile["tls"]
)
session._config = config
def _():
try:
session.connect()
except Exception as e:
logger.error(e)
sublime.error_message(
"Could not connect:\n Make sure the server is up\n\
and your credentials are correct."
)
# If the connect was successfull, save the credentials in memory for the session:
profiles = get_setting("profiles")
selected_profile_id = get_profile_index_by_name(profiles, self.connprofile["name"])
profiles[selected_profile_id] = self.connprofile # pyright: ignore
sublime.load_settings("Codemp.sublime-settings").set("profiles", profiles)
sublime.set_timeout_async(_)
def maybe_get_password(self):
def __(pwd):
self.connprofile["password"] = pwd
self.update_config_and_connect()
panel = self.window.show_input_panel("Password:", "", __, None, None)
# Very undocumented feature, the input panel if has the setting 'password' set to true
# will hide the input.
panel.settings().set("password", True)
def maybe_get_user(self):
def __(usr):
self.connprofile["username"] = usr
self.maybe_get_password()
panel = self.window.show_input_panel("Username:", "", __, None, None)
panel.settings().set("password", False)
def run(self): # pyright: ignore[reportIncompatibleMethodOverride]
def _run(index):
profile = profiles[index]
default_profile = get_default_profile(profiles)
self.connprofile = {**default_profile, **profile}
if self.connprofile["username"] and self.connprofile["password"]:
self.update_config_and_connect()
if not self.connprofile["username"] and not self.connprofile["password"]:
self.maybe_get_user()
if self.connprofile["username"] and not self.connprofile["password"]:
self.maybe_get_password()
profiles = valid_profiles(get_setting("profiles"))
qplist = []
for p in profiles:
hint = f"host: {p['host']}:{p['port']}"
user = p["username"]
pwd = " : *******" if p["password"] else ""
details = user + pwd
qplist.append(qpi(p["name"], details, letter="P", hint=hint))
show_qp(self.window, qplist, _run, placeholder="Profile")
# Disconnect Command
class CodempDisconnectCommand(sublime_plugin.WindowCommand):
def is_enabled(self):
return session.is_active()
def run(self):
cli = session.client
for ws in workspaces.lookup():
if cli.leave_workspace(ws.id):
workspaces.remove(ws)
session.drop_client()
logger.info(f"disconnected from server '{session.config.host}'!")
# Join Workspace Command
class CodempJoinWorkspaceCommand(sublime_plugin.WindowCommand):
def is_enabled(self) -> bool:
return session.is_active()
def input_description(self):
return "Join:"
def input(self, args):
if "workspace_id" not in args:
wslist = session.get_workspaces()
return SimpleListInput(
[("workspace_id", wslist)],
)
def run(self, workspace_id): # pyright: ignore[reportIncompatibleMethodOverride]
if workspace_id is None:
return
logger.info(f"Joining workspace: '{workspace_id}'...")
try:
ws = session.client.attach_workspace(workspace_id).wait()
except Exception as e:
logger.error(f"Could not join workspace '{workspace_id}': {e}")
sublime.error_message(f"Could not join workspace '{workspace_id}'")
raise e
logger.debug("Joined! Adding workspace to registry")
workspaces.register(ws)
# Leave Workspace Command
class CodempLeaveWorkspaceCommand(sublime_plugin.WindowCommand):
def is_enabled(self):
return session.is_active() and workspaces.hasactive()
def input(self, args):
if "workspace_id" not in args:
return SimpleListInput(
("workspace_id", session.client.active_workspaces()),
)
def run(self, workspace_id: str): # pyright: ignore[reportIncompatibleMethodOverride]
try:
workspaces.remove(workspace_id)
finally:
if not session.client.leave_workspace(workspace_id):
logger.error(f"could not leave the workspace '{workspace_id}'")
else:
logger.debug(f"successfully left the workspace '{workspace_id}'")
class CodempInviteToWorkspaceCommand(sublime_plugin.WindowCommand):
def is_enabled(self) -> bool:
return session.is_active() and workspaces.hasactive() > 0
def input(self, args):
if "workspace_id" not in args:
wslist = session.get_workspaces(owned=True, invited=False)
return SimpleListInput(
[("workspace_id", wslist), ("user", "invitee's username")]
)
if "user" not in args:
return SimpleTextInput(("user", "invitee's username"))
def run(self, workspace_id: str, user: str): # pyright: ignore[reportIncompatibleMethodOverride]
try:
session.client.invite_to_workspace(workspace_id, user)
logger.debug(f"invite sent to user {user} for workspace {workspace_id}.")
except Exception as e:
logger.error(f"Could not invite to workspace: {e}")
class CodempCreateWorkspaceCommand(sublime_plugin.WindowCommand):
def is_enabled(self):
return session.is_active()
# def input(self, args):
# if "workspace_id" not in args:
# return SimpleTextInput(("workspace_id", "new workspace name"))
def run(self, workspace_id: str): # pyright: ignore[reportIncompatibleMethodOverride]
try:
session.client.create_workspace(workspace_id)
except Exception as e:
logger.error(f"Could not create workspace: {e}")
class CodempDeleteWorkspaceCommand(sublime_plugin.WindowCommand):
def is_enabled(self):
return session.is_active()
# def input(self, args):
# workspaces = session.get_workspaces(owned=True, invited=False) # noqa: F841
# if "workspace_id" not in args:
# return SimpleListInput(("workspace_id", workspaces))
def run(self, workspace_id: str): # pyright: ignore[reportIncompatibleMethodOverride]
if workspace_id in workspaces:
if not sublime.ok_cancel_dialog(
"You are currently attached to '{workspace_id}'.\n\
Do you want to detach and delete it?",
ok_title="yes", title="Delete Workspace?",
): return
self.window.run_command(
"codemp_leave_workspace",
{"workspace_id": workspace_id})
else:
if not sublime.ok_cancel_dialog(
f"Confirm you want to delete the workspace '{workspace_id}'",
ok_title="delete", title="Delete Workspace?",
): return
session.client.delete_workspace(workspace_id).wait()