Skip to content

Commit 7f637cd

Browse files
author
Korbinian Kram
committed
release version 2.4
- introduces the access control and chat functionality - Python bindings are included in the offical supported package
1 parent e9f53f1 commit 7f637cd

File tree

89 files changed

+4313
-381
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+4313
-381
lines changed

Bindings/Python/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ set(SOURCE
3333
PyAccessControlModule.h
3434
PyAgentConnection.cpp
3535
PyAgentConnection.h
36+
PyChatModule.cpp
37+
PyChatModule.h
3638
PyInstantSupportModule.cpp
3739
PyInstantSupportModule.h
3840
PyLogging.cpp

Bindings/Python/PyAccessControlModule.cpp

Lines changed: 100 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,34 @@ namespace
4040

4141
// Methods
4242

43-
PyObject* PyAccessControlModule_setCallbacks(PyAccessControlModule* self, PyObject* arg)
43+
PyObject* PyAccessControlModule_setCallbacks(
44+
PyAccessControlModule* self,
45+
PyObject* args,
46+
PyObject* kwargs)
4447
{
4548
using Feature = tvagentapi::IAccessControlModule::Feature;
4649
using Access = tvagentapi::IAccessControlModule::Access;
4750

48-
if (!PyDict_Check(arg))
51+
char accessChangedArgName[] = "accessChangedCallback";
52+
char accessRequestArgName[] = "accessRequestCallback";
53+
54+
PyObject* accessChangedCallback = Py_None;
55+
PyObject* accessRequestCallback = Py_None;
56+
57+
char* kwargList[] = {accessChangedArgName, accessRequestArgName, {}};
58+
if (!PyArg_ParseTupleAndKeywords(
59+
args,
60+
kwargs,
61+
"|OO:setCallbacks",
62+
kwargList,
63+
&accessChangedCallback,
64+
&accessRequestCallback))
4965
{
50-
PyErr_Format(PyExc_TypeError, "expected dict instance, got %R", arg);
5166
return nullptr;
5267
}
5368

54-
const char* accessChangedCbkName = "accessChangedCallback";
55-
const char* accessRequestCbName = "accessRequestCallback";
56-
57-
PyObject* accessChangedCallback = PyDict_GetItemString(arg, accessChangedCbkName);
58-
PyObject* accessRequestCallback = PyDict_GetItemString(arg, accessRequestCbName);
69+
accessChangedCallback = accessChangedCallback == Py_None ? nullptr : accessChangedCallback;
70+
accessRequestCallback = accessRequestCallback == Py_None ? nullptr : accessRequestCallback;
5971

6072
if (accessChangedCallback && !PyCallable_Check(accessChangedCallback))
6173
{
@@ -214,48 +226,114 @@ PyObject* PyAccessControlModule_rejectAccessRequest(PyAccessControlModule* self,
214226
return NoneOrInternalError(self->m_module->rejectAccessRequest(feature));
215227
}
216228

229+
namespace DocStrings
230+
{
231+
232+
PyDoc_STRVAR(isSupported,
233+
R"__(isSupported($self)
234+
--
235+
236+
Returns whether the current module is supported by the SDK and the IoT Agent counterpart.
237+
238+
:return True if the current module is supported, False otherwise.
239+
)__");
240+
241+
PyDoc_STRVAR(setCallbacks,
242+
R"__(setCallbacks($self,
243+
accessChangedCallback=None,
244+
accessRequestCallback=None)
245+
--
246+
247+
Sets callbacks to handle Access changes and incoming access confirmation requests.
248+
249+
:param accessChangedCallback: called when an Access permission for a specific Feature has been changed
250+
:type accessChangedCallback: callback(tvagentapi.IAccessControlModule.Feature feature, tvagentapi.IAccessControlModule.Access access)
251+
:param accessRequestCallback: called when a remote party attempts to use a feature whose current Access permission is set to "After Confirmation"
252+
:type accessRequestCallback: callback(tvagentapi.IAccessControlModule.Feature feature)
253+
)__");
254+
255+
PyDoc_STRVAR(getAccess,
256+
R"__(getAccess($self, feature)
257+
--
258+
259+
Requests the current Access permission for the given Feature.
260+
261+
:param tvagentapi.IAccessControlModule.Feature feature: Feature for which the current access permission is being queried.
262+
:return Access permission enum value.
263+
)__");
264+
265+
PyDoc_STRVAR(setAccess,
266+
R"__(setAccess($self, feature, access)
267+
--
268+
269+
Sets the given Access permission for the given Feature.
270+
271+
:param tvagentapi.IAccessControlModule.Feature feature: Feature for which the current access permission is being set.
272+
:param tvagentapi.IAccessControlModule.Access access: Access permission being set for the feature.
273+
)__");
274+
275+
PyDoc_STRVAR(acceptAccessRequest,
276+
R"__(acceptAccessRequest($self, feature)
277+
--
278+
279+
Accepts an incoming access request for the given feature.
280+
281+
:param tvagentapi.IAccessControlModule.Feature feature: Feature for which request is accepted.
282+
)__");
283+
284+
PyDoc_STRVAR(rejectAccessRequest,
285+
R"__(rejectAccessRequest($self, feature)
286+
--
287+
288+
Rejects an incoming access request for the given feature.
289+
290+
:param tvagentapi.IAccessControlModule.Feature feature: Feature for which request is rejected.
291+
)__");
292+
293+
} // namespace DocStrings
294+
217295
PyMethodDef PyAccessControlModule_methods[] =
218296
{
297+
{
298+
"isSupported",
299+
WeakConnectionCall<PyAccessControlModule, PyAccessControlModule_isSupported>,
300+
METH_NOARGS,
301+
DocStrings::isSupported
302+
},
303+
219304
{
220305
"setCallbacks",
221-
WeakConnectionCall<PyAccessControlModule, PyAccessControlModule_setCallbacks>,
222-
METH_O,
223-
"set access control callbacks"
306+
PyCFunctionCast(WeakConnectionCall<PyAccessControlModule, PyAccessControlModule_setCallbacks>),
307+
METH_VARARGS | METH_KEYWORDS,
308+
DocStrings::setCallbacks
224309
},
225310

226311
{
227312
"getAccess",
228313
WeakConnectionCall<PyAccessControlModule, PyAccessControlModule_getAccess>,
229314
METH_O,
230-
"for given Feature fetch Access mode"
315+
DocStrings::getAccess
231316
},
232317

233318
{
234319
"setAccess",
235320
WeakConnectionCall<PyAccessControlModule, PyAccessControlModule_setAccess>,
236321
METH_VARARGS,
237-
"for given Feature set Access mode"
238-
},
239-
240-
{
241-
"isSupported",
242-
WeakConnectionCall<PyAccessControlModule, PyAccessControlModule_isSupported>,
243-
METH_NOARGS,
244-
"check if the module is supported"
322+
DocStrings::setAccess
245323
},
246324

247325
{
248326
"acceptAccessRequest",
249327
WeakConnectionCall<PyAccessControlModule, PyAccessControlModule_acceptAccessRequest>,
250328
METH_O,
251-
"for given Feature accept incoming access request"
329+
DocStrings::acceptAccessRequest
252330
},
253331

254332
{
255333
"rejectAccessRequest",
256334
WeakConnectionCall<PyAccessControlModule, PyAccessControlModule_rejectAccessRequest>,
257335
METH_O,
258-
"for given Feature reject incoming access request"
336+
DocStrings::rejectAccessRequest
259337
},
260338

261339
{} // Sentinel

Bindings/Python/PyAgentConnection.cpp

Lines changed: 93 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "PyAccessControlModule.h"
3131
#include "PyInstantSupportModule.h"
3232
#include "PyTVSessionManagementModule.h"
33+
#include "PyChatModule.h"
3334
#include "PyLogging.h"
3435
#include "PyTVAgentAPI.h"
3536
#include "PythonHelpers.h"
@@ -123,6 +124,9 @@ PyObject* PyAgentConnection_getModule(PyAgentConnection* self, PyObject* arg)
123124
case tvagentapi::IModule::Type::TVSessionManagement:
124125
return reinterpret_cast<PyObject*>(
125126
MakeWrapperObject<PyTVSessionManagementModule>(self));
127+
case tvagentapi::IModule::Type::Chat:
128+
return reinterpret_cast<PyObject*>(
129+
MakeWrapperObject<PyChatModule>(self));
126130
}
127131
PyErr_BadInternalCall();
128132
return nullptr;
@@ -133,26 +137,36 @@ PyObject* PyAgentConnection_getModule(PyAgentConnection* self, PyObject* arg)
133137
return pyModule;
134138
}
135139

136-
PyObject* PyAgentConnection_setStatusChangedCallback(PyAgentConnection* self, PyObject* args)
140+
PyObject* PyAgentConnection_setCallbacks(
141+
PyAgentConnection* self,
142+
PyObject* args,
143+
PyObject* kwargs)
137144
{
138-
PyObject* arg = Py_None;
139-
// parse optional argument (if not present, 'arg' won't be initialized)
140-
if (!PyArg_ParseTuple(args, "|O", &arg))
145+
PyObject* statusChangedArg = Py_None;
146+
147+
char statusChangedArgName[] = "statusChanged";
148+
char* kwargList[] = {statusChangedArgName, {}};
149+
if (!PyArg_ParseTupleAndKeywords(
150+
args,
151+
kwargs,
152+
"|O:setCallbacks",
153+
kwargList,
154+
&statusChangedArg))
141155
{
142156
return nullptr;
143157
}
144158

145-
PyObject* callable = arg == Py_None ? nullptr : arg;
159+
statusChangedArg = statusChangedArg == Py_None ? nullptr : statusChangedArg;
146160

147-
if (callable && !PyCallable_Check(callable))
161+
if (statusChangedArg && !PyCallable_Check(statusChangedArg))
148162
{
149-
PyErr_Format(PyExc_TypeError, "%R is not callable", callable);
163+
PyErr_Format(PyExc_TypeError, "%R is not callable", statusChangedArg);
150164
return nullptr;
151165
}
152166

153-
Py_XINCREF(callable);
167+
Py_XINCREF(statusChangedArg);
154168
Py_XDECREF(self->m_pyStatusChangedCallback);
155-
self->m_pyStatusChangedCallback = callable;
169+
self->m_pyStatusChangedCallback = statusChangedArg;
156170

157171
auto statusChangedCallback = [](
158172
tvagentapi::IAgentConnection::Status status,
@@ -172,9 +186,9 @@ PyObject* PyAgentConnection_setStatusChangedCallback(PyAgentConnection* self, Py
172186
Py_DECREF(enumVal);
173187
};
174188

175-
if (callable)
189+
if (statusChangedArg)
176190
{
177-
self->m_connection->setStatusChangedCallback({statusChangedCallback, callable});
191+
self->m_connection->setStatusChangedCallback({statusChangedCallback, statusChangedArg});
178192
}
179193
else
180194
{
@@ -184,37 +198,93 @@ PyObject* PyAgentConnection_setStatusChangedCallback(PyAgentConnection* self, Py
184198
Py_RETURN_NONE;
185199
}
186200

201+
namespace DocStrings
202+
{
203+
204+
PyDoc_STRVAR(start,
205+
R"__(start($self)
206+
--
207+
208+
Tries to establish a connection to a running TeamViewer IoT Agent and maintains it until stop() is called.
209+
The connection is re-established automatically if it was lost.
210+
To be notified about the connectivity, set the statusChanged callback.
211+
)__");
212+
213+
PyDoc_STRVAR(stop,
214+
R"__(stop($self)
215+
--
216+
217+
Shuts down all communication with the TeamViewer IoT Agent and changes state afterwards to Disconnected.
218+
)__");
219+
220+
PyDoc_STRVAR(processEvents,
221+
R"__(processEvents($self, waitForMoreEvents, timeoutMs)
222+
--
223+
224+
Is responsible for executing all actions/events/etc. (or simply: "events") that are pending in the order they are issued:
225+
- triggers user's callbacks
226+
- updates internal states
227+
- notifies modules
228+
- handles modules' requests
229+
The method can optionally wait for more events if no events are queued.
230+
231+
:param bool waitForMoreEvents: if true and no queued events, wait for events to be queued, otherwise process the queued events immediately.
232+
:param int timeoutMs: wait timeout in milliseconds. If zero, wait indefinitely.
233+
)__");
234+
235+
PyDoc_STRVAR(getModule,
236+
R"__(getModule($self, type)
237+
--
238+
239+
Returns an abstract module if possible for the given type.
240+
241+
:param tvagentapi.Module.Type type: what type of module to create.
242+
:return module object.
243+
)__");
244+
245+
PyDoc_STRVAR(setCallbacks,
246+
R"__(setCallbacks($self, statusChanged=None)
247+
--
248+
249+
Sets callback to handle changes in connection status.
250+
251+
:param statusChanged: called when the connection status changes
252+
:type statusChanged: callback(tvagentapi.AgentConnection.Status status)
253+
)__");
254+
255+
} // namespace DocStrings
256+
187257
PyMethodDef PyAgentConnection_methods[] =
188258
{
189259
{
190260
"start",
191-
reinterpret_cast<PyCFunction>(PyAgentConnection_start),
261+
PyCFunctionCast(PyAgentConnection_start),
192262
METH_NOARGS,
193-
"start connection"
263+
DocStrings::start
194264
},
195265
{
196266
"stop",
197-
reinterpret_cast<PyCFunction>(PyAgentConnection_stop),
267+
PyCFunctionCast(PyAgentConnection_stop),
198268
METH_NOARGS,
199-
"stop connection"
269+
DocStrings::stop
200270
},
201271
{
202272
"processEvents",
203-
reinterpret_cast<PyCFunction>(PyAgentConnection_processEvents),
273+
PyCFunctionCast(PyAgentConnection_processEvents),
204274
METH_VARARGS | METH_KEYWORDS,
205-
"process events"
275+
DocStrings::processEvents
206276
},
207277
{
208278
"getModule",
209-
reinterpret_cast<PyCFunction>(PyAgentConnection_getModule),
279+
PyCFunctionCast(PyAgentConnection_getModule),
210280
METH_O,
211-
"get module for type"
281+
DocStrings::getModule
212282
},
213283
{
214-
"setStatusChangedCallback",
215-
reinterpret_cast<PyCFunction>(PyAgentConnection_setStatusChangedCallback),
216-
METH_VARARGS,
217-
"set status changed callback"
284+
"setCallbacks",
285+
PyCFunctionCast(PyAgentConnection_setCallbacks),
286+
METH_VARARGS | METH_KEYWORDS,
287+
DocStrings::setCallbacks
218288
},
219289

220290
{} // Sentinel

0 commit comments

Comments
 (0)