diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | _pytest/conftest.py | 104 | ||||
-rw-r--r-- | _pytest/data/message-changed.json | 19 | ||||
-rw-r--r-- | _pytest/data/message-deleted.json | 9 | ||||
-rw-r--r-- | _pytest/data/message-normal.json | 8 | ||||
-rw-r--r-- | _pytest/data/message-normal2.json | 8 | ||||
-rw-r--r-- | _pytest/test_process_message.py | 40 | ||||
-rw-r--r-- | wee_slack.py | 63 |
8 files changed, 247 insertions, 6 deletions
@@ -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_")} |