createsonline 0.1.26__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 (152) hide show
  1. createsonline/__init__.py +46 -0
  2. createsonline/admin/__init__.py +7 -0
  3. createsonline/admin/content.py +526 -0
  4. createsonline/admin/crud.py +805 -0
  5. createsonline/admin/field_builder.py +559 -0
  6. createsonline/admin/integration.py +482 -0
  7. createsonline/admin/interface.py +2562 -0
  8. createsonline/admin/model_creator.py +513 -0
  9. createsonline/admin/model_manager.py +388 -0
  10. createsonline/admin/modern_dashboard.py +498 -0
  11. createsonline/admin/permissions.py +264 -0
  12. createsonline/admin/user_forms.py +594 -0
  13. createsonline/ai/__init__.py +202 -0
  14. createsonline/ai/fields.py +1226 -0
  15. createsonline/ai/orm.py +325 -0
  16. createsonline/ai/services.py +1244 -0
  17. createsonline/app.py +506 -0
  18. createsonline/auth/__init__.py +8 -0
  19. createsonline/auth/management.py +228 -0
  20. createsonline/auth/models.py +552 -0
  21. createsonline/cli/__init__.py +5 -0
  22. createsonline/cli/commands/__init__.py +122 -0
  23. createsonline/cli/commands/database.py +416 -0
  24. createsonline/cli/commands/info.py +173 -0
  25. createsonline/cli/commands/initdb.py +218 -0
  26. createsonline/cli/commands/project.py +545 -0
  27. createsonline/cli/commands/serve.py +173 -0
  28. createsonline/cli/commands/shell.py +93 -0
  29. createsonline/cli/commands/users.py +148 -0
  30. createsonline/cli/main.py +2041 -0
  31. createsonline/cli/manage.py +274 -0
  32. createsonline/config/__init__.py +9 -0
  33. createsonline/config/app.py +2577 -0
  34. createsonline/config/database.py +179 -0
  35. createsonline/config/docs.py +384 -0
  36. createsonline/config/errors.py +160 -0
  37. createsonline/config/orm.py +43 -0
  38. createsonline/config/request.py +93 -0
  39. createsonline/config/settings.py +176 -0
  40. createsonline/data/__init__.py +23 -0
  41. createsonline/data/dataframe.py +925 -0
  42. createsonline/data/io.py +453 -0
  43. createsonline/data/series.py +557 -0
  44. createsonline/database/__init__.py +60 -0
  45. createsonline/database/abstraction.py +440 -0
  46. createsonline/database/assistant.py +585 -0
  47. createsonline/database/fields.py +442 -0
  48. createsonline/database/migrations.py +132 -0
  49. createsonline/database/models.py +604 -0
  50. createsonline/database.py +438 -0
  51. createsonline/http/__init__.py +28 -0
  52. createsonline/http/client.py +535 -0
  53. createsonline/ml/__init__.py +55 -0
  54. createsonline/ml/classification.py +552 -0
  55. createsonline/ml/clustering.py +680 -0
  56. createsonline/ml/metrics.py +542 -0
  57. createsonline/ml/neural.py +560 -0
  58. createsonline/ml/preprocessing.py +784 -0
  59. createsonline/ml/regression.py +501 -0
  60. createsonline/performance/__init__.py +19 -0
  61. createsonline/performance/cache.py +444 -0
  62. createsonline/performance/compression.py +335 -0
  63. createsonline/performance/core.py +419 -0
  64. createsonline/project_init.py +789 -0
  65. createsonline/routing.py +528 -0
  66. createsonline/security/__init__.py +34 -0
  67. createsonline/security/core.py +811 -0
  68. createsonline/security/encryption.py +349 -0
  69. createsonline/server.py +295 -0
  70. createsonline/static/css/admin.css +263 -0
  71. createsonline/static/css/common.css +358 -0
  72. createsonline/static/css/dashboard.css +89 -0
  73. createsonline/static/favicon.ico +0 -0
  74. createsonline/static/icons/icon-128x128.png +0 -0
  75. createsonline/static/icons/icon-128x128.webp +0 -0
  76. createsonline/static/icons/icon-16x16.png +0 -0
  77. createsonline/static/icons/icon-16x16.webp +0 -0
  78. createsonline/static/icons/icon-180x180.png +0 -0
  79. createsonline/static/icons/icon-180x180.webp +0 -0
  80. createsonline/static/icons/icon-192x192.png +0 -0
  81. createsonline/static/icons/icon-192x192.webp +0 -0
  82. createsonline/static/icons/icon-256x256.png +0 -0
  83. createsonline/static/icons/icon-256x256.webp +0 -0
  84. createsonline/static/icons/icon-32x32.png +0 -0
  85. createsonline/static/icons/icon-32x32.webp +0 -0
  86. createsonline/static/icons/icon-384x384.png +0 -0
  87. createsonline/static/icons/icon-384x384.webp +0 -0
  88. createsonline/static/icons/icon-48x48.png +0 -0
  89. createsonline/static/icons/icon-48x48.webp +0 -0
  90. createsonline/static/icons/icon-512x512.png +0 -0
  91. createsonline/static/icons/icon-512x512.webp +0 -0
  92. createsonline/static/icons/icon-64x64.png +0 -0
  93. createsonline/static/icons/icon-64x64.webp +0 -0
  94. createsonline/static/image/android-chrome-192x192.png +0 -0
  95. createsonline/static/image/android-chrome-512x512.png +0 -0
  96. createsonline/static/image/apple-touch-icon.png +0 -0
  97. createsonline/static/image/favicon-16x16.png +0 -0
  98. createsonline/static/image/favicon-32x32.png +0 -0
  99. createsonline/static/image/favicon.ico +0 -0
  100. createsonline/static/image/favicon.svg +17 -0
  101. createsonline/static/image/icon-128x128.png +0 -0
  102. createsonline/static/image/icon-128x128.webp +0 -0
  103. createsonline/static/image/icon-16x16.png +0 -0
  104. createsonline/static/image/icon-16x16.webp +0 -0
  105. createsonline/static/image/icon-180x180.png +0 -0
  106. createsonline/static/image/icon-180x180.webp +0 -0
  107. createsonline/static/image/icon-192x192.png +0 -0
  108. createsonline/static/image/icon-192x192.webp +0 -0
  109. createsonline/static/image/icon-256x256.png +0 -0
  110. createsonline/static/image/icon-256x256.webp +0 -0
  111. createsonline/static/image/icon-32x32.png +0 -0
  112. createsonline/static/image/icon-32x32.webp +0 -0
  113. createsonline/static/image/icon-384x384.png +0 -0
  114. createsonline/static/image/icon-384x384.webp +0 -0
  115. createsonline/static/image/icon-48x48.png +0 -0
  116. createsonline/static/image/icon-48x48.webp +0 -0
  117. createsonline/static/image/icon-512x512.png +0 -0
  118. createsonline/static/image/icon-512x512.webp +0 -0
  119. createsonline/static/image/icon-64x64.png +0 -0
  120. createsonline/static/image/icon-64x64.webp +0 -0
  121. createsonline/static/image/logo-header-h100.png +0 -0
  122. createsonline/static/image/logo-header-h100.webp +0 -0
  123. createsonline/static/image/logo-header-h200@2x.png +0 -0
  124. createsonline/static/image/logo-header-h200@2x.webp +0 -0
  125. createsonline/static/image/logo.png +0 -0
  126. createsonline/static/js/admin.js +274 -0
  127. createsonline/static/site.webmanifest +35 -0
  128. createsonline/static/templates/admin/base.html +87 -0
  129. createsonline/static/templates/admin/dashboard.html +217 -0
  130. createsonline/static/templates/admin/model_form.html +270 -0
  131. createsonline/static/templates/admin/model_list.html +202 -0
  132. createsonline/static/test_script.js +15 -0
  133. createsonline/static/test_styles.css +59 -0
  134. createsonline/static_files.py +365 -0
  135. createsonline/templates/404.html +100 -0
  136. createsonline/templates/admin_login.html +169 -0
  137. createsonline/templates/base.html +102 -0
  138. createsonline/templates/index.html +151 -0
  139. createsonline/templates.py +205 -0
  140. createsonline/testing.py +322 -0
  141. createsonline/utils.py +448 -0
  142. createsonline/validation/__init__.py +49 -0
  143. createsonline/validation/fields.py +598 -0
  144. createsonline/validation/models.py +504 -0
  145. createsonline/validation/validators.py +561 -0
  146. createsonline/views.py +184 -0
  147. createsonline-0.1.26.dist-info/METADATA +46 -0
  148. createsonline-0.1.26.dist-info/RECORD +152 -0
  149. createsonline-0.1.26.dist-info/WHEEL +5 -0
  150. createsonline-0.1.26.dist-info/entry_points.txt +2 -0
  151. createsonline-0.1.26.dist-info/licenses/LICENSE +21 -0
  152. createsonline-0.1.26.dist-info/top_level.txt +1 -0
@@ -0,0 +1,498 @@
1
+ # createsonline/admin/modern_dashboard.py
2
+ """
3
+ CREATESONLINE Modern Admin Dashboard
4
+
5
+ Clean, database-driven admin interface - NO hardcoded demo data.
6
+ Similar to Django Admin and Wagtail Admin.
7
+ """
8
+ from typing import Dict, List, Any, Optional
9
+ from datetime import datetime
10
+
11
+
12
+ class ModernAdminDashboard:
13
+ """Modern admin dashboard with database-driven content"""
14
+
15
+ def __init__(self, admin_site):
16
+ self.admin_site = admin_site
17
+
18
+ async def render(self, request, user=None) -> str:
19
+ """Render the complete admin dashboard"""
20
+ try:
21
+ from sqlalchemy import create_engine
22
+ from sqlalchemy.orm import sessionmaker
23
+ from createsonline.auth.models import User, Group, Permission
24
+ import os
25
+
26
+ database_url = os.getenv("DATABASE_URL", "sqlite:///./createsonline.db")
27
+ engine = create_engine(database_url, echo=False)
28
+ SessionLocal = sessionmaker(bind=engine)
29
+ session = SessionLocal()
30
+
31
+ try:
32
+ # Get users count
33
+ users_count = session.query(User).count()
34
+ users_list = session.query(User).order_by(User.date_joined.desc()).limit(5).all()
35
+
36
+ # Get groups count
37
+ groups_count = session.query(Group).count()
38
+
39
+ # Get permissions count
40
+ permissions_count = session.query(Permission).count()
41
+
42
+ # Get model stats
43
+ model_stats = []
44
+ for model_name, model_admin in self.admin_site._registry.items():
45
+ model_class = model_admin.model
46
+
47
+ try:
48
+ count = session.query(model_class).count()
49
+ except:
50
+ count = 0
51
+
52
+ model_stats.append({
53
+ 'name': model_name,
54
+ 'verbose_name': model_class.__name__.replace('_', ' ').title(),
55
+ 'count': count,
56
+ 'url': f'/admin/{model_name.lower()}'
57
+ })
58
+
59
+ # Render dashboard
60
+ html = self._render_html(
61
+ users_count=users_count,
62
+ users_list=users_list,
63
+ groups_count=groups_count,
64
+ permissions_count=permissions_count,
65
+ model_stats=model_stats,
66
+ user=user
67
+ )
68
+
69
+ return html
70
+
71
+ finally:
72
+ session.close()
73
+
74
+ except Exception as e:
75
+ print(f"Error rendering dashboard: {e}")
76
+ import traceback
77
+ traceback.print_exc()
78
+ return self._render_error()
79
+
80
+ def _render_html(self, users_count, users_list, groups_count, permissions_count, model_stats, user) -> str:
81
+ """Render dashboard HTML"""
82
+
83
+ # Users list HTML
84
+ users_html = ""
85
+ if users_list:
86
+ for u in users_list:
87
+ role = "Superuser" if u.is_superuser else ("Staff" if u.is_staff else "User")
88
+ users_html += f"""
89
+ <div class="item">
90
+ <div class="item-icon">👤</div>
91
+ <div class="item-info">
92
+ <div class="item-name">{u.username}</div>
93
+ <div class="item-meta">{u.email} • {role}</div>
94
+ </div>
95
+ <a href="/admin/user/{u.id}/edit" class="item-action">Edit</a>
96
+ </div>
97
+ """
98
+ else:
99
+ users_html = '<div class="empty-state">No users yet</div>'
100
+
101
+ # Models list HTML
102
+ models_html = ""
103
+ for stat in model_stats:
104
+ models_html += f"""
105
+ <div class="model-card" onclick="window.location.href='{stat['url']}'">
106
+ <div class="model-header">
107
+ <span class="model-icon">📊</span>
108
+ <span class="model-count">{stat['count']}</span>
109
+ </div>
110
+ <div class="model-name">{stat['verbose_name']}</div>
111
+ <div class="model-actions">
112
+ <a href="{stat['url']}" class="model-link">View all →</a>
113
+ </div>
114
+ </div>
115
+ """
116
+
117
+ username = user.username if user and hasattr(user, 'username') else 'Admin'
118
+
119
+ html = f"""
120
+ <!DOCTYPE html>
121
+ <html lang="en">
122
+ <head>
123
+ <meta charset="UTF-8">
124
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
125
+ <title>Admin Dashboard - CREATESONLINE</title>
126
+ <style>
127
+ * {{
128
+ margin: 0;
129
+ padding: 0;
130
+ box-sizing: border-box;
131
+ }}
132
+
133
+ body {{
134
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
135
+ background: #0a0a0a;
136
+ color: #ffffff;
137
+ padding: 20px;
138
+ }}
139
+
140
+ .header {{
141
+ background: #1a1a1a;
142
+ padding: 25px 30px;
143
+ border-radius: 12px;
144
+ border: 1px solid #2a2a2a;
145
+ margin-bottom: 30px;
146
+ display: flex;
147
+ justify-content: space-between;
148
+ align-items: center;
149
+ }}
150
+
151
+ h1 {{
152
+ font-size: 2em;
153
+ background: linear-gradient(135deg, #ffffff 0%, #a0a0a0 100%);
154
+ -webkit-background-clip: text;
155
+ -webkit-text-fill-color: transparent;
156
+ }}
157
+
158
+ .user-info {{
159
+ display: flex;
160
+ align-items: center;
161
+ gap: 20px;
162
+ }}
163
+
164
+ .username {{
165
+ color: #b0b0b0;
166
+ }}
167
+
168
+ .btn-logout {{
169
+ padding: 10px 20px;
170
+ background: #2a2a2a;
171
+ color: #ffffff;
172
+ border: 1px solid #3a3a3a;
173
+ border-radius: 8px;
174
+ text-decoration: none;
175
+ cursor: pointer;
176
+ font-weight: 500;
177
+ }}
178
+
179
+ .btn-logout:hover {{
180
+ background: #3a3a3a;
181
+ }}
182
+
183
+ .dashboard-grid {{
184
+ display: grid;
185
+ grid-template-columns: 1fr 1fr;
186
+ gap: 30px;
187
+ margin-bottom: 30px;
188
+ }}
189
+
190
+ .section {{
191
+ background: #1a1a1a;
192
+ padding: 25px;
193
+ border-radius: 12px;
194
+ border: 1px solid #2a2a2a;
195
+ }}
196
+
197
+ .section-header {{
198
+ display: flex;
199
+ justify-content: space-between;
200
+ align-items: center;
201
+ margin-bottom: 20px;
202
+ padding-bottom: 15px;
203
+ border-bottom: 1px solid #2a2a2a;
204
+ }}
205
+
206
+ .section-title {{
207
+ font-size: 1.3em;
208
+ font-weight: 600;
209
+ display: flex;
210
+ align-items: center;
211
+ gap: 10px;
212
+ }}
213
+
214
+ .section-count {{
215
+ color: #888;
216
+ font-size: 0.9em;
217
+ }}
218
+
219
+ .btn-add {{
220
+ padding: 8px 16px;
221
+ background: linear-gradient(135deg, #ffffff 0%, #e0e0e0 100%);
222
+ color: #0a0a0a;
223
+ border: none;
224
+ border-radius: 6px;
225
+ text-decoration: none;
226
+ font-weight: 600;
227
+ font-size: 0.9em;
228
+ display: inline-flex;
229
+ align-items: center;
230
+ gap: 6px;
231
+ }}
232
+
233
+ .btn-add:hover {{
234
+ background: linear-gradient(135deg, #e0e0e0 0%, #c0c0c0 100%);
235
+ }}
236
+
237
+ .item {{
238
+ padding: 15px;
239
+ background: #0a0a0a;
240
+ border-radius: 8px;
241
+ margin-bottom: 10px;
242
+ display: flex;
243
+ align-items: center;
244
+ gap: 15px;
245
+ }}
246
+
247
+ .item-icon {{
248
+ font-size: 1.8em;
249
+ }}
250
+
251
+ .item-info {{
252
+ flex: 1;
253
+ }}
254
+
255
+ .item-name {{
256
+ font-weight: 600;
257
+ margin-bottom: 4px;
258
+ }}
259
+
260
+ .item-meta {{
261
+ color: #888;
262
+ font-size: 0.85em;
263
+ }}
264
+
265
+ .item-action {{
266
+ padding: 6px 12px;
267
+ background: #2a2a2a;
268
+ color: #ffffff;
269
+ border-radius: 6px;
270
+ text-decoration: none;
271
+ font-size: 0.85em;
272
+ }}
273
+
274
+ .item-action:hover {{
275
+ background: #3a3a3a;
276
+ }}
277
+
278
+ .empty-state {{
279
+ text-align: center;
280
+ padding: 40px;
281
+ color: #666;
282
+ }}
283
+
284
+ .models-grid {{
285
+ display: grid;
286
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
287
+ gap: 15px;
288
+ }}
289
+
290
+ .model-card {{
291
+ background: #0a0a0a;
292
+ padding: 20px;
293
+ border-radius: 8px;
294
+ border: 1px solid #2a2a2a;
295
+ cursor: pointer;
296
+ transition: all 0.2s;
297
+ }}
298
+
299
+ .model-card:hover {{
300
+ border-color: #ffffff;
301
+ transform: translateY(-2px);
302
+ }}
303
+
304
+ .model-header {{
305
+ display: flex;
306
+ justify-content: space-between;
307
+ align-items: center;
308
+ margin-bottom: 12px;
309
+ }}
310
+
311
+ .model-icon {{
312
+ font-size: 2em;
313
+ }}
314
+
315
+ .model-count {{
316
+ font-size: 1.5em;
317
+ font-weight: 700;
318
+ color: #ffffff;
319
+ }}
320
+
321
+ .model-name {{
322
+ font-weight: 600;
323
+ margin-bottom: 8px;
324
+ }}
325
+
326
+ .model-actions {{
327
+ display: flex;
328
+ gap: 10px;
329
+ }}
330
+
331
+ .model-link {{
332
+ color: #888;
333
+ text-decoration: none;
334
+ font-size: 0.85em;
335
+ }}
336
+
337
+ .model-link:hover {{
338
+ color: #ffffff;
339
+ }}
340
+
341
+ .stats-row {{
342
+ display: flex;
343
+ gap: 15px;
344
+ margin-bottom: 20px;
345
+ }}
346
+
347
+ .stat-box {{
348
+ flex: 1;
349
+ background: #0a0a0a;
350
+ padding: 15px;
351
+ border-radius: 8px;
352
+ text-align: center;
353
+ }}
354
+
355
+ .stat-value {{
356
+ font-size: 2em;
357
+ font-weight: 700;
358
+ background: linear-gradient(135deg, #ffffff 0%, #a0a0a0 100%);
359
+ -webkit-background-clip: text;
360
+ -webkit-text-fill-color: transparent;
361
+ margin-bottom: 5px;
362
+ }}
363
+
364
+ .stat-label {{
365
+ color: #888;
366
+ font-size: 0.85em;
367
+ }}
368
+
369
+ @media (max-width: 768px) {{
370
+ .dashboard-grid {{
371
+ grid-template-columns: 1fr;
372
+ }}
373
+
374
+ .models-grid {{
375
+ grid-template-columns: 1fr;
376
+ }}
377
+ }}
378
+ </style>
379
+ </head>
380
+ <body>
381
+ <div class="header">
382
+ <h1>CREATESONLINE Admin</h1>
383
+ <div class="user-info">
384
+ <span class="username">👤 {username}</span>
385
+ <form method="POST" action="/admin/logout" style="display: inline;">
386
+ <button type="submit" class="btn-logout">Logout</button>
387
+ </form>
388
+ </div>
389
+ </div>
390
+
391
+ <div class="dashboard-grid">
392
+ <!-- Users Section -->
393
+ <div class="section">
394
+ <div class="section-header">
395
+ <div>
396
+ <div class="section-title">
397
+ 👥 Users
398
+ <span class="section-count">({users_count})</span>
399
+ </div>
400
+ </div>
401
+ <a href="/admin/user/add" class="btn-add">
402
+ <span>+</span> Create User
403
+ </a>
404
+ </div>
405
+
406
+ <div class="stats-row">
407
+ <div class="stat-box">
408
+ <div class="stat-value">{users_count}</div>
409
+ <div class="stat-label">Total Users</div>
410
+ </div>
411
+ <div class="stat-box">
412
+ <div class="stat-value">{groups_count}</div>
413
+ <div class="stat-label">Groups</div>
414
+ </div>
415
+ <div class="stat-box">
416
+ <div class="stat-value">{permissions_count}</div>
417
+ <div class="stat-label">Permissions</div>
418
+ </div>
419
+ </div>
420
+
421
+ <div class="users-list">
422
+ {users_html}
423
+ </div>
424
+
425
+ {f'<a href="/admin/user" style="display: block; text-align: center; margin-top: 15px; color: #888; text-decoration: none;">View all users →</a>' if users_count > 5 else ''}
426
+ </div>
427
+
428
+ <!-- Models Section -->
429
+ <div class="section">
430
+ <div class="section-header">
431
+ <div class="section-title">
432
+ 📊 Models
433
+ <span class="section-count">({len(model_stats)})</span>
434
+ </div>
435
+ </div>
436
+
437
+ <div class="models-grid">
438
+ {models_html}
439
+ </div>
440
+ </div>
441
+ </div>
442
+ </body>
443
+ </html>
444
+ """
445
+ return html
446
+
447
+ def _render_error(self) -> str:
448
+ """Render error page"""
449
+ return """
450
+ <!DOCTYPE html>
451
+ <html lang="en">
452
+ <head>
453
+ <meta charset="UTF-8">
454
+ <title>Error - CREATESONLINE Admin</title>
455
+ <style>
456
+ body {{
457
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
458
+ background: #0a0a0a;
459
+ color: #ffffff;
460
+ display: flex;
461
+ align-items: center;
462
+ justify-content: center;
463
+ min-height: 100vh;
464
+ padding: 20px;
465
+ }}
466
+ .error {{
467
+ text-align: center;
468
+ }}
469
+ h1 {{
470
+ font-size: 3em;
471
+ margin-bottom: 20px;
472
+ }}
473
+ p {{
474
+ color: #888;
475
+ margin-bottom: 30px;
476
+ }}
477
+ a {{
478
+ padding: 12px 24px;
479
+ background: #ffffff;
480
+ color: #0a0a0a;
481
+ text-decoration: none;
482
+ border-radius: 8px;
483
+ font-weight: 600;
484
+ }}
485
+ </style>
486
+ </head>
487
+ <body>
488
+ <div class="error">
489
+ <h1>⚠️</h1>
490
+ <h2>Database Error</h2>
491
+ <p>Could not connect to database. Please run migrations:</p>
492
+ <code>python -m createsonline.cli.manage migrate</code>
493
+ <br><br>
494
+ <a href="/">Go to Homepage</a>
495
+ </div>
496
+ </body>
497
+ </html>
498
+ """