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.
Files changed (47) hide show
  1. tina4_python/Auth.py +222 -0
  2. tina4_python/Constant.py +43 -0
  3. tina4_python/Database.py +591 -0
  4. tina4_python/DatabaseResult.py +107 -0
  5. tina4_python/DatabaseTypes.py +15 -0
  6. tina4_python/Debug.py +126 -0
  7. tina4_python/Env.py +37 -0
  8. tina4_python/Localization.py +42 -0
  9. tina4_python/Messages.py +30 -0
  10. tina4_python/MiddleWare.py +90 -0
  11. tina4_python/Migration.py +107 -0
  12. tina4_python/ORM.py +639 -0
  13. tina4_python/Queue.py +615 -0
  14. tina4_python/Request.py +19 -0
  15. tina4_python/Response.py +121 -0
  16. tina4_python/Router.py +423 -0
  17. tina4_python/Session.py +342 -0
  18. tina4_python/ShellColors.py +20 -0
  19. tina4_python/Swagger.py +228 -0
  20. tina4_python/Template.py +107 -0
  21. tina4_python/Webserver.py +429 -0
  22. tina4_python/Websocket.py +49 -0
  23. tina4_python/__init__.py +392 -0
  24. tina4_python/messages.pot +83 -0
  25. tina4_python/public/css/readme.md +0 -0
  26. tina4_python/public/favicon.ico +0 -0
  27. tina4_python/public/images/403.png +0 -0
  28. tina4_python/public/images/404.png +0 -0
  29. tina4_python/public/images/500.png +0 -0
  30. tina4_python/public/images/logo.png +0 -0
  31. tina4_python/public/images/readme.md +0 -0
  32. tina4_python/public/js/readme.md +0 -0
  33. tina4_python/public/js/reconnecting-websocket.js +365 -0
  34. tina4_python/public/js/tina4helper.js +397 -0
  35. tina4_python/public/swagger/index.html +90 -0
  36. tina4_python/public/swagger/oauth2-redirect.html +63 -0
  37. tina4_python/templates/errors/403.twig +10 -0
  38. tina4_python/templates/errors/404.twig +10 -0
  39. tina4_python/templates/errors/500.twig +11 -0
  40. tina4_python/templates/readme.md +1 -0
  41. tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
  42. tina4_python/translations/en/LC_MESSAGES/messages.po +80 -0
  43. tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
  44. tina4_python/translations/fr/LC_MESSAGES/messages.po +84 -0
  45. tina4_python-0.2.122.dist-info/METADATA +465 -0
  46. tina4_python-0.2.122.dist-info/RECORD +47 -0
  47. tina4_python-0.2.122.dist-info/WHEEL +4 -0
@@ -0,0 +1,397 @@
1
+ var formToken = null;
2
+
3
+ /**
4
+ * Sends an http request
5
+ * @param url
6
+ * @param request
7
+ * @param method
8
+ * @param callback
9
+ */
10
+ function sendRequest (url, request, method, callback) {
11
+ if (url === undefined) {
12
+ url = "";
13
+ }
14
+ if (request === undefined) {
15
+ request = null;
16
+ }
17
+ if (method === undefined) {
18
+ method = 'GET';
19
+ }
20
+
21
+ //Inject the new token
22
+ if (formToken !== null) {
23
+ const regex = /formToken=(.*)/gm;
24
+ const subst = `formToken=${formToken}`;
25
+ url = url.replace(regex, subst);
26
+ if (url.indexOf('formToken') === -1) {
27
+ if (url.indexOf('?') === -1) {
28
+ url += '?formToken='+formToken;
29
+ } else {
30
+ url += '&formToken='+formToken;
31
+ }
32
+ }
33
+ }
34
+
35
+ const xhr = new XMLHttpRequest();
36
+ xhr.open(method, url, true);
37
+
38
+ xhr.onreadystatechange = function () {
39
+ if (xhr.readyState === 4 && xhr.status === 200) {
40
+ let content = xhr.response;
41
+
42
+ if (xhr.getResponseHeader('FreshToken') !== '' && xhr.getResponseHeader('FreshToken') !== null) {
43
+ formToken = xhr.getResponseHeader('FreshToken');
44
+ }
45
+
46
+ try {
47
+ content = JSON.parse(content);
48
+ callback(content);
49
+ } catch (exception) {
50
+ callback (content);
51
+ }
52
+
53
+ } else if (xhr.status !== 200) {
54
+ let content = xhr.response;
55
+ console.log('An unexpected response occurred while sending request',url, content, xhr.status, xhr.readyState, xhr, xhr.getResponseHeader('Location'));
56
+ callback(xhr.status+" An error occurred, see the console")
57
+ }
58
+ };
59
+
60
+ if (method === 'POST') {
61
+ xhr.send(request);
62
+ } else {
63
+ xhr.send(null);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Gets form data based on a form Id
69
+ * @param formId
70
+ * @returns {FormData}
71
+ */
72
+ function getFormData(formId) {
73
+ let data = new FormData();
74
+ let elements = document.querySelectorAll("#" + formId + " select, #" + formId + " input, #" + formId + " textarea");
75
+ for (let ie = 0; ie < elements.length; ie++ )
76
+ {
77
+ let element = elements[ie];
78
+ //refresh the token
79
+ if (element.name === 'formToken' && formToken !== null) {
80
+ element.value = formToken;
81
+ }
82
+ if (element.name) {
83
+ if (element.type === 'file') {
84
+ for (let i = 0; i < element.files.length; i++) {
85
+ let fileData = element.files[i];
86
+ let elementName = element.name;
87
+ if (fileData !== undefined) {
88
+ if (element.files.length > 1 && !elementName.includes('[')) {
89
+ elementName = elementName + '[]';
90
+ }
91
+ data.append(elementName, fileData, fileData.name);
92
+ }
93
+ }
94
+ } else if (element.type === 'checkbox' || element.type === 'radio') {
95
+ if (element.checked) {
96
+ data.append(element.name, element.value)
97
+ } else {
98
+ if (element.type !== 'radio') {
99
+ data.append(element.name, "0")
100
+ }
101
+ }
102
+ } else {
103
+ if (element.value === '') {
104
+ element.value = null;
105
+ }
106
+ data.append(element.name, element.value);
107
+ }
108
+ }
109
+ }
110
+ return data;
111
+ }
112
+
113
+ /**
114
+ * Handles the data returned from a request
115
+ * @param data
116
+ * @param targetElement
117
+ */
118
+ function handleHtmlData(data, targetElement) {
119
+ //Strip out the scripts
120
+ if (data === "") return '';
121
+ const parser = new DOMParser();
122
+ const htmlData = parser.parseFromString(data.includes !== undefined && data.includes('<html>') ? data : '<body>'+data+'</body></html>', 'text/html');
123
+ const body = htmlData.querySelector('body');
124
+ const scripts = body.querySelectorAll('script');
125
+ // remove the script tags
126
+ body.querySelectorAll('script').forEach(script => script.remove());
127
+
128
+ if (targetElement !== null) {
129
+ if (body.children.length > 0) {
130
+ document.getElementById(targetElement).replaceChildren(...body.children);
131
+ } else {
132
+ document.getElementById(targetElement).replaceChildren(body.innerHTML);
133
+ }
134
+ if (scripts) {
135
+ scripts.forEach(script => {
136
+ const newScript = document.createElement("script");
137
+ newScript.type = 'text/javascript';
138
+ newScript.async = true;
139
+ newScript.textContent = script.innerText;
140
+ document.getElementById(targetElement).append(newScript);
141
+ });
142
+ }
143
+ } else {
144
+ if (scripts) {
145
+ scripts.forEach(script => {
146
+ const newScript = document.createElement("script");
147
+ newScript.type = 'text/javascript';
148
+ newScript.async = true;
149
+ newScript.textContent = script.innerText;
150
+ document.body.append(newScript);
151
+ console.log(newScript);
152
+ });
153
+ }
154
+
155
+ return body.innerHTML;
156
+ }
157
+
158
+ return '';
159
+ }
160
+
161
+ /**
162
+ * Loads a page to a target html element
163
+ * @param loadURL
164
+ * @param targetElement
165
+ * @param callback
166
+ * @callback
167
+ */
168
+ function loadPage(loadURL, targetElement, callback = null) {
169
+ if (targetElement === undefined) targetElement = 'content';
170
+ sendRequest(loadURL, null, "GET", function(data) {
171
+ let processedHTML = '';
172
+ if (document.getElementById(targetElement) !== null) {
173
+ processedHTML = handleHtmlData(data, targetElement);
174
+ } else {
175
+ if (callback) {
176
+ callback(data);
177
+ } else {
178
+ console.log('TINA4 - define targetElement or callback for loadPage', data);
179
+ }
180
+ return;
181
+ }
182
+
183
+ if (callback) {
184
+ callback(processedHTML, data);
185
+ }
186
+ });
187
+ }
188
+
189
+ /**
190
+ * Shows a form from a URL in a target html element
191
+ * @param action
192
+ * @param loadURL
193
+ * @param targetElement
194
+ * @param callback
195
+ */
196
+ function showForm(action, loadURL, targetElement, callback = null) {
197
+ if (targetElement === undefined) targetElement = 'form';
198
+
199
+ if (action === 'create') action = 'GET';
200
+ if (action === 'edit') action = 'GET';
201
+ if (action === 'delete') action = 'DELETE';
202
+
203
+ sendRequest(loadURL, null, action, function(data) {
204
+ let processedHTML = '';
205
+ if (data.message !== undefined) {
206
+ processedHTML = handleHtmlData ((data.message), targetElement);
207
+ } else {
208
+ if (document.getElementById(targetElement) !== null) {
209
+ processedHTML = handleHtmlData (data, targetElement);
210
+ } else {
211
+ if (callback) {
212
+ callback(data);
213
+ } else {
214
+ console.log('TINA4 - define targetElement or callback for showForm', data);
215
+ }
216
+ return;
217
+ }
218
+ }
219
+
220
+ if (callback) {
221
+ callback(processedHTML);
222
+ }
223
+ });
224
+ }
225
+
226
+ /**
227
+ * Post URL posts data to a specific url
228
+ * @param url
229
+ * @param data
230
+ * @param targetElement
231
+ * @param callback
232
+ */
233
+ function postUrl(url, data, targetElement, callback= null) {
234
+ sendRequest(url, data, 'POST', function(data) {
235
+ let processedHTML = '';
236
+ if (data.message !== undefined) {
237
+ processedHTML = handleHtmlData ((data.message), targetElement);
238
+ } else {
239
+ if (document.getElementById(targetElement) !== null) {
240
+ processedHTML = handleHtmlData (data, targetElement);
241
+ } else {
242
+ if (callback) {
243
+ callback(data);
244
+ } else {
245
+ console.log('TINA4 - define targetElement or callback for postUrl', data);
246
+ }
247
+ return;
248
+ }
249
+ }
250
+
251
+ if (callback) {
252
+ callback(processedHTML,data)
253
+ }
254
+ });
255
+ }
256
+
257
+ /**
258
+ * Saves a form to a POST end point
259
+ * @param formId
260
+ * @param targetURL
261
+ * @param targetElement
262
+ * @param callback - optional
263
+ */
264
+ function saveForm(formId, targetURL, targetElement, callback = null) {
265
+ if (targetElement === undefined) targetElement = 'message';
266
+ //compile a data model
267
+ let data = getFormData(formId);
268
+
269
+ postUrl(targetURL, data, targetElement, callback);
270
+ }
271
+
272
+ /**
273
+ * Alias of saveForm
274
+ * @param formId
275
+ * @param targetURL
276
+ * @param targetElement
277
+ * @param callback
278
+ */
279
+ function postForm(formId, targetURL, targetElement, callback = null){
280
+ saveForm(formId, targetURL, targetElement, callback)
281
+ }
282
+
283
+ /**
284
+ * Alias of saveForm
285
+ * @param formId
286
+ * @param targetURL
287
+ * @param targetElement
288
+ * @param callback
289
+ */
290
+ function submitForm(formId, targetURL, targetElement, callback = null){
291
+ saveForm(formId, targetURL, targetElement, callback)
292
+ }
293
+
294
+ /**
295
+ * Shows a message
296
+ * @param message
297
+ * @param alertType
298
+ * @param element
299
+ */
300
+ function showMessage(message, alertType, element) {
301
+ if (alertType === undefined) {
302
+ alertType = 'info';
303
+ }
304
+
305
+ if (!element) {
306
+ element = "message";
307
+ }
308
+
309
+ document.getElementById(element).innerHTML = '<div class="alert alert-' + alertType + ' alert-dismissible fade show" role="alert"><strong>Info</strong> ' + message + '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button></div>';
310
+
311
+ // Function to close alert after 10 seconds with a slide-up effect.
312
+ $(".alert").delay(10000).slideUp(200, function() {
313
+ $(this).alert('close');
314
+ });
315
+ }
316
+
317
+ /**
318
+ * Set cookie
319
+ * @param name
320
+ * @param value
321
+ * @param days
322
+ */
323
+ function setCookie(name, value, days) {
324
+ let expires = "";
325
+ if (days) {
326
+ let date = new Date();
327
+ date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
328
+ expires = "; expires=" + date.toUTCString();
329
+ }
330
+ document.cookie = name + "=" + (value || "") + expires + "; path=/";
331
+ }
332
+
333
+ /**
334
+ * Get cookie
335
+ * @param name
336
+ * @returns {null|string}
337
+ */
338
+ function getCookie(name) {
339
+ let nameEQ = name + "=";
340
+ let ca = document.cookie.split(';');
341
+ for (let i = 0; i < ca.length; i++) {
342
+ var c = ca[i];
343
+ while (c.charAt(0) == ' ') c = c.substring(1, c.length);
344
+ if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
345
+ }
346
+ return null;
347
+ }
348
+
349
+ //https://stackoverflow.com/questions/4068373/center-a-popup-window-on-screen
350
+ const popupCenter = ({url, title, w, h}) => {
351
+ // Fixes dual-screen position Most browsers Firefox
352
+ const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screenX;
353
+ const dualScreenTop = window.screenTop !== undefined ? window.screenTop : window.screenY;
354
+
355
+ const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
356
+ const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height;
357
+
358
+ const systemZoom = width / window.screen.availWidth;
359
+ const left = (width - w) / 2 / systemZoom + dualScreenLeft
360
+ const top = (height - h) / 2 / systemZoom + dualScreenTop
361
+ const newWindow = window.open(url, title,
362
+ `
363
+ directories=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=no,
364
+ width=${w / systemZoom},
365
+ height=${h / systemZoom},
366
+ top=${top},
367
+ left=${left}
368
+ `
369
+ )
370
+
371
+ if (window.focus) newWindow.focus();
372
+ return newWindow;
373
+ }
374
+
375
+ /**
376
+ * Opens a popup window
377
+ * @param pdfReportPath
378
+ */
379
+ function openReport(pdfReportPath){
380
+ if (pdfReportPath.indexOf("No data available") < 0){
381
+ open(pdfReportPath, "content", "target=_blank, toolbar=no, scrollbars=yes, resizable=yes, width=800, height=600, top=0, left=0");
382
+ }
383
+ else {
384
+ window.alert("Sorry , unable to print a report according to your selection!");
385
+ }
386
+ }
387
+
388
+ /**
389
+ * Does a GET request to an end point
390
+ * @param loadURL
391
+ * @param callback
392
+ */
393
+ function getRoute(loadURL, callback) {
394
+ sendRequest(loadURL, null, 'GET', function(data) {
395
+ callback(handleHtmlData (data, null));
396
+ });
397
+ }
@@ -0,0 +1,90 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Swagger UI</title>
6
+ <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700"
7
+ rel="stylesheet">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.14/swagger-ui.min.css" integrity="sha512-+9UD8YSD9GF7FzOH38L9S6y56aYNx3R4dYbOCgvTJ2ZHpJScsahNdaMQJU/8osUiz9FPu0YZ8wdKf4evUbsGSg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
9
+ <style>
10
+ html {
11
+ box-sizing: border-box;
12
+ overflow: -moz-scrollbars-vertical;
13
+ overflow-y: scroll;
14
+ }
15
+ *,
16
+ *:before,
17
+ *:after {
18
+ box-sizing: inherit;
19
+ }
20
+
21
+ body {
22
+ margin: 0;
23
+ background: #fafafa;
24
+ }
25
+ </style>
26
+ </head>
27
+
28
+ <body>
29
+
30
+ <svg style="position:absolute;width:0;height:0"
31
+ xmlns="http://www.w3.org/2000/svg">
32
+ <defs>
33
+ <symbol id="unlocked" viewBox="0 0 20 20">
34
+ <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
35
+ </symbol>
36
+
37
+ <symbol id="locked" viewBox="0 0 20 20">
38
+ <path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"/>
39
+ </symbol>
40
+
41
+ <symbol id="close" viewBox="0 0 20 20">
42
+ <path d="M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"/>
43
+ </symbol>
44
+
45
+ <symbol id="large-arrow" viewBox="0 0 20 20">
46
+ <path d="M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"/>
47
+ </symbol>
48
+
49
+ <symbol id="large-arrow-down" viewBox="0 0 20 20">
50
+ <path d="M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"/>
51
+ </symbol>
52
+
53
+
54
+ <symbol id="jump-to" viewBox="0 0 24 24">
55
+ <path d="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"/>
56
+ </symbol>
57
+
58
+ <symbol id="expand" viewBox="0 0 24 24">
59
+ <path d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>
60
+ </symbol>
61
+
62
+ </defs>
63
+ </svg>
64
+
65
+ <div id="swagger-ui"></div>
66
+
67
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.14/swagger-ui-bundle.js" integrity="sha512-mVvFSCxt0sK0FeL8C7n8BcHh10quzdwfxQbjRaw9pRdKNNep3YQusJS5e2/q4GYt4Ma5yWXSJraoQzXPgZd2EQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
68
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.14/swagger-ui-standalone-preset.min.js" integrity="sha512-UrYi+60Ci3WWWcoDXbMmzpoi1xpERbwjPGij6wTh8fXl81qNdioNNHExr9ttnBebKF0ZbVnPlTPlw+zECUK1Xw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
69
+ <script>
70
+ window.onload = function () {
71
+
72
+ // Build a system
73
+ const ui = SwaggerUIBundle({
74
+ url: "{SWAGGER_ROUTE}/swagger.json",
75
+ dom_id: '#swagger-ui',
76
+ deepLinking: true,
77
+ presets: [
78
+ SwaggerUIBundle.presets.apis
79
+ ],
80
+ plugins: [
81
+ SwaggerUIBundle.plugins.DownloadUrl
82
+ ]
83
+ })
84
+
85
+ window.ui = ui
86
+ }
87
+ </script>
88
+ </body>
89
+
90
+ </html>
@@ -0,0 +1,63 @@
1
+ <!doctype html>
2
+ <html lang="en-US">
3
+ <body onload="run()">
4
+ </body>
5
+ </html>
6
+ <script>
7
+ 'use strict';
8
+
9
+ function run() {
10
+ var oauth2 = window.opener.swaggerUIRedirectOauth2;
11
+ var sentState = oauth2.state;
12
+ var redirectUrl = oauth2.redirectUrl;
13
+ var isValid, qp, arr;
14
+
15
+ if (/code|token|error/.test(window.location.hash)) {
16
+ qp = window.location.hash.substring(1);
17
+ } else {
18
+ qp = location.search.substring(1);
19
+ }
20
+
21
+ arr = qp.split("&")
22
+ arr.forEach(function (v, i, _arr) {
23
+ _arr[i] = '"' + v.replace('=', '":"') + '"';
24
+ })
25
+ qp = qp ? JSON.parse('{' + arr.join() + '}',
26
+ function (key, value) {
27
+ return key === "" ? value : decodeURIComponent(value)
28
+ }
29
+ ) : {}
30
+
31
+ isValid = qp.state === sentState
32
+
33
+ if ((
34
+ oauth2.auth.schema.get("flow") === "accessCode" ||
35
+ oauth2.auth.schema.get("flow") === "authorizationCode"
36
+ ) && !oauth2.auth.code) {
37
+ if (!isValid) {
38
+ oauth2.errCb({
39
+ authId: oauth2.auth.name,
40
+ source: "auth",
41
+ level: "warning",
42
+ message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
43
+ });
44
+ }
45
+
46
+ if (qp.code) {
47
+ delete oauth2.state;
48
+ oauth2.auth.code = qp.code;
49
+ oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
50
+ } else {
51
+ oauth2.errCb({
52
+ authId: oauth2.auth.name,
53
+ source: "auth",
54
+ level: "error",
55
+ message: "Authorization failed: no accessCode received from the server"
56
+ });
57
+ }
58
+ } else {
59
+ oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
60
+ }
61
+ window.close();
62
+ }
63
+ </script>
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>403 Error - {{ server.REQUEST_URI }}</title>
5
+ </head>
6
+ <body style="text-align: center">
7
+ <h2>Well this is really amazing, you must have hit this end point up incorrectly {{ server.url }}!</h2>
8
+ <img src="{{ baseURL }}/images/403.png" alt="403 Error - {{ server.url }}">
9
+ </body>
10
+ </html>
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>404 Error - {{ server.url }}</title>
5
+ </head>
6
+ <body style="text-align: center">
7
+ <h2>Well this is really amazing, we haven't created any content for {{ server.url }}!</h2>
8
+ <img src="{{ baseURL }}/images/404.png" alt="404 Error - {{ server.url }}">
9
+ </body>
10
+ </html>
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>500 Error - {{ server.url }}</title>
5
+ </head>
6
+ <body style="text-align: center">
7
+ <h2>Oops, somebody pushed some code that broke stuff on {{ server.url }}!</h2>
8
+ <img src="{{ baseURL }}/images/500.png" alt="500 Error - {{ server.url }}">
9
+ <pre>{{ error_message }}</pre>
10
+ </body>
11
+ </html>
@@ -0,0 +1 @@
1
+ ### Use the templates folder to store your twig files
@@ -0,0 +1,80 @@
1
+ # English translations for Tin4Python.
2
+ # This file is distributed under the same license as the Tin4Python project.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: PROJECT VERSION\n"
6
+ "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
7
+ "POT-Creation-Date: 2024-02-14 17:55+0200\n"
8
+ "PO-Revision-Date: 2024-02-14 17:56+0200\n"
9
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
10
+ "Language: en\n"
11
+ "Language-Team: en <LL@li.org>\n"
12
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
13
+ "MIME-Version: 1.0\n"
14
+ "Content-Type: text/plain; charset=utf-8\n"
15
+ "Content-Transfer-Encoding: 8bit\n"
16
+ "Generated-By: Babel 2.13.1\n"
17
+
18
+ #: tina4_python/Messages.py:5
19
+ msgid "Debug: {message}"
20
+ msgstr "Debug: {message}"
21
+
22
+ #: tina4_python/Messages.py:6
23
+ msgid "Warning: {message}"
24
+ msgstr "Warning: {message}"
25
+
26
+ #: tina4_python/Messages.py:7
27
+ msgid "Error: {message}"
28
+ msgstr "Error: {message}"
29
+
30
+ #: tina4_python/Messages.py:8
31
+ msgid "Info: {message}"
32
+ msgstr "Info: {message}"
33
+
34
+ #: tina4_python/Messages.py:12
35
+ msgid "Matching: {matching}"
36
+ msgstr "Matching: {matching}"
37
+
38
+ #: tina4_python/Messages.py:13
39
+ msgid "Variables: {variables}"
40
+ msgstr "Variables: {variables}"
41
+
42
+ #: tina4_python/Messages.py:14
43
+ msgid "Root Path {root_path} {url}"
44
+ msgstr "Root Path {root_path} {url}"
45
+
46
+ #: tina4_python/Messages.py:15
47
+ msgid "Attempting to serve static file: {static_file}"
48
+ msgstr "Attempting to serve static file: {static_file}"
49
+
50
+ #: tina4_python/Messages.py:16
51
+ msgid "Attempting to serve CSS file: {css_file}"
52
+ msgstr "Attempting to serve CSS file: {css_file}"
53
+
54
+ #: tina4_python/Messages.py:17
55
+ msgid "Attempting to serve image file: {image_file}"
56
+ msgstr "Attempting to serve image file: {image_file}"
57
+
58
+ #: tina4_python/__init__.py:14
59
+ msgid "Assuming root path: {root_path}, library path: {library_path}"
60
+ msgstr "Assuming root path: {root_path}, library path: {library_path}"
61
+
62
+ #: tina4_python/__init__.py:15
63
+ msgid "Load all things"
64
+ msgstr "Load all things"
65
+
66
+ #: tina4_python/__init__.py:16
67
+ msgid "Server started http://{host_name}:{port}"
68
+ msgstr "Server started http://{host_name}:{port}"
69
+
70
+ #: tina4_python/__init__.py:17
71
+ msgid "Server stopped."
72
+ msgstr "Server stopped."
73
+
74
+ #: tina4_python/__init__.py:18
75
+ msgid "Starting webserver on {port}"
76
+ msgstr "Starting webserver on {port}"
77
+
78
+ #: tina4_python/__init__.py:19
79
+ msgid "Entry point name ... {name}"
80
+ msgstr "Entry point name ... {name}"