cherrypy-foundation 1.0.0__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 (136) hide show
  1. cherrypy_foundation/__init__.py +0 -0
  2. cherrypy_foundation/components/ColorModes.jinja +70 -0
  3. cherrypy_foundation/components/Datatable.css +47 -0
  4. cherrypy_foundation/components/Datatable.jinja +63 -0
  5. cherrypy_foundation/components/Datatable.js +358 -0
  6. cherrypy_foundation/components/Field.css +10 -0
  7. cherrypy_foundation/components/Field.jinja +66 -0
  8. cherrypy_foundation/components/Field.js +56 -0
  9. cherrypy_foundation/components/Fields.jinja +4 -0
  10. cherrypy_foundation/components/Flash.jinja +13 -0
  11. cherrypy_foundation/components/Icon.jinja +3 -0
  12. cherrypy_foundation/components/LocaleSelection.jinja +13 -0
  13. cherrypy_foundation/components/LocaleSelection.js +26 -0
  14. cherrypy_foundation/components/SideBySideMultiSelect.css +25 -0
  15. cherrypy_foundation/components/SideBySideMultiSelect.jinja +9 -0
  16. cherrypy_foundation/components/SideBySideMultiSelect.js +9 -0
  17. cherrypy_foundation/components/Typeahead.css +55 -0
  18. cherrypy_foundation/components/Typeahead.jinja +106 -0
  19. cherrypy_foundation/components/Typeahead.js +8 -0
  20. cherrypy_foundation/components/__init__.py +51 -0
  21. cherrypy_foundation/components/tests/__init__.py +0 -0
  22. cherrypy_foundation/components/tests/test_static.py +90 -0
  23. cherrypy_foundation/components/vendor/bootstrap-icons/bootstrap-icons.css +2106 -0
  24. cherrypy_foundation/components/vendor/bootstrap-icons/bootstrap-icons.min.css +5 -0
  25. cherrypy_foundation/components/vendor/bootstrap-icons/fonts/bootstrap-icons.woff +0 -0
  26. cherrypy_foundation/components/vendor/bootstrap-icons/fonts/bootstrap-icons.woff2 +0 -0
  27. cherrypy_foundation/components/vendor/bootstrap5/css/bootstrap.css +9262 -0
  28. cherrypy_foundation/components/vendor/bootstrap5/css/bootstrap.css.map +95 -0
  29. cherrypy_foundation/components/vendor/bootstrap5/css/bootstrap.min.css +6 -0
  30. cherrypy_foundation/components/vendor/bootstrap5/css/bootstrap.min.css.map +7 -0
  31. cherrypy_foundation/components/vendor/bootstrap5/js/bootstrap.js +4846 -0
  32. cherrypy_foundation/components/vendor/bootstrap5/js/bootstrap.js.map +1 -0
  33. cherrypy_foundation/components/vendor/bootstrap5/js/bootstrap.min.js +7 -0
  34. cherrypy_foundation/components/vendor/bootstrap5/js/bootstrap.min.js.map +7 -0
  35. cherrypy_foundation/components/vendor/bootstrap5/js/color-modes.js +80 -0
  36. cherrypy_foundation/components/vendor/datatables/css/dataTables.dataTables.css +849 -0
  37. cherrypy_foundation/components/vendor/datatables/css/dataTables.dataTables.min.css +1 -0
  38. cherrypy_foundation/components/vendor/datatables/images/sort_asc.png +0 -0
  39. cherrypy_foundation/components/vendor/datatables/images/sort_asc_disabled.png +0 -0
  40. cherrypy_foundation/components/vendor/datatables/images/sort_both.png +0 -0
  41. cherrypy_foundation/components/vendor/datatables/images/sort_desc.png +0 -0
  42. cherrypy_foundation/components/vendor/datatables/images/sort_desc_disabled.png +0 -0
  43. cherrypy_foundation/components/vendor/datatables/js/dataTables.js +14073 -0
  44. cherrypy_foundation/components/vendor/datatables/js/dataTables.min.js +4 -0
  45. cherrypy_foundation/components/vendor/datatables-extensions/Buttons/css/buttons.dataTables.css +556 -0
  46. cherrypy_foundation/components/vendor/datatables-extensions/Buttons/css/buttons.dataTables.min.css +1 -0
  47. cherrypy_foundation/components/vendor/datatables-extensions/Buttons/js/buttons.html5.js +1700 -0
  48. cherrypy_foundation/components/vendor/datatables-extensions/Buttons/js/buttons.html5.min.js +8 -0
  49. cherrypy_foundation/components/vendor/datatables-extensions/Buttons/js/dataTables.buttons.js +2944 -0
  50. cherrypy_foundation/components/vendor/datatables-extensions/Buttons/js/dataTables.buttons.min.js +4 -0
  51. cherrypy_foundation/components/vendor/datatables-extensions/FixedHeader/css/fixedHeader.dataTables.css +13 -0
  52. cherrypy_foundation/components/vendor/datatables-extensions/FixedHeader/css/fixedHeader.dataTables.min.css +1 -0
  53. cherrypy_foundation/components/vendor/datatables-extensions/FixedHeader/js/dataTables.fixedHeader.js +1202 -0
  54. cherrypy_foundation/components/vendor/datatables-extensions/FixedHeader/js/dataTables.fixedHeader.min.js +4 -0
  55. cherrypy_foundation/components/vendor/datatables-extensions/JSZip/jszip.js +11577 -0
  56. cherrypy_foundation/components/vendor/datatables-extensions/JSZip/jszip.min.js +13 -0
  57. cherrypy_foundation/components/vendor/datatables-extensions/Responsive/css/responsive.dataTables.css +194 -0
  58. cherrypy_foundation/components/vendor/datatables-extensions/Responsive/css/responsive.dataTables.min.css +1 -0
  59. cherrypy_foundation/components/vendor/datatables-extensions/Responsive/js/dataTables.responsive.js +1861 -0
  60. cherrypy_foundation/components/vendor/datatables-extensions/Responsive/js/dataTables.responsive.min.js +4 -0
  61. cherrypy_foundation/components/vendor/datatables-extensions/pdfmake/build/pdfmake.js +75023 -0
  62. cherrypy_foundation/components/vendor/datatables-extensions/pdfmake/build/pdfmake.min.js +3 -0
  63. cherrypy_foundation/components/vendor/datatables-extensions/pdfmake/build/vfs_fonts.js +6 -0
  64. cherrypy_foundation/components/vendor/datatables-extensions/rowgroup/css/rowGroup.dataTables.css +53 -0
  65. cherrypy_foundation/components/vendor/datatables-extensions/rowgroup/css/rowGroup.dataTables.min.css +1 -0
  66. cherrypy_foundation/components/vendor/datatables-extensions/rowgroup/js/dataTables.rowGroup.js +485 -0
  67. cherrypy_foundation/components/vendor/datatables-extensions/rowgroup/js/dataTables.rowGroup.min.js +4 -0
  68. cherrypy_foundation/components/vendor/jquery/jquery.min.js +2 -0
  69. cherrypy_foundation/components/vendor/multi/LICENSE +7 -0
  70. cherrypy_foundation/components/vendor/multi/README.md +109 -0
  71. cherrypy_foundation/components/vendor/multi/multi.css +95 -0
  72. cherrypy_foundation/components/vendor/multi/multi.js +328 -0
  73. cherrypy_foundation/components/vendor/popper/popper.js +1825 -0
  74. cherrypy_foundation/components/vendor/popper/popper.min.js +6 -0
  75. cherrypy_foundation/components/vendor/typeahead/jquery.typeahead.min.css +1 -0
  76. cherrypy_foundation/components/vendor/typeahead/jquery.typeahead.min.js +10 -0
  77. cherrypy_foundation/error_page.py +94 -0
  78. cherrypy_foundation/flash.py +50 -0
  79. cherrypy_foundation/form.py +119 -0
  80. cherrypy_foundation/logging.py +103 -0
  81. cherrypy_foundation/passwd.py +65 -0
  82. cherrypy_foundation/plugins/__init__.py +0 -0
  83. cherrypy_foundation/plugins/db.py +286 -0
  84. cherrypy_foundation/plugins/ldap.py +257 -0
  85. cherrypy_foundation/plugins/restapi.py +74 -0
  86. cherrypy_foundation/plugins/scheduler.py +287 -0
  87. cherrypy_foundation/plugins/smtp.py +223 -0
  88. cherrypy_foundation/plugins/tests/__init__.py +0 -0
  89. cherrypy_foundation/plugins/tests/test_db.py +118 -0
  90. cherrypy_foundation/plugins/tests/test_ldap.py +451 -0
  91. cherrypy_foundation/plugins/tests/test_scheduler.py +100 -0
  92. cherrypy_foundation/plugins/tests/test_scheduler_db.py +107 -0
  93. cherrypy_foundation/plugins/tests/test_smtp.py +140 -0
  94. cherrypy_foundation/sessions.py +93 -0
  95. cherrypy_foundation/tests/__init__.py +72 -0
  96. cherrypy_foundation/tests/templates/test_flash.html +9 -0
  97. cherrypy_foundation/tests/templates/test_form.html +16 -0
  98. cherrypy_foundation/tests/templates/test_url.html +15 -0
  99. cherrypy_foundation/tests/test_error_page.py +78 -0
  100. cherrypy_foundation/tests/test_flash.py +61 -0
  101. cherrypy_foundation/tests/test_form.py +148 -0
  102. cherrypy_foundation/tests/test_logging.py +78 -0
  103. cherrypy_foundation/tests/test_passwd.py +51 -0
  104. cherrypy_foundation/tests/test_sessions.py +89 -0
  105. cherrypy_foundation/tests/test_url.py +161 -0
  106. cherrypy_foundation/tools/__init__.py +0 -0
  107. cherrypy_foundation/tools/auth.py +263 -0
  108. cherrypy_foundation/tools/auth_mfa.py +249 -0
  109. cherrypy_foundation/tools/i18n.py +529 -0
  110. cherrypy_foundation/tools/jinja2.py +158 -0
  111. cherrypy_foundation/tools/ratelimit.py +265 -0
  112. cherrypy_foundation/tools/secure_headers.py +119 -0
  113. cherrypy_foundation/tools/sessions_timeout.py +167 -0
  114. cherrypy_foundation/tools/tests/__init__.py +0 -0
  115. cherrypy_foundation/tools/tests/components/Button.jinja +2 -0
  116. cherrypy_foundation/tools/tests/locales/de/LC_MESSAGES/messages.mo +0 -0
  117. cherrypy_foundation/tools/tests/locales/de/LC_MESSAGES/messages.po +15 -0
  118. cherrypy_foundation/tools/tests/locales/fr/LC_MESSAGES/messages.mo +0 -0
  119. cherrypy_foundation/tools/tests/locales/fr/LC_MESSAGES/messages.po +15 -0
  120. cherrypy_foundation/tools/tests/locales/messages.pot +2 -0
  121. cherrypy_foundation/tools/tests/templates/test_jinja2.html +11 -0
  122. cherrypy_foundation/tools/tests/templates/test_jinjax.html +9 -0
  123. cherrypy_foundation/tools/tests/templates/test_jinjax_i18n.html +22 -0
  124. cherrypy_foundation/tools/tests/test_auth.py +110 -0
  125. cherrypy_foundation/tools/tests/test_auth_mfa.py +369 -0
  126. cherrypy_foundation/tools/tests/test_i18n.py +247 -0
  127. cherrypy_foundation/tools/tests/test_jinja2.py +153 -0
  128. cherrypy_foundation/tools/tests/test_ratelimit.py +109 -0
  129. cherrypy_foundation/tools/tests/test_secure_headers.py +200 -0
  130. cherrypy_foundation/url.py +66 -0
  131. cherrypy_foundation/widgets.py +48 -0
  132. cherrypy_foundation-1.0.0.dist-info/METADATA +71 -0
  133. cherrypy_foundation-1.0.0.dist-info/RECORD +136 -0
  134. cherrypy_foundation-1.0.0.dist-info/WHEEL +5 -0
  135. cherrypy_foundation-1.0.0.dist-info/licenses/LICENSE.md +674 -0
  136. cherrypy_foundation-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,328 @@
1
+ /**
2
+ * multi.js
3
+ * A user-friendly replacement for select boxes with multiple attribute enabled.
4
+ *
5
+ * Author: Fabian Lindfors
6
+ * License: MIT
7
+ */
8
+ var multi = (function() {
9
+ var disabled_limit = false; // This will prevent to reset the "disabled" because of the limit at every click
10
+
11
+ // Helper function to trigger an event on an element
12
+ var trigger_event = function(type, el) {
13
+ var e = document.createEvent("HTMLEvents");
14
+ e.initEvent(type, false, true);
15
+ el.dispatchEvent(e);
16
+ };
17
+
18
+ // Check if there is a limit and if is reached
19
+ var check_limit = function (select, settings) {
20
+ var limit = settings.limit;
21
+ if (limit > -1) {
22
+ // Count current selected
23
+ var selected_count = 0;
24
+ for (var i = 0; i < select.options.length; i++) {
25
+ if (select.options[i].selected) {
26
+ selected_count++;
27
+ }
28
+ }
29
+
30
+ // Reached the limit
31
+ if (selected_count === limit) {
32
+ this.disabled_limit = true;
33
+
34
+ // Trigger the function (if there is)
35
+ if (typeof settings.limit_reached === "function") {
36
+ settings.limit_reached();
37
+ }
38
+
39
+ // Disable all non-selected option
40
+ for (var i = 0; i < select.options.length; i++) {
41
+ var opt = select.options[i];
42
+
43
+ if (!opt.selected) {
44
+ opt.setAttribute("disabled", true);
45
+ }
46
+ }
47
+ } else if (this.disabled_limit) {
48
+ // Enable options (only if they weren't disabled on init)
49
+ for (var i = 0; i < select.options.length; i++) {
50
+ var opt = select.options[i];
51
+
52
+ if (opt.getAttribute("data-origin-disabled") === "false") {
53
+ opt.removeAttribute("disabled");
54
+ }
55
+ }
56
+
57
+ this.disabled_limit = false;
58
+ }
59
+ }
60
+ };
61
+
62
+ // Toggles the target option on the select
63
+ var toggle_option = function(select, event, settings) {
64
+ var option = select.options[event.target.getAttribute("multi-index")];
65
+
66
+ if (option.disabled) {
67
+ return;
68
+ }
69
+
70
+ option.selected = !option.selected;
71
+
72
+ check_limit(select, settings);
73
+
74
+ trigger_event("change", select);
75
+ };
76
+
77
+ // Refreshes an already constructed multi.js instance
78
+ var refresh_select = function(select, settings) {
79
+ // Clear columns
80
+ select.wrapper.selected.innerHTML = "";
81
+ select.wrapper.non_selected.innerHTML = "";
82
+
83
+ // Add headers to columns
84
+ if (settings.non_selected_header && settings.selected_header) {
85
+ var non_selected_header = document.createElement("div");
86
+ var selected_header = document.createElement("div");
87
+
88
+ non_selected_header.className = "header";
89
+ selected_header.className = "header";
90
+
91
+ non_selected_header.innerText = settings.non_selected_header;
92
+ selected_header.innerText = settings.selected_header;
93
+
94
+ select.wrapper.non_selected.appendChild(non_selected_header);
95
+ select.wrapper.selected.appendChild(selected_header);
96
+ }
97
+
98
+ // Get search value
99
+ if (select.wrapper.search) {
100
+ var query = select.wrapper.search.value;
101
+ }
102
+
103
+ // Current group
104
+ var item_group = null;
105
+ var current_optgroup = null;
106
+
107
+ // Loop over select options and add to the non-selected and selected columns
108
+ for (var i = 0; i < select.options.length; i++) {
109
+ var option = select.options[i];
110
+
111
+ var value = option.value;
112
+ var label = option.textContent || option.innerText;
113
+
114
+ var row = document.createElement("button");
115
+ row.tabIndex = 0;
116
+ row.className = "item";
117
+ row.innerText = label;
118
+ row.setAttribute("type", "button");
119
+ row.setAttribute("data-value", value);
120
+ row.setAttribute("multi-index", i);
121
+
122
+ if (option.disabled) {
123
+ row.className += " disabled";
124
+ }
125
+
126
+ // Add row to selected column if option selected
127
+ if (option.selected) {
128
+ row.className += " selected";
129
+ var clone = row.cloneNode(true);
130
+ select.wrapper.selected.appendChild(clone);
131
+ }
132
+
133
+ // Create group if entering a new optgroup
134
+ if (
135
+ option.parentNode.nodeName == "OPTGROUP" &&
136
+ option.parentNode != current_optgroup
137
+ ) {
138
+ current_optgroup = option.parentNode;
139
+ item_group = document.createElement("div");
140
+ item_group.className = "item-group";
141
+
142
+ if (option.parentNode.label) {
143
+ var groupLabel = document.createElement("span");
144
+ groupLabel.innerHTML = option.parentNode.label;
145
+ groupLabel.className = "group-label";
146
+ item_group.appendChild(groupLabel);
147
+ }
148
+
149
+ select.wrapper.non_selected.appendChild(item_group);
150
+ }
151
+
152
+ // Clear group if not inside optgroup
153
+ if (option.parentNode == select) {
154
+ item_group = null;
155
+ current_optgroup = null;
156
+ }
157
+
158
+ // Apply search filtering
159
+ if (
160
+ !query ||
161
+ (query && label.toLowerCase().indexOf(query.toLowerCase()) > -1)
162
+ ) {
163
+ // Append to group if one exists, else just append to wrapper
164
+ if (item_group != null) {
165
+ item_group.appendChild(row);
166
+ } else {
167
+ select.wrapper.non_selected.appendChild(row);
168
+ }
169
+ }
170
+ }
171
+
172
+ // Hide empty optgroups
173
+ if (settings.hide_empty_groups) {
174
+ var optgroups = document.getElementsByClassName('item-group');
175
+ for (var i = 0; i < optgroups.length; i++) {
176
+ // Hide optgroup if optgroup only contains a group label
177
+ if (optgroups[i].childElementCount < 2) {
178
+ optgroups[i].style.display = 'none';
179
+ }
180
+ }
181
+ }
182
+ };
183
+
184
+ // Intializes and constructs an multi.js instance
185
+ var init = function(select, settings) {
186
+ /**
187
+ * Set up settings (optional parameter) and its default values
188
+ *
189
+ * Default values:
190
+ * enable_search : true
191
+ * search_placeholder : "Search..."
192
+ */
193
+ settings = typeof settings !== "undefined" ? settings : {};
194
+
195
+ settings["enable_search"] =
196
+ typeof settings["enable_search"] !== "undefined"
197
+ ? settings["enable_search"]
198
+ : true;
199
+ settings["search_placeholder"] =
200
+ typeof settings["search_placeholder"] !== "undefined"
201
+ ? settings["search_placeholder"]
202
+ : "Search...";
203
+ settings["non_selected_header"] =
204
+ typeof settings["non_selected_header"] !== "undefined"
205
+ ? settings["non_selected_header"]
206
+ : null;
207
+ settings["selected_header"] =
208
+ typeof settings["selected_header"] !== "undefined"
209
+ ? settings["selected_header"]
210
+ : null;
211
+ settings["limit"] =
212
+ typeof settings["limit"] !== "undefined"
213
+ ? parseInt(settings["limit"])
214
+ : -1;
215
+ if (isNaN(settings["limit"])) {
216
+ settings["limit"] = -1;
217
+ }
218
+ settings["hide_empty_groups"] =
219
+ typeof settings["hide_empty_groups"] !== "undefined"
220
+ ? settings["hide_empty_groups"]
221
+ : false;
222
+
223
+ // Check if already initalized
224
+ if (select.dataset.multijs != null) {
225
+ return;
226
+ }
227
+
228
+ // Make sure element is select and multiple is enabled
229
+ if (select.nodeName != "SELECT" || !select.multiple) {
230
+ return;
231
+ }
232
+
233
+ // Hide select
234
+ select.style.display = "none";
235
+ select.setAttribute("data-multijs", true);
236
+
237
+ // Start constructing selector
238
+ var wrapper = document.createElement("div");
239
+ wrapper.className = "multi-wrapper";
240
+
241
+ // Add search bar
242
+ if (settings.enable_search) {
243
+ var search = document.createElement("input");
244
+ search.className = "search-input";
245
+ search.type = "text";
246
+ search.setAttribute("placeholder", settings.search_placeholder);
247
+ search.setAttribute("title", settings.search_placeholder);
248
+
249
+ search.addEventListener("input", function() {
250
+ refresh_select(select, settings);
251
+ });
252
+
253
+ wrapper.appendChild(search);
254
+ wrapper.search = search;
255
+ }
256
+
257
+ // Add columns for selected and non-selected
258
+ var non_selected = document.createElement("div");
259
+ non_selected.className = "non-selected-wrapper";
260
+
261
+ var selected = document.createElement("div");
262
+ selected.className = "selected-wrapper";
263
+
264
+ // Add click handler to toggle the selected status
265
+ wrapper.addEventListener("click", function(event) {
266
+ if (event.target.getAttribute("multi-index")) {
267
+ toggle_option(select, event, settings);
268
+ }
269
+ });
270
+
271
+ // Add keyboard handler to toggle the selected status
272
+ wrapper.addEventListener("keypress", function(event) {
273
+ var is_action_key = event.keyCode === 32 || event.keyCode === 13;
274
+ var is_option = event.target.getAttribute("multi-index");
275
+
276
+ if (is_option && is_action_key) {
277
+ // Prevent the default action to stop scrolling when space is pressed
278
+ event.preventDefault();
279
+ toggle_option(select, event, settings);
280
+ }
281
+ });
282
+
283
+ wrapper.appendChild(non_selected);
284
+ wrapper.appendChild(selected);
285
+
286
+ wrapper.non_selected = non_selected;
287
+ wrapper.selected = selected;
288
+
289
+ select.wrapper = wrapper;
290
+
291
+ // Add multi.js wrapper after select element
292
+ select.parentNode.insertBefore(wrapper, select.nextSibling);
293
+
294
+ // Save current state
295
+ for (var i = 0; i < select.options.length; i++) {
296
+ var option = select.options[i];
297
+ option.setAttribute("data-origin-disabled", option.disabled);
298
+ }
299
+
300
+ // Check limit on initialization
301
+ check_limit(select, settings);
302
+
303
+ // Initialize selector with values from select element
304
+ refresh_select(select, settings);
305
+
306
+ // Refresh selector when select values change
307
+ select.addEventListener("change", function() {
308
+ refresh_select(select, settings);
309
+ });
310
+ };
311
+
312
+ return init;
313
+ })();
314
+
315
+ // Add jQuery wrapper if jQuery is present
316
+ if (typeof jQuery !== "undefined") {
317
+ (function($) {
318
+ $.fn.multi = function(settings) {
319
+ settings = typeof settings !== "undefined" ? settings : {};
320
+
321
+ return this.each(function() {
322
+ var $select = $(this);
323
+
324
+ multi($select.get(0), settings);
325
+ });
326
+ };
327
+ })(jQuery);
328
+ }