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.
- tina4_python/Auth.py +222 -0
- tina4_python/Constant.py +43 -0
- tina4_python/Database.py +591 -0
- tina4_python/DatabaseResult.py +107 -0
- tina4_python/DatabaseTypes.py +15 -0
- tina4_python/Debug.py +126 -0
- tina4_python/Env.py +37 -0
- tina4_python/Localization.py +42 -0
- tina4_python/Messages.py +30 -0
- tina4_python/MiddleWare.py +90 -0
- tina4_python/Migration.py +107 -0
- tina4_python/ORM.py +639 -0
- tina4_python/Queue.py +615 -0
- tina4_python/Request.py +19 -0
- tina4_python/Response.py +121 -0
- tina4_python/Router.py +423 -0
- tina4_python/Session.py +342 -0
- tina4_python/ShellColors.py +20 -0
- tina4_python/Swagger.py +228 -0
- tina4_python/Template.py +107 -0
- tina4_python/Webserver.py +429 -0
- tina4_python/Websocket.py +49 -0
- tina4_python/__init__.py +392 -0
- tina4_python/messages.pot +83 -0
- tina4_python/public/css/readme.md +0 -0
- tina4_python/public/favicon.ico +0 -0
- tina4_python/public/images/403.png +0 -0
- tina4_python/public/images/404.png +0 -0
- tina4_python/public/images/500.png +0 -0
- tina4_python/public/images/logo.png +0 -0
- tina4_python/public/images/readme.md +0 -0
- tina4_python/public/js/readme.md +0 -0
- tina4_python/public/js/reconnecting-websocket.js +365 -0
- tina4_python/public/js/tina4helper.js +397 -0
- tina4_python/public/swagger/index.html +90 -0
- tina4_python/public/swagger/oauth2-redirect.html +63 -0
- tina4_python/templates/errors/403.twig +10 -0
- tina4_python/templates/errors/404.twig +10 -0
- tina4_python/templates/errors/500.twig +11 -0
- tina4_python/templates/readme.md +1 -0
- tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
- tina4_python/translations/en/LC_MESSAGES/messages.po +80 -0
- tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
- tina4_python/translations/fr/LC_MESSAGES/messages.po +84 -0
- tina4_python-0.2.122.dist-info/METADATA +465 -0
- tina4_python-0.2.122.dist-info/RECORD +47 -0
- tina4_python-0.2.122.dist-info/WHEEL +4 -0
tina4_python/__init__.py
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
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: E403,F401,E402
|
|
7
|
+
import asyncio
|
|
8
|
+
import gettext
|
|
9
|
+
import logging
|
|
10
|
+
import os
|
|
11
|
+
import shutil
|
|
12
|
+
import importlib
|
|
13
|
+
import sys
|
|
14
|
+
import threading
|
|
15
|
+
import traceback
|
|
16
|
+
import sass
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
from watchdog.observers import Observer
|
|
19
|
+
from watchdog.events import PatternMatchingEventHandler, FileSystemEvent
|
|
20
|
+
from tina4_python.Router import get
|
|
21
|
+
from tina4_python import Messages, Constant
|
|
22
|
+
from tina4_python.Swagger import Swagger
|
|
23
|
+
from tina4_python.Env import load_env
|
|
24
|
+
from tina4_python.Webserver import Webserver
|
|
25
|
+
from tina4_python.Router import Router
|
|
26
|
+
from tina4_python.Localization import localize
|
|
27
|
+
from tina4_python.Auth import Auth
|
|
28
|
+
from tina4_python.Debug import Debug
|
|
29
|
+
from tina4_python.ShellColors import ShellColors
|
|
30
|
+
from tina4_python.Session import Session
|
|
31
|
+
|
|
32
|
+
_ = gettext.gettext
|
|
33
|
+
|
|
34
|
+
# Server startup messages
|
|
35
|
+
MSG_ASSUMING_ROOT_PATH = _('Assuming root path: {root_path}, library path: {library_path}')
|
|
36
|
+
MSG_LOAD_ALL_THINGS = _('Load all things')
|
|
37
|
+
MSG_SERVER_STARTED = _('Server started http://{host_name}:{port}')
|
|
38
|
+
MSG_SERVER_STOPPED = _('Server stopped.')
|
|
39
|
+
MSG_STARTING_WEBSERVER = _('Starting webserver on {port}')
|
|
40
|
+
MSG_ENTRY_POINT_NAME = _('Entry point name ... {name}')
|
|
41
|
+
|
|
42
|
+
if os.getenv('environment') is not None:
|
|
43
|
+
environment = ".env." + os.getenv('environment')
|
|
44
|
+
else:
|
|
45
|
+
environment = ".env"
|
|
46
|
+
|
|
47
|
+
load_env(environment)
|
|
48
|
+
|
|
49
|
+
debug_level = os.getenv("TINA4_DEBUG_LEVEL", Constant.TINA4_LOG_ALL)
|
|
50
|
+
print(ShellColors.bright_yellow + "Setting debug mode", debug_level, ShellColors.end)
|
|
51
|
+
|
|
52
|
+
if importlib.util.find_spec("jurigged"):
|
|
53
|
+
import jurigged
|
|
54
|
+
|
|
55
|
+
# Define the variable to be used for global routes
|
|
56
|
+
library_path = os.path.dirname(os.path.realpath(__file__))
|
|
57
|
+
root_path = os.path.realpath(os.getcwd())
|
|
58
|
+
sys.path.append(root_path)
|
|
59
|
+
|
|
60
|
+
if not os.path.exists(root_path + os.sep + "logs"):
|
|
61
|
+
os.makedirs(root_path + os.sep + "logs")
|
|
62
|
+
|
|
63
|
+
localize()
|
|
64
|
+
|
|
65
|
+
Debug(Messages.MSG_ASSUMING_ROOT_PATH.format(root_path=root_path, library_path=library_path),
|
|
66
|
+
Constant.TINA4_LOG_INFO)
|
|
67
|
+
|
|
68
|
+
tina4_routes = {}
|
|
69
|
+
tina4_current_request = {}
|
|
70
|
+
tina4_api_key = None
|
|
71
|
+
tina4_auth = Auth(root_path)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# Set up the global exception handler
|
|
75
|
+
def global_exception_handler(exception):
|
|
76
|
+
debug_level = Constant.TINA4_LOG_DEBUG
|
|
77
|
+
error = str(exception)
|
|
78
|
+
tb_str = ''.join(traceback.format_exception(None, exception, exception.__traceback__))
|
|
79
|
+
error_string = "Exception Error: " + error + "\n" + tb_str + "\nYou are seeing this error because Tina4 is in debug mode"
|
|
80
|
+
Debug.error(error_string)
|
|
81
|
+
if (os.getenv("TINA4_DEBUG_LEVEL", [Constant.TINA4_LOG_ALL]) == "[TINA4_LOG_ALL]"
|
|
82
|
+
or debug_level in os.getenv("TINA4_DEBUG_LEVEL", [Constant.TINA4_LOG_ALL])):
|
|
83
|
+
pass
|
|
84
|
+
else:
|
|
85
|
+
error_string = "An exception happened"
|
|
86
|
+
return error_string
|
|
87
|
+
|
|
88
|
+
def start_in_thread(target, exception_hook=None):
|
|
89
|
+
"""
|
|
90
|
+
Starts a method in a thread
|
|
91
|
+
:param exception_hook:
|
|
92
|
+
:param target:
|
|
93
|
+
:return:
|
|
94
|
+
"""
|
|
95
|
+
if exception_hook is not None:
|
|
96
|
+
threading.excepthook = exception_hook
|
|
97
|
+
thread = threading.Thread(target=target)
|
|
98
|
+
thread.start()
|
|
99
|
+
|
|
100
|
+
token = tina4_auth.get_token({"name": "Tina4"})
|
|
101
|
+
Debug("TEST TOKEN", token, Constant.TINA4_LOG_DEBUG)
|
|
102
|
+
Debug("VALID TOKEN", tina4_auth.valid(token + "a"), Constant.TINA4_LOG_DEBUG)
|
|
103
|
+
Debug("VALID TOKEN", tina4_auth.valid(token), Constant.TINA4_LOG_DEBUG)
|
|
104
|
+
Debug("PAYLOAD", tina4_auth.get_payload(token), Constant.TINA4_LOG_DEBUG)
|
|
105
|
+
|
|
106
|
+
if "API_KEY" in os.environ:
|
|
107
|
+
tina4_api_key = os.environ["API_KEY"]
|
|
108
|
+
|
|
109
|
+
# Hack for local development
|
|
110
|
+
if root_path.count("tina4_python") > 0:
|
|
111
|
+
root_path = root_path.split("tina4_python")[0][:-1]
|
|
112
|
+
|
|
113
|
+
# Make the beginning files for the tina4stack
|
|
114
|
+
if not os.path.exists(root_path + os.sep + "src"):
|
|
115
|
+
os.makedirs(root_path + os.sep + "src" + os.sep + "routes")
|
|
116
|
+
os.makedirs(root_path + os.sep + "src" + os.sep + "scss")
|
|
117
|
+
os.makedirs(root_path + os.sep + "src" + os.sep + "orm")
|
|
118
|
+
os.makedirs(root_path + os.sep + "src" + os.sep + "app")
|
|
119
|
+
|
|
120
|
+
with open(root_path + os.sep + "src" + os.sep + "__init__.py", 'w') as init_file:
|
|
121
|
+
init_file.write('# Start your project here')
|
|
122
|
+
init_file.write('\n')
|
|
123
|
+
if not os.path.isfile(root_path + os.sep + "app.py") and not os.path.isdir(root_path + os.sep + "tina4_python"):
|
|
124
|
+
with open(root_path + os.sep + "app.py", 'w') as app_file:
|
|
125
|
+
app_file.write('# Starting point for tina4_python, you shouldn''t need to change anything here')
|
|
126
|
+
app_file.write('\n')
|
|
127
|
+
app_file.write('from tina4_python import *')
|
|
128
|
+
app_file.write('\n')
|
|
129
|
+
|
|
130
|
+
if not os.path.exists(root_path + os.sep + "src" + os.sep + "app"):
|
|
131
|
+
os.makedirs(root_path + os.sep + "src" + os.sep + "app")
|
|
132
|
+
|
|
133
|
+
# copy over templates if needed - required for errors
|
|
134
|
+
if not os.path.exists(root_path + os.sep + "src" + os.sep + "templates"):
|
|
135
|
+
source_dir = library_path + os.sep + "templates"
|
|
136
|
+
destination_dir = root_path + os.sep + "src" + os.sep + "templates"
|
|
137
|
+
shutil.copytree(source_dir, destination_dir)
|
|
138
|
+
|
|
139
|
+
# copy over public if needed - required for static files like images and logos
|
|
140
|
+
if not os.path.exists(root_path + os.sep + "src" + os.sep + "public"):
|
|
141
|
+
source_dir = library_path + os.sep + "public"
|
|
142
|
+
destination_dir = root_path + os.sep + "src" + os.sep + "public"
|
|
143
|
+
shutil.copytree(source_dir, destination_dir)
|
|
144
|
+
|
|
145
|
+
# please keep in place otherwise autoloading of files does not work nicely, if you want this to work
|
|
146
|
+
# add __init__.py files in your folders
|
|
147
|
+
# ignore F403
|
|
148
|
+
if os.path.exists(root_path + os.sep + "src"):
|
|
149
|
+
try:
|
|
150
|
+
exec("from src import *")
|
|
151
|
+
except ImportError as e:
|
|
152
|
+
Debug("Cannot import src folder", str(e), Constant.TINA4_LOG_ERROR)
|
|
153
|
+
else:
|
|
154
|
+
Debug("Missing src folder", Constant.TINA4_LOG_WARNING)
|
|
155
|
+
|
|
156
|
+
if os.path.exists(root_path + os.sep + "src" + os.sep + "routes"):
|
|
157
|
+
try:
|
|
158
|
+
exec("from src.routes import *")
|
|
159
|
+
except ImportError as e:
|
|
160
|
+
Debug("Cannot import src.routes folder", str(e), Constant.TINA4_LOG_ERROR)
|
|
161
|
+
else:
|
|
162
|
+
Debug("Missing src/routes folder", Constant.TINA4_LOG_WARNING)
|
|
163
|
+
|
|
164
|
+
if os.path.exists(root_path + os.sep + "src" + os.sep + "app"):
|
|
165
|
+
try:
|
|
166
|
+
exec("from src.app import *")
|
|
167
|
+
except ImportError as e:
|
|
168
|
+
Debug("Cannot import src.app folder", str(e), Constant.TINA4_LOG_ERROR)
|
|
169
|
+
else:
|
|
170
|
+
Debug("Missing src/app folder", Constant.TINA4_LOG_WARNING)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
# compile sass
|
|
174
|
+
def compile_scss():
|
|
175
|
+
try:
|
|
176
|
+
if os.path.exists(root_path + os.sep + "src" + os.sep + "scss"):
|
|
177
|
+
Debug("Compiling scss", Constant.TINA4_LOG_DEBUG)
|
|
178
|
+
sass.compile(dirname=(root_path + os.sep + 'src' + os.sep + 'scss',
|
|
179
|
+
root_path + os.sep + 'src' + os.sep + 'public' + os.sep + 'css'),
|
|
180
|
+
output_style='compressed')
|
|
181
|
+
except sass.CompileError as E:
|
|
182
|
+
Debug('Error compiling SASS ', E, Constant.TINA4_LOG_ERROR)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
compile_scss()
|
|
186
|
+
|
|
187
|
+
class SassCompiler(PatternMatchingEventHandler):
|
|
188
|
+
def on_modified(self, event: FileSystemEvent) -> None:
|
|
189
|
+
if not event.is_directory:
|
|
190
|
+
compile_scss()
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
if os.path.exists(root_path + os.sep + "src" + os.sep + "scss"):
|
|
194
|
+
observer = Observer()
|
|
195
|
+
event_handler = SassCompiler(patterns=["*.sass", "*.scss"])
|
|
196
|
+
observer.schedule(event_handler, path=root_path + os.sep + "src" + os.sep + "scss", recursive=True)
|
|
197
|
+
observer.start()
|
|
198
|
+
else:
|
|
199
|
+
Debug("Missing scss folder", Constant.TINA4_LOG_WARNING)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
# end compile sass
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def file_get_contents(file_path):
|
|
206
|
+
return Path(file_path).read_text()
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
# Add swagger routes
|
|
210
|
+
@get(os.getenv("SWAGGER_ROUTE", "/swagger") + "/swagger.json")
|
|
211
|
+
async def get_swagger_json(request, response):
|
|
212
|
+
json = Swagger.get_json(request)
|
|
213
|
+
return response(json)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@get(os.getenv("SWAGGER_ROUTE", "/swagger"))
|
|
217
|
+
async def get_swagger(request, response):
|
|
218
|
+
html = file_get_contents(
|
|
219
|
+
root_path + os.sep + "src" + os.sep + "public" + os.sep + "swagger" + os.sep + "index.html")
|
|
220
|
+
|
|
221
|
+
html = html.replace("{SWAGGER_ROUTE}", os.getenv("SWAGGER_ROUTE", "/swagger"))
|
|
222
|
+
return response(html)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
async def app(scope, receive, send):
|
|
226
|
+
"""
|
|
227
|
+
Runs normal hypercorn, uvicorn, granian
|
|
228
|
+
:param scope:
|
|
229
|
+
:param receive:
|
|
230
|
+
:param send:
|
|
231
|
+
:return:
|
|
232
|
+
"""
|
|
233
|
+
body = b""
|
|
234
|
+
while True and scope['type'] == 'http' or scope['type'] == 'websocket':
|
|
235
|
+
if scope['type'] != 'websocket':
|
|
236
|
+
message = await receive()
|
|
237
|
+
else:
|
|
238
|
+
message = {'type': 'websocket'}
|
|
239
|
+
|
|
240
|
+
if "body" in message:
|
|
241
|
+
body += message["body"]
|
|
242
|
+
if message['type'] == 'lifespan.startup':
|
|
243
|
+
await send({'type': 'lifespan.startup.complete'})
|
|
244
|
+
return
|
|
245
|
+
elif message['type'] == 'lifespan.shutdown':
|
|
246
|
+
await send({'type': 'lifespan.shutdown.complete'})
|
|
247
|
+
return
|
|
248
|
+
elif message["type"] == "http.disconnect" or message["type"] == "websocket.disconnect":
|
|
249
|
+
return
|
|
250
|
+
elif not message.get("more_body"):
|
|
251
|
+
webserver = Webserver(scope["server"][0], scope["server"][1])
|
|
252
|
+
parsed_headers = {}
|
|
253
|
+
parsed_headers_lowercase = {}
|
|
254
|
+
for header in scope["headers"]:
|
|
255
|
+
parsed_headers[header[0].decode()] = header[1].decode()
|
|
256
|
+
parsed_headers_lowercase[header[0].decode().lower()] = header[1].decode()
|
|
257
|
+
|
|
258
|
+
if "content-length" not in parsed_headers_lowercase and "accept" in parsed_headers_lowercase:
|
|
259
|
+
parsed_headers_lowercase["content-type"] = parsed_headers_lowercase["accept"].split(",")[0]
|
|
260
|
+
parsed_headers["Content-Type"] = parsed_headers_lowercase["content-type"]
|
|
261
|
+
|
|
262
|
+
if "content-length" not in parsed_headers_lowercase:
|
|
263
|
+
parsed_headers_lowercase["content-length"] = 0
|
|
264
|
+
parsed_headers_lowercase["Content-Length"] = parsed_headers_lowercase["content-length"]
|
|
265
|
+
|
|
266
|
+
webserver.headers = parsed_headers
|
|
267
|
+
webserver.lowercase_headers = parsed_headers_lowercase
|
|
268
|
+
|
|
269
|
+
webserver.path = scope["path"] + "?" + scope["query_string"].decode()
|
|
270
|
+
|
|
271
|
+
if "method" in scope:
|
|
272
|
+
webserver.method = scope["method"]
|
|
273
|
+
else:
|
|
274
|
+
webserver.method = "GET"
|
|
275
|
+
|
|
276
|
+
if message["type"] == "http.request":
|
|
277
|
+
webserver.content_raw = body
|
|
278
|
+
else:
|
|
279
|
+
webserver.content_raw = b""
|
|
280
|
+
webserver.content_length = parsed_headers_lowercase["content-length"]
|
|
281
|
+
webserver.router_handler = Router()
|
|
282
|
+
|
|
283
|
+
cookie_list = {}
|
|
284
|
+
if "cookie" in webserver.lowercase_headers:
|
|
285
|
+
cookie_list_temp = webserver.lowercase_headers["cookie"].split(";")
|
|
286
|
+
for cookie_value in cookie_list_temp:
|
|
287
|
+
cookie = cookie_value.split("=", 1)
|
|
288
|
+
cookie_list[cookie[0].strip()] = cookie[1].strip()
|
|
289
|
+
|
|
290
|
+
webserver.cookies = cookie_list
|
|
291
|
+
|
|
292
|
+
# initialize the session
|
|
293
|
+
webserver.session = Session(os.getenv("TINA4_SESSION", "PY_SESS"),
|
|
294
|
+
os.getenv("TINA4_SESSION_FOLDER", root_path + os.sep + "sessions"),
|
|
295
|
+
os.getenv("TINA4_SESSION_HANDLER", "SessionFileHandler")
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
if os.getenv("TINA4_SESSION", "PY_SESS") in webserver.cookies:
|
|
299
|
+
webserver.session.load(webserver.cookies[os.getenv("TINA4_SESSION", "PY_SESS")])
|
|
300
|
+
else:
|
|
301
|
+
webserver.cookies[os.getenv("TINA4_SESSION", "PY_SESS")] = webserver.session.start()
|
|
302
|
+
|
|
303
|
+
tina4_response, tina4_headers = await webserver.get_response(webserver.method, (scope, receive, send), True)
|
|
304
|
+
|
|
305
|
+
if message["type"] != "websocket":
|
|
306
|
+
response_headers = []
|
|
307
|
+
for header in tina4_headers:
|
|
308
|
+
header = header.split(":")
|
|
309
|
+
response_headers.append([header[0].strip().encode(), header[1].strip().encode()])
|
|
310
|
+
|
|
311
|
+
await send({
|
|
312
|
+
'type': 'http.response.start',
|
|
313
|
+
'status': tina4_response.http_code,
|
|
314
|
+
'headers': response_headers,
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
if isinstance(tina4_response.content, str):
|
|
318
|
+
await send({
|
|
319
|
+
'type': 'http.response.body',
|
|
320
|
+
'body': tina4_response.content.encode(),
|
|
321
|
+
})
|
|
322
|
+
else:
|
|
323
|
+
await send({
|
|
324
|
+
'type': 'http.response.body',
|
|
325
|
+
'body': tina4_response.content,
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def run_web_server(in_hostname="localhost", in_port=7145):
|
|
330
|
+
Debug(Messages.MSG_STARTING_WEBSERVER.format(port=in_port), Constant.TINA4_LOG_INFO)
|
|
331
|
+
webserver(in_hostname, in_port)
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def webserver(host_name, port):
|
|
335
|
+
"""
|
|
336
|
+
Runs the correct webserver
|
|
337
|
+
:param host_name:
|
|
338
|
+
:param port:
|
|
339
|
+
:return:
|
|
340
|
+
"""
|
|
341
|
+
if os.getenv('TINA4_DEFAULT_WEBSERVER', 'FALSE').upper() == 'TRUE':
|
|
342
|
+
Debug("Using default webserver", Constant.TINA4_LOG_INFO)
|
|
343
|
+
# runs the built-in webserver (websockets) don't work on windows
|
|
344
|
+
web_server = Webserver(host_name, int(port)) # HTTPServer((host_name, int(port)), Webserver)
|
|
345
|
+
web_server.router_handler = Router()
|
|
346
|
+
# Fix the display to make it clickable
|
|
347
|
+
if host_name == "0.0.0.0":
|
|
348
|
+
host_name = "localhost"
|
|
349
|
+
Debug(Messages.MSG_SERVER_STARTED.format(host_name=host_name, port=port), Constant.TINA4_LOG_INFO)
|
|
350
|
+
try:
|
|
351
|
+
asyncio.run(web_server.serve_forever())
|
|
352
|
+
except KeyboardInterrupt:
|
|
353
|
+
pass
|
|
354
|
+
web_server.server_close()
|
|
355
|
+
else:
|
|
356
|
+
# Runs a hyper corn server
|
|
357
|
+
Debug("Using hypercorn webserver", Constant.TINA4_LOG_INFO)
|
|
358
|
+
try:
|
|
359
|
+
from hypercorn.config import Config
|
|
360
|
+
from hypercorn.asyncio import serve
|
|
361
|
+
config = Config()
|
|
362
|
+
config.bind = [host_name + ":" + str(port)]
|
|
363
|
+
asyncio.run(serve(app, config))
|
|
364
|
+
except Exception as e:
|
|
365
|
+
Debug("Not running Hypercorn webserver", str(e), Constant.TINA4_LOG_WARNING)
|
|
366
|
+
|
|
367
|
+
Debug(Messages.MSG_SERVER_STOPPED, Constant.TINA4_LOG_INFO)
|
|
368
|
+
|
|
369
|
+
if importlib.util.find_spec("jurigged"):
|
|
370
|
+
Debug("Jurigged enabled", Constant.TINA4_LOG_INFO)
|
|
371
|
+
jurigged.watch(["./src/app", "./src/orm", "./src/routes", "./src/templates"])
|
|
372
|
+
|
|
373
|
+
# Start up a webserver based on params passed on the command line
|
|
374
|
+
HOSTNAME = "localhost"
|
|
375
|
+
PORT = 7145
|
|
376
|
+
if len(sys.argv) > 1:
|
|
377
|
+
PORT = sys.argv[1]
|
|
378
|
+
if ":" in PORT:
|
|
379
|
+
SERVER_CONFIG = PORT.split(":")
|
|
380
|
+
HOSTNAME = SERVER_CONFIG[0]
|
|
381
|
+
PORT = SERVER_CONFIG[1]
|
|
382
|
+
|
|
383
|
+
if PORT != "stop" and PORT != "manual":
|
|
384
|
+
try:
|
|
385
|
+
PORT = int(PORT)
|
|
386
|
+
run_web_server(HOSTNAME, PORT)
|
|
387
|
+
except Exception as e:
|
|
388
|
+
Debug("Not running webserver", str(e), Constant.TINA4_LOG_WARNING)
|
|
389
|
+
else:
|
|
390
|
+
Debug("Webserver is set to manual start, please call " + ShellColors.bright_red +
|
|
391
|
+
"run_web_server(<HOSTNAME>, <PORT>)" + ShellColors.end + " in your code",
|
|
392
|
+
Constant.TINA4_LOG_WARNING)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Translations template for PROJECT.
|
|
2
|
+
# Copyright (C) 2024 ORGANIZATION
|
|
3
|
+
# This file is distributed under the same license as the PROJECT project.
|
|
4
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, 2024.
|
|
5
|
+
#
|
|
6
|
+
#, fuzzy
|
|
7
|
+
msgid ""
|
|
8
|
+
msgstr ""
|
|
9
|
+
"Project-Id-Version: PROJECT VERSION\n"
|
|
10
|
+
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
|
11
|
+
"POT-Creation-Date: 2024-02-14 18:17+0200\n"
|
|
12
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
14
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
15
|
+
"MIME-Version: 1.0\n"
|
|
16
|
+
"Content-Type: text/plain; charset=utf-8\n"
|
|
17
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
18
|
+
"Generated-By: Babel 2.13.1\n"
|
|
19
|
+
|
|
20
|
+
#: Messages.py:5
|
|
21
|
+
msgid "Debug: {message}"
|
|
22
|
+
msgstr ""
|
|
23
|
+
|
|
24
|
+
#: Messages.py:6
|
|
25
|
+
msgid "Warning: {message}"
|
|
26
|
+
msgstr ""
|
|
27
|
+
|
|
28
|
+
#: Messages.py:7
|
|
29
|
+
msgid "Error: {message}"
|
|
30
|
+
msgstr ""
|
|
31
|
+
|
|
32
|
+
#: Messages.py:8
|
|
33
|
+
msgid "Info: {message}"
|
|
34
|
+
msgstr ""
|
|
35
|
+
|
|
36
|
+
#: Messages.py:12
|
|
37
|
+
msgid "Matching: {matching}"
|
|
38
|
+
msgstr ""
|
|
39
|
+
|
|
40
|
+
#: Messages.py:13
|
|
41
|
+
msgid "Variables: {variables}"
|
|
42
|
+
msgstr ""
|
|
43
|
+
|
|
44
|
+
#: Messages.py:14
|
|
45
|
+
msgid "Root Path {root_path} {url}"
|
|
46
|
+
msgstr ""
|
|
47
|
+
|
|
48
|
+
#: Messages.py:15
|
|
49
|
+
msgid "Attempting to serve static file: {static_file}"
|
|
50
|
+
msgstr ""
|
|
51
|
+
|
|
52
|
+
#: Messages.py:16
|
|
53
|
+
msgid "Attempting to serve CSS file: {css_file}"
|
|
54
|
+
msgstr ""
|
|
55
|
+
|
|
56
|
+
#: Messages.py:17
|
|
57
|
+
msgid "Attempting to serve image file: {image_file}"
|
|
58
|
+
msgstr ""
|
|
59
|
+
|
|
60
|
+
#: __init__.py:15
|
|
61
|
+
msgid "Assuming root path: {root_path}, library path: {library_path}"
|
|
62
|
+
msgstr ""
|
|
63
|
+
|
|
64
|
+
#: __init__.py:16
|
|
65
|
+
msgid "Load all things"
|
|
66
|
+
msgstr ""
|
|
67
|
+
|
|
68
|
+
#: __init__.py:17
|
|
69
|
+
msgid "Server started http://{host_name}:{port}"
|
|
70
|
+
msgstr ""
|
|
71
|
+
|
|
72
|
+
#: __init__.py:18
|
|
73
|
+
msgid "Server stopped."
|
|
74
|
+
msgstr ""
|
|
75
|
+
|
|
76
|
+
#: __init__.py:19
|
|
77
|
+
msgid "Starting webserver on {port}"
|
|
78
|
+
msgstr ""
|
|
79
|
+
|
|
80
|
+
#: __init__.py:20
|
|
81
|
+
msgid "Entry point name ... {name}"
|
|
82
|
+
msgstr ""
|
|
83
|
+
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|