summaryrefslogtreecommitdiff
path: root/broker.py
diff options
context:
space:
mode:
Diffstat (limited to 'broker.py')
-rw-r--r--broker.py50
1 files changed, 50 insertions, 0 deletions
diff --git a/broker.py b/broker.py
index 0fd9721..35ba21c 100644
--- a/broker.py
+++ b/broker.py
@@ -115,6 +115,16 @@ def init_db():
);
""")
db.execute("""
+ CREATE TABLE IF NOT EXISTS host_bindings (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ slack_user_id TEXT NOT NULL,
+ host TEXT NOT NULL,
+ username TEXT NOT NULL,
+ home_path TEXT NOT NULL,
+ UNIQUE(slack_user_id, host)
+ );
+ """)
+ db.execute("""
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
slack_user_id TEXT DEFAULT '',
@@ -497,6 +507,7 @@ def _start_slack_listener():
"`/restart-worker` — Restart the worker bound to this channel\n"
"`/stop-worker` — Stop worker and unbind from channel\n"
"`/unbind` — Unbind worker without stopping it\n"
+ "`/bind-host host:user:home` — Bind a host so you can use `~/` in paths\n"
"`/help` — Show this message\n\n"
"*In channels with a bound worker:*\n"
"• `@bot message` — Chat with the worker (instant, stays in context)\n"
@@ -516,6 +527,8 @@ def _start_slack_listener():
_handle_worker_command(channel, "stop", user_id, cmd_text, ch_type)
elif command == "/unbind":
_handle_unbind(channel, user_id)
+ elif command == "/bind-host":
+ _handle_bind_host(channel, user_id, cmd_text)
return
if req.type != "events_api":
@@ -881,6 +894,42 @@ def _start_slack_listener():
db.close()
slack_client.chat_postMessage(channel=channel, text=f"Unbound from worker `{session}`. Use `/init-worker` to bind a new one.")
+ def _handle_bind_host(channel, slack_user_id, cmd_text):
+ """/bind-host host:username:home_path — e.g. /bind-host timan1:yurenh2:/home/yurenh2"""
+ parts = cmd_text.strip().split(":")
+ if len(parts) < 3:
+ slack_client.chat_postMessage(channel=channel, text=(
+ "Usage: `/bind-host host:username:home_path`\n"
+ "Example: `/bind-host timan1:yurenh2:/home/yurenh2`\n"
+ "After binding, you can use `~/` in paths: `/init-worker timan1:~/project`"
+ ))
+ return
+ host = parts[0].strip()
+ username = parts[1].strip()
+ home_path = ":".join(parts[2:]).strip() # 防止路径里有冒号
+ db = get_db()
+ db.execute(
+ "INSERT OR REPLACE INTO host_bindings (slack_user_id, host, username, home_path) VALUES (?, ?, ?, ?)",
+ (slack_user_id, host, username, home_path),
+ )
+ db.commit()
+ db.close()
+ slack_client.chat_postMessage(channel=channel, text=f"✅ Bound `{host}` → user `{username}`, home `{home_path}`\nNow you can use: `/init-worker {host}:~/your-project`")
+
+ def _resolve_path(slack_user_id, host, path):
+ """Expand ~ in path using host_bindings"""
+ if "~" not in path:
+ return path
+ db = get_db()
+ row = db.execute(
+ "SELECT home_path FROM host_bindings WHERE slack_user_id = ? AND host = ?",
+ (slack_user_id, host),
+ ).fetchone()
+ db.close()
+ if row:
+ return path.replace("~", row["home_path"])
+ return path
+
def _handle_init_worker(channel, channel_name, user_id, cmd_text):
"""处理 /init-worker 命令"""
if not cmd_text or ":" not in cmd_text:
@@ -893,6 +942,7 @@ def _start_slack_listener():
host, path = cmd_text.split(":", 1)
host = host.strip()
path = path.strip()
+ path = _resolve_path(user_id, host, path)
# 检查是否已有这个路径的 worker
existing = _find_worker_by_path(host, path)