aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--_pytest/conftest.py104
-rw-r--r--_pytest/data/message-changed.json19
-rw-r--r--_pytest/data/message-deleted.json9
-rw-r--r--_pytest/data/message-normal.json8
-rw-r--r--_pytest/data/message-normal2.json8
-rw-r--r--_pytest/test_process_message.py40
-rw-r--r--wee_slack.py63
8 files changed, 247 insertions, 6 deletions
diff --git a/README.md b/README.md
index 47973f5..7c4a8ff 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,8 @@ A WeeChat native client for Slack.com. Provides supplemental features only avail
Features
--------
+ * **New** edited messages work just like the official clients, where the original message changes and has (edited) appended.
+ * **New** unfurled urls dont generate a new message, but replace the original with more info as it is received.
* **New** regex style message editing (s/oldtext/newtext/)
* Caches message history, making startup MUCH faster
* Smarter redraw of dynamic buffer info (much lower CPU %)
diff --git a/_pytest/conftest.py b/_pytest/conftest.py
new file mode 100644
index 0000000..0cbceb9
--- /dev/null
+++ b/_pytest/conftest.py
@@ -0,0 +1,104 @@
+import pytest
+from wee_slack import SlackServer
+from wee_slack import Channel
+from wee_slack import User
+from wee_slack import SearchList
+import wee_slack
+
+class FakeWeechat():
+ """
+ this is the thing that acts as "w." everywhere..
+ basically mock out all of the weechat calls here i guess
+ """
+ WEECHAT_RC_OK = True
+
+ def __init__(self):
+ print "INITIALIZE FAKE WEECHAT"
+ def prnt(*args):
+ output = "("
+ for arg in args:
+ if arg != None:
+ output += "{}, ".format(arg)
+ print "w.prnt {}".format(output)
+ def hdata_get(*args):
+ return "0x000001"
+ def hdata_pointer(*args):
+ return "0x000002"
+ def hdata_time(*args):
+ return "1355517519"
+ def hdata_string(*args):
+ return "testuser"
+
+ def __getattr__(self, name):
+ def method(*args):
+ print "called {}".format(name)
+ if args:
+ print "\twith args: {}".format(args)
+ return method
+
+@pytest.fixture
+def fake_weechat():
+ wee_slack.w = FakeWeechat()
+ pass
+
+
+@pytest.fixture
+def slack_debug():
+ wee_slack.slack_debug = "debug_buffer_ptr"
+
+@pytest.fixture
+def server(fake_weechat, monkeypatch):
+#def server(monkeypatch, mychannels, myusers):
+ def mock_connect_to_slack(*args):
+ return True
+ monkeypatch.setattr(SlackServer, 'connect_to_slack', mock_connect_to_slack)
+ myserver = SlackServer('xoxo-12345')
+ myserver.identifier = 'test.slack.com'
+ myserver.nick = 'myusername'
+ return myserver
+
+@pytest.fixture
+def myservers(server):
+ servers = SearchList()
+ servers.append(server)
+ return servers
+
+
+
+@pytest.fixture
+def channel(monkeypatch, server):
+ def mock_buffer_prnt(*args):
+ print "called buffer_prnt\n\twith args: {}".format(args)
+ return
+ def mock_do_nothing(*args):
+ print args
+ return True
+ monkeypatch.setattr(Channel, 'create_buffer', mock_do_nothing)
+ monkeypatch.setattr(Channel, 'attach_buffer', mock_do_nothing)
+ monkeypatch.setattr(Channel, 'set_topic', mock_do_nothing)
+ monkeypatch.setattr(Channel, 'set_topic', mock_do_nothing)
+ monkeypatch.setattr(Channel, 'buffer_prnt', mock_buffer_prnt)
+ mychannel = Channel(server, '#testchan', 'C2147483705', True, last_read=0, prepend_name="", members=[], topic="")
+ return mychannel
+
+@pytest.fixture
+def mychannels(channel):
+ channels = SearchList()
+ channels.append(channel)
+ return channels
+
+@pytest.fixture
+def user(monkeypatch, server):
+ wee_slack.domain = None
+ wee_slack.colorize_nicks = True
+ pass
+ myuser = User(server, "testuser", 'U2147483697', presence="away")
+ myuser.color = ''
+ return myuser
+
+@pytest.fixture
+def myusers(monkeypatch, user):
+ users = SearchList()
+ users.append(user)
+ return users
+
diff --git a/_pytest/data/message-changed.json b/_pytest/data/message-changed.json
new file mode 100644
index 0000000..5a229dc
--- /dev/null
+++ b/_pytest/data/message-changed.json
@@ -0,0 +1,19 @@
+{
+ "type": "message",
+ "subtype": "message_changed",
+ "hidden": true,
+ "channel": "C2147483705",
+ "ts": "1355517529.000005",
+ "message": {
+ "type": "message",
+ "user": "U2147483697",
+ "text": "Hello world",
+ "ts": "1355517519.000005",
+ "edited": {
+ "user": "U2147483697",
+ "ts": "12341234"
+ }
+ },
+
+ "myserver": "test.slack.com"
+}
diff --git a/_pytest/data/message-deleted.json b/_pytest/data/message-deleted.json
new file mode 100644
index 0000000..91190b3
--- /dev/null
+++ b/_pytest/data/message-deleted.json
@@ -0,0 +1,9 @@
+{
+ "type": "message",
+ "subtype": "message_deleted",
+ "hidden": true,
+ "channel": "C2147483705",
+ "ts": "1358878755.000001",
+ "deleted_ts": "1355517519.000005",
+ "myserver": "test.slack.com"
+}
diff --git a/_pytest/data/message-normal.json b/_pytest/data/message-normal.json
new file mode 100644
index 0000000..f3dc568
--- /dev/null
+++ b/_pytest/data/message-normal.json
@@ -0,0 +1,8 @@
+{
+ "type": "message",
+ "channel": "C2147483705",
+ "user": "U2147483697",
+ "text": "Hello world",
+ "ts": "1355517523.000005",
+ "myserver": "test.slack.com"
+}
diff --git a/_pytest/data/message-normal2.json b/_pytest/data/message-normal2.json
new file mode 100644
index 0000000..b67be66
--- /dev/null
+++ b/_pytest/data/message-normal2.json
@@ -0,0 +1,8 @@
+{
+ "type": "message",
+ "channel": "C2147483705",
+ "user": "U2147483697",
+ "text": "A Second message!",
+ "ts": "1355517524.000005",
+ "myserver": "test.slack.com"
+}
diff --git a/_pytest/test_process_message.py b/_pytest/test_process_message.py
new file mode 100644
index 0000000..6c58336
--- /dev/null
+++ b/_pytest/test_process_message.py
@@ -0,0 +1,40 @@
+
+import wee_slack
+import pytest
+import json
+from collections import defaultdict
+
+
+def test_process_message(slack_debug, monkeypatch, myservers, mychannels, myusers):
+ called = defaultdict(int)
+ wee_slack.servers = myservers
+ wee_slack.channels = mychannels
+ wee_slack.users = myusers
+ wee_slack.message_cache = {}
+ wee_slack.servers[0].users = myusers
+
+ def mock_buffer_prnt(*args):
+ called['buffer_prnt'] += 1
+ monkeypatch.setattr(wee_slack.Channel, 'buffer_prnt', mock_buffer_prnt)
+
+# def mock_buffer_prnt_changed(*args):
+# called['buffer_prnt_changed'] += 1
+# print args
+# monkeypatch.setattr(wee_slack.Channel, 'buffer_prnt_changed', mock_buffer_prnt_changed)
+
+
+ messages = []
+ messages.append( json.loads(open('_pytest/data/message-normal.json', 'r').read()) )
+ messages.append( json.loads(open('_pytest/data/message-normal2.json', 'r').read()) )
+ messages.append( json.loads(open('_pytest/data/message-changed.json', 'r').read()) )
+ messages.append( json.loads(open('_pytest/data/message-deleted.json', 'r').read()) )
+ for m in messages:
+ wee_slack.process_message(m)
+ print called
+# assert called['buffer_prnt'] == 2
+# assert called['buffer_prnt_changed'] == 1
+
+
+
+
+
diff --git a/wee_slack.py b/wee_slack.py
index 5b089d1..bd8292a 100644
--- a/wee_slack.py
+++ b/wee_slack.py
@@ -19,7 +19,7 @@ except:
SCRIPT_NAME = "slack_extension"
SCRIPT_AUTHOR = "Ryan Huber <rhuber@gmail.com>"
-SCRIPT_VERSION = "0.97.20"
+SCRIPT_VERSION = "0.97.21"
SCRIPT_LICENSE = "MIT"
SCRIPT_DESC = "Extends weechat for typing notification/search/etc on slack.com"
@@ -293,11 +293,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
@@ -539,6 +541,18 @@ class Channel(SlackThing):
if w.buffer_get_string(self.channel_buffer, "short_name") != (color + new_name):
w.buffer_set(self.channel_buffer, "short_name", color + new_name)
+ def buffer_prnt_changed(self, user, text, time, append=""):
+ if user:
+ if self.server.users.find(user):
+ name = self.server.users.find(user).formatted_name()
+ else:
+ name = user
+ name = name.decode('utf-8')
+ modify_buffer_line(self.channel_buffer, name, text, time, append)
+ else:
+ modify_buffer_line(self.channel_buffer, None, text, time, append)
+ return False
+
def buffer_prnt(self, user='unknown user', message='no message', time=0):
set_read_marker = False
time_float = float(time)
@@ -1154,6 +1168,32 @@ def cache_message(message_json, from_me=False):
if len(message_cache[channel]) > BACKLOG_SIZE:
message_cache[channel] = message_cache[channel][-BACKLOG_SIZE:]
+
+def modify_buffer_line(buffer, user, new_message, time, append):
+ time = int(float(time))
+ own_lines = w.hdata_pointer(w.hdata_get('buffer'), buffer, 'own_lines')
+ if own_lines:
+ line = w.hdata_pointer(w.hdata_get('lines'), own_lines, 'last_line')
+ hdata_line = w.hdata_get('line')
+ hdata_line_data = w.hdata_get('line_data')
+
+ while line:
+ data = w.hdata_pointer(hdata_line, line, 'data')
+ if data:
+ date = w.hdata_time(hdata_line_data, data, 'date')
+ prefix = w.hdata_string(hdata_line_data, data, 'prefix')
+ if user and (int(date) == int(time) and user == prefix):
+# w.prnt("", "found matching time date is {}, time is {} ".format(date, time))
+ w.hdata_update(hdata_line_data, data, {"message": "{}{}".format(new_message, append)})
+ break
+ elif not user and (int(date) == int(time)):
+ w.hdata_update(hdata_line_data, data, {"message": "{}{}".format(new_message, append)})
+ else:
+ pass
+ line = w.hdata_move(hdata_line, line, -1)
+ return w.WEECHAT_RC_OK
+
+
def process_message(message_json):
try:
# send these messages elsewhere
@@ -1185,7 +1225,7 @@ def process_message(message_json):
text = unfurl_refs(text)
if "attachments" in message_json:
- text += u"--- {}".format(unwrap_attachments(message_json))
+ text += u" --- {}".format(unwrap_attachments(message_json))
text = text.lstrip()
text = text.replace("\t", " ")
name = get_user(message_json, server)
@@ -1193,7 +1233,18 @@ def process_message(message_json):
text = text.encode('utf-8')
name = name.encode('utf-8')
- channel.buffer_prnt(name, text, time)
+ if "subtype" in message_json and message_json["subtype"] == "message_changed":
+ if "edited" in message_json["message"]:
+ append = " (edited)"
+ else:
+ append = ''
+ channel.buffer_prnt_changed(message_json["message"]["user"], text, message_json["message"]["ts"], append)
+ elif "subtype" in message_json and message_json["subtype"] == "message_deleted":
+ append = "(deleted)"
+ text = ""
+ channel.buffer_prnt_changed(None, text, message_json["deleted_ts"], append)
+ else:
+ channel.buffer_prnt(name, text, time)
except:
dbg("cannot process message {}".format(message_json))
@@ -1514,7 +1565,6 @@ def config_changed_cb(data, option, value):
if channels_not_on_current_server_color == "0":
channels_not_on_current_server_color = False
colorize_nicks = w.config_get_plugin('colorize_nicks') == "1"
- slack_debug = None
debug_mode = w.config_get_plugin("debug_mode").lower()
if debug_mode != '' and debug_mode != 'false':
create_slack_debug_buffer()
@@ -1563,6 +1613,7 @@ if __name__ == "__main__":
legacy_mode = True
# Global var section
+ slack_debug = None
config_changed_cb("", "", "")
cmds = {k[8:]: v for k, v in globals().items() if k.startswith("command_")}