aboutsummaryrefslogtreecommitdiffstats
path: root/wee_slack.py
diff options
context:
space:
mode:
authorRyan Huber <rhuber@gmail.com>2015-01-17 23:45:38 -0800
committerRyan Huber <rhuber@gmail.com>2015-01-17 23:45:38 -0800
commitb4bca4c6f2f32f5fb8121d837a2dc81b200f33e1 (patch)
treedbd005cfc61e72ee0a1c7ff0e85361d9f1b28d02 /wee_slack.py
parentdbdca4a9f227f284ce20f60c919c14b38c0ef617 (diff)
downloadwee-slack-b4bca4c6f2f32f5fb8121d837a2dc81b200f33e1.tar.gz
autopep8'd
Diffstat (limited to 'wee_slack.py')
-rw-r--r--wee_slack.py407
1 files changed, 283 insertions, 124 deletions
diff --git a/wee_slack.py b/wee_slack.py
index b59e084..267ab34 100644
--- a/wee_slack.py
+++ b/wee_slack.py
@@ -10,7 +10,7 @@ import urlparse
import HTMLParser
from websocket import create_connection
-#hack to make tests possible.. better way?
+# hack to make tests possible.. better way?
try:
import weechat as w
except:
@@ -25,64 +25,74 @@ SCRIPT_DESC = "Extends weechat for typing notification/search/etc on slack.com"
BACKLOG_SIZE = 200
SLACK_API_TRANSLATOR = {
- "channel": {
- "history" : "channels.history",
- "join" : "channels.join",
- "leave" : "channels.leave",
- "mark" : "channels.mark",
- "info" : "channels.info"
- },
- "im": {
- "history" : "im.history",
- "leave" : "im.close",
- "mark" : "im.mark"
- },
- "group": {
- "history" : "groups.history",
- "join" : "channels.join",
- "leave" : "groups.leave",
- "mark" : "groups.mark"
- }
-
- }
+ "channel": {
+ "history": "channels.history",
+ "join": "channels.join",
+ "leave": "channels.leave",
+ "mark": "channels.mark",
+ "info": "channels.info"
+ },
+ "im": {
+ "history": "im.history",
+ "leave": "im.close",
+ "mark": "im.mark"
+ },
+ "group": {
+ "history": "groups.history",
+ "join": "channels.join",
+ "leave": "groups.leave",
+ "mark": "groups.mark"
+ }
+
+}
+
def dbg(message, fout=False, main_buffer=False):
message = "DEBUG: " + str(message)
message = message.encode('ascii', 'ignore')
if fout:
- file('/tmp/debug.log', 'a+').writelines(message+'\n')
- if slack_debug != None:
+ file('/tmp/debug.log', 'a+').writelines(message + '\n')
+ if slack_debug is not None:
if not main_buffer:
w.prnt(slack_debug, message)
else:
w.prnt("", message)
-#hilarious, i know
+# hilarious, i know
+
+
class Meta(list):
+
def __init__(self, attribute, search_list):
self.attribute = attribute
self.search_list = search_list
+
def __str__(self):
string = ''
for each in self.search_list.get_all(self.attribute):
string += str(each) + ' '
return string
+
def __repr__(self):
self.search_list.get_all(self.attribute)
+
def __getitem__(self, index):
channels = self.get_all()
return channels[index]
+
def __iter__(self):
channels = self.get_all()
for channel in channels:
yield channel
+
def get_all(self):
items = []
items += self.search_list.get_all(self.attribute)
return items
+
def find(self, name):
items = self.search_list.find_deep(name, self.attribute)
- items = [x for x in items if x != None]
+ items = [x for x in items if x is not None]
if len(items) == 1:
return items[0]
elif len(items) == 0:
@@ -91,17 +101,21 @@ class Meta(list):
dbg("probably something bad happened with meta items: {}".format(items))
return items
raise AmbiguousProblemError
+
def find_first(self, name):
items = self.find(name)
if items.__class__ == list:
return items[0]
else:
return False
+
def find_by_class(self, class_name):
items = self.search_list.find_by_class_deep(class_name, self.attribute)
return items
+
class SearchList(list):
+
def find(self, name):
items = []
for child in self:
@@ -114,41 +128,47 @@ class SearchList(list):
return items[0]
elif items != []:
return items
+
def find_deep(self, name, attribute):
items = []
for child in self:
if child.__class__ == self.__class__:
- if items != None:
+ if items is not None:
items += child.find_deep(name, attribute)
elif dir(child).count('find') == 1:
- if items != None:
+ if items is not None:
items.append(child.find(name, attribute))
if items != []:
return items
+
def get_all(self, attribute):
items = []
for child in self:
if child.__class__ == self.__class__:
items += child.get_all(attribute)
else:
- items += (eval("child."+attribute))
+ items += (eval("child." + attribute))
return items
+
def find_by_class(self, class_name):
items = []
for child in self:
if child.__class__ == class_name:
items.append(child)
return items
+
def find_by_class_deep(self, class_name, attribute):
items = []
for child in self:
if child.__class__ == self.__class__:
items += child.find_by_class_deep(class_name, attribute)
else:
- items += (eval('child.'+attribute).find_by_class(class_name))
+ items += (eval('child.' + attribute).find_by_class(class_name))
return items
+
class SlackServer(object):
+
def __init__(self, token):
self.nick = None
self.name = None
@@ -167,37 +187,45 @@ class SlackServer(object):
self.identifier = None
self.connect_to_slack()
+
def __eq__(self, compare_str):
if compare_str == self.identifier or compare_str == self.token or compare_str == self.buffer:
return True
else:
return False
+
def __str__(self):
return "{}".format(self.identifier)
+
def __repr__(self):
return "{}".format(self.identifier)
+
def find(self, name, attribute):
- attribute = eval("self."+attribute)
+ attribute = eval("self." + attribute)
return attribute.find(name)
+
def send_to_websocket(self, data):
try:
self.ws.send(data)
dbg("Sent {}...".format(data[:100]))
except:
self.connected = False
+
def ping(self):
if self.ping_counter > 999:
self.ping_counter = 0
- request = {"type":"ping", "id":self.ping_counter}
+ request = {"type": "ping", "id": self.ping_counter}
self.send_to_websocket(json.dumps(request))
self.ping_counter += 1
+
def connect_to_slack(self):
t = time.time()
if not self.connecting:
- async_slack_api_request("slack.com", self.token, "rtm.start", {"ts":t})
+ async_slack_api_request("slack.com", self.token, "rtm.start", {"ts": t})
self.connecting = True
+
def connected_to_slack(self, login_data):
- if login_data["ok"] == True:
+ if login_data["ok"]:
self.domain = login_data["team"]["domain"] + ".slack.com"
dbg("connected to {}".format(self.domain))
self.identifier = self.domain
@@ -219,10 +247,12 @@ class SlackServer(object):
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 ")
self.connected = False
+
def create_local_buffer(self):
if not w.buffer_search("", self.domain):
self.buffer = w.buffer_new(self.domain, "buffer_input_cb", "", "", "")
w.buffer_set(self.buffer, "nicklist", "1")
+
def create_slack_websocket(self, data):
web_socket_url = data['url']
try:
@@ -232,35 +262,37 @@ class SlackServer(object):
return True
except:
return False
+
def create_slack_mappings(self, data):
for item in data["users"]:
self.users.append(User(self, item["name"], item["id"], item["presence"]))
for item in data["channels"]:
- if not item.has_key("last_read"):
+ if "last_read" not in item:
item["last_read"] = 0
- if not item.has_key("members"):
+ if "members" not in item:
item["members"] = []
- if not item.has_key("topic"):
+ 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"]))
for item in data["groups"]:
- if not item.has_key("last_read"):
+ 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"]))
for item in data["ims"]:
- if not item.has_key("last_read"):
+ if "last_read" not in item:
item["last_read"] = 0
name = self.users.find(item["user"]).name
self.channels.append(DmChannel(self, name, item["id"], item["is_open"], item["last_read"]))
for item in self.channels:
item.get_history()
+
def buffer_prnt(self, message='no message', user="SYSTEM", backlog=False):
message = message.encode('ascii', 'ignore')
- if backlog == True:
+ if backlog:
tags = "no_highlight,notify_none,logger_backlog_end"
else:
tags = ""
@@ -270,16 +302,21 @@ class SlackServer(object):
pass
#w.prnt("", "%s\t%s" % (user, message))
+
class SlackThing(object):
+
def __init__(self, name, identifier):
self.name = name
self.identifier = identifier
self.channel_buffer = None
+
def __str__(self):
return self.name
+
def __repr__(self):
return self.name
+
def buffer_input_cb(b, buffer, data):
channel = channels.find(buffer)
channel.send_message(data)
@@ -287,7 +324,9 @@ def buffer_input_cb(b, buffer, data):
channel.mark_read(True)
return w.WEECHAT_RC_ERROR
+
class Channel(SlackThing):
+
def __init__(self, server, name, identifier, active, last_read=0, prepend_name="", members=[], topic=""):
super(Channel, self).__init__(name, identifier)
self.type = "channel"
@@ -305,11 +344,13 @@ class Channel(SlackThing):
self.attach_buffer()
self.update_nicklist()
self.set_topic(self.topic)
+
def __eq__(self, compare_str):
- if compare_str == self.fullname() or compare_str == self.name or compare_str == self.identifier or compare_str == self.name[1:] or (compare_str == self.channel_buffer and self.channel_buffer != None):
+ if compare_str == self.fullname() or compare_str == self.name or compare_str == self.identifier or compare_str == self.name[1:] or (compare_str == self.channel_buffer and self.channel_buffer is not None):
return True
else:
return False
+
def create_buffer(self):
channel_buffer = w.buffer_search("", "{}.{}".format(self.server.domain, self.name))
if channel_buffer:
@@ -321,6 +362,7 @@ class Channel(SlackThing):
else:
w.buffer_set(self.channel_buffer, "localvar_set_type", 'channel')
w.buffer_set(self.channel_buffer, "short_name", 'loading..')
+
def attach_buffer(self):
channel_buffer = w.buffer_search("", "{}.{}".format(self.server.domain, self.name))
if channel_buffer != main_weechat_buffer:
@@ -328,10 +370,12 @@ class Channel(SlackThing):
# w.buffer_set(self.channel_buffer, "highlight_words", self.server.nick)
else:
self.channel_buffer = None
+
def detach_buffer(self):
- if self.channel_buffer != None:
+ if self.channel_buffer is not None:
w.buffer_close(self.channel_buffer)
self.channel_buffer = None
+
def update_nicklist(self):
w.buffer_set(self.channel_buffer, "nicklist", "1")
w.nicklist_remove_all(self.channel_buffer)
@@ -341,28 +385,37 @@ class Channel(SlackThing):
w.nicklist_add_nick(self.channel_buffer, "", user.name, user.color(), " ", "", 1)
else:
w.nicklist_add_nick(self.channel_buffer, "", user.name, user.color(), "+", "", 1)
+
def fullname(self):
return "{}.{}".format(self.server.domain, self.name)
+
def has_user(self, name):
return name in self.members
+
def user_join(self, name):
self.members.add(name)
self.update_nicklist()
+
def user_leave(self, name):
if name in self.members:
self.members.remove(name)
self.update_nicklist()
+
def set_active(self):
self.active = True
+
def set_inactive(self):
self.active = False
+
def set_typing(self, user):
self.typing[user] = time.time()
+
def send_message(self, message):
message = self.linkify_text(message)
dbg(message)
- request = {"type":"message", "channel":self.identifier, "text": message}
+ request = {"type": "message", "channel": self.identifier, "text": message}
self.server.send_to_websocket(json.dumps(request))
+
def linkify_text(self, message):
message = message.split(' ')
for item in enumerate(message):
@@ -376,43 +429,51 @@ class Channel(SlackThing):
message[item[0]] = "<#{}>{}".format(self.server.channels.find(named[0]).identifier, named[1])
dbg(message)
return " ".join(message)
+
def set_topic(self, topic):
topic = topic.encode('ascii', 'ignore')
- w.buffer_set(self.channel_buffer, "title", topic);
+ w.buffer_set(self.channel_buffer, "title", topic)
+
def open(self, update_remote=True):
self.create_buffer()
self.active = True
self.get_history()
t = time.time()
- async_slack_api_request(self.server.domain, self.server.token, SLACK_API_TRANSLATOR[self.type]["info"], {"name":self.name.lstrip("#"), "ts":t})
+ async_slack_api_request(self.server.domain, self.server.token, SLACK_API_TRANSLATOR[self.type]["info"], {"name": self.name.lstrip("#"), "ts": t})
if update_remote:
- async_slack_api_request(self.server.domain, self.server.token, SLACK_API_TRANSLATOR[self.type]["join"], {"name":self.name.lstrip("#"), "ts":t})
+ async_slack_api_request(self.server.domain, self.server.token, SLACK_API_TRANSLATOR[self.type]["join"], {"name": self.name.lstrip("#"), "ts": t})
+
def close(self, update_remote=True):
- if self.active == True:
+ if self.active:
self.active = False
self.detach_buffer()
if update_remote:
t = time.time()
- async_slack_api_request(self.server.domain, self.server.token, SLACK_API_TRANSLATOR[self.type]["leave"], {"channel":self.identifier, "ts":t})
+ async_slack_api_request(self.server.domain, self.server.token, SLACK_API_TRANSLATOR[self.type]["leave"], {"channel": self.identifier, "ts": t})
+
def closed(self):
self.channel_buffer = None
self.close()
+
def unset_typing(self, user):
try:
del self.typing[user]
except:
pass
+
def is_someone_typing(self):
for user in self.typing.keys():
if self.typing[user] + 4 > time.time():
return True
return False
+
def get_typing_list(self):
typing = []
for user in self.typing.keys():
if self.typing[user] + 4 > time.time():
typing.append(user)
return typing
+
def mark_read(self, update_remote=True):
t = time.time()
@@ -421,20 +482,23 @@ class Channel(SlackThing):
if update_remote:
self.last_read = time.time()
self.set_read_marker(self.last_read)
+
def set_read_marker(self, time):
- async_slack_api_request(self.server.domain, self.server.token, SLACK_API_TRANSLATOR[self.type]["mark"], {"channel":self.identifier, "ts":time})
+ async_slack_api_request(self.server.domain, self.server.token, SLACK_API_TRANSLATOR[self.type]["mark"], {"channel": self.identifier, "ts": time})
+
def rename(self):
if current_domain_name() != self.server.domain and channels_not_on_current_server_color:
color = channels_not_on_current_server_color
else:
color = "default"
color = w.color(color)
- if self.is_someone_typing() == True:
+ if self.is_someone_typing():
new_name = ">{}".format(self.name[1:])
else:
new_name = self.name
if self.channel_buffer:
w.buffer_set(self.channel_buffer, "short_name", color + new_name)
+
def buffer_prnt(self, user='unknown user', message='no message', time=0, backlog=False):
set_read_marker = False
time = float(time)
@@ -459,31 +523,37 @@ class Channel(SlackThing):
message = message[len(self.previous_prnt_message):]
message = HTMLParser.HTMLParser().unescape(message)
w.prnt_date_tags(self.channel_buffer, time, tags, "{}\t{}".format(name, message))
- #eventually maybe - doesn't reprint name if next message is same user
- #if name != self.previous_prnt_name:
+ # eventually maybe - doesn't reprint name if next message is same user
+ # if name != self.previous_prnt_name:
# w.prnt_date_tags(self.channel_buffer, time, tags, "%s\t%s" % (name, message))
# self.previous_prnt_name = name
- #else:
+ # else:
# w.prnt_date_tags(self.channel_buffer, time, tags, "%s\t%s" % ("", message))
self.previous_prnt_message = message
if set_read_marker:
self.mark_read(False)
else:
self.open(False)
+
def get_history(self):
if self.active:
t = time.time()
- async_slack_api_request(self.server.domain, self.server.token, SLACK_API_TRANSLATOR[self.type]["history"], {"channel":self.identifier, "ts":t, "count":BACKLOG_SIZE})
+ async_slack_api_request(self.server.domain, self.server.token, SLACK_API_TRANSLATOR[self.type]["history"], {"channel": self.identifier, "ts": t, "count": BACKLOG_SIZE})
+
class GroupChannel(Channel):
+
def __init__(self, server, name, identifier, active, last_read=0, prepend_name="", members=[], topic=""):
super(GroupChannel, self).__init__(server, name, identifier, active, last_read, prepend_name, members, topic)
self.type = "group"
+
class DmChannel(Channel):
+
def __init__(self, server, name, identifier, active, last_read=0, prepend_name=""):
super(DmChannel, self).__init__(server, name, identifier, active, last_read, prepend_name)
self.type = "im"
+
def rename(self):
if current_domain_name() != self.server.domain and channels_not_on_current_server_color:
color = channels_not_on_current_server_color
@@ -497,7 +567,9 @@ class DmChannel(Channel):
if self.channel_buffer:
w.buffer_set(self.channel_buffer, "short_name", color + new_name)
+
class User(SlackThing):
+
def __init__(self, server, name, identifier, presence="away"):
super(User, self).__init__(name, identifier)
self.channel_buffer = w.info_get("irc_buffer", "{}.{}".format(domain, self.name))
@@ -508,11 +580,13 @@ class User(SlackThing):
else:
self.nicklist_pointer = w.nicklist_add_nick(server.buffer, "", self.name, self.color(), "+", "", 1)
# w.nicklist_add_nick(server.buffer, "", self.colorized_name(), "", "", "", 1)
+
def __eq__(self, compare_str):
- if compare_str == self.name or compare_str == "@" + self.name or compare_str == self.identifier:
+ if compare_str == self.name or compare_str == "@" + self.name or compare_str == self.identifier:
return True
else:
return False
+
def set_active(self):
self.presence = "active"
for channel in self.server.channels:
@@ -520,6 +594,7 @@ class User(SlackThing):
channel.update_nicklist()
w.nicklist_nick_set(self.server.buffer, self.nicklist_pointer, "prefix", "+")
w.nicklist_nick_set(self.server.buffer, self.nicklist_pointer, "visible", "1")
+
def set_inactive(self):
self.presence = "away"
for channel in self.server.channels:
@@ -527,22 +602,26 @@ class User(SlackThing):
channel.update_nicklist()
w.nicklist_nick_set(self.server.buffer, self.nicklist_pointer, "prefix", " ")
w.nicklist_nick_set(self.server.buffer, self.nicklist_pointer, "visible", "0")
+
def color(self):
if colorize_nicks:
return w.info_get('irc_nick_color_name', self.name)
else:
return "default"
+
def colorized_name(self):
if colorize_nicks:
color = w.info_get('irc_nick_color', self.name)
def_color = w.color('default')
- return color+self.name+def_color
+ return color + self.name + def_color
else:
return self.name
+
def open(self):
t = time.time() + 1
#reply = async_slack_api_request("im.open", {"channel":self.identifier,"ts":t})
- async_slack_api_request(self.server.domain, self.server.token, "im.open", {"user":self.identifier, "ts":t})
+ async_slack_api_request(self.server.domain, self.server.token, "im.open", {"user": self.identifier, "ts": t})
+
def slack_command_cb(data, current_buffer, args):
a = args.split(' ', 1)
@@ -556,6 +635,7 @@ def slack_command_cb(data, current_buffer, args):
# w.prnt("", "Command not found or exception: "+function_name)
return w.WEECHAT_RC_OK
+
def me_command_cb(data, current_buffer, args):
if channels.find(current_buffer):
channel = channels.find(current_buffer)
@@ -564,6 +644,7 @@ def me_command_cb(data, current_buffer, args):
buffer_input_cb("", current_buffer, message)
return w.WEECHAT_RC_OK
+
def join_command_cb(data, current_buffer, args):
if channels.find(current_buffer) or servers.find(current_buffer):
channel = args.split()[1]
@@ -572,6 +653,7 @@ def join_command_cb(data, current_buffer, args):
else:
return w.WEECHAT_RC_OK
+
def part_command_cb(data, current_buffer, args):
if channels.find(current_buffer) or servers.find(current_buffer):
args = args.split()
@@ -584,69 +666,84 @@ def part_command_cb(data, current_buffer, args):
else:
return w.WEECHAT_RC_OK
+
def command_talk(current_buffer, args):
servers.find(current_domain_name()).users.find(args).open()
+
def command_join(current_buffer, args):
servers.find(current_domain_name()).channels.find(args).open()
+
def command_channels(current_buffer, args):
server = servers.find(current_domain_name())
for channel in server.channels:
line = "{:<25} {} {}".format(channel.name, channel.identifier, channel.active)
server.buffer_prnt(line)
+
def command_users(current_buffer, args):
server = servers.find(current_domain_name())
for user in server.users:
line = "{:<40} {} {}".format(user.colorized_name(), user.identifier, user.presence)
server.buffer_prnt(line)
+
def command_setallreadmarkers(current_buffer, args):
if args:
for channel in channels:
channel.set_read_marker(args)
+
def command_changetoken(current_buffer, args):
w.config_set_plugin('slack_api_token', args)
+
def command_test(current_buffer, args):
if slack_buffer:
w.prnt(slack_buffer, "worked!")
+
def command_away(current_buffer, args):
server = servers.find(current_domain_name())
- async_slack_api_request(server.domain, server.token, 'presence.set', {"presence":"away"})
+ async_slack_api_request(server.domain, server.token, 'presence.set', {"presence": "away"})
+
def command_back(current_buffer, args):
server = servers.find(current_domain_name())
- async_slack_api_request(server.domain, server.token, 'presence.set', {"presence":"active"})
+ async_slack_api_request(server.domain, server.token, 'presence.set', {"presence": "active"})
+
def command_markread(current_buffer, args):
- #refactor this - one liner i think
+ # refactor this - one liner i think
channel = current_buffer_name(short=True)
domain = current_domain_name()
if servers.find(domain).channels.find(channel):
servers.find(domain).channels.find(channel).mark_read()
+
def command_neveraway(current_buffer, args):
global never_away
- if never_away == True:
+ if never_away:
never_away = False
dbg("unset never_away")
else:
never_away = True
dbg("set never_away")
+
def command_printvar(current_buffer, args):
w.prnt("", str(eval(args)))
+
def command_p(current_buffer, args):
w.prnt("", str(eval(args)))
+
def command_debug(current_buffer, args):
create_slack_debug_buffer()
+
def command_debugstring(current_buffer, args):
global debug_string
if args == '':
@@ -654,6 +751,7 @@ def command_debugstring(current_buffer, args):
else:
debug_string = args
+
def command_search(current_buffer, args):
pass
# if not slack_buffer:
@@ -668,6 +766,7 @@ def command_search(current_buffer, args):
# formatted_message = "%s / %s:\t%s" % (message["channel"]["name"], message['username'], message['text'])
# w.prnt(slack_buffer,str(formatted_message))
+
def command_nick(current_buffer, args):
pass
# urllib.urlopen("https://%s/account/settings" % (domain))
@@ -675,25 +774,26 @@ def command_nick(current_buffer, args):
# browser.form['username'] = args
# reply = browser.submit()
-### Websocket handling methods
+# Websocket handling methods
+
def slack_websocket_cb(data, fd):
server = data
try:
data = servers.find(server).ws.recv()
message_json = json.loads(data)
- #this magic attaches json that helps find the right dest
+ # this magic attaches json that helps find the right dest
message_json['myserver'] = server
except:
return w.WEECHAT_RC_OK
- #dispatch here
- if message_json.has_key("type"):
+ # dispatch here
+ if "type" in message_json:
function_name = message_json["type"]
else:
function_name = "unknown"
try:
proc[function_name](message_json)
- #dbg(function_name)
+ # dbg(function_name)
except KeyError:
pass
if function_name:
@@ -703,15 +803,18 @@ def slack_websocket_cb(data, fd):
w.bar_item_update("slack_typing_notice")
return w.WEECHAT_RC_OK
+
def process_pong(message_json):
pass
+
def process_team_join(message_json):
server = servers.find(message_json["myserver"])
item = message_json["user"]
server.users.append(User(server, item["name"], item["id"], item["presence"]))
w.prnt(server.buffer, "New user joined: {}".format(item["name"]))
+
def process_presence_change(message_json):
buffer_name = "{}.{}".format(domain, message_json["user"])
buf_ptr = w.buffer_search("", buffer_name)
@@ -720,18 +823,21 @@ def process_presence_change(message_json):
else:
users.find(message_json["user"]).set_inactive()
+
def process_channel_marked(message_json):
channel = channels.find(message_json["channel"])
channel.mark_read(False)
if not legacy_mode:
w.buffer_set(channel.channel_buffer, "hotlist", "-1")
+
def process_group_marked(message_json):
channel = channels.find(message_json["channel"])
channel.mark_read(False)
if not legacy_mode:
w.buffer_set(channel.channel_buffer, "hotlist", "-1")
+
def process_channel_created(message_json):
server = servers.find(message_json["myserver"])
item = message_json["channel"]
@@ -742,20 +848,24 @@ def process_channel_created(message_json):
server.channels.append(Channel(server, item["name"], item["id"], item["is_open"], item["last_read"], "#", item["members"], item["topic"]))
w.prnt(server.buffer, "New channel created: {}".format(item["name"]))
+
def process_channel_left(message_json):
server = servers.find(message_json["myserver"])
server.channels.find(message_json["channel"]).close(False)
+
def process_channel_join(message_json):
server = servers.find(message_json["myserver"])
channel = server.channels.find(message_json["channel"])
channel.user_join(message_json["user"])
+
def process_channel_topic(message_json):
server = servers.find(message_json["myserver"])
channel = server.channels.find(message_json["channel"])
channel.set_topic(message_json["topic"])
+
def process_channel_joined(message_json):
server = servers.find(message_json["myserver"])
if server.channels.find(message_json["channel"]["name"]):
@@ -764,15 +874,18 @@ def process_channel_joined(message_json):
item = message_json["channel"]
server.channels.append(Channel(server, item["name"], item["id"], item["is_open"], item["last_read"], "#", item["members"], item["topic"]))
+
def process_channel_leave(message_json):
server = servers.find(message_json["myserver"])
channel = server.channels.find(message_json["channel"])
channel.user_leave(message_json["user"])
+
def process_group_left(message_json):
server = servers.find(message_json["myserver"])
server.channels.find(message_json["channel"]).close(False)
+
def process_group_joined(message_json):
server = servers.find(message_json["myserver"])
if server.channels.find(message_json["channel"]["name"]):
@@ -781,20 +894,24 @@ def process_group_joined(message_json):
item = message_json["channel"]
server.channels.append(GroupChannel(server, item["name"], item["id"], item["is_open"], item["last_read"], "#", item["members"], item["topic"]))
+
def process_im_close(message_json):
server = servers.find(message_json["myserver"])
server.channels.find(message_json["channel"]).close(False)
+
def process_im_open(message_json):
server = servers.find(message_json["myserver"])
server.channels.find(message_json["channel"]).open(False)
+
def process_im_marked(message_json):
channel = channels.find(message_json["channel"])
channel.mark_read(False)
if not legacy_mode:
w.buffer_set(channel.channel_buffer, "hotlist", "-1")
+
def process_im_created(message_json):
server = servers.find(message_json["myserver"])
item = message_json["channel"]
@@ -806,42 +923,46 @@ def process_im_created(message_json):
server.channels.append(DmChannel(server, channel_name, item["id"], item["is_open"], item["last_read"]))
w.prnt(server.buffer, "New channel created: {}".format(item["name"]))
+
def process_user_typing(message_json):
server = servers.find(message_json["myserver"])
server.channels.find(message_json["channel"]).set_typing(server.users.find(message_json["user"]).name)
-#todo: does this work?
+# todo: does this work?
+
+
def process_error(message_json):
pass
#connected = False
-#def process_message_changed(message_json):
+# def process_message_changed(message_json):
# process_message(message_json)
+
def process_message(message_json):
mark_silly_channels_read(message_json["channel"])
- #send these messages elsewhere
+ # send these messages elsewhere
known_subtypes = ['channel_join', 'channel_leave', 'channel_topic']
- if message_json.has_key("subtype") and message_json["subtype"] in known_subtypes:
+ if "subtype" in message_json and message_json["subtype"] in known_subtypes:
proc[message_json["subtype"]](message_json)
else:
- #move message properties down to root of json object
+ # move message properties down to root of json object
message_json = unwrap_message(message_json)
server = servers.find(message_json["myserver"])
channel = channels.find(message_json["channel"])
time = message_json['ts']
- if message_json.has_key("fallback"):
+ if "fallback" in message_json:
text = message_json["fallback"]
- elif message_json.has_key("text"):
+ elif "text" in message_json:
text = message_json["text"]
else:
text = ""
text = unfurl_refs(text)
- if message_json.has_key("attachments"):
+ if "attachments" in message_json:
text += "--- {}".format(unwrap_attachments(message_json))
text = text.lstrip()
text = text.replace("\t", " ")
@@ -851,41 +972,44 @@ def process_message(message_json):
server.channels.find(channel).buffer_prnt(name, text, time)
+
def unwrap_message(message_json):
- if message_json.has_key("message"):
- if message_json["message"].has_key("attachments"):
+ if "message" in message_json:
+ if "attachments" in message_json["message"]:
message_json["attachments"] = message_json["message"]["attachments"]
- if message_json["message"].has_key("text"):
- if message_json.has_key("text"):
+ if "text" in message_json["message"]:
+ if "text" in message_json:
message_json["text"] += message_json["message"]["text"]
dbg("added text!")
else:
message_json["text"] = message_json["message"]["text"]
- if message_json["message"].has_key("fallback"):
- if message_json.has_key("fallback"):
+ if "fallback" in message_json["message"]:
+ if "fallback" in message_json:
message_json["fallback"] += message_json["message"]["fallback"]
else:
message_json["fallback"] = message_json["message"]["fallback"]
return message_json
+
def unwrap_attachments(message_json):
attachment_text = ''
for attachment in message_json["attachments"]:
- if attachment.has_key("fallback"):
+ if "fallback" in attachment:
attachment_text += attachment["fallback"]
attachment_text = attachment_text.encode('ascii', 'ignore')
return attachment_text
+
def unfurl_refs(text):
if text.find('<') > -1:
newtext = []
text = text.split(" ")
for item in text:
- #dbg(item)
+ # dbg(item)
start = item.find('<')
end = item.find('>')
if start > -1 and end > -1:
- item = item[start+1:end]
+ item = item[start + 1:end]
if item.find('|') > -1:
item = item.split('|')[0]
if item.startswith('@U'):
@@ -903,23 +1027,25 @@ def unfurl_refs(text):
else:
return text
+
def get_user(message_json, server):
- if message_json.has_key('user'):
+ if 'user' in message_json:
name = server.users.find(message_json['user']).name
- elif message_json.has_key('username'):
+ elif 'username' in message_json:
name = "-{}-".format(message_json["username"])
- elif message_json.has_key('service_name'):
+ elif 'service_name' in message_json:
name = "-{}-".format(message_json["service_name"])
- elif message_json.has_key('bot_id'):
+ elif 'bot_id' in message_json:
name = "-{}-".format(message_json["bot_id"])
else:
name = ""
return name
-### END Websocket handling methods
+# END Websocket handling methods
+
def typing_bar_item_cb(data, buffer, args):
- typers = [x for x in channels.get_all() if x.is_someone_typing() == True]
+ typers = [x for x in channels.get_all() if x.is_someone_typing()]
if len(typers) > 0:
direct_typers = []
channel_typers = []
@@ -939,36 +1065,41 @@ def typing_bar_item_cb(data, buffer, args):
return color + "typing: " + typing_here
return ""
+
def typing_update_cb(data, remaining_calls):
w.bar_item_update("slack_typing_notice")
return w.WEECHAT_RC_OK
+
def buffer_list_update_cb(data, remaining_calls):
gray_check = False
if len(servers) > 1:
gray_check = True
- #for channel in channels.find_by_class(Channel) + channels.find_by_class(GroupChannel):
+ # for channel in channels.find_by_class(Channel) + channels.find_by_class(GroupChannel):
for channel in channels:
channel.rename()
return w.WEECHAT_RC_OK
+
def hotlist_cache_update_cb(data, remaining_calls):
- #this keeps the hotlist dupe up to date for the buffer switch, but is prob technically a race condition. (meh)
+ # this keeps the hotlist dupe up to date for the buffer switch, but is prob technically a race condition. (meh)
global hotlist
prev_hotlist = hotlist
hotlist = w.infolist_get("hotlist", "", "")
w.infolist_free(prev_hotlist)
return w.WEECHAT_RC_OK
+
def buffer_closing_cb(signal, sig_type, data):
if channels.find(data):
channels.find(data).closed()
return w.WEECHAT_RC_OK
+
def buffer_switch_cb(signal, sig_type, data):
global previous_buffer, hotlist
- #this is to see if we need to gray out things in the buffer list
- buffer_list_update_cb('','')
+ # this is to see if we need to gray out things in the buffer list
+ buffer_list_update_cb('', '')
if channels.find(previous_buffer):
channels.find(previous_buffer).mark_read()
@@ -976,6 +1107,7 @@ def buffer_switch_cb(signal, sig_type, data):
previous_buffer = data
return w.WEECHAT_RC_OK
+
def typing_notification_cb(signal, sig_type, data):
if len(w.buffer_get_string(data, "input")) > 8:
global typing_timer
@@ -984,38 +1116,44 @@ def typing_notification_cb(signal, sig_type, data):
channel = channels.find(current_buffer_name())
if channel:
identifier = channel.identifier
- request = {"type":"typing", "channel":identifier}
+ request = {"type": "typing", "channel": identifier}
channel.server.send_to_websocket(json.dumps(request))
typing_timer = now
return w.WEECHAT_RC_OK
-#NOTE: figured i'd do this because they do
+# NOTE: figured i'd do this because they do
+
+
def slack_ping_cb(data, remaining):
servers.find(data).ping()
return w.WEECHAT_RC_OK
+
def slack_connection_persistence_cb(data, remaining_calls):
for server in servers:
if not server.connected:
server.buffer_prnt("Disconnected from slack, trying to reconnect..")
- if server.ws_hook != None:
+ if server.ws_hook is not None:
w.unhook(server.ws_hook)
server.connect_to_slack()
return w.WEECHAT_RC_OK
+
def slack_never_away_cb(data, remaining):
global never_away
- if never_away == True:
+ if never_away:
for server in servers:
identifier = server.channels.find("slackbot").identifier
- request = {"type":"typing", "channel":identifier}
+ request = {"type": "typing", "channel": identifier}
#request = {"type":"typing","channel":"slackbot"}
server.send_to_websocket(json.dumps(request))
return w.WEECHAT_RC_OK
-### Slack specific requests
+# Slack specific requests
+
+# NOTE: switched to async/curl because sync slowed down the UI
+
-#NOTE: switched to async/curl because sync slowed down the UI
def async_slack_api_request(domain, token, request, post_data, priority=False):
#t = time.time()
post_elements = pickle.dumps([domain, token, request, post_data])
@@ -1025,42 +1163,54 @@ def async_slack_api_request(domain, token, request, post_data, priority=False):
post = {"post": "1", "postfields": post_data}
url = 'https://{}/api/{}'.format(domain, request)
queue_item = ['url:{}'.format(url), post, 20000, 'url_processor_cb', post_elements]
- if priority != True:
+ if not priority:
queue.append(QueueItem(queue_item, 'do_url', 'url_processor_cb'))
else:
queue.insert(0, QueueItem(queue_item, 'do_url', 'url_processor_cb'))
+
class QueueLock(object):
+
def __init__(self):
self.max_active = 3
self.active_count = 0
self.counter = 0
self.timer = time.time()
pass
+
def lock(self):
self.active_count += 1
+
def unlock(self):
self.active_count -= 1
+
def check(self):
if time.time() > (self.counter + self.timer) and self.active_count < self.max_active:
return True
else:
return False
+
def bad(self):
self.counter += 1
self.timer = time.time()
+
def good(self):
self.counter = 0
+
class QueueItem(object):
+
def __init__(self, data, method, callback_method=None):
self.method = method
self.callback_method = callback_method
self.data = data
+
def __getitem__(self, index):
return self.data[index]
+
def __str__(self):
return str(self.data)
+
def __repr__(self):
return str(self.data)
@@ -1068,11 +1218,12 @@ queue = []
async_queue_lock = QueueLock()
captain_of_hooks = []
+
def do_url(item):
global captain_of_hooks
try:
query = urlparse.parse_qs(item[1]["postfields"])
- if query.has_key("channel") and item[0].find('history') > -1:
+ if "channel" in query and item[0].find('history') > -1:
channel = query["channel"][0]
channel = channels.find(channel)
channel.server.buffer_prnt("downloading channel history for {}".format(channel.name), backlog=True)
@@ -1082,6 +1233,7 @@ def do_url(item):
# w.hook_process_hashtable(*item)
captain_of_hooks.append(w.hook_process(command, 20000, item[3], item[4]))
+
def async_queue_cb(data, remaining_calls):
global async_queue_lock
if async_queue_lock.check():
@@ -1092,14 +1244,16 @@ def async_queue_cb(data, remaining_calls):
method(item)
return w.WEECHAT_RC_OK
-#funny, right?
+# funny, right?
big_data = {}
+
+
def url_processor_cb(data, command, return_code, out, err):
global async_queue_lock, big_data, captain_of_hooks
# if return_code == 0 or -1:
data = pickle.loads(data)
identifier = sha.sha(str(data) + command).hexdigest()
- if not big_data.has_key(identifier):
+ if identifier not in big_data:
big_data[identifier] = ''
big_data[identifier] += out
if return_code == 0:
@@ -1108,7 +1262,7 @@ def url_processor_cb(data, command, return_code, out, err):
my_json = json.loads(big_data[identifier])
async_queue_lock.good()
except:
-# if big_data[identifier] != '':
+ # if big_data[identifier] != '':
dbg("curl failed, doing again...")
dbg("curl length: {} identifier {}\n{}".format(len(big_data[identifier]), identifier, data))
@@ -1124,18 +1278,18 @@ def url_processor_cb(data, command, return_code, out, err):
else:
query = data[3]
- if query.has_key("channel"):
+ if "channel" in query:
channel = query["channel"]
token = data[1]
- if my_json.has_key("messages"):
+ if "messages" in my_json:
messages = my_json["messages"].reverse()
for message in my_json["messages"]:
message["myserver"] = servers.find(token).domain
message["channel"] = servers.find(token).channels.find(channel).identifier
process_message(message)
- if my_json.has_key("channel"):
- if my_json["channel"].has_key("members"):
- channels.find(my_json["channel"]["id"]).members = set(my_json["channel"]["members"])
+ if "channel" in my_json:
+ if "members" in my_json["channel"]:
+ channels.find(my_json["channel"]["id"]).members = set(my_json["channel"]["members"])
elif return_code != -1:
big_data.pop(identifier, None)
async_queue_lock.unlock()
@@ -1143,15 +1297,17 @@ def url_processor_cb(data, command, return_code, out, err):
return w.WEECHAT_RC_OK
+
def mark_silly_channels_read(channel):
name = channels.find(channel).name
if name in channels_always_marked_read:
if channels.find(channel):
channels.find(channel).mark_read()
-### END Slack specific requests
+# END Slack specific requests
+
+# Utility Methods
-### Utility Methods
def current_domain_name():
buffer = w.current_buffer()
@@ -1163,6 +1319,7 @@ def current_domain_name():
name = ".".join(name.split(".")[:-1])
return name
+
def current_buffer_name(short=False):
buffer = w.current_buffer()
#number = w.buffer_get_integer(buffer, "number")
@@ -1174,11 +1331,13 @@ def current_buffer_name(short=False):
pass
return name
+
def closed_slack_buffer_cb(data, buffer):
global slack_buffer
slack_buffer = None
return w.WEECHAT_RC_OK
+
def create_slack_buffer():
global slack_buffer
slack_buffer = w.buffer_new("slack", "", "", "closed_slack_buffer_cb", "")
@@ -1186,20 +1345,23 @@ def create_slack_buffer():
#w.buffer_set(slack_buffer, "display", "1")
return w.WEECHAT_RC_OK
+
def closed_slack_debug_buffer_cb(data, buffer):
global slack_debug
slack_debug = None
return w.WEECHAT_RC_OK
+
def create_slack_debug_buffer():
global slack_debug, debug_string
- if slack_debug != None:
+ if slack_debug is not None:
w.buffer_set(slack_debug, "display", "1")
else:
debug_string = None
slack_debug = w.buffer_new("slack-debug", "", "", "closed_slack_debug_buffer_cb", "")
w.buffer_set(slack_debug, "notify", "0")
+
def config_changed_cb(data, option, value):
global slack_api_token, channels_always_marked_read, channels_not_on_current_server_color, colorize_nicks, slack_debug, debug_mode
slack_api_token = w.config_get_plugin("slack_api_token")
@@ -1218,12 +1380,12 @@ def config_changed_cb(data, option, value):
create_slack_debug_buffer()
return w.WEECHAT_RC_OK
-### END Utility Methods
+# END Utility Methods
# Main
if __name__ == "__main__":
if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE,
- SCRIPT_DESC, "", ""):
+ SCRIPT_DESC, "", ""):
if not w.config_get_plugin('slack_api_token'):
w.config_set_plugin('slack_api_token', "INSERT VALID KEY HERE!")
@@ -1236,17 +1398,15 @@ if __name__ == "__main__":
if not w.config_get_plugin('colorize_nicks'):
w.config_set_plugin('colorize_nicks', "1")
-
version = w.info_get("version_number", "") or 0
if int(version) >= 0x00040400:
legacy_mode = False
else:
legacy_mode = True
- ### Global var section
+ # Global var section
config_changed_cb("", "", "")
-
cmds = {k[8:]: v for k, v in globals().items() if k.startswith("command_")}
proc = {k[8:]: v for k, v in globals().items() if k.startswith("process_")}
@@ -1259,7 +1419,7 @@ if __name__ == "__main__":
hotlist = w.infolist_get("hotlist", "", "")
main_weechat_buffer = w.info_get("irc_buffer", "{}.{}".format(domain, "DOESNOTEXIST!@#$"))
- ### End global var section
+ # End global var section
#channels = SearchList()
servers = SearchList()
@@ -1272,21 +1432,20 @@ if __name__ == "__main__":
w.hook_timer(100, 0, 0, "async_queue_cb", "")
w.hook_timer(3000, 0, 0, "slack_connection_persistence_cb", "")
- ### attach to the weechat hooks we need
+ # attach to the weechat hooks we need
w.hook_timer(1000, 0, 0, "typing_update_cb", "")
w.hook_timer(1000, 0, 0, "buffer_list_update_cb", "")
w.hook_timer(1000, 0, 0, "hotlist_cache_update_cb", "")
- w.hook_timer(1000 * 60* 29, 0, 0, "slack_never_away_cb", "")
+ w.hook_timer(1000 * 60 * 29, 0, 0, "slack_never_away_cb", "")
w.hook_signal('buffer_closing', "buffer_closing_cb", "")
w.hook_signal('buffer_switch', "buffer_switch_cb", "")
w.hook_signal('window_switch', "buffer_switch_cb", "")
w.hook_signal('input_text_changed', "typing_notification_cb", "")
- w.hook_command('slack','Plugin to allow typing notification and sync of read markers for slack.com', 'stuff', 'stuff2', '|'.join(cmds.keys()), 'slack_command_cb', '')
- w.hook_command('me','', 'stuff', 'stuff2', '', 'me_command_cb', '')
+ w.hook_command('slack', 'Plugin to allow typing notification and sync of read markers for slack.com', 'stuff', 'stuff2', '|'.join(cmds.keys()), 'slack_command_cb', '')
+ w.hook_command('me', '', 'stuff', 'stuff2', '', 'me_command_cb', '')
# w.hook_command('me', 'me_command_cb', '')
w.hook_command_run('/join', 'join_command_cb', '')
w.hook_command_run('/part', 'part_command_cb', '')
w.hook_command_run('/leave', 'part_command_cb', '')
w.bar_item_new('slack_typing_notice', 'typing_bar_item_cb', '')
- ### END attach to the weechat hooks we need
-
+ # END attach to the weechat hooks we need