|
1 | 1 | import base64 |
2 | 2 | import calendar |
3 | 3 | import datetime |
| 4 | +import decimal |
4 | 5 | import gzip |
| 6 | +import hashlib |
5 | 7 | import json |
6 | 8 | import logging |
| 9 | +import random |
| 10 | +import re |
7 | 11 | import time |
8 | 12 | import uuid |
9 | 13 | from types import ModuleType |
| 14 | +from urllib.parse import unquote |
10 | 15 |
|
11 | 16 | import jsonschema |
| 17 | +import pytz |
12 | 18 |
|
13 | 19 |
|
14 | 20 | # This encoder/decoder replicates the type conversion behavior of |
@@ -259,16 +265,32 @@ class CustomParser(SpiffBpmnParser): |
259 | 265 | del SPIFF_CONFIG[SendTask] |
260 | 266 | del SPIFF_CONFIG[StartEvent] |
261 | 267 |
|
| 268 | +def _markdown_file_download_link(file_reference): |
| 269 | + # Arena passes "data:<mimetype>;name=<name>;base64,spifffiledatadigest+<sha256>"; |
| 270 | + # Ed's forms keep the file contents inline instead of a digest. |
| 271 | + metadata, payload = file_reference.rsplit(";base64,", 1) |
| 272 | + match = re.fullmatch(r"spifffiledatadigest\+([0-9a-f]{64})", payload) |
| 273 | + digest = match.group(1) if match else hashlib.sha256(base64.b64decode(payload)).hexdigest() |
| 274 | + filename = unquote(metadata.split(";name=", 1)[1]) if ";name=" in metadata else digest |
| 275 | + label = re.sub(r"([\\\\`*\[\]_<>&])", r"\\\1", filename) |
| 276 | + return f"[{label}](http://local.spiff/process-data-file-download/local/0/{digest})" |
| 277 | + |
| 278 | + |
262 | 279 | class CustomEnvironment(TaskDataEnvironment): |
263 | 280 | def __init__(self): |
264 | 281 | # TODO: would be nice to get these from the client so we don't have to code change for globals |
265 | 282 | super().__init__(environment_globals={ |
266 | 283 | "calendar": calendar, |
267 | 284 | "datetime": datetime.datetime, |
| 285 | + "decimal": decimal, |
268 | 286 | "json": json, |
269 | 287 | "jsonschema": jsonschema, |
| 288 | + "pytz": pytz, |
| 289 | + "random": random, |
| 290 | + "re": re, |
270 | 291 | "time": time, |
271 | 292 | "timedelta": datetime.timedelta, |
| 293 | + "uuid": uuid, |
272 | 294 | }) |
273 | 295 |
|
274 | 296 | def _build_external_context(self, context, external_context=None): |
@@ -301,6 +323,8 @@ def _build_external_context(self, context, external_context=None): |
301 | 323 | external_context["get_process_initiator_user"] = lambda: { |
302 | 324 | key: value for key, value in process_initiator_user.items() |
303 | 325 | } |
| 326 | + external_context["markdown_file_download_link"] = _markdown_file_download_link |
| 327 | + external_context["get_markdown_file_download_link"] = _markdown_file_download_link |
304 | 328 | external_context["get_group_members"] = lambda group_name: [ |
305 | 329 | "group_member_1@example.com", |
306 | 330 | "group_member_2@example.com", |
|
0 commit comments