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.
- {tina4_python-0.2.29 → tina4_python-0.2.31}/PKG-INFO +1 -1
- {tina4_python-0.2.29 → tina4_python-0.2.31}/pyproject.toml +1 -1
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Database.py +52 -8
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Router.py +10 -4
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/__init__.py +2 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/swagger/index.html +2 -2
- {tina4_python-0.2.29 → tina4_python-0.2.31}/README.md +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Auth.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Constant.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/DatabaseResult.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Debug.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Env.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Localization.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Messages.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/MiddleWare.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Migration.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Request.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Response.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Session.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/ShellColors.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Swagger.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Template.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/Webserver.py +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/messages.pot +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/css/readme.md +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/favicon.ico +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/images/403.png +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/images/404.png +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/images/logo.png +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/images/readme.md +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/js/readme.md +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/js/tina4helper.js +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/templates/errors/403.twig +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/templates/errors/404.twig +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/templates/readme.md +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
|
@@ -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
|
-
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/public/swagger/oauth2-redirect.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/en/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/en/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/fr/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-0.2.29 → tina4_python-0.2.31}/tina4_python/translations/fr/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|