tina4-python 0.2.122__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. tina4_python/Auth.py +222 -0
  2. tina4_python/Constant.py +43 -0
  3. tina4_python/Database.py +591 -0
  4. tina4_python/DatabaseResult.py +107 -0
  5. tina4_python/DatabaseTypes.py +15 -0
  6. tina4_python/Debug.py +126 -0
  7. tina4_python/Env.py +37 -0
  8. tina4_python/Localization.py +42 -0
  9. tina4_python/Messages.py +30 -0
  10. tina4_python/MiddleWare.py +90 -0
  11. tina4_python/Migration.py +107 -0
  12. tina4_python/ORM.py +639 -0
  13. tina4_python/Queue.py +615 -0
  14. tina4_python/Request.py +19 -0
  15. tina4_python/Response.py +121 -0
  16. tina4_python/Router.py +423 -0
  17. tina4_python/Session.py +342 -0
  18. tina4_python/ShellColors.py +20 -0
  19. tina4_python/Swagger.py +228 -0
  20. tina4_python/Template.py +107 -0
  21. tina4_python/Webserver.py +429 -0
  22. tina4_python/Websocket.py +49 -0
  23. tina4_python/__init__.py +392 -0
  24. tina4_python/messages.pot +83 -0
  25. tina4_python/public/css/readme.md +0 -0
  26. tina4_python/public/favicon.ico +0 -0
  27. tina4_python/public/images/403.png +0 -0
  28. tina4_python/public/images/404.png +0 -0
  29. tina4_python/public/images/500.png +0 -0
  30. tina4_python/public/images/logo.png +0 -0
  31. tina4_python/public/images/readme.md +0 -0
  32. tina4_python/public/js/readme.md +0 -0
  33. tina4_python/public/js/reconnecting-websocket.js +365 -0
  34. tina4_python/public/js/tina4helper.js +397 -0
  35. tina4_python/public/swagger/index.html +90 -0
  36. tina4_python/public/swagger/oauth2-redirect.html +63 -0
  37. tina4_python/templates/errors/403.twig +10 -0
  38. tina4_python/templates/errors/404.twig +10 -0
  39. tina4_python/templates/errors/500.twig +11 -0
  40. tina4_python/templates/readme.md +1 -0
  41. tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
  42. tina4_python/translations/en/LC_MESSAGES/messages.po +80 -0
  43. tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
  44. tina4_python/translations/fr/LC_MESSAGES/messages.po +84 -0
  45. tina4_python-0.2.122.dist-info/METADATA +465 -0
  46. tina4_python-0.2.122.dist-info/RECORD +47 -0
  47. tina4_python-0.2.122.dist-info/WHEEL +4 -0
@@ -0,0 +1,342 @@
1
+ #
2
+ # Tina4 - This is not a 4ramework.
3
+ # Copy-right 2007 - current Tina4
4
+ # License: MIT https://opensource.org/licenses/MIT
5
+ #
6
+ # flake8: noqa: E501
7
+ import os
8
+ from http import cookies
9
+ import sys
10
+ import importlib
11
+ import hashlib
12
+ import tina4_python
13
+ from tina4_python.Debug import Debug
14
+ from tina4_python import Constant
15
+
16
+ class SessionHandler(object):
17
+ """
18
+ Base class for session handling.
19
+ """
20
+
21
+ @staticmethod
22
+ def load(session, _hash):
23
+ pass
24
+
25
+ @staticmethod
26
+ def set(session, _key, _value):
27
+ try:
28
+ session.session_values[_key] = _value
29
+ session.save()
30
+ return True
31
+ except Exception:
32
+ return False
33
+
34
+ @staticmethod
35
+ def unset(session, _key):
36
+ if _key in session.session_values:
37
+ del session.session_values[_key]
38
+ session.save()
39
+ return True
40
+ else:
41
+ return False
42
+
43
+ @staticmethod
44
+ def get(session, _key):
45
+ if _key in session.session_values:
46
+ return session.session_values[_key]
47
+ else:
48
+ return None
49
+
50
+ @staticmethod
51
+ def close(session):
52
+ pass
53
+
54
+ @staticmethod
55
+ def save(session):
56
+ pass
57
+
58
+ class SessionFileHandler(SessionHandler):
59
+ """
60
+ Session File Handler
61
+ """
62
+ @staticmethod
63
+ def load(session, _hash):
64
+ session.session_hash = _hash
65
+ if os.path.isfile(session.session_path + os.sep + _hash):
66
+ with open(session.session_path + os.sep + _hash, "r") as file:
67
+ token = file.read()
68
+ file.close()
69
+ if tina4_python.tina4_auth.valid(token):
70
+ payload = tina4_python.tina4_auth.get_payload(token)
71
+ for key in payload:
72
+ if key != "expires":
73
+ session.set(key, payload[key])
74
+ else:
75
+ Debug("Session expired, starting a new one", Constant.TINA4_LOG_DEBUG)
76
+ session.start(_hash)
77
+ else:
78
+ Debug("Cannot load session, starting a new one", Constant.TINA4_LOG_DEBUG)
79
+ session.start(_hash)
80
+
81
+ @staticmethod
82
+ def close(session):
83
+ try:
84
+ if os.path.isfile(session.session_path + os.sep + session.session_hash):
85
+ os.remove(session.session_path + os.sep + session.session_hash)
86
+ return True
87
+ except Exception:
88
+ return False
89
+
90
+ @staticmethod
91
+ def save(session):
92
+ try:
93
+ if not os.path.exists(session.session_path):
94
+ os.makedirs(session.session_path)
95
+ token = tina4_python.tina4_auth.get_token(payload_data=session.session_values)
96
+ with open(session.session_path + os.sep + session.session_hash, "w") as file:
97
+ file.write(token)
98
+ file.close()
99
+ return True
100
+ except Exception as E:
101
+ Debug("Session save failure", E, Constant.TINA4_LOG_ERROR)
102
+ return False
103
+
104
+ class SessionRedisHandler(SessionHandler):
105
+
106
+ @staticmethod
107
+ def __init_redis():
108
+ try:
109
+ redis = importlib.import_module("redis")
110
+ except Exception as e:
111
+ Debug("Redis not installed, install with pip install redis or poetry add redis", str(e), Constant.TINA4_LOG_ERROR)
112
+ sys.exit(1)
113
+
114
+ if os.getenv("TINA4_SESSION_REDIS_SECRET", "") != "":
115
+ redis_instance = redis.Redis(host=os.getenv("TINA4_SESSION_REDIS_HOST", "localhost"),
116
+ port=os.getenv("TINA4_SESSION_REDIS_PORT",6379),
117
+ password=os.getenv("TINA4_SESSION_REDIS_SECRET", ""),
118
+ decode_responses=True)
119
+ else:
120
+ redis_instance = redis.Redis(host=os.getenv("TINA4_SESSION_REDIS_HOST", "localhost"),
121
+ port=os.getenv("TINA4_SESSION_REDIS_PORT",6379),
122
+ decode_responses=True)
123
+ return redis_instance
124
+
125
+ """
126
+ Session Redis Handler
127
+ """
128
+ @staticmethod
129
+ def load(session, _hash):
130
+ """
131
+ Loads the redis session
132
+ :param session:
133
+ :param _hash:
134
+ :return:
135
+ """
136
+ try:
137
+ session.session_hash = _hash
138
+ r = SessionRedisHandler.__init_redis()
139
+ token = r.get(_hash)
140
+ if tina4_python.tina4_auth.valid(token):
141
+ payload = tina4_python.tina4_auth.get_payload(token)
142
+ for key in payload:
143
+ if key != "expires":
144
+ session.set(key, payload[key])
145
+ else:
146
+ Debug("Session expired, starting a new one", Constant.TINA4_LOG_WARNING)
147
+ _hash = None
148
+ session.start(_hash)
149
+ except Exception:
150
+ Debug("Redis not available, sessions will fail", Constant.TINA4_LOG_ERROR)
151
+
152
+
153
+ @staticmethod
154
+ def close(session):
155
+ """
156
+ Closes the redis session
157
+ :param session:
158
+ :return:
159
+ """
160
+ r = SessionRedisHandler.__init_redis()
161
+ try:
162
+ r.set(session.session_hash, "")
163
+ return True
164
+ except Exception:
165
+ return False
166
+
167
+ @staticmethod
168
+ def save(session):
169
+ """
170
+ Saves the redis session
171
+ :param session:
172
+ :return:
173
+ """
174
+ r = SessionRedisHandler.__init_redis()
175
+ try:
176
+ token = tina4_python.tina4_auth.get_token(payload_data=session.session_values)
177
+ r.set(session.session_hash, token)
178
+ return True
179
+ except Exception as e:
180
+ Debug("Session save failure", str(e), Constant.TINA4_LOG_ERROR)
181
+ return False
182
+
183
+ class SessionValkeyHandler(SessionHandler):
184
+
185
+ @staticmethod
186
+ def __init_valkey():
187
+ try:
188
+ valkey = importlib.import_module("valkey")
189
+ except Exception as e:
190
+ Debug("Valkey not installed, install with pip/uv", str(e), Constant.TINA4_LOG_ERROR)
191
+ sys.exit(1)
192
+
193
+ params = {
194
+ "host": os.getenv("TINA4_SESSION_VALKEY_HOST", "localhost"),
195
+ "port": int(os.getenv("TINA4_SESSION_VALKEY_PORT", 6379)),
196
+ "decode_responses": True
197
+ }
198
+ if os.getenv("TINA4_SESSION_VALKEY_SECRET", ""):
199
+ params["password"] = os.getenv("TINA4_SESSION_VALKEY_SECRET", "")
200
+ params["username"] = os.getenv("TINA4_SESSION_VALKEY_USER", "default")
201
+
202
+ if os.getenv("TINA4_SESSION_VALKEY_SSL", "False").upper() == "TRUE":
203
+ params["ssl"] = True
204
+
205
+ valkey_instance = valkey.Valkey(**params)
206
+
207
+ return valkey_instance
208
+
209
+ """
210
+ Session Valkey Handler
211
+ """
212
+ @staticmethod
213
+ def load(session, _hash):
214
+ """
215
+ Loads the Valkey session
216
+ :param session:
217
+ :param _hash:
218
+ :return:
219
+ """
220
+ try:
221
+ session.session_hash = _hash
222
+ r = SessionValkeyHandler.__init_valkey()
223
+ token = r.get(_hash)
224
+ if tina4_python.tina4_auth.valid(token):
225
+ payload = tina4_python.tina4_auth.get_payload(token)
226
+ for key in payload:
227
+ if key != "expires":
228
+ session.set(key, payload[key])
229
+ else:
230
+ Debug("Session expired, starting a new one", Constant.TINA4_LOG_DEBUG)
231
+ session.start(_hash)
232
+ except Exception:
233
+ Debug("Valkey not available, sessions will fail", Constant.TINA4_LOG_ERROR)
234
+
235
+
236
+ @staticmethod
237
+ def close(session):
238
+ """
239
+ Closes the Valkey session
240
+ :param session:
241
+ :return:
242
+ """
243
+ r = SessionValkeyHandler.__init_valkey()
244
+ try:
245
+ r.set(session.session_hash, "")
246
+ return True
247
+ except Exception:
248
+ return False
249
+
250
+ @staticmethod
251
+ def save(session):
252
+ """
253
+ Saves the Valkey session
254
+ :param session:
255
+ :return:
256
+ """
257
+ r = SessionValkeyHandler.__init_valkey()
258
+ try:
259
+ token = tina4_python.tina4_auth.get_token(payload_data=session.session_values)
260
+ r.set(session.session_hash, token)
261
+ return True
262
+ except Exception as e:
263
+ Debug("Session save failure", str(e), Constant.TINA4_LOG_ERROR)
264
+ return False
265
+
266
+ class Session:
267
+
268
+ def __init__(self, _default_name="PY_SESS", _default_path="sessions", _default_handler="SessionFileHandler"):
269
+ self.session_name = _default_name
270
+ self.cookie = cookies.SimpleCookie()
271
+ self.session_path = _default_path
272
+ self.session_values = {}
273
+ self.session_hash = ""
274
+ self.default_handler = _default_handler
275
+ exec("self.default_handler = "+_default_handler)
276
+
277
+ def start(self, _hash=None):
278
+ # create a file for the session?
279
+ # set the cookie for the session
280
+ token = tina4_python.tina4_auth.get_token(payload_data=self.session_values)
281
+ if _hash is None:
282
+ file_hash = hashlib.md5(token.encode()).hexdigest()
283
+ else:
284
+ file_hash = _hash
285
+ self.session_hash = file_hash
286
+ self.save()
287
+
288
+ return file_hash
289
+
290
+ def load(self, _hash):
291
+ """
292
+ Loads a session based on the hash
293
+ :param _hash:
294
+ :return:
295
+ """
296
+ self.default_handler.load(self, _hash)
297
+
298
+ def set(self, _key, _value):
299
+ """
300
+ Sets a session key value
301
+ :param _key:
302
+ :param _value:
303
+ :return:
304
+ """
305
+ return self.default_handler.set(self, _key, _value)
306
+
307
+
308
+ def unset(self, _key):
309
+ """
310
+ Unsets the session key
311
+ :param _key:
312
+ :return:
313
+ """
314
+ return self.default_handler.unset(self, _key)
315
+
316
+ def get(self, _key):
317
+ """
318
+ Returns false if session cannot be retrieved
319
+ :param _key:
320
+ :return:
321
+ """
322
+ return self.default_handler.get(self, _key)
323
+
324
+ def close(self):
325
+ """
326
+ Close the session and remove the file or record
327
+ :return:
328
+ """
329
+ return self.default_handler.close(self)
330
+
331
+ def save(self):
332
+ """
333
+ Saves the session information
334
+ :return:
335
+ """
336
+ return self.default_handler.save(self)
337
+
338
+ def __iter__(self):
339
+ for key, value in self.session_values.items():
340
+ if key != "expires":
341
+ yield key, value
342
+
@@ -0,0 +1,20 @@
1
+ class ShellColors:
2
+ end = '\033[0m'
3
+ bold = '\033[1m'
4
+ under_line = '\033[4m'
5
+ black = "\033[0;30m"
6
+ red = "\033[0;31m"
7
+ green = "\033[0;32m"
8
+ yellow = "\033[0;33m"
9
+ blue = "\033[0;34m"
10
+ magenta = "\033[0;35m"
11
+ cyan = "\033[0;36m"
12
+ white = "\033[0;37m"
13
+ bright_black = "\033[0;90m"
14
+ bright_red = "\033[0;91m"
15
+ bright_green = "\033[0;92m"
16
+ bright_yellow = "\033[0;93m"
17
+ bright_blue = "\033[0;94m"
18
+ bright_magenta = "\033[0;95m"
19
+ bright_cyan = "\033[0;96m"
20
+ bright_white = "\033[0;97m"
@@ -0,0 +1,228 @@
1
+ #
2
+ # Tina4 - This is not a 4ramework.
3
+ # Copy-right 2007 - current Tina4
4
+ # License: MIT https://opensource.org/licenses/MIT
5
+ #
6
+ # flake8: noqa: E501
7
+ import os
8
+ import re
9
+ import tina4_python
10
+ from tina4_python import Constant, Debug
11
+
12
+
13
+ class Swagger:
14
+ @staticmethod
15
+ def set_swagger_value(callback, key_name, value):
16
+ if callback not in tina4_python.tina4_routes:
17
+ tina4_python.tina4_routes[callback] = {}
18
+ if "swagger" not in tina4_python.tina4_routes[callback]:
19
+ tina4_python.tina4_routes[callback]["swagger"] = {}
20
+ tina4_python.tina4_routes[callback]["swagger"][key_name] = value
21
+
22
+ @staticmethod
23
+ def add_descripton(description, callback):
24
+ Swagger.set_swagger_value(callback, "description", description)
25
+
26
+ @staticmethod
27
+ def add_summary(summary, callback):
28
+ Swagger.set_swagger_value(callback, "summary", summary)
29
+
30
+ @staticmethod
31
+ def add_secure(callback):
32
+ Swagger.set_swagger_value(callback, "secure", True)
33
+
34
+ @staticmethod
35
+ def add_tags(tags, callback):
36
+ Swagger.set_swagger_value(callback, "tags", tags)
37
+
38
+ @staticmethod
39
+ def add_example(example, callback):
40
+ Swagger.set_swagger_value(callback, "example", example)
41
+
42
+ @staticmethod
43
+ def add_params(params, callback):
44
+ Swagger.set_swagger_value(callback, "params", params)
45
+
46
+ @staticmethod
47
+ def get_path_inputs(route_path):
48
+ url_segments = route_path.strip('/').split('/')
49
+ route_segments = route_path.strip('/').split('/')
50
+ try:
51
+ variables = {}
52
+ for i, segment in enumerate(route_segments):
53
+ if '{' in segment and '}' in segment: # parameter part
54
+ param_name = re.search(r'{(.*?)}', segment).group(1)
55
+ variables[param_name] = url_segments[i]
56
+
57
+ params = []
58
+ for variable in variables:
59
+ params.append({"name": variable, "in": "path", "type": "string"})
60
+ except Exception as e:
61
+ Debug.error("Failed to parse path inputs", str(e))
62
+ return []
63
+
64
+ return params
65
+
66
+ @staticmethod
67
+ def get_swagger_entry(url, method, tags, summary, description, produces, security, params=None, example=None,
68
+ responses=None):
69
+
70
+ if params is None:
71
+ params = []
72
+
73
+ schema = {}
74
+ if example is not None:
75
+ schema = {"type": "object", "example": example}
76
+
77
+ secure_annotation = [],
78
+ if security:
79
+ secure_annotation = [{"bearerAuth": []}]
80
+
81
+ new_params = []
82
+ for param in params:
83
+ param_value = param.split("=")
84
+ if len(param_value) < 2:
85
+ param_value.append("")
86
+ new_params.append({"name": param_value[0], "in": "query", "type": "string", "default": param_value[1]})
87
+
88
+ params = [*new_params, *Swagger.get_path_inputs(url)]
89
+
90
+ entry = {
91
+ "tags": tags,
92
+ "summary": summary,
93
+ "description": description,
94
+ "produces": produces,
95
+ "parameters": params,
96
+ "requestBody": {
97
+ "description": "Example Object",
98
+ "required": True,
99
+ "content": {
100
+ "application/json": {
101
+ "schema": schema
102
+ }
103
+ }
104
+ },
105
+ "security": secure_annotation,
106
+ "responses": responses
107
+ }
108
+
109
+ if method == Constant.TINA4_GET or example is None:
110
+ del entry["requestBody"]
111
+
112
+ return entry
113
+
114
+ @staticmethod
115
+ def parse_swagger(swagger):
116
+ if "tags" not in swagger:
117
+ swagger["tags"] = []
118
+ if "params" not in swagger:
119
+ swagger["params"] = []
120
+ if "description" not in swagger:
121
+ swagger["description"] = ""
122
+ if "summary" not in swagger:
123
+ swagger["summary"] = ""
124
+ if "example" not in swagger:
125
+ swagger["example"] = None
126
+ if "secure" not in swagger:
127
+ swagger["secure"] = None
128
+
129
+ if isinstance(swagger["tags"], str):
130
+ swagger["tags"] = [swagger["tags"]]
131
+
132
+ return swagger
133
+
134
+ @staticmethod
135
+ def get_json(request):
136
+ paths = {}
137
+ for route in tina4_python.tina4_routes.values():
138
+
139
+ if "swagger" in route:
140
+ if route["swagger"] is not None:
141
+ swagger = Swagger.parse_swagger(route["swagger"])
142
+ responses = {
143
+ "200": {"description": "Success"},
144
+ "400": {"description": "Failed"}
145
+ }
146
+
147
+ if route["route"] not in paths:
148
+ paths[route["route"]] = {}
149
+ paths[route["route"]][route["method"].lower()] = Swagger.get_swagger_entry(route["route"],
150
+ route["method"].lower(),
151
+ swagger["tags"],
152
+ swagger["summary"],
153
+ swagger["description"],
154
+ ["application/json",
155
+ "html/text"],
156
+ swagger["secure"],
157
+ swagger["params"],
158
+ swagger["example"],
159
+ responses)
160
+
161
+ if "host" in request.headers:
162
+ host_name = request.headers["host"]
163
+ else:
164
+ host_name = os.getenv("HOST_NAME", "localhost")
165
+
166
+ json_object = {
167
+ "openapi": "3.0.0",
168
+ "host": host_name,
169
+ "info": {
170
+ "title": os.getenv("SWAGGER_TITLE", "Tina4 Project(SWAGGER_TITLE)"),
171
+ "description": os.getenv("SWAGGER_DESCRIPTION", "Description(SWAGGER_DESCRIPTION)"),
172
+ "version": os.getenv("SWAGGER_VERSION", "1.0.0(SWAGGER_VERSION)")
173
+ },
174
+ "components": {
175
+ "securitySchemes": {"bearerAuth": {"type": "http", "scheme": "bearer", "bearerFormat": "JWT"}}},
176
+ "basePath": "",
177
+ "paths": paths
178
+ }
179
+
180
+ return json_object
181
+
182
+
183
+ def description(text):
184
+ def actual_description(callback):
185
+ Swagger.add_descripton(text, callback)
186
+ return callback
187
+
188
+ return actual_description
189
+
190
+
191
+ def summary(text):
192
+ def actual_summary(callback):
193
+ Swagger.add_summary(text, callback)
194
+ return callback
195
+
196
+ return actual_summary
197
+
198
+
199
+ def secure():
200
+ def actual_secure(callback):
201
+ Swagger.add_secure(callback)
202
+ return callback
203
+
204
+ return actual_secure
205
+
206
+
207
+ def tags(tags):
208
+ def actual_tags(callback):
209
+ Swagger.add_tags(tags, callback)
210
+ return callback
211
+
212
+ return actual_tags
213
+
214
+
215
+ def example(example):
216
+ def actual_example(callback):
217
+ Swagger.add_example(example, callback)
218
+ return callback
219
+
220
+ return actual_example
221
+
222
+
223
+ def params(params):
224
+ def actual_params(callback):
225
+ Swagger.add_params(params, callback)
226
+ return callback
227
+
228
+ return actual_params
@@ -0,0 +1,107 @@
1
+ #
2
+ # Tina4 - This is not a 4ramework.
3
+ # Copy-right 2007 - current Tina4
4
+ # License: MIT https://opensource.org/licenses/MIT
5
+ #
6
+ # flake8: noqa: E501
7
+ import os
8
+ import json
9
+ import tina4_python
10
+ from tina4_python import Constant
11
+ from tina4_python.Debug import Debug
12
+ from pathlib import Path
13
+ from datetime import datetime, date
14
+ from jinja2 import Environment, FileSystemLoader, Undefined
15
+ from tina4_python.Session import Session
16
+ from random import random as RANDOM
17
+
18
+
19
+ class Template:
20
+ # initializes the twig template engine
21
+ @staticmethod
22
+ def init_twig(path):
23
+ if hasattr(Template, "twig"):
24
+ Debug("Twig found on " + path, Constant.TINA4_LOG_DEBUG)
25
+ return Template.twig
26
+ Debug("Initializing Twig on " + path, Constant.TINA4_LOG_DEBUG)
27
+ twig_path = Path(path)
28
+ Template.twig = Environment(loader=FileSystemLoader(Path(twig_path)))
29
+ Template.twig.add_extension('jinja2.ext.debug')
30
+ Template.twig.add_extension('jinja2.ext.do')
31
+ Template.twig.globals['RANDOM'] = RANDOM
32
+ Template.twig.globals['formToken'] = Template.get_form_token
33
+ Template.twig.filters['formToken'] = Template.get_form_token_input
34
+ if Constant.TINA4_LOG_DEBUG in os.getenv("TINA4_DEBUG_LEVEL") or Constant.TINA4_LOG_ALL in os.getenv(
35
+ "TINA4_DEBUG_LEVEL"):
36
+ Template.twig.globals['dump'] = Template.dump
37
+ else:
38
+ Template.twig.globals['dump'] = Template.production_dump
39
+ Debug("Twig Initialized on " + path, Constant.TINA4_LOG_INFO)
40
+ return Template.twig
41
+
42
+ @staticmethod
43
+ def production_dump(param):
44
+ Debug.error("DUMP FOUND ON PAGE!")
45
+ return ""
46
+
47
+ @staticmethod
48
+ def dump(param):
49
+ if param is not None and not isinstance(param, Undefined):
50
+ def json_serialize(obj):
51
+ if isinstance(obj, (date, datetime)):
52
+ return obj.isoformat()
53
+ if isinstance(obj, Session):
54
+ return obj.session_values
55
+ raise TypeError("Type %s not serializable to Jinja2 template" % type(obj))
56
+
57
+ return "<pre>" + json.dumps(param, indent=True, default=json_serialize) + "</pre>"
58
+ else:
59
+ return ""
60
+
61
+ @staticmethod
62
+ def get_form_token(payload={}):
63
+ return tina4_python.tina4_auth.get_token(payload)
64
+
65
+ @staticmethod
66
+ def get_form_token_input(form_name):
67
+ return '<input type="hidden" name="formToken" value="' + Template.get_form_token(
68
+ {"formName": form_name}) + '"><!--"' + str(datetime.now().isoformat()) + '"-->'
69
+
70
+ @staticmethod
71
+ def convert_special_types(obj):
72
+ if isinstance(obj, dict):
73
+ return {k: Template.convert_special_types(v) for k, v in obj.items()}
74
+ elif isinstance(obj, list):
75
+ return [Template.convert_special_types(i) for i in obj]
76
+ elif isinstance(obj, (date, datetime)):
77
+ return obj.isoformat()
78
+ else:
79
+ return obj
80
+
81
+ @staticmethod
82
+ def render_twig_template(template_or_file_name, data=None):
83
+ if data is None:
84
+ data = {"request": tina4_python.tina4_current_request}
85
+ else:
86
+ data.update({"request": tina4_python.tina4_current_request})
87
+
88
+ data = Template.convert_special_types(data)
89
+
90
+ twig = Template.init_twig(tina4_python.root_path + os.sep + "src" + os.sep + "templates")
91
+ try:
92
+ if twig.get_template(template_or_file_name):
93
+ template = twig.get_template(template_or_file_name)
94
+ content = template.render(data)
95
+ else:
96
+ template = twig.from_string(template_or_file_name)
97
+ content = template.render(data)
98
+
99
+ except Exception as e:
100
+ Debug("Error rendering twig file", template_or_file_name, e, Constant.TINA4_LOG_ERROR)
101
+ content = str(e)
102
+
103
+ return content
104
+
105
+ @staticmethod
106
+ def render(template_or_file_name, data=None):
107
+ return Template.render_twig_template(template_or_file_name, data)