-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathksc.py
128 lines (108 loc) · 4.19 KB
/
ksc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# ksc.py
#
# Copyright 2019 Franz Brauße <[email protected]>
#
# This file is part of ksc.
# See the LICENSE file for terms of distribution.
from ctypes import *
class ksc_ffi:
class log(Structure):
pass
class envelope(Structure):
pass
class data(Structure):
pass
class socket(Structure):
pass
def __init__(self):
self._ksc = CDLL('./libksc.so')
ksc_ffi_log_p = POINTER(ksc_ffi.log)
ksc_envelope_p = POINTER(ksc_ffi.envelope)
ksc_data_p = POINTER(ksc_ffi.data)
ksc_p = POINTER(ksc_ffi.socket)
for k, v in {
'log_create': (ksc_ffi_log_p, (c_int, c_char_p)),
'log_destroy': (c_void_p, (ksc_ffi_log_p,)),
'log_restrict_context': (c_int, (ksc_ffi_log_p, c_char_p, c_char_p)),
'envelope_get_source': (c_char_p, (ksc_envelope_p,)),
'envelope_get_source_device_id': (c_int64, (ksc_envelope_p,)),
'envelope_get_timestamp': (c_int64, (ksc_envelope_p,)),
'data_get_body': (c_char_p, (ksc_data_p,)),
'data_get_group_id_base64': (c_char_p, (ksc_data_p,)),
'data_get_timestamp': (c_int64, (ksc_data_p,)),
'get_udata': (c_void_p, (ksc_p,)),
'start': (ksc_p, (c_char_p, # json_store_path
CFUNCTYPE(c_int, ksc_p, ksc_envelope_p), # on_receipt
CFUNCTYPE(c_int, ksc_p, ksc_envelope_p, ksc_data_p), # on_data
CFUNCTYPE(None, ksc_p), # on_open
CFUNCTYPE(None, c_void_p, c_void_p), # on_close
ksc_ffi_log_p,
c_char_p, # server_cert_path
c_int, # on_close_do_reconnect
c_void_p)),
'stop': (None, (ksc_p,)),
'send_message': (c_int, (ksc_p,
c_char_p, # recipient
c_char_p, # body
c_int, # end_session
CFUNCTYPE(None, c_int, c_char_p, c_void_p), # on_response
c_void_p)),
}.items():
k2 = 'ksc_ffi_' + k
(getattr(self._ksc, k2).restype,
getattr(self._ksc, k2).argtypes) = v
setattr(self, k, getattr(self._ksc, k2))
class log:
def __init__(self, fd, level, restricted_contexts = {}):
self.fd = fd
self.level = level
self.restricted_contexts = restricted_contexts
def __del__(self):
print('log __del__')
class ksc:
def __init__(self):
self._ffi = ksc_ffi()
# level is one of 'none', 'error', 'warn', 'info', 'note', 'debug'
def _log_create(self, fd, level):
return self._ffi.log_create(fd, level.encode())
def _log_destroy(self, log):
self._ffi.log_destroy(log)
def _log_restrict_context(self, log, desc, level):
return self._ffi.log_restrict_context(log, desc.encode(),
level.encode())
@staticmethod
def _zero(obj):
return 0 if obj is None else obj
def start(self, json_store_path, server_cert_path, log = None,
on_receipt = None, on_data = None, on_open = None,
on_close = None, on_close_do_reconnect = False, data = None):
if log is not None:
ffi_log = self._log_create(log.fd, log.level)
for desc, level in log.restricted_contexts.items():
self._log_restrict_context(ffi_log, desc, level)
else:
ffi_log = None
r = self._ffi.start(json_store_path.encode(),
self._ffi.start.argtypes[1](ksc._zero(on_receipt)),
self._ffi.start.argtypes[2](ksc._zero(on_data)),
self._ffi.start.argtypes[3](ksc._zero(on_open)),
self._ffi.start.argtypes[4](ksc._zero(on_close)),
ffi_log,
server_cert_path.encode(),
on_close_do_reconnect, data)
if ffi_log is not None:
self._log_destroy(ffi_log)
return r
def stop(self, k):
self._ffi.stop(k)
def send_message(self, k, recipient, body, end_session = False, on_response = None, data = None):
return self._ffi.send_message(k, recipient.encode(), body.encode(), end_session,
self._ffi.send_message.argtypes[4](ksc._zero(on_response)),
data)
"""
from ksc import ksc, log
k = ksc()
sock = k.start(LOCAL_PATH, 'share/whisper.store.asn1', log = log(2, 'debug'))
k.send_message(sock, NUMBER, 'hi from Python')
k.stop(sock)
"""