aboutsummaryrefslogtreecommitdiffstats
path: root/slack
diff options
context:
space:
mode:
Diffstat (limited to 'slack')
-rw-r--r--slack/proxy.py65
-rw-r--r--slack/slack_workspace.py70
2 files changed, 134 insertions, 1 deletions
diff --git a/slack/proxy.py b/slack/proxy.py
new file mode 100644
index 0000000..ba8e81d
--- /dev/null
+++ b/slack/proxy.py
@@ -0,0 +1,65 @@
+from __future__ import annotations
+
+import weechat
+
+
+class Proxy:
+ @property
+ def name(self):
+ return weechat.config_string(weechat.config_get("weechat.network.proxy_curl"))
+
+ @property
+ def enabled(self):
+ return bool(self.type)
+
+ @property
+ def _proxy_option_prefix(self):
+ return f"weechat.proxy.{self.name}"
+
+ @property
+ def type(self):
+ return weechat.config_string(
+ weechat.config_get(f"{self._proxy_option_prefix}.type")
+ )
+
+ @property
+ def address(self):
+ return weechat.config_string(
+ weechat.config_get(f"{self._proxy_option_prefix}.address")
+ )
+
+ @property
+ def port(self):
+ return weechat.config_integer(
+ weechat.config_get(f"{self._proxy_option_prefix}.port")
+ )
+
+ @property
+ def ipv6(self):
+ return weechat.config_boolean(
+ weechat.config_get(f"{self._proxy_option_prefix}.ipv6")
+ )
+
+ @property
+ def username(self):
+ return weechat.config_string(
+ weechat.config_get(f"{self._proxy_option_prefix}.username")
+ )
+
+ @property
+ def password(self):
+ return weechat.config_string(
+ weechat.config_get(f"{self._proxy_option_prefix}.password")
+ )
+
+ @property
+ def curl_option(self):
+ if not self.enabled:
+ return ""
+
+ user = (
+ f"{self.username}:{self.password}@"
+ if self.username and self.password
+ else ""
+ )
+ return f"-x{self.type}://{user}{self.address}:{self.port}"
diff --git a/slack/slack_workspace.py b/slack/slack_workspace.py
index c95821c..0ddef89 100644
--- a/slack/slack_workspace.py
+++ b/slack/slack_workspace.py
@@ -1,14 +1,21 @@
from __future__ import annotations
-from typing import Dict
+import json
+import socket
+import ssl
+import time
+from typing import Any, Dict
import weechat
+from websocket import ABNF, WebSocketConnectionClosedException, create_connection
+from slack.proxy import Proxy
from slack.shared import shared
from slack.slack_api import SlackApi
from slack.slack_conversation import SlackConversation
from slack.slack_user import SlackUser
from slack.task import Future, create_task
+from slack.util import get_callback_name
class SlackUsers(Dict[str, Future[SlackUser]]):
@@ -44,6 +51,8 @@ class SlackWorkspace:
self.id = rtm_connect["team"]["id"]
self.my_user = await self.users[rtm_connect["self"]["id"]]
+ await self.connect_ws(rtm_connect["url"])
+
# "types": "public_channel,private_channel,im",
user_channels_response = await self.api.fetch_users_conversations(
"public_channel"
@@ -63,3 +72,62 @@ class SlackWorkspace:
# print([c["name"] for c in user_channels])
self.is_connected = True
weechat.bar_item_update("input_text")
+
+ async def connect_ws(self, url: str):
+ sslopt_ca_certs = {}
+ if hasattr(ssl, "get_default_verify_paths") and callable(
+ ssl.get_default_verify_paths
+ ):
+ ssl_defaults = ssl.get_default_verify_paths()
+ if ssl_defaults.cafile is not None:
+ sslopt_ca_certs = {"ca_certs": ssl_defaults.cafile}
+
+ proxy = Proxy()
+ proxy_options = {
+ "proxy_type": proxy.type,
+ "http_proxy_host": proxy.address,
+ "http_proxy_port": proxy.port,
+ "http_proxy_auth": (proxy.username, proxy.password),
+ "http_proxy_timeout": self.config.slack_timeout.value,
+ }
+ # TODO: Handle errors
+ self.ws = create_connection(
+ url,
+ self.config.slack_timeout.value,
+ sslopt=sslopt_ca_certs,
+ **proxy_options,
+ )
+
+ self.hook = weechat.hook_fd(
+ self.ws.sock.fileno(),
+ 1,
+ 0,
+ 0,
+ get_callback_name(self.ws_read_cb),
+ "",
+ )
+ self.ws.sock.setblocking(False)
+
+ def ws_read_cb(self, data: str, fd: int) -> int:
+ while True:
+ try:
+ opcode, recv_data = self.ws.recv_data(control_frame=True)
+ except ssl.SSLWantReadError:
+ # No more data to read at this time.
+ return weechat.WEECHAT_RC_OK
+ except (WebSocketConnectionClosedException, socket.error) as e:
+ # TODO: Handle error
+ # handle_socket_error(e, team, "receive")
+ print(e)
+ return weechat.WEECHAT_RC_OK
+
+ if opcode == ABNF.OPCODE_PONG:
+ self.last_pong_time = time.time()
+ return weechat.WEECHAT_RC_OK
+ elif opcode != ABNF.OPCODE_TEXT:
+ return weechat.WEECHAT_RC_OK
+
+ self.ws_recv(json.loads(recv_data.decode()))
+
+ def ws_recv(self, data: Any):
+ print(f"received: {data}")