aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md17
-rw-r--r--wee_slack.py70
2 files changed, 64 insertions, 23 deletions
diff --git a/README.md b/README.md
index 7c4a8ff..0296092 100644
--- a/README.md
+++ b/README.md
@@ -3,11 +3,6 @@
wee-slack
=========
-**Important:**
- Just updated with some **huge** performance improvements! Seriously, **upgrade now**. Weechat 1.1 or newer is now required. There was code to work around issues that no longer exist in newer versions. You should upgrade to if you wish to use continue using wee-slack.
-
------------
-
A WeeChat native client for Slack.com. Provides supplemental features only available in the web/mobile clients such as: synchronizing read markers, typing notification, search, (and more)! Connects via the Slack API, and maintains a persistent websocket for notification of events.
![animated screenshot](https://dl.dropboxusercontent.com/u/566560/slack.gif)
@@ -46,6 +41,7 @@ Dependencies
------------
* WeeChat 1.1+ http://weechat.org/
* websocket-client https://pypi.python.org/pypi/websocket-client/
+ * curl http://curl.haxx.se/
Setup
------
@@ -63,11 +59,20 @@ wee-slack doesn't use the Slack IRC gateway. If you currently connect via the ga
/python reload
```
-####1. Install websocket-client lib
+####1. Install dependencies
+
+##### OSX
+```
+pip install websocket-client
+```
+
+##### Linux (ubuntu)
```
+sudo apt-get install curl
pip install websocket-client
```
+
####2. copy wee_slack.py to ~/.weechat/python/autoload
```
wget https://raw.githubusercontent.com/rawdigits/wee-slack/master/wee_slack.py
diff --git a/wee_slack.py b/wee_slack.py
index b444aa3..467a29c 100644
--- a/wee_slack.py
+++ b/wee_slack.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
#
+
from functools import wraps
import time
import json
@@ -9,6 +10,7 @@ import re
import urllib
import urlparse
import HTMLParser
+import sys
from websocket import create_connection
# hack to make tests possible.. better way?
@@ -19,7 +21,7 @@ except:
SCRIPT_NAME = "slack_extension"
SCRIPT_AUTHOR = "Ryan Huber <rhuber@gmail.com>"
-SCRIPT_VERSION = "0.97.21"
+SCRIPT_VERSION = "0.97.25"
SCRIPT_LICENSE = "MIT"
SCRIPT_DESC = "Extends weechat for typing notification/search/etc on slack.com"
@@ -211,14 +213,16 @@ class SlackServer(object):
self.communication_counter += 1
return self.communication_counter
- def send_to_websocket(self, data):
+ def send_to_websocket(self, data, expect_reply=True):
+ data["id"] = self.get_communication_id()
+ message = json.dumps(data)
try:
- data["id"] = self.get_communication_id()
- message = json.dumps(data)
- self.message_buffer[data["id"]] = data
+ if expect_reply:
+ self.message_buffer[data["id"]] = data
self.ws.send(message)
dbg("Sent {}...".format(message[:100]))
except:
+ dbg("Unexpected error: {}\nSent: {}".format(sys.exc_info()[0], data))
self.connected = False
def ping(self):
@@ -251,6 +255,16 @@ class SlackServer(object):
self.connecting = False
self.print_connection_info(login_data)
+ if len(self.message_buffer) > 0:
+ for message_id in self.message_buffer.keys():
+ if self.message_buffer[message_id]["type"] != 'ping':
+ resend = self.message_buffer.pop(message_id)
+ dbg("Resent failed message.")
+ self.send_to_websocket(resend)
+ #sleep to prevent being disconnected by websocket server
+ time.sleep(1)
+ else:
+ self.message_buffer.pop(message_id)
return True
else:
w.prnt("", "\n!! slack.com login error: " + login_data["error"] + "\n Please check your API token with\n \"/set plugins.var.python.slack_extension.slack_api_token (token)\"\n\n ")
@@ -293,11 +307,13 @@ class SlackServer(object):
if "topic" not in item:
item["topic"] = {}
item["topic"]["value"] = ""
- self.channels.append(Channel(self, item["name"], item["id"], item["is_member"], item["last_read"], "#", item["members"], item["topic"]["value"]))
+ if not item["is_archived"]:
+ self.channels.append(Channel(self, item["name"], item["id"], item["is_member"], item["last_read"], "#", item["members"], item["topic"]["value"]))
for item in data["groups"]:
if "last_read" not in item:
item["last_read"] = 0
- self.channels.append(GroupChannel(self, item["name"], item["id"], item["is_open"], item["last_read"], "#", item["members"], item["topic"]["value"]))
+ if not item["is_archived"]:
+ self.channels.append(GroupChannel(self, item["name"], item["id"], item["is_open"], item["last_read"], "#", item["members"], item["topic"]["value"]))
for item in data["ims"]:
if "last_read" not in item:
item["last_read"] = 0
@@ -390,6 +406,7 @@ class Channel(SlackThing):
channel_buffer = w.buffer_search("", "{}.{}".format(self.server.domain, self.name))
if channel_buffer != main_weechat_buffer:
self.channel_buffer = channel_buffer
+ w.buffer_set(self.channel_buffer, "localvar_set_nick", self.server.nick)
# w.buffer_set(self.channel_buffer, "highlight_words", self.server.nick)
else:
self.channel_buffer = None
@@ -454,8 +471,10 @@ class Channel(SlackThing):
def linkify_text(self, message):
message = message.split(' ')
for item in enumerate(message):
- if item[1].startswith('@'):
+ if item[1].startswith('@') and len(item[1]) > 1:
named = re.match('.*[@#](\w+)(\W*)', item[1]).groups()
+ if named[0] in ["group", "channel"]:
+ message[item[0]] = "<!{}>".format(named[0])
if self.server.users.find(named[0]):
message[item[0]] = "<@{}>{}".format(self.server.users.find(named[0]).identifier, named[1])
if item[1].startswith('#') and self.server.channels.find(item[1]):
@@ -491,7 +510,10 @@ class Channel(SlackThing):
async_slack_api_request(self.server.domain, self.server.token, SLACK_API_TRANSLATOR[self.type]["leave"], {"channel": self.identifier})
def closed(self):
- message_cache.pop(self.identifier)
+ try:
+ message_cache.pop(self.identifier)
+ except KeyError:
+ pass
self.channel_buffer = None
self.last_received = None
self.close()
@@ -1029,14 +1051,18 @@ def process_team_join(message_json):
server.users.append(User(server, item["name"], item["id"], item["presence"]))
server.buffer_prnt(server.buffer, "New user joined: {}".format(item["name"]))
+def process_manual_presence_change(message_json):
+ process_presence_change(message_json)
def process_presence_change(message_json):
- buffer_name = "{}.{}".format(domain, message_json["user"])
+ server = servers.find(message_json["myserver"])
+ nick = message_json.get("user", server.nick)
+ buffer_name = "{}.{}".format(domain, nick)
buf_ptr = w.buffer_search("", buffer_name)
if message_json["presence"] == 'active':
- users.find(message_json["user"]).set_active()
+ users.find(nick).set_active()
else:
- users.find(message_json["user"]).set_inactive()
+ users.find(nick).set_inactive()
def process_channel_marked(message_json):
@@ -1060,7 +1086,7 @@ def process_channel_created(message_json):
server.channels.find(message_json["channel"]["name"]).open(False)
else:
item = message_json["channel"]
- server.channels.append(Channel(server, item["name"], item["id"], item["is_open"], item["last_read"], "#", item["members"], item["topic"]))
+ server.channels.append(Channel(server, item["name"], item["id"], item["is_open"], item["last_read"], "#", item["members"], item["topic"]["value"]))
server.buffer_prnt("New channel created: {}".format(item["name"]))
@@ -1087,7 +1113,7 @@ def process_channel_joined(message_json):
server.channels.find(message_json["channel"]["name"]).open(False)
else:
item = message_json["channel"]
- server.channels.append(Channel(server, item["name"], item["id"], item["is_open"], item["last_read"], "#", item["members"], item["topic"]))
+ server.channels.append(Channel(server, item["name"], item["id"], item["is_open"], item["last_read"], "#", item["members"], item["topic"]["value"]))
def process_channel_leave(message_json):
@@ -1096,6 +1122,11 @@ def process_channel_leave(message_json):
channel.user_leave(message_json["user"])
+def process_channel_archive(message_json):
+ channel = server.channels.find(message_json["channel"])
+ channel.detach_buffer()
+
+
def process_group_left(message_json):
server = servers.find(message_json["myserver"])
server.channels.find(message_json["channel"]).close(False)
@@ -1107,7 +1138,12 @@ def process_group_joined(message_json):
server.channels.find(message_json["channel"]["name"]).open(False)
else:
item = message_json["channel"]
- server.channels.append(GroupChannel(server, item["name"], item["id"], item["is_open"], item["last_read"], "#", item["members"], item["topic"]))
+ server.channels.append(GroupChannel(server, item["name"], item["id"], item["is_open"], item["last_read"], "#", item["members"], item["topic"]["value"]))
+
+
+def process_group_archive(message_json):
+ channel = server.channels.find(message_json["channel"])
+ channel.detach_buffer()
def process_im_close(message_json):
@@ -1405,7 +1441,7 @@ def typing_notification_cb(signal, sig_type, data):
if channel:
identifier = channel.identifier
request = {"type": "typing", "channel": identifier}
- channel.server.send_to_websocket(request)
+ channel.server.send_to_websocket(request, expect_reply=False)
typing_timer = now
return w.WEECHAT_RC_OK
@@ -1434,7 +1470,7 @@ def slack_never_away_cb(data, remaining):
identifier = server.channels.find("slackbot").identifier
request = {"type": "typing", "channel": identifier}
#request = {"type":"typing","channel":"slackbot"}
- server.send_to_websocket(request)
+ server.send_to_websocket(request, expect_reply=False)
return w.WEECHAT_RC_OK
# Slack specific requests