tina4-python 0.2.21__tar.gz → 0.2.24__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.21 → tina4_python-0.2.24}/PKG-INFO +1 -1
- {tina4_python-0.2.21 → tina4_python-0.2.24}/pyproject.toml +1 -1
- tina4_python-0.2.24/tina4_python/.env +6 -0
- tina4_python-0.2.24/tina4_python/MiddleWare.py +71 -0
- tina4_python-0.2.24/tina4_python/Request.py +18 -0
- tina4_python-0.2.24/tina4_python/Response.py +94 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Router.py +84 -28
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Webserver.py +2 -2
- tina4_python-0.2.24/tina4_python/secrets/domain.cert +21 -0
- tina4_python-0.2.24/tina4_python/secrets/private.key +30 -0
- tina4_python-0.2.24/tina4_python/secrets/public.key +9 -0
- tina4_python-0.2.21/tina4_python/Request.py +0 -24
- tina4_python-0.2.21/tina4_python/Response.py +0 -77
- {tina4_python-0.2.21 → tina4_python-0.2.24}/README.md +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Auth.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Constant.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Database.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/DatabaseResult.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Debug.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Env.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Localization.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Messages.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Migration.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Session.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/ShellColors.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Swagger.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/Template.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/__init__.py +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/messages.pot +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/public/css/readme.md +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/public/favicon.ico +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/public/images/403.png +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/public/images/404.png +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/public/images/logo.png +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/public/images/readme.md +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/public/js/readme.md +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/public/js/tina4helper.js +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/public/swagger/index.html +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/templates/errors/403.twig +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/templates/errors/404.twig +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/templates/readme.md +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
class MiddleWare:
|
|
4
|
+
def __init__(self, middleware_class):
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
:param middleware_class:
|
|
8
|
+
"""
|
|
9
|
+
self.before_methods = []
|
|
10
|
+
self.after_methods = []
|
|
11
|
+
self.any_methods = []
|
|
12
|
+
self.middleware_class = middleware_class
|
|
13
|
+
|
|
14
|
+
self.methods_list = [method for method in vars(middleware_class) if callable(
|
|
15
|
+
getattr(middleware_class, method)) and not method.startswith("__")]
|
|
16
|
+
|
|
17
|
+
for method in self.methods_list:
|
|
18
|
+
if method.startswith("before"):
|
|
19
|
+
self.before_methods.append(method)
|
|
20
|
+
elif method.startswith("after"):
|
|
21
|
+
self.after_methods.append(method)
|
|
22
|
+
else:
|
|
23
|
+
self.any_methods.append(method)
|
|
24
|
+
|
|
25
|
+
def call_before_methods(self, request, response):
|
|
26
|
+
"""
|
|
27
|
+
Call before methods
|
|
28
|
+
:param request:
|
|
29
|
+
:param response:
|
|
30
|
+
:return:
|
|
31
|
+
"""
|
|
32
|
+
for method in self.before_methods:
|
|
33
|
+
method = getattr(self.middleware_class, method)
|
|
34
|
+
request, response = method(request, response)
|
|
35
|
+
return request, response
|
|
36
|
+
|
|
37
|
+
def call_after_methods(self, request, response):
|
|
38
|
+
"""
|
|
39
|
+
Call after methods
|
|
40
|
+
:param request:
|
|
41
|
+
:param response:
|
|
42
|
+
:return:
|
|
43
|
+
"""
|
|
44
|
+
for method in self.after_methods:
|
|
45
|
+
method = getattr(self.middleware_class, method)
|
|
46
|
+
request, response = method(request, response)
|
|
47
|
+
return request, response
|
|
48
|
+
|
|
49
|
+
def call_any_methods(self, request, response):
|
|
50
|
+
"""
|
|
51
|
+
Call any methods
|
|
52
|
+
:param request:
|
|
53
|
+
:param response:
|
|
54
|
+
:return:
|
|
55
|
+
"""
|
|
56
|
+
for method in self.any_methods:
|
|
57
|
+
method = getattr(self.middleware_class, method)
|
|
58
|
+
request, response = method(request, response)
|
|
59
|
+
return request, response
|
|
60
|
+
|
|
61
|
+
def call_direct_method(self, request, response, method_name):
|
|
62
|
+
"""
|
|
63
|
+
Call direct methods
|
|
64
|
+
:param request:
|
|
65
|
+
:param response:
|
|
66
|
+
:param method_name:
|
|
67
|
+
:return:
|
|
68
|
+
"""
|
|
69
|
+
method = getattr(self.middleware_class, method_name)
|
|
70
|
+
request, response = method(request, response)
|
|
71
|
+
return request, response
|
|
@@ -0,0 +1,18 @@
|
|
|
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 inspect
|
|
8
|
+
|
|
9
|
+
request = None
|
|
10
|
+
body = None
|
|
11
|
+
params = {}
|
|
12
|
+
headers = {}
|
|
13
|
+
cookies = {}
|
|
14
|
+
url = None
|
|
15
|
+
session = None
|
|
16
|
+
files = {}
|
|
17
|
+
raw_data = None
|
|
18
|
+
raw_content = None
|
|
@@ -0,0 +1,94 @@
|
|
|
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 json
|
|
8
|
+
import inspect
|
|
9
|
+
from types import ModuleType
|
|
10
|
+
from tina4_python import Constant
|
|
11
|
+
from tina4_python import DatabaseResult
|
|
12
|
+
from tina4_python.Debug import Debug
|
|
13
|
+
|
|
14
|
+
headers = {}
|
|
15
|
+
content = ""
|
|
16
|
+
http_code = Constant.HTTP_OK
|
|
17
|
+
content_type = Constant.TEXT_HTML
|
|
18
|
+
|
|
19
|
+
class Response:
|
|
20
|
+
def __init__(self, content_in=None, http_code_in=None, content_type_in=None,
|
|
21
|
+
headers_in=None):
|
|
22
|
+
global headers
|
|
23
|
+
global content
|
|
24
|
+
global http_code
|
|
25
|
+
global content_type
|
|
26
|
+
|
|
27
|
+
if content is not None:
|
|
28
|
+
content_in = content + content_in
|
|
29
|
+
|
|
30
|
+
if (not isinstance(content_in, bool) and not isinstance(content_in, object)
|
|
31
|
+
and not isinstance(content_in,bytes)
|
|
32
|
+
and not isinstance(content_in, str)
|
|
33
|
+
and not isinstance(content_in, list) and inspect.isclass(type(content_in))):
|
|
34
|
+
content_in = dict(content_in)
|
|
35
|
+
|
|
36
|
+
# check if database result
|
|
37
|
+
if type(content_in) is DatabaseResult.DatabaseResult:
|
|
38
|
+
content_type = Constant.APPLICATION_JSON
|
|
39
|
+
content_in = content_in.to_json()
|
|
40
|
+
|
|
41
|
+
# convert the dictionary or list into JSON
|
|
42
|
+
if not isinstance(content_in, bool) and type(content_in) is dict or type(content_in) is list:
|
|
43
|
+
content_in = json.dumps(content_in)
|
|
44
|
+
content_type = Constant.APPLICATION_JSON
|
|
45
|
+
|
|
46
|
+
if isinstance(content_in, bool):
|
|
47
|
+
if content_in:
|
|
48
|
+
content_in = "True"
|
|
49
|
+
else:
|
|
50
|
+
content_in = "False"
|
|
51
|
+
|
|
52
|
+
if isinstance(content_in, ModuleType):
|
|
53
|
+
content_in = json.dumps({"error": "Cannot decode object of type " + str(type(content_in))})
|
|
54
|
+
content_type = Constant.APPLICATION_JSON
|
|
55
|
+
|
|
56
|
+
self.headers = headers_in if headers_in is not None else headers
|
|
57
|
+
self.content = content_in if content_in is not None else content
|
|
58
|
+
self.http_code = http_code_in if http_code_in is not None else http_code
|
|
59
|
+
self.content_type = content_type_in if content_type_in is not None else content_type
|
|
60
|
+
headers = self.headers
|
|
61
|
+
http_code = self.http_code
|
|
62
|
+
content_type = self.content_type
|
|
63
|
+
content = self.content
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def redirect(redirect_url):
|
|
67
|
+
"""
|
|
68
|
+
Redirects a request to redirect_url
|
|
69
|
+
:param redirect_url:
|
|
70
|
+
:return:
|
|
71
|
+
"""
|
|
72
|
+
global headers
|
|
73
|
+
global content
|
|
74
|
+
global http_code
|
|
75
|
+
global content_type
|
|
76
|
+
headers = {}
|
|
77
|
+
http_code = Constant.HTTP_REDIRECT
|
|
78
|
+
headers["Location"] = redirect_url
|
|
79
|
+
content = ""
|
|
80
|
+
content_type = Constant.TEXT_HTML
|
|
81
|
+
return Response("", http_code, content_type, headers)
|
|
82
|
+
|
|
83
|
+
@staticmethod
|
|
84
|
+
def add_header(key, value):
|
|
85
|
+
"""
|
|
86
|
+
Adds a header for the response
|
|
87
|
+
:param key:
|
|
88
|
+
:param value:
|
|
89
|
+
:return:
|
|
90
|
+
"""
|
|
91
|
+
global headers
|
|
92
|
+
headers[key] = value
|
|
93
|
+
|
|
94
|
+
|
|
@@ -13,9 +13,10 @@ import io
|
|
|
13
13
|
import tina4_python
|
|
14
14
|
from tina4_python import Constant
|
|
15
15
|
from tina4_python.Debug import Debug
|
|
16
|
+
from tina4_python import Response
|
|
16
17
|
from tina4_python import Request
|
|
17
|
-
from tina4_python.Response import Response
|
|
18
18
|
from tina4_python.Template import Template
|
|
19
|
+
from tina4_python.MiddleWare import MiddleWare
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class Router:
|
|
@@ -59,18 +60,27 @@ class Router:
|
|
|
59
60
|
# Renders the URL and returns the content
|
|
60
61
|
@staticmethod
|
|
61
62
|
async def get_result(url, method, request, headers, session):
|
|
63
|
+
global Request
|
|
64
|
+
global Response
|
|
65
|
+
|
|
66
|
+
Response.headers = {}
|
|
67
|
+
Response.content = ""
|
|
68
|
+
Response.http_code = Constant.HTTP_OK
|
|
69
|
+
result = None
|
|
70
|
+
|
|
62
71
|
Debug("Root Path " + tina4_python.root_path + " " + url, method, Constant.TINA4_LOG_DEBUG)
|
|
63
72
|
tina4_python.tina4_current_request["url"] = url
|
|
64
73
|
tina4_python.tina4_current_request["headers"] = headers
|
|
65
74
|
|
|
66
75
|
# we can add other methods later but right now we validate posts
|
|
67
|
-
if method in [Constant.TINA4_GET, Constant.TINA4_POST, Constant.TINA4_PUT, Constant.TINA4_PATCH,
|
|
76
|
+
if method in [Constant.TINA4_GET, Constant.TINA4_POST, Constant.TINA4_PUT, Constant.TINA4_PATCH,
|
|
77
|
+
Constant.TINA4_DELETE]:
|
|
68
78
|
content_type = "text/html"
|
|
69
79
|
if "content-type" in headers:
|
|
70
80
|
content_type = headers["content-type"]
|
|
71
81
|
|
|
72
82
|
if content_type == "application/json":
|
|
73
|
-
content = {"error": "403 - Forbidden", "data": {"server": {"url": url}}}
|
|
83
|
+
content = {"error": "403 - Forbidden", "data": {"server": {"url": url}}}
|
|
74
84
|
else:
|
|
75
85
|
content = Template.render_twig_template(
|
|
76
86
|
"errors/403.twig", {"server": {"url": url}})
|
|
@@ -93,14 +103,11 @@ class Router:
|
|
|
93
103
|
validated = True
|
|
94
104
|
|
|
95
105
|
if not validated and method != Constant.TINA4_GET:
|
|
96
|
-
return Response(content, Constant.HTTP_FORBIDDEN, Constant.TEXT_HTML)
|
|
106
|
+
return Response.Response(content, Constant.HTTP_FORBIDDEN, Constant.TEXT_HTML)
|
|
97
107
|
else:
|
|
98
108
|
if request["body"] is not None and "formToken" in request["body"]:
|
|
99
109
|
del request["body"]["formToken"]
|
|
100
110
|
|
|
101
|
-
# default response
|
|
102
|
-
result = Response("", Constant.HTTP_NOT_FOUND, Constant.TEXT_HTML)
|
|
103
|
-
|
|
104
111
|
# split URL and extract query string
|
|
105
112
|
url_parts = url.split('?')
|
|
106
113
|
url = url_parts[0]
|
|
@@ -111,7 +118,7 @@ class Router:
|
|
|
111
118
|
if os.path.isfile(static_file):
|
|
112
119
|
mime_type = mimetypes.guess_type(url)[0]
|
|
113
120
|
with open(static_file, 'rb') as file:
|
|
114
|
-
return Response(file.read(), Constant.HTTP_OK, mime_type)
|
|
121
|
+
return Response.Response(file.read(), Constant.HTTP_OK, mime_type)
|
|
115
122
|
|
|
116
123
|
old_stdout = None
|
|
117
124
|
for route in tina4_python.tina4_routes.values():
|
|
@@ -119,15 +126,16 @@ class Router:
|
|
|
119
126
|
continue
|
|
120
127
|
Debug("Matching route " + route['route'] + " to " + url, Constant.TINA4_LOG_DEBUG)
|
|
121
128
|
if Router.match(url, route['route']):
|
|
122
|
-
if
|
|
129
|
+
if "swagger" in route and route["swagger"] is not None and "secure" in route["swagger"]:
|
|
123
130
|
if route["swagger"]["secure"] and not validated:
|
|
124
|
-
return Response(content, Constant.HTTP_FORBIDDEN, Constant.TEXT_HTML)
|
|
131
|
+
return Response.Response(content, Constant.HTTP_FORBIDDEN, Constant.TEXT_HTML)
|
|
125
132
|
|
|
126
133
|
router_response = route["callback"]
|
|
127
134
|
|
|
128
135
|
# Add the inline variables & construct a Request variable
|
|
129
136
|
request["params"].update(Router.variables)
|
|
130
137
|
|
|
138
|
+
|
|
131
139
|
Request.request = request # Add the request object
|
|
132
140
|
Request.headers = headers # Add the headers
|
|
133
141
|
Request.params = request["params"]
|
|
@@ -136,34 +144,57 @@ class Router:
|
|
|
136
144
|
Request.raw_data = request["raw_data"] if "raw_data" in request else None
|
|
137
145
|
Request.raw_request = request["raw_request"] if "raw_request" in request else None
|
|
138
146
|
Request.raw_content = request["raw_content"] if "raw_content" in request else None
|
|
147
|
+
Request.url = url
|
|
139
148
|
|
|
140
149
|
tina4_python.tina4_current_request = Request
|
|
141
150
|
|
|
142
|
-
old_stdout = sys.stdout
|
|
151
|
+
old_stdout = sys.stdout # Memorize the default stdout stream
|
|
143
152
|
sys.stdout = buffer = io.StringIO()
|
|
144
|
-
result = await router_response(request=Request, response=Response)
|
|
145
153
|
|
|
146
|
-
if "
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
if "middleware" in route:
|
|
155
|
+
middleware_runner = MiddleWare(route["middleware"]["class"])
|
|
156
|
+
|
|
157
|
+
if "methods" in route["middleware"]:
|
|
158
|
+
for method in route["middleware"]["methods"]:
|
|
159
|
+
Request, Response = middleware_runner.call_direct_method(Request, Response, method)
|
|
151
160
|
else:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
result.headers["Pragma"] = "cache"
|
|
161
|
+
Request, Response = middleware_runner.call_before_methods(Request, Response)
|
|
162
|
+
Request, Response = middleware_runner.call_any_methods(Request, Response)
|
|
163
|
+
|
|
164
|
+
result = await router_response(request=Request, response=Response.Response)
|
|
157
165
|
|
|
166
|
+
if "middleware" in route:
|
|
167
|
+
middleware_runner = MiddleWare(route["middleware"]["class"])
|
|
168
|
+
|
|
169
|
+
if "methods" in route["middleware"]:
|
|
170
|
+
for method in route["middleware"]["methods"]:
|
|
171
|
+
Request, result = middleware_runner.call_direct_method(Request, result, method)
|
|
172
|
+
else:
|
|
173
|
+
Request, result = middleware_runner.call_after_methods(Request, result)
|
|
174
|
+
Request, result = middleware_runner.call_any_methods(Request, result)
|
|
175
|
+
|
|
176
|
+
if result is not None:
|
|
177
|
+
if "cache" in route and route["cache"] is not None:
|
|
178
|
+
if not route["cache"]["cached"]:
|
|
179
|
+
result.headers["Cache-Control"] = "max-age=1, must-revalidate"
|
|
180
|
+
result.headers["Pragma"] = "no-cache"
|
|
181
|
+
result.headers["Clear-Site-Data"] = "cache"
|
|
182
|
+
else:
|
|
183
|
+
result.headers["Cache-Control"] = "max-age=" + str(
|
|
184
|
+
route["cache"]["max_age"]) + ", must-revalidate"
|
|
185
|
+
result.headers["Pragma"] = "cache"
|
|
186
|
+
else:
|
|
187
|
+
result.headers["Cache-Control"] = "max-age=-1, must-revalidate"
|
|
188
|
+
result.headers["Pragma"] = "cache"
|
|
158
189
|
|
|
159
190
|
break
|
|
160
191
|
|
|
161
192
|
if result is None:
|
|
162
193
|
sys.stdout = old_stdout
|
|
163
194
|
try:
|
|
164
|
-
return Response(json.loads(buffer.getvalue()), Constant.HTTP_OK, Constant.APPLICATION_JSON)
|
|
195
|
+
return Response.Response(json.loads(buffer.getvalue()), Constant.HTTP_OK, Constant.APPLICATION_JSON)
|
|
165
196
|
except:
|
|
166
|
-
return Response(buffer.getvalue(), Constant.HTTP_OK, Constant.TEXT_HTML)
|
|
197
|
+
return Response.Response(buffer.getvalue(), Constant.HTTP_OK, Constant.TEXT_HTML)
|
|
167
198
|
|
|
168
199
|
# If no route is matched, serve 404
|
|
169
200
|
if result.http_code == Constant.HTTP_NOT_FOUND:
|
|
@@ -183,12 +214,12 @@ class Router:
|
|
|
183
214
|
result.headers["Pragma"] = "no-cache"
|
|
184
215
|
content = Template.render_twig_template(twig_file, {"request": tina4_python.tina4_current_request})
|
|
185
216
|
if content != "":
|
|
186
|
-
return Response(content, Constant.HTTP_OK, Constant.TEXT_HTML, result.headers)
|
|
217
|
+
return Response.Response(content, Constant.HTTP_OK, Constant.TEXT_HTML, result.headers)
|
|
187
218
|
|
|
188
219
|
if result.http_code == Constant.HTTP_NOT_FOUND:
|
|
189
220
|
content = Template.render_twig_template(
|
|
190
221
|
"errors/404.twig", {"server": {"url": url}})
|
|
191
|
-
return Response(content, Constant.HTTP_NOT_FOUND, Constant.TEXT_HTML)
|
|
222
|
+
return Response.Response(content, Constant.HTTP_NOT_FOUND, Constant.TEXT_HTML)
|
|
192
223
|
|
|
193
224
|
return result
|
|
194
225
|
|
|
@@ -208,7 +239,8 @@ class Router:
|
|
|
208
239
|
def add(method, route, callback):
|
|
209
240
|
Debug("Adding a route: " + route, Constant.TINA4_LOG_DEBUG)
|
|
210
241
|
if not callback in tina4_python.tina4_routes:
|
|
211
|
-
tina4_python.tina4_routes[callback] = {"route": route, "callback": callback, "method": method,
|
|
242
|
+
tina4_python.tina4_routes[callback] = {"route": route, "callback": callback, "method": method,
|
|
243
|
+
"swagger": None, "cached": False}
|
|
212
244
|
else:
|
|
213
245
|
tina4_python.tina4_routes[callback]["route"] = route
|
|
214
246
|
tina4_python.tina4_routes[callback]["callback"] = callback
|
|
@@ -226,6 +258,7 @@ def get(path: str):
|
|
|
226
258
|
:param arguments:
|
|
227
259
|
:return:
|
|
228
260
|
"""
|
|
261
|
+
|
|
229
262
|
def actual_get(callback):
|
|
230
263
|
route_paths = path.split('|')
|
|
231
264
|
for route_path in route_paths:
|
|
@@ -241,6 +274,7 @@ def post(path):
|
|
|
241
274
|
:param path:
|
|
242
275
|
:return:
|
|
243
276
|
"""
|
|
277
|
+
|
|
244
278
|
def actual_post(callback):
|
|
245
279
|
route_paths = path.split('|')
|
|
246
280
|
for route_path in route_paths:
|
|
@@ -256,6 +290,7 @@ def put(path):
|
|
|
256
290
|
:param path:
|
|
257
291
|
:return:
|
|
258
292
|
"""
|
|
293
|
+
|
|
259
294
|
def actual_put(callback):
|
|
260
295
|
route_paths = path.split('|')
|
|
261
296
|
for route_path in route_paths:
|
|
@@ -271,6 +306,7 @@ def patch(path):
|
|
|
271
306
|
:param path:
|
|
272
307
|
:return:
|
|
273
308
|
"""
|
|
309
|
+
|
|
274
310
|
def actual_patch(callback):
|
|
275
311
|
route_paths = path.split('|')
|
|
276
312
|
for route_path in route_paths:
|
|
@@ -286,6 +322,7 @@ def delete(path):
|
|
|
286
322
|
:param path:
|
|
287
323
|
:return:
|
|
288
324
|
"""
|
|
325
|
+
|
|
289
326
|
def actual_delete(callback):
|
|
290
327
|
route_paths = path.split('|')
|
|
291
328
|
for route_path in route_paths:
|
|
@@ -294,6 +331,7 @@ def delete(path):
|
|
|
294
331
|
|
|
295
332
|
return actual_delete
|
|
296
333
|
|
|
334
|
+
|
|
297
335
|
def cached(is_cached, max_age=60):
|
|
298
336
|
"""
|
|
299
337
|
Sets whether the route is cached or not
|
|
@@ -301,10 +339,28 @@ def cached(is_cached, max_age=60):
|
|
|
301
339
|
:param max_age:
|
|
302
340
|
:return:
|
|
303
341
|
"""
|
|
342
|
+
|
|
304
343
|
def actual_cached(callback):
|
|
305
344
|
if callback not in tina4_python.tina4_routes:
|
|
306
345
|
tina4_python.tina4_routes[callback] = {}
|
|
307
346
|
tina4_python.tina4_routes[callback]["cache"] = {"cached": is_cached, "max_age": max_age}
|
|
308
347
|
return callback
|
|
309
348
|
|
|
310
|
-
return actual_cached
|
|
349
|
+
return actual_cached
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def middleware(middleware, specific_methods=[]):
|
|
353
|
+
"""
|
|
354
|
+
Sets middleware for the route and methods that need to be called
|
|
355
|
+
:param middleware:
|
|
356
|
+
:param specific_methods:
|
|
357
|
+
:return:
|
|
358
|
+
"""
|
|
359
|
+
|
|
360
|
+
def actual_middleware(callback):
|
|
361
|
+
if callback not in tina4_python.tina4_routes:
|
|
362
|
+
tina4_python.tina4_routes[callback] = {}
|
|
363
|
+
tina4_python.tina4_routes[callback]["middleware"] = {"class": middleware, "methods": specific_methods}
|
|
364
|
+
return callback
|
|
365
|
+
|
|
366
|
+
return actual_middleware
|
|
@@ -111,7 +111,7 @@ class Webserver:
|
|
|
111
111
|
else:
|
|
112
112
|
body = None
|
|
113
113
|
|
|
114
|
-
request = {"params": params, "body": body, "raw_data": self.request, "headers": self.lowercase_headers, "raw_request": self.request_raw, "raw_content": self.content_raw}
|
|
114
|
+
request = {"params": params, "body": body, "raw_data": self.request, "url": self.path, "headers": self.lowercase_headers, "raw_request": self.request_raw, "raw_content": self.content_raw}
|
|
115
115
|
|
|
116
116
|
tina4_python.tina4_current_request = request
|
|
117
117
|
|
|
@@ -125,7 +125,7 @@ class Webserver:
|
|
|
125
125
|
"Origin, X-Requested-With, Content-Type, Accept, Authorization", headers)
|
|
126
126
|
self.send_header("Access-Control-Allow-Credentials", "True", headers)
|
|
127
127
|
self.send_header("Content-Type", response.content_type, headers)
|
|
128
|
-
self.send_header("Content-Length", str(len(response.content)), headers)
|
|
128
|
+
# self.send_header("Content-Length", str(len(response.content)), headers)
|
|
129
129
|
self.send_header("Connection", "Keep-Alive", headers)
|
|
130
130
|
self.send_header("Keep-Alive", "timeout=5, max=30", headers)
|
|
131
131
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
|
2
|
+
MIIDYDCCAkigAwIBAgIUJjBSwd6Q0OCzupqeXqQ7hO8tFNYwDQYJKoZIhvcNAQEL
|
|
3
|
+
BQAwXDELMAkGA1UEBhMCWkExFTATBgNVBAgMDFdFU1RFUk4gQ0FQRTESMBAGA1UE
|
|
4
|
+
BwwJQ0FQRSBUT1dOMQ4wDAYDVQQKDAVUaW5hNDESMBAGA1UEAwwJbG9jYWxob3N0
|
|
5
|
+
MCAXDTI0MDcyNzA4MjQxNVoYDzIyOTgwNTExMDgyNDE1WjBcMQswCQYDVQQGEwJa
|
|
6
|
+
QTEVMBMGA1UECAwMV0VTVEVSTiBDQVBFMRIwEAYDVQQHDAlDQVBFIFRPV04xDjAM
|
|
7
|
+
BgNVBAoMBVRpbmE0MRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
|
|
8
|
+
AQUAA4IBDwAwggEKAoIBAQDto8HrQp5L2dFwgutTfct8BxRxfQ+9O4kHyWzhzeO4
|
|
9
|
+
WvLeDqyAA46HsPcb8Ku6hW+SWht9REToALr4hKXCFxUo6KP9KBNkrA0fZsjQM5SP
|
|
10
|
+
Cc197WAL3AG3XpzqN13bOiphVeqLSqAPCZEitd6YQ8IdBHgNX/+JrC8t7KFBzyVx
|
|
11
|
+
nCnTfO5ixdaeKQZhFMcIFrxelm1gBZ0ClgmcCdkIveIMNWpo1a61fiU33Bm5717m
|
|
12
|
+
jy4ncgoL8Q6Vy9KtidmdmXIYbkcf6uEYXvGkyjODUzvF3tbzvMIoMJts0XD52ZQh
|
|
13
|
+
vHq9qaQlB4T69IVkdvS8hCYftPcympOjzpMrojzxQhJZAgMBAAGjGDAWMBQGA1Ud
|
|
14
|
+
EQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAuaVKMhmsgPso9Vrm
|
|
15
|
+
4emZscFanrzV7W7pXbFxO1wK/XxWQRrxRS40e5SBeDUYJmoVcC9CojbtYSZ0vav2
|
|
16
|
+
CHENA3LPPLi703Z5fe8TxiU64PssJe6IyZ7FveaTiCQ4TdsPPEsq+hoMpXykj/GL
|
|
17
|
+
7holeO6xY2KvrKgEBXOPuniTvPQLJKalfmiHNBg2pEkJeNly9mK/jQQ1kYFz1FaK
|
|
18
|
+
DgNt6DWlTitsx4s85ryKcpYR3jljacPpuPOWiAlNw47jOefTFhBFR9oXxxvAEPRC
|
|
19
|
+
xnc1hXhxsnOzcFuNDAxSa3uW2bZpcEeoJxscjNUqeu/Lk1tFQWLsliJuqKxMBRcD
|
|
20
|
+
qqZ75Q==
|
|
21
|
+
-----END CERTIFICATE-----
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
|
2
|
+
Proc-Type: 4,ENCRYPTED
|
|
3
|
+
DEK-Info: AES-256-CBC,C9FC3C8CF276DF95D130298E7F6844AB
|
|
4
|
+
|
|
5
|
+
9aa638h4jOTIypRhQLDEzB7MTAs9AupUFYttF8T+eJ32EeNB+0FQNfD8r6CEZeMf
|
|
6
|
+
vp64suhWxlJhHRnpKogg9K8ioig36Fy+0Ung/va0ysozb1LZ2ct2QHcCIsyJypzC
|
|
7
|
+
wPe+iEx8GR0zCL88fU//xIlb/SAxAEnFYFW44IpHQMjzZ2PJ7cJswlA80l4Ualc4
|
|
8
|
+
RwTz0ZmEGWUE6CxoSCck26xDn57yH+pm76D98AS78TwgEBKbK8VtC12+Xp4LvP/H
|
|
9
|
+
lgDrcTekTWd/zUfGaL1q3kMIQ1Az4xIDQuxjVcsKsRyTvtHjS1G7AQUPBXc2N6Tm
|
|
10
|
+
zMHUkZR/niqvNZjyyNlaTdQoAdHAswxQKS+NQHegbP3+l8fGFlSG6AVYGl+ALInt
|
|
11
|
+
8DeoYuaZhgRLTEGA+Dkw5TNFgdTqnaZgrXE1AflffYGBX4Q6ddW+rUfJ6s/RHmcj
|
|
12
|
+
eM9rCaFijSTJNupGe3uQJrmtgsAmBhotzYnswkQJwTk+HP0lvf+A7t72OfmBJsqx
|
|
13
|
+
MYdIi4hPKKai3s/Gbu9e/vS7/vYVPNaJAGJ5NJwqa518nxdb2Es/9Lnx7ts9J7lw
|
|
14
|
+
c15xjASh7gQsJojdEbOaaIUCqqi4BQX/koa4V3zPJ5KtZ3qqYzlw1NEOX63IAKLh
|
|
15
|
+
GN3pDiIuYc1by/6HSFDaY1gSx+ZRyn5Ie+4DuFS8W/PVdkE+kPKHCSdQifJ2E9ym
|
|
16
|
+
c2lYA0leKfH5z4SBv9TphwwTtsS8anHTvWyPy1jLHyH81FSr2u13bu0GiY+Q9Q9V
|
|
17
|
+
YJqXM/5M8w8+Nu9pcXDZbrcw2jb3gG1EYHVdXXMM3j/V/fhFmvixng5DDr4ghPNn
|
|
18
|
+
jAH9fX5UD289XzmYzXOhSRW7ovxv3jlFbKxT/Yj2pZwA8FWHG2IVsdHFK/VrjxG8
|
|
19
|
+
QRexMEYjE7gSzgJymc7ML1WgnY1ZFphD/6P5DBt0wWL+23EJ++OCHyVFzS5f4f3Z
|
|
20
|
+
YrJ51iIvyJB33Dq5xdT+peq+rBO9skwlfrn3M/WrD6fmE7sB71CDdNvL0c9yfjJO
|
|
21
|
+
MqxYcRzyClYl5bEB10zEShDMWS5uvJJl93Av+k8ZKm0kE2NXyL+HlaADp1zXzJ8E
|
|
22
|
+
G54LZLOlsJHebATRFLpxJ6lT6N7AUHCH0f0SnyyH+epxbbUlH1uB76beSeLypCw2
|
|
23
|
+
DyQg/aOP3FfuQG8mKmIECZ8qqXtDv3tM9hu/rvzEUkYOUfXi3xpVaRxA2nre9SAB
|
|
24
|
+
7ZVDQv6QWDBHr+6F30znzZEhDqgas+s6MqG5zuEWSmWVja5Fv9JV/mPD8ZUZX5++
|
|
25
|
+
ZYguplD7Ht9sqw3fyrMk7WbSsFEYr2jrHc3lmVAK8g+wmNjJwKCBiR3cmoPFReEF
|
|
26
|
+
B6PZ+cTka1sOrDDz19bsy31yLac2u6o4pg+1yv1iGP4y2VsOyLE3vz3Pvl3i0PP/
|
|
27
|
+
C18loanx66f2sIps7HjcFk8eElhs/tAJ+tANOluhlzSlZhrmRuwXCFd7k+wOB8iI
|
|
28
|
+
+pnud/XlZU3invJYi9IHfwNw1dE9dPjchHIXb75py+vpLhkDzWSMEpGlTx8MpTwe
|
|
29
|
+
O4mb4azV8J0vFCq+hvvpHIG7on+NlFYWqjSdBgImo74eSDFTYDtYji5/D3MJQaxw
|
|
30
|
+
-----END RSA PRIVATE KEY-----
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
|
2
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7aPB60KeS9nRcILrU33L
|
|
3
|
+
fAcUcX0PvTuJB8ls4c3juFry3g6sgAOOh7D3G/CruoVvklobfURE6AC6+ISlwhcV
|
|
4
|
+
KOij/SgTZKwNH2bI0DOUjwnNfe1gC9wBt16c6jdd2zoqYVXqi0qgDwmRIrXemEPC
|
|
5
|
+
HQR4DV//iawvLeyhQc8lcZwp03zuYsXWnikGYRTHCBa8XpZtYAWdApYJnAnZCL3i
|
|
6
|
+
DDVqaNWutX4lN9wZue9e5o8uJ3IKC/EOlcvSrYnZnZlyGG5HH+rhGF7xpMozg1M7
|
|
7
|
+
xd7W87zCKDCbbNFw+dmUIbx6vamkJQeE+vSFZHb0vIQmH7T3MpqTo86TK6I88UIS
|
|
8
|
+
WQIDAQAB
|
|
9
|
+
-----END PUBLIC KEY-----
|
|
@@ -1,24 +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
|
-
class Request:
|
|
8
|
-
"""
|
|
9
|
-
Request object to store parameters, headers, etc.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
def __init__(self, body=None, params=None, headers=None, request=None, raw_data=None, raw_request=None, raw_content=None):
|
|
13
|
-
self.body = body if body is not None else None
|
|
14
|
-
self.params = params if params is not None else {}
|
|
15
|
-
self.headers = headers if headers is not None else {}
|
|
16
|
-
self.request = request if request is not None else {}
|
|
17
|
-
self.cookies = {}
|
|
18
|
-
self.cookies = {}
|
|
19
|
-
self.session = None
|
|
20
|
-
self.files = {}
|
|
21
|
-
self.raw_data = raw_data if raw_data is not None else None
|
|
22
|
-
self.raw_request = raw_request if raw_request is not None else None
|
|
23
|
-
self.raw_content = raw_content if raw_content is not None else None
|
|
24
|
-
|
|
@@ -1,77 +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 json
|
|
8
|
-
import inspect
|
|
9
|
-
from types import ModuleType
|
|
10
|
-
from tina4_python import Constant
|
|
11
|
-
from tina4_python import DatabaseResult
|
|
12
|
-
from tina4_python.Debug import Debug
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class Response:
|
|
16
|
-
"""
|
|
17
|
-
response object for router
|
|
18
|
-
:param content
|
|
19
|
-
:param http_code
|
|
20
|
-
:param content_type
|
|
21
|
-
:param headers
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
def __init__(self, content, http_code=Constant.HTTP_OK, content_type=Constant.TEXT_HTML, headers=None):
|
|
25
|
-
self.headers = headers if headers is not None else {}
|
|
26
|
-
|
|
27
|
-
if content is None:
|
|
28
|
-
content = ""
|
|
29
|
-
# try to make content into a dictionary
|
|
30
|
-
elif not isinstance(content, bool) and not isinstance(content, object) and not isinstance(content, bytes) and not isinstance(content, str) and not isinstance(content, list) and inspect.isclass(type(content)):
|
|
31
|
-
content = dict(content)
|
|
32
|
-
|
|
33
|
-
# check if database result
|
|
34
|
-
if type(content) is DatabaseResult.DatabaseResult:
|
|
35
|
-
content_type = Constant.APPLICATION_JSON
|
|
36
|
-
content = content.to_json()
|
|
37
|
-
|
|
38
|
-
# convert the dictionary or list into JSON
|
|
39
|
-
if not isinstance(content, bool) and type(content) is dict or type(content) is list:
|
|
40
|
-
content = json.dumps(content)
|
|
41
|
-
content_type = Constant.APPLICATION_JSON
|
|
42
|
-
|
|
43
|
-
if isinstance(content, bool):
|
|
44
|
-
if content:
|
|
45
|
-
content = "True"
|
|
46
|
-
else:
|
|
47
|
-
content = "False"
|
|
48
|
-
|
|
49
|
-
if isinstance(content, ModuleType):
|
|
50
|
-
content = json.dumps({"error": "Cannot decode object of type "+str(type(content))})
|
|
51
|
-
content_type = Constant.APPLICATION_JSON
|
|
52
|
-
|
|
53
|
-
self.content = content
|
|
54
|
-
self.http_code = http_code
|
|
55
|
-
self.content_type = content_type
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@staticmethod
|
|
59
|
-
def redirect(redirect_url):
|
|
60
|
-
"""
|
|
61
|
-
Redirects a request to redirect_url
|
|
62
|
-
:param redirect_url:
|
|
63
|
-
:return:
|
|
64
|
-
"""
|
|
65
|
-
headers = {}
|
|
66
|
-
http_code = Constant.HTTP_REDIRECT
|
|
67
|
-
headers["Location"] = redirect_url
|
|
68
|
-
return Response("", http_code=http_code, headers=headers)
|
|
69
|
-
|
|
70
|
-
def add_header(self, key, value):
|
|
71
|
-
"""
|
|
72
|
-
Adds a header for the response
|
|
73
|
-
:param key:
|
|
74
|
-
:param value:
|
|
75
|
-
:return:
|
|
76
|
-
"""
|
|
77
|
-
self.headers[key] = value
|
|
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.21 → tina4_python-0.2.24}/tina4_python/public/swagger/oauth2-redirect.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/translations/en/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/translations/en/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/translations/fr/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-0.2.21 → tina4_python-0.2.24}/tina4_python/translations/fr/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|