forked from platypush/platypush
[#366] Context variables should be dynamically assigned through locals()
instead of exec()
.
Closes: #366
This commit is contained in:
parent
6c2e9deda4
commit
f8e0b5e17e
3 changed files with 7 additions and 65 deletions
|
@ -1,7 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
import re
|
|
||||||
from threading import Thread
|
|
||||||
import time
|
import time
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from frozendict import frozendict
|
from frozendict import frozendict
|
||||||
|
@ -91,7 +90,7 @@ class HttpRequest:
|
||||||
|
|
||||||
Thread(target=_thread_func, name='HttpPoll').start()
|
Thread(target=_thread_func, name='HttpPoll').start()
|
||||||
|
|
||||||
def get_new_items(self, response):
|
def get_new_items(self, *_, **__):
|
||||||
"""Gets new items out of a response"""
|
"""Gets new items out of a response"""
|
||||||
raise NotImplementedError(
|
raise NotImplementedError(
|
||||||
"get_new_items must be implemented in a derived class"
|
"get_new_items must be implemented in a derived class"
|
||||||
|
@ -105,34 +104,6 @@ class HttpRequest:
|
||||||
yield key, value
|
yield key, value
|
||||||
|
|
||||||
|
|
||||||
class JsonHttpRequest(HttpRequest):
|
|
||||||
"""
|
|
||||||
Specialization of the HttpRequest class for JSON requests.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, *args, path=None, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.path = path
|
|
||||||
self.seen_entries = set()
|
|
||||||
|
|
||||||
def get_new_items(self, response):
|
|
||||||
response = response.json()
|
|
||||||
new_entries = []
|
|
||||||
|
|
||||||
if self.path:
|
|
||||||
m = re.match(r'\${\s*(.*)\s*}', self.path)
|
|
||||||
if m:
|
|
||||||
response = eval(m.group(1)) # pylint: disable=eval-used
|
|
||||||
|
|
||||||
for entry in response:
|
|
||||||
flattened_entry = deep_freeze(entry)
|
|
||||||
if flattened_entry not in self.seen_entries:
|
|
||||||
new_entries.append(entry)
|
|
||||||
self.seen_entries.add(flattened_entry)
|
|
||||||
|
|
||||||
return new_entries
|
|
||||||
|
|
||||||
|
|
||||||
def deep_freeze(x):
|
def deep_freeze(x):
|
||||||
"""
|
"""
|
||||||
Deep freezes a Python object - works for strings, dictionaries, sets and
|
Deep freezes a Python object - works for strings, dictionaries, sets and
|
||||||
|
|
|
@ -141,19 +141,8 @@ class Request(Message):
|
||||||
for k, v in context.items():
|
for k, v in context.items():
|
||||||
if isinstance(v, Message):
|
if isinstance(v, Message):
|
||||||
v = json.loads(str(v))
|
v = json.loads(str(v))
|
||||||
try:
|
|
||||||
exec('{}={}'.format(k, v)) # pylint: disable=exec-used
|
locals()[k] = v
|
||||||
except Exception:
|
|
||||||
if isinstance(v, str):
|
|
||||||
try:
|
|
||||||
exec( # pylint: disable=exec-used
|
|
||||||
'{}="{}"'.format(k, re.sub(r'(^|[^\\])"', '\1\\"', v))
|
|
||||||
)
|
|
||||||
except Exception as e2:
|
|
||||||
logger.debug(
|
|
||||||
'Could not set context variable %s=%s: %s', k, v, e2
|
|
||||||
)
|
|
||||||
logger.debug('Context: %s', context)
|
|
||||||
|
|
||||||
parsed_value = ''
|
parsed_value = ''
|
||||||
if not isinstance(_value, str):
|
if not isinstance(_value, str):
|
||||||
|
|
|
@ -422,10 +422,7 @@ class WhileProcedure(LoopProcedure):
|
||||||
response = Response()
|
response = Response()
|
||||||
context = self._get_context(**context)
|
context = self._get_context(**context)
|
||||||
for k, v in context.items():
|
for k, v in context.items():
|
||||||
try:
|
locals()[k] = v
|
||||||
exec(f'{k}={v}') # pylint: disable=exec-used
|
|
||||||
except Exception as e:
|
|
||||||
logger.debug('Evaluation error: %s=%s: %s', k, v, e)
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
condition_true = eval(self.condition) # pylint: disable=eval-used
|
condition_true = eval(self.condition) # pylint: disable=eval-used
|
||||||
|
@ -451,10 +448,7 @@ class WhileProcedure(LoopProcedure):
|
||||||
if response.output and isinstance(response.output, dict):
|
if response.output and isinstance(response.output, dict):
|
||||||
new_context = self._get_context(**response.output)
|
new_context = self._get_context(**response.output)
|
||||||
for k, v in new_context.items():
|
for k, v in new_context.items():
|
||||||
try:
|
locals()[k] = v
|
||||||
exec(f'{k}={v}') # pylint: disable=exec-used
|
|
||||||
except Exception as e:
|
|
||||||
logger.debug('Evaluation error: %s=%s: %s', k, v, e)
|
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@ -550,19 +544,7 @@ class IfProcedure(Procedure):
|
||||||
|
|
||||||
def execute(self, *_, **context):
|
def execute(self, *_, **context):
|
||||||
for k, v in context.items():
|
for k, v in context.items():
|
||||||
try:
|
locals()[k] = v
|
||||||
exec(f'{k}={v}') # pylint: disable=exec-used
|
|
||||||
except Exception:
|
|
||||||
if isinstance(v, str):
|
|
||||||
try:
|
|
||||||
exec( # pylint: disable=exec-used
|
|
||||||
f'{k}="' + re.sub(r'(^|[^\\])"', '\1\\"', v) + '"'
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
logger.debug(
|
|
||||||
'Could not set context variable %s=%s: %s', k, v, e
|
|
||||||
)
|
|
||||||
logger.debug('Context: %s', context)
|
|
||||||
|
|
||||||
condition_true = eval(self.condition) # pylint: disable=eval-used
|
condition_true = eval(self.condition) # pylint: disable=eval-used
|
||||||
response = Response()
|
response = Response()
|
||||||
|
|
Loading…
Reference in a new issue