From e8b82c47ca1ce73f55f22078caf724e7bce21c3a Mon Sep 17 00:00:00 2001 From: Christopher Charbonneau Wells <10456740+cdubz@users.noreply.github.com> Date: Mon, 28 Oct 2024 07:46:05 -0700 Subject: [PATCH] #2502 - Add jinja2 template handling to request body and headers (#2740) --- .gitignore | 1 + changedetectionio/forms.py | 35 ++++++++++++++++++++++-- changedetectionio/processors/__init__.py | 7 +++++ changedetectionio/templates/edit.html | 17 +++++++----- changedetectionio/tests/test_request.py | 11 +++++--- 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 39fc0dd0..99839fec 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,6 @@ dist venv test-datastore/* test-datastore +test-memory.log *.egg-info* .vscode/settings.json diff --git a/changedetectionio/forms.py b/changedetectionio/forms.py index f99496e5..81869988 100644 --- a/changedetectionio/forms.py +++ b/changedetectionio/forms.py @@ -515,6 +515,7 @@ class processor_text_json_diff_form(commonSettingsForm): if not super().validate(): return False + from changedetectionio.safe_jinja import render as jinja_render result = True # Fail form validation when a body is set for a GET @@ -524,18 +525,46 @@ class processor_text_json_diff_form(commonSettingsForm): # Attempt to validate jinja2 templates in the URL try: - from changedetectionio.safe_jinja import render as jinja_render jinja_render(template_str=self.url.data) except ModuleNotFoundError as e: # incase jinja2_time or others is missing logger.error(e) - self.url.errors.append(e) + self.url.errors.append(f'Invalid template syntax configuration: {e}') result = False except Exception as e: logger.error(e) - self.url.errors.append('Invalid template syntax') + self.url.errors.append(f'Invalid template syntax: {e}') result = False + # Attempt to validate jinja2 templates in the body + if self.body.data and self.body.data.strip(): + try: + jinja_render(template_str=self.body.data) + except ModuleNotFoundError as e: + # incase jinja2_time or others is missing + logger.error(e) + self.body.errors.append(f'Invalid template syntax configuration: {e}') + result = False + except Exception as e: + logger.error(e) + self.body.errors.append(f'Invalid template syntax: {e}') + result = False + + # Attempt to validate jinja2 templates in the headers + if len(self.headers.data) > 0: + try: + for header, value in self.headers.data.items(): + jinja_render(template_str=value) + except ModuleNotFoundError as e: + # incase jinja2_time or others is missing + logger.error(e) + self.headers.errors.append(f'Invalid template syntax configuration: {e}') + result = False + except Exception as e: + logger.error(e) + self.headers.errors.append(f'Invalid template syntax in "{header}" header: {e}') + result = False + return result class SingleExtraProxy(Form): diff --git a/changedetectionio/processors/__init__.py b/changedetectionio/processors/__init__.py index e0682a25..7586d4c7 100644 --- a/changedetectionio/processors/__init__.py +++ b/changedetectionio/processors/__init__.py @@ -102,6 +102,7 @@ class difference_detection_processor(): self.fetcher.browser_steps_screenshot_path = os.path.join(self.datastore.datastore_path, self.watch.get('uuid')) # Tweak the base config with the per-watch ones + from changedetectionio.safe_jinja import render as jinja_render request_headers = CaseInsensitiveDict() ua = self.datastore.data['settings']['requests'].get('default_ua') @@ -118,9 +119,15 @@ class difference_detection_processor(): if 'Accept-Encoding' in request_headers and "br" in request_headers['Accept-Encoding']: request_headers['Accept-Encoding'] = request_headers['Accept-Encoding'].replace(', br', '') + for header_name in request_headers: + request_headers.update({header_name: jinja_render(template_str=request_headers.get(header_name))}) + timeout = self.datastore.data['settings']['requests'].get('timeout') request_body = self.watch.get('body') + if request_body: + request_body = jinja_render(template_str=self.watch.get('body')) + request_method = self.watch.get('method') ignore_status_codes = self.watch.get('ignore_status_codes', False) diff --git a/changedetectionio/templates/edit.html b/changedetectionio/templates/edit.html index 5847962f..a0a8f988 100644 --- a/changedetectionio/templates/edit.html +++ b/changedetectionio/templates/edit.html @@ -65,8 +65,8 @@
{{ render_field(form.url, placeholder="https://...", required=true, class="m-d") }} - Some sites use JavaScript to create the content, for this you should use the Chrome/WebDriver Fetcher
- You can use variables in the URL, perfect for inserting the current date and other logic, help and examples here
+
Some sites use JavaScript to create the content, for this you should use the Chrome/WebDriver Fetcher
+
Variables are supported in the URL (help and examples here).
{{ render_field(form.processor) }} @@ -149,21 +149,24 @@ {{ render_field(form.method) }}
- {{ render_field(form.body, rows=5, placeholder="Example + {{ render_field(form.body, rows=7, placeholder="Example { \"name\":\"John\", \"age\":30, - \"car\":null + \"car\":null, + \"year\":{% now 'Europe/Berlin', '%Y' %} }") }}
+
Variables are supported in the request body (help and examples here).