tina4-python 0.2.29__tar.gz → 0.2.31__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 (40) hide show
  1. {tina4_python-0.2.29 → tina4_python-0.2.31}/PKG-INFO +1 -1
  2. {tina4_python-0.2.29 → tina4_python-0.2.31}/pyproject.toml +1 -1
  3. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Database.py +52 -8
  4. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Router.py +10 -4
  5. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/__init__.py +2 -0
  6. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/swagger/index.html +2 -2
  7. {tina4_python-0.2.29 → tina4_python-0.2.31}/README.md +0 -0
  8. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Auth.py +0 -0
  9. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Constant.py +0 -0
  10. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/DatabaseResult.py +0 -0
  11. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Debug.py +0 -0
  12. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Env.py +0 -0
  13. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Localization.py +0 -0
  14. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Messages.py +0 -0
  15. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/MiddleWare.py +0 -0
  16. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Migration.py +0 -0
  17. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Request.py +0 -0
  18. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Response.py +0 -0
  19. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Session.py +0 -0
  20. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/ShellColors.py +0 -0
  21. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Swagger.py +0 -0
  22. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Template.py +0 -0
  23. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Webserver.py +0 -0
  24. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/messages.pot +0 -0
  25. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/css/readme.md +0 -0
  26. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/favicon.ico +0 -0
  27. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/images/403.png +0 -0
  28. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/images/404.png +0 -0
  29. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/images/logo.png +0 -0
  30. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/images/readme.md +0 -0
  31. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/js/readme.md +0 -0
  32. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/js/tina4helper.js +0 -0
  33. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
  34. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/templates/errors/403.twig +0 -0
  35. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/templates/errors/404.twig +0 -0
  36. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/templates/readme.md +0 -0
  37. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
  38. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
  39. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
  40. {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tina4-python
3
- Version: 0.2.29
3
+ Version: 0.2.31
4
4
  Summary: Tina4Python - This is not another framework for Python
5
5
  Author: Andre van Zuydam
6
6
  Author-email: andrevanzuydam@gmail.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "tina4-python"
3
- version = "0.2.29"
3
+ version = "0.2.31"
4
4
  description = "Tina4Python - This is not another framework for Python"
5
5
  authors = ["Andre van Zuydam <andrevanzuydam@gmail.com>"]
6
6
  readme = "README.md"
@@ -16,7 +16,7 @@ from tina4_python.DatabaseResult import DatabaseResult
16
16
  class Database:
17
17
  SQLITE = "sqlite3"
18
18
  FIREBIRD = "firebird.driver"
19
- MYSQL = "mysql"
19
+ MYSQL = "mysql.connector"
20
20
  POSTGRES = "postgres"
21
21
 
22
22
  def __init__(self, _connection_string, _username="", _password=""):
@@ -39,8 +39,7 @@ class Database:
39
39
  self.dba = self.database_module.connect(self.database_path)
40
40
  self.port = None
41
41
  self.host = None
42
-
43
- if self.database_engine == self.FIREBIRD:
42
+ elif self.database_engine == self.FIREBIRD:
44
43
  # <host>/<port>:<file>
45
44
  temp_params = self.database_path.split(":", 1)
46
45
  host_port = temp_params[0].split("/", 1)
@@ -57,10 +56,32 @@ class Database:
57
56
  user=self.username,
58
57
  password=self.password
59
58
  )
59
+ else:
60
+ temp_params = self.database_path.split(":", 1)
61
+ host_port = temp_params[0].split("/", 1)
62
+ self.host = host_port[0]
63
+ if len(host_port) > 1:
64
+ self.port = int(host_port[1])
65
+ else:
66
+ self.port = 0
67
+
68
+ self.database_path = temp_params[1]
69
+
70
+ self.dba = self.database_module.connect(
71
+ database=self.database_path,
72
+ port=self.port,
73
+ host=self.host,
74
+ user=self.username,
75
+ password=self.password
76
+ )
60
77
 
61
78
  Debug("DATABASE:", self.database_module, self.host, self.port, self.database_path, self.username,
62
79
  Constant.TINA4_LOG_DEBUG)
63
80
 
81
+ def database_exists(self, database_name):
82
+
83
+ return True
84
+
64
85
  def current_timestamp(self):
65
86
  """
66
87
  Gets the current timestamp based on the database being used
@@ -103,14 +124,15 @@ class Database:
103
124
  """
104
125
  # modify the select statement for limit and skip
105
126
  if self.database_engine == self.FIREBIRD:
106
- sql = f"select first {limit} skip {skip} * from ({sql})"
127
+ sql = f"select first {limit} skip {skip} * from ({sql}) as t"
107
128
  elif self.database_engine == self.SQLITE:
108
- sql = f"select * from ({sql}) limit {skip},{limit}"
129
+ sql = f"select * from ({sql}) as t limit {skip},{limit}"
109
130
  else:
110
- sql = f"select * from ({sql}) limit {skip},{limit}"
131
+ sql = f"select * from ({sql}) as t limit {skip},{limit}"
111
132
 
112
133
  cursor = self.dba.cursor()
113
134
  try:
135
+ sql = self.parse_place_holders(sql)
114
136
  cursor.execute(sql, params)
115
137
  return self.get_database_result(cursor)
116
138
  except Exception as e:
@@ -126,6 +148,7 @@ class Database:
126
148
  :return:
127
149
  """
128
150
  # Calling the fetch method with limit as 1 and returning the result
151
+ sql = self.parse_place_holders(sql)
129
152
  record = self.fetch(sql, params=params, limit=1, skip=skip)
130
153
  if record.error is None and record.count == 1:
131
154
  data = {}
@@ -141,6 +164,19 @@ class Database:
141
164
  else:
142
165
  return None
143
166
 
167
+ def parse_place_holders(self, sql):
168
+ """
169
+ Sanitizes a sql statement to replace param chars with the appropriate placeholders
170
+ MYSQL expects %s and firebird, posgres and sqlite expect ?
171
+ :param sql:
172
+ :return:
173
+ """
174
+
175
+ if self.database_engine == self.MYSQL:
176
+ return sql.replace("?", "%s")
177
+ else:
178
+ return sql.replace("%s", "?")
179
+
144
180
  def execute(self, sql, params=()):
145
181
  """
146
182
  Execute a query based on a sql statement
@@ -148,13 +184,18 @@ class Database:
148
184
  :param params:
149
185
  :return:
150
186
  """
187
+ sql = self.parse_place_holders(sql)
151
188
  cursor = self.dba.cursor()
152
189
  # Running an execute statement and committing any changes to the database
153
190
  try:
154
191
  cursor.execute(sql, params)
155
- if "returning" in sql:
192
+ if "returning" in sql.lower():
156
193
  return self.get_database_result(cursor)
157
194
  else:
195
+ # see if we are mysql and if we are insert statement to get the last record
196
+ if "insert" in sql.lower() and self.database_engine == self.MYSQL:
197
+ return DatabaseResult([{"id": cursor.lastrowid}], [], None)
198
+
158
199
  # On success return an empty result set with no error
159
200
  return DatabaseResult(None, [], None)
160
201
  except Exception as e:
@@ -169,6 +210,7 @@ class Database:
169
210
  :param params:
170
211
  :return:
171
212
  """
213
+ sql = self.parse_place_holders(sql)
172
214
  cursor = self.dba.cursor()
173
215
  # Running an execute statement and committing any changes to the database
174
216
  try:
@@ -246,7 +288,9 @@ class Database:
246
288
 
247
289
  sql = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})"
248
290
 
249
- sql += f" returning ({primary_key})"
291
+ if self.database_engine == self.FIREBIRD or self.database_engine == self.SQLITE:
292
+ sql += f" returning ({primary_key})"
293
+
250
294
  records = DatabaseResult()
251
295
  for record in data:
252
296
  record = self.sanitize(record)
@@ -11,10 +11,10 @@ import os
11
11
  import sys
12
12
  import io
13
13
  import tina4_python
14
- from tina4_python import Constant
15
- from tina4_python.Debug import Debug
14
+ from tina4_python import Constant,Auth
16
15
  from tina4_python import Response
17
16
  from tina4_python import Request
17
+ from tina4_python.Debug import Debug
18
18
  from tina4_python.Template import Template
19
19
  from tina4_python.MiddleWare import MiddleWare
20
20
 
@@ -107,6 +107,7 @@ class Router:
107
107
  return Response.Response(content, Constant.HTTP_FORBIDDEN, Constant.TEXT_HTML)
108
108
  else:
109
109
  if request["body"] is not None and "formToken" in request["body"]:
110
+ request["params"]["formToken"] = request["body"]["formToken"]
110
111
  del request["body"]["formToken"]
111
112
 
112
113
  # split URL and extract query string
@@ -181,6 +182,7 @@ class Router:
181
182
  Request, result = middleware_runner.call_any_methods(Request, result)
182
183
 
183
184
  if result is not None:
185
+ result.headers["FreshToken"] = tina4_python.tina4_auth.get_token({"path": url})
184
186
  if "cache" in route and route["cache"] is not None:
185
187
  if not route["cache"]["cached"]:
186
188
  result.headers["Cache-Control"] = "max-age=1, must-revalidate"
@@ -196,12 +198,14 @@ class Router:
196
198
  break
197
199
 
198
200
  if result is None and old_stdout is not None:
201
+ result = Response
202
+ result.headers["FreshToken"] = tina4_python.tina4_auth.get_token({"path": url})
199
203
  sys.stdout = old_stdout
200
204
  if buffer.getvalue() != "":
201
205
  try:
202
- return Response.Response(json.loads(buffer.getvalue()), Constant.HTTP_OK, Constant.APPLICATION_JSON)
206
+ return Response.Response(json.loads(buffer.getvalue()), Constant.HTTP_OK, Constant.APPLICATION_JSON, result.headers)
203
207
  except:
204
- return Response.Response(buffer.getvalue(), Constant.HTTP_OK, Constant.TEXT_HTML)
208
+ return Response.Response(buffer.getvalue(), Constant.HTTP_OK, Constant.TEXT_HTML, result.headers)
205
209
  else:
206
210
  result = Response
207
211
  result.http_code = Constant.HTTP_NOT_FOUND
@@ -223,6 +227,7 @@ class Router:
223
227
  tina4_python.root_path + os.sep + "src" + os.sep + "templates" + os.sep + twig_file,
224
228
  Constant.TINA4_LOG_DEBUG)
225
229
 
230
+ result.headers["FreshToken"] = tina4_python.tina4_auth.get_token({"path": url})
226
231
  result.headers["Cache-Control"] = "max-age=-1, public"
227
232
  result.headers["Pragma"] = "no-cache"
228
233
  content = Template.render_twig_template(twig_file, {"request": tina4_python.tina4_current_request})
@@ -234,6 +239,7 @@ class Router:
234
239
  "errors/404.twig", {"server": {"url": url}})
235
240
  return Response.Response(content, Constant.HTTP_NOT_FOUND, Constant.TEXT_HTML)
236
241
 
242
+ result.headers["FreshToken"] = tina4_python.tina4_auth.get_token({"path": url})
237
243
  return result
238
244
 
239
245
  @staticmethod
@@ -186,6 +186,8 @@ async def get_swagger_json(request, response):
186
186
  async def get_swagger(request, response):
187
187
  html = file_get_contents(
188
188
  root_path + os.sep + "src" + os.sep + "public" + os.sep + "swagger" + os.sep + "index.html")
189
+
190
+ html = html.replace("{SWAGGER_ROUTE}", os.getenv("SWAGGER_ROUTE", "/swagger"))
189
191
  return response(html)
190
192
 
191
193
 
@@ -71,7 +71,7 @@
71
71
 
72
72
  // Build a system
73
73
  const ui = SwaggerUIBundle({
74
- url: "/swagger/swagger.json",
74
+ url: "{SWAGGER_ROUTE}/swagger.json",
75
75
  dom_id: '#swagger-ui',
76
76
  deepLinking: true,
77
77
  presets: [
@@ -87,4 +87,4 @@
87
87
  </script>
88
88
  </body>
89
89
 
90
- </html>
90
+ </html>
File without changes