aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrygve Aaberge <trygveaa@gmail.com>2017-04-15 01:54:22 +0200
committerTrygve Aaberge <trygveaa@gmail.com>2017-04-15 11:57:34 +0200
commit5e1c7e593d70972afb9a55f29d13adaf145d0166 (patch)
tree19937ba5efb80d9eb6acabf7aec56358cbc3d590
parent281adc84a156c12a1a32f96ad1a82a299be286f5 (diff)
downloadwee-slack-5e1c7e593d70972afb9a55f29d13adaf145d0166.tar.gz
Create a wrapper around weechat which handles encoding
This encodes everything sent into weechat, and decodes the return values, so we don't have to do it every place we call weechat. We still have to decode the arguments in all of the callback functions though. The encode_to_utf8 and decode_from_utf8 functions traverses data structures and encodes/decodes all of the strings inside the structures.
-rw-r--r--wee_slack.py52
1 files changed, 51 insertions, 1 deletions
diff --git a/wee_slack.py b/wee_slack.py
index a2b7e1e..125cee2 100644
--- a/wee_slack.py
+++ b/wee_slack.py
@@ -13,6 +13,7 @@ import re
import urllib
import sys
import traceback
+import collections
import ssl
import random
import string
@@ -21,7 +22,7 @@ from websocket import create_connection, WebSocketConnectionClosedException
# hack to make tests possible.. better way?
try:
- import weechat as w
+ import weechat
except:
pass
@@ -104,6 +105,53 @@ if hasattr(ssl, "get_default_verify_paths") and callable(ssl.get_default_verify_
if ssl_defaults.cafile is not None:
sslopt_ca_certs = {'ca_certs': ssl_defaults.cafile}
+###### Unicode handling
+
+
+def encode_to_utf8(data):
+ if isinstance(data, unicode):
+ return data.encode('utf-8')
+ if isinstance(data, bytes):
+ return data
+ elif isinstance(data, collections.Mapping):
+ return dict(map(encode_to_utf8, data.iteritems()))
+ elif isinstance(data, collections.Iterable):
+ return type(data)(map(encode_to_utf8, data))
+ else:
+ return data
+
+
+def decode_from_utf8(data):
+ if isinstance(data, bytes):
+ return data.decode('utf-8')
+ if isinstance(data, unicode):
+ return data
+ elif isinstance(data, collections.Mapping):
+ return dict(map(decode_from_utf8, data.iteritems()))
+ elif isinstance(data, collections.Iterable):
+ return type(data)(map(decode_from_utf8, data))
+ else:
+ return data
+
+
+class WeechatWrapper(object):
+ def __init__(self, wrapped_class):
+ self.wrapped_class = wrapped_class
+
+ def __getattr__(self, attr):
+ orig_attr = self.wrapped_class.__getattribute__(attr)
+ if callable(orig_attr):
+ def hooked(*args, **kwargs):
+ result = orig_attr(*encode_to_utf8(args), **encode_to_utf8(kwargs))
+ # Prevent wrapped_class from becoming unwrapped
+ if result == self.wrapped_class:
+ return self
+ return decode_from_utf8(result)
+ return hooked
+ else:
+ return decode_from_utf8(orig_attr)
+
+
##### BEGIN NEW
IGNORED_EVENTS = [
@@ -3240,6 +3288,8 @@ def trace_calls(frame, event, arg):
# Main
if __name__ == "__main__":
+ w = WeechatWrapper(weechat)
+
if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE,
SCRIPT_DESC, "script_unloaded", ""):