tina4-python 0.2.126__tar.gz → 0.2.128__tar.gz

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 (52) hide show
  1. {tina4_python-0.2.126 → tina4_python-0.2.128}/PKG-INFO +1 -1
  2. {tina4_python-0.2.126 → tina4_python-0.2.128}/pyproject.toml +1 -1
  3. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/CRUD.py +70 -9
  4. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Database.py +4 -0
  5. tina4_python-0.2.128/tina4_python/DatabaseResult.py +67 -0
  6. tina4_python-0.2.126/tina4_python/DatabaseResult.py +0 -116
  7. {tina4_python-0.2.126 → tina4_python-0.2.128}/.gitignore +0 -0
  8. {tina4_python-0.2.126 → tina4_python-0.2.128}/README.md +0 -0
  9. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Auth.py +0 -0
  10. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Constant.py +0 -0
  11. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/DatabaseTypes.py +0 -0
  12. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Debug.py +0 -0
  13. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Env.py +0 -0
  14. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/HtmlElement.py +0 -0
  15. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Localization.py +0 -0
  16. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Messages.py +0 -0
  17. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/MiddleWare.py +0 -0
  18. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Migration.py +0 -0
  19. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/ORM.py +0 -0
  20. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Queue.py +0 -0
  21. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Request.py +0 -0
  22. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Response.py +0 -0
  23. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Router.py +0 -0
  24. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Session.py +0 -0
  25. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/ShellColors.py +0 -0
  26. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Swagger.py +0 -0
  27. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Template.py +0 -0
  28. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Webserver.py +0 -0
  29. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/Websocket.py +0 -0
  30. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/__init__.py +0 -0
  31. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/messages.pot +0 -0
  32. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/css/readme.md +0 -0
  33. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/favicon.ico +0 -0
  34. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/images/403.png +0 -0
  35. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/images/404.png +0 -0
  36. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/images/500.png +0 -0
  37. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/images/logo.png +0 -0
  38. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/images/readme.md +0 -0
  39. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/js/readme.md +0 -0
  40. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/js/reconnecting-websocket.js +0 -0
  41. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/js/tina4helper.js +0 -0
  42. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/swagger/index.html +0 -0
  43. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
  44. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/templates/components/crud.twig +0 -0
  45. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/templates/errors/403.twig +0 -0
  46. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/templates/errors/404.twig +0 -0
  47. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/templates/errors/500.twig +0 -0
  48. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/templates/readme.md +0 -0
  49. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
  50. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
  51. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
  52. {tina4_python-0.2.126 → tina4_python-0.2.128}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tina4-python
3
- Version: 0.2.126
3
+ Version: 0.2.128
4
4
  Summary: Tina4Python - This is not another framework for Python
5
5
  Author-email: Andre van Zuydam <andrevanzuydam@gmail.com>
6
6
  Requires-Python: <4.0,>=3.12
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tina4-python"
3
- version = "0.2.126"
3
+ version = "0.2.128"
4
4
  description = "Tina4Python - This is not another framework for Python"
5
5
  authors = [
6
6
  {name = "Andre van Zuydam",email = "andrevanzuydam@gmail.com"}
@@ -1,3 +1,7 @@
1
+ import base64
2
+ import datetime
3
+ from decimal import Decimal
4
+
1
5
  from tina4_python.Debug import Debug
2
6
  import re
3
7
  from tina4_python.Template import Template
@@ -6,6 +10,7 @@ from tina4_python.Router import Router
6
10
  import tina4_python
7
11
  import os
8
12
  import shutil
13
+ import json
9
14
 
10
15
  class CRUD:
11
16
 
@@ -17,8 +22,7 @@ class CRUD:
17
22
  self.search_columns = []
18
23
  self.total_count = 0
19
24
  self.sql = None
20
-
21
- import re
25
+ self.error = ""
22
26
 
23
27
  def strip_sql_pagination(self, sql: str) -> str:
24
28
  """
@@ -139,7 +143,6 @@ class CRUD:
139
143
  def to_crud(self, request, options=None):
140
144
  table_name = self.get_table_name(self.sql)
141
145
  table_nice_name = Template.get_nice_label(table_name)
142
- twig_file = self.ensure_crud_template(table_name + ".twig")
143
146
 
144
147
  if options is None:
145
148
  options = {}
@@ -159,6 +162,13 @@ class CRUD:
159
162
  if "search_columns" in options:
160
163
  self.search_columns = options["search_columns"]
161
164
 
165
+ crud_name = table_name
166
+ if "name" in options:
167
+ crud_name = options["name"]
168
+
169
+ twig_file = self.ensure_crud_template(crud_name + ".twig")
170
+
171
+
162
172
  async def get_record(request, response):
163
173
  limit = int(request.params.get("limit", options.get("limit", 10)))
164
174
  offset = int(request.params.get("offset", options.get("offset", 0)))
@@ -209,21 +219,72 @@ class CRUD:
209
219
  self.dba.commit()
210
220
  return response({"message": f"<script>showMessage('{table_nice_name} Record deleted');</script>"}, HTTP_OK, APPLICATION_JSON)
211
221
 
212
- Router.add(TINA4_GET, os.path.join(request.url, table_name).replace("\\", "/"), get_record)
213
- Router.add(TINA4_POST, os.path.join(request.url, table_name).replace("\\", "/"), post_record)
214
- Router.add(TINA4_POST, os.path.join(request.url, table_name, "{"+options["primary_key"]+"}").replace("\\", "/"), update_record)
215
- Router.add(TINA4_DELETE, os.path.join(request.url, table_name, "{"+options["primary_key"]+"}").replace("\\", "/"), delete_record)
222
+ Router.add(TINA4_GET, os.path.join(request.url, crud_name).replace("\\", "/"), get_record)
223
+ Router.add(TINA4_POST, os.path.join(request.url, crud_name).replace("\\", "/"), post_record)
224
+ Router.add(TINA4_POST, os.path.join(request.url, crud_name, "{"+options["primary_key"]+"}").replace("\\", "/"), update_record)
225
+ Router.add(TINA4_DELETE, os.path.join(request.url, crud_name, "{"+options["primary_key"]+"}").replace("\\", "/"), delete_record)
216
226
 
217
227
  fields = []
218
228
  for column in self.columns:
219
229
  fields.append({"name": column, "label": Template.get_nice_label(column)})
220
230
 
231
+
221
232
  html = Template.render(twig_file.replace(os.path.join(tina4_python.root_path, "src", "templates"), "").replace("\\", "/"),
222
- {"columns": fields, "records": self.records,
223
- "table_name": table_name,
233
+ {"columns": fields, "records": self.to_array(),
234
+ "table_name": crud_name,
224
235
  "total_records": self.total_count,
225
236
  "options": options})
226
237
 
227
238
  return html
228
239
 
229
240
 
241
+ def to_array(self, _filter=None):
242
+ """
243
+ Creates an array or list of the items
244
+ :return:
245
+ """
246
+ if self.error is not None:
247
+ return {"error": self.error}
248
+ elif len(self.records) > 0:
249
+ # check all the records - if we get bytes we base64encode them for the json to work
250
+ json_records = []
251
+ for record in self.records:
252
+ json_record = {}
253
+ for key in record:
254
+ if isinstance(record[key], Decimal):
255
+ json_record[key] = float(record[key])
256
+ elif isinstance(record[key], (datetime.date, datetime.datetime)):
257
+ json_record[key] = record[key].isoformat()
258
+ elif isinstance(record[key], memoryview):
259
+ json_record[key] = base64.b64encode(record[key].tobytes()).decode('utf-8')
260
+ elif isinstance(record[key], bytes):
261
+ json_record[key] = base64.b64encode(record[key]).decode('utf-8')
262
+ else:
263
+ json_record[key] = record[key]
264
+
265
+ if _filter is not None:
266
+ json_record = _filter(json_record)
267
+
268
+ json_records.append(json_record)
269
+
270
+ return json_records
271
+ else:
272
+ return []
273
+
274
+ def to_list(self, _filter=None):
275
+ return self.to_array(_filter)
276
+
277
+ def to_json(self, _filter=None):
278
+ return json.dumps(self.to_array(_filter))
279
+
280
+ def __iter__(self):
281
+ return iter(self.to_array())
282
+
283
+ def __getitem__(self, item):
284
+ if item < len(self.records):
285
+ return self.records[item]
286
+ else:
287
+ return {}
288
+
289
+ def __str__(self):
290
+ return self.to_json()
@@ -10,6 +10,8 @@ import sys
10
10
  import importlib
11
11
  import datetime
12
12
  import json
13
+ from decimal import Decimal
14
+
13
15
  from tina4_python import Debug, Constant
14
16
  from tina4_python.Constant import TINA4_LOG_ERROR
15
17
  from tina4_python.DatabaseResult import DatabaseResult
@@ -351,6 +353,8 @@ class Database:
351
353
  if record.error is None and record.count == 1:
352
354
  data = {}
353
355
  for key in record.records[0]:
356
+ if isinstance(record.records[0][key], Decimal):
357
+ data[key] = float(record.records[0][key])
354
358
  if isinstance(record.records[0][key], (datetime.date, datetime.datetime)):
355
359
  data[key] = record.records[0][key].isoformat()
356
360
  if isinstance(record.records[0][key], bytes):
@@ -0,0 +1,67 @@
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 base64
8
+ import json
9
+ import datetime
10
+ from decimal import Decimal
11
+ from tina4_python.CRUD import CRUD
12
+ class DatabaseResult(CRUD):
13
+ def __init__(self, _records=None, _columns=None, _error=None, count=None, limit=None, skip=None, sql=None, dba=None):
14
+ """
15
+ DatabaseResult constructor
16
+ :param _records:
17
+ :param _columns:
18
+ :param _error:
19
+ :param count:
20
+ :param limit:
21
+ :param skip:
22
+ """
23
+ super().__init__()
24
+ if count is not None:
25
+ self.total_count = count
26
+ else:
27
+ self.total_count = 0
28
+
29
+ if limit is not None:
30
+ self.limit = limit
31
+ else:
32
+ self.limit = 0
33
+
34
+ if skip is not None:
35
+ self.skip = skip
36
+ else:
37
+ self.skip = 0
38
+
39
+ if _records is not None:
40
+ self.records = _records
41
+ else:
42
+ self.records = []
43
+
44
+ self.count = len(self.records)
45
+
46
+ if _columns is not None:
47
+ self.columns = _columns
48
+ else:
49
+ self.columns = []
50
+
51
+ if sql is not None:
52
+ self.sql = sql
53
+
54
+ if dba is not None:
55
+ self.dba = dba
56
+
57
+ self.error = _error
58
+
59
+ def to_paginate(self):
60
+
61
+ return {"recordsTotal": self.total_count, "recordsOffset": self.skip, "recordCount": self.count,
62
+ "recordsFiltered": self.total_count, "fields": self.columns, "data": self.to_array(),
63
+ "dataError": self.error}
64
+
65
+
66
+
67
+
@@ -1,116 +0,0 @@
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 base64
8
- import json
9
- import datetime
10
- from decimal import Decimal
11
- from tina4_python.CRUD import CRUD
12
- class DatabaseResult(CRUD):
13
- def __init__(self, _records=None, _columns=None, _error=None, count=None, limit=None, skip=None, sql=None, dba=None):
14
- """
15
- DatabaseResult constructor
16
- :param _records:
17
- :param _columns:
18
- :param _error:
19
- :param count:
20
- :param limit:
21
- :param skip:
22
- """
23
- super().__init__()
24
- if count is not None:
25
- self.total_count = count
26
- else:
27
- self.total_count = 0
28
-
29
- if limit is not None:
30
- self.limit = limit
31
- else:
32
- self.limit = 0
33
-
34
- if skip is not None:
35
- self.skip = skip
36
- else:
37
- self.skip = 0
38
-
39
- if _records is not None:
40
- self.records = _records
41
- else:
42
- self.records = []
43
-
44
- self.count = len(self.records)
45
-
46
- if _columns is not None:
47
- self.columns = _columns
48
- else:
49
- self.columns = []
50
-
51
- if sql is not None:
52
- self.sql = sql
53
-
54
- if dba is not None:
55
- self.dba = dba
56
-
57
- self.error = _error
58
-
59
- def to_paginate(self):
60
-
61
- return {"recordsTotal": self.total_count, "recordsOffset": self.skip, "recordCount": self.count,
62
- "recordsFiltered": self.total_count, "fields": self.columns, "data": self.to_array(),
63
- "dataError": self.error}
64
-
65
- def to_array(self, _filter=None):
66
- """
67
- Creates an array or list of the items
68
- :return:
69
- """
70
- if self.error is not None:
71
- return {"error": self.error}
72
- elif len(self.records) > 0:
73
- # check all the records - if we get bytes we base64encode them for the json to work
74
- json_records = []
75
- for record in self.records:
76
- json_record = {}
77
- for key in record:
78
- if isinstance(record[key], Decimal):
79
- json_record[key] = float(record[key])
80
- elif isinstance(record[key], (datetime.date, datetime.datetime)):
81
- json_record[key] = record[key].isoformat()
82
- elif isinstance(record[key], memoryview):
83
- json_record[key] = base64.b64encode(record[key].tobytes()).decode('utf-8')
84
- elif isinstance(record[key], bytes):
85
- json_record[key] = base64.b64encode(record[key]).decode('utf-8')
86
- else:
87
- json_record[key] = record[key]
88
-
89
- if _filter is not None:
90
- json_record = _filter(json_record)
91
-
92
- json_records.append(json_record)
93
-
94
- return json_records
95
- else:
96
- return []
97
-
98
- def to_list(self, _filter=None):
99
- return self.to_array(_filter)
100
-
101
- def to_json(self, _filter=None):
102
- return json.dumps(self.to_array(_filter))
103
-
104
- def __iter__(self):
105
- return iter(self.to_array())
106
-
107
- def __getitem__(self, item):
108
- if item < len(self.records):
109
- return self.records[item]
110
- else:
111
- return {}
112
-
113
- def __str__(self):
114
- return self.to_json()
115
-
116
-
File without changes