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.
- createsonline/__init__.py +46 -0
- createsonline/admin/__init__.py +7 -0
- createsonline/admin/content.py +526 -0
- createsonline/admin/crud.py +805 -0
- createsonline/admin/field_builder.py +559 -0
- createsonline/admin/integration.py +482 -0
- createsonline/admin/interface.py +2562 -0
- createsonline/admin/model_creator.py +513 -0
- createsonline/admin/model_manager.py +388 -0
- createsonline/admin/modern_dashboard.py +498 -0
- createsonline/admin/permissions.py +264 -0
- createsonline/admin/user_forms.py +594 -0
- createsonline/ai/__init__.py +202 -0
- createsonline/ai/fields.py +1226 -0
- createsonline/ai/orm.py +325 -0
- createsonline/ai/services.py +1244 -0
- createsonline/app.py +506 -0
- createsonline/auth/__init__.py +8 -0
- createsonline/auth/management.py +228 -0
- createsonline/auth/models.py +552 -0
- createsonline/cli/__init__.py +5 -0
- createsonline/cli/commands/__init__.py +122 -0
- createsonline/cli/commands/database.py +416 -0
- createsonline/cli/commands/info.py +173 -0
- createsonline/cli/commands/initdb.py +218 -0
- createsonline/cli/commands/project.py +545 -0
- createsonline/cli/commands/serve.py +173 -0
- createsonline/cli/commands/shell.py +93 -0
- createsonline/cli/commands/users.py +148 -0
- createsonline/cli/main.py +2041 -0
- createsonline/cli/manage.py +274 -0
- createsonline/config/__init__.py +9 -0
- createsonline/config/app.py +2577 -0
- createsonline/config/database.py +179 -0
- createsonline/config/docs.py +384 -0
- createsonline/config/errors.py +160 -0
- createsonline/config/orm.py +43 -0
- createsonline/config/request.py +93 -0
- createsonline/config/settings.py +176 -0
- createsonline/data/__init__.py +23 -0
- createsonline/data/dataframe.py +925 -0
- createsonline/data/io.py +453 -0
- createsonline/data/series.py +557 -0
- createsonline/database/__init__.py +60 -0
- createsonline/database/abstraction.py +440 -0
- createsonline/database/assistant.py +585 -0
- createsonline/database/fields.py +442 -0
- createsonline/database/migrations.py +132 -0
- createsonline/database/models.py +604 -0
- createsonline/database.py +438 -0
- createsonline/http/__init__.py +28 -0
- createsonline/http/client.py +535 -0
- createsonline/ml/__init__.py +55 -0
- createsonline/ml/classification.py +552 -0
- createsonline/ml/clustering.py +680 -0
- createsonline/ml/metrics.py +542 -0
- createsonline/ml/neural.py +560 -0
- createsonline/ml/preprocessing.py +784 -0
- createsonline/ml/regression.py +501 -0
- createsonline/performance/__init__.py +19 -0
- createsonline/performance/cache.py +444 -0
- createsonline/performance/compression.py +335 -0
- createsonline/performance/core.py +419 -0
- createsonline/project_init.py +789 -0
- createsonline/routing.py +528 -0
- createsonline/security/__init__.py +34 -0
- createsonline/security/core.py +811 -0
- createsonline/security/encryption.py +349 -0
- createsonline/server.py +295 -0
- createsonline/static/css/admin.css +263 -0
- createsonline/static/css/common.css +358 -0
- createsonline/static/css/dashboard.css +89 -0
- createsonline/static/favicon.ico +0 -0
- createsonline/static/icons/icon-128x128.png +0 -0
- createsonline/static/icons/icon-128x128.webp +0 -0
- createsonline/static/icons/icon-16x16.png +0 -0
- createsonline/static/icons/icon-16x16.webp +0 -0
- createsonline/static/icons/icon-180x180.png +0 -0
- createsonline/static/icons/icon-180x180.webp +0 -0
- createsonline/static/icons/icon-192x192.png +0 -0
- createsonline/static/icons/icon-192x192.webp +0 -0
- createsonline/static/icons/icon-256x256.png +0 -0
- createsonline/static/icons/icon-256x256.webp +0 -0
- createsonline/static/icons/icon-32x32.png +0 -0
- createsonline/static/icons/icon-32x32.webp +0 -0
- createsonline/static/icons/icon-384x384.png +0 -0
- createsonline/static/icons/icon-384x384.webp +0 -0
- createsonline/static/icons/icon-48x48.png +0 -0
- createsonline/static/icons/icon-48x48.webp +0 -0
- createsonline/static/icons/icon-512x512.png +0 -0
- createsonline/static/icons/icon-512x512.webp +0 -0
- createsonline/static/icons/icon-64x64.png +0 -0
- createsonline/static/icons/icon-64x64.webp +0 -0
- createsonline/static/image/android-chrome-192x192.png +0 -0
- createsonline/static/image/android-chrome-512x512.png +0 -0
- createsonline/static/image/apple-touch-icon.png +0 -0
- createsonline/static/image/favicon-16x16.png +0 -0
- createsonline/static/image/favicon-32x32.png +0 -0
- createsonline/static/image/favicon.ico +0 -0
- createsonline/static/image/favicon.svg +17 -0
- createsonline/static/image/icon-128x128.png +0 -0
- createsonline/static/image/icon-128x128.webp +0 -0
- createsonline/static/image/icon-16x16.png +0 -0
- createsonline/static/image/icon-16x16.webp +0 -0
- createsonline/static/image/icon-180x180.png +0 -0
- createsonline/static/image/icon-180x180.webp +0 -0
- createsonline/static/image/icon-192x192.png +0 -0
- createsonline/static/image/icon-192x192.webp +0 -0
- createsonline/static/image/icon-256x256.png +0 -0
- createsonline/static/image/icon-256x256.webp +0 -0
- createsonline/static/image/icon-32x32.png +0 -0
- createsonline/static/image/icon-32x32.webp +0 -0
- createsonline/static/image/icon-384x384.png +0 -0
- createsonline/static/image/icon-384x384.webp +0 -0
- createsonline/static/image/icon-48x48.png +0 -0
- createsonline/static/image/icon-48x48.webp +0 -0
- createsonline/static/image/icon-512x512.png +0 -0
- createsonline/static/image/icon-512x512.webp +0 -0
- createsonline/static/image/icon-64x64.png +0 -0
- createsonline/static/image/icon-64x64.webp +0 -0
- createsonline/static/image/logo-header-h100.png +0 -0
- createsonline/static/image/logo-header-h100.webp +0 -0
- createsonline/static/image/logo-header-h200@2x.png +0 -0
- createsonline/static/image/logo-header-h200@2x.webp +0 -0
- createsonline/static/image/logo.png +0 -0
- createsonline/static/js/admin.js +274 -0
- createsonline/static/site.webmanifest +35 -0
- createsonline/static/templates/admin/base.html +87 -0
- createsonline/static/templates/admin/dashboard.html +217 -0
- createsonline/static/templates/admin/model_form.html +270 -0
- createsonline/static/templates/admin/model_list.html +202 -0
- createsonline/static/test_script.js +15 -0
- createsonline/static/test_styles.css +59 -0
- createsonline/static_files.py +365 -0
- createsonline/templates/404.html +100 -0
- createsonline/templates/admin_login.html +169 -0
- createsonline/templates/base.html +102 -0
- createsonline/templates/index.html +151 -0
- createsonline/templates.py +205 -0
- createsonline/testing.py +322 -0
- createsonline/utils.py +448 -0
- createsonline/validation/__init__.py +49 -0
- createsonline/validation/fields.py +598 -0
- createsonline/validation/models.py +504 -0
- createsonline/validation/validators.py +561 -0
- createsonline/views.py +184 -0
- createsonline-0.1.26.dist-info/METADATA +46 -0
- createsonline-0.1.26.dist-info/RECORD +152 -0
- createsonline-0.1.26.dist-info/WHEEL +5 -0
- createsonline-0.1.26.dist-info/entry_points.txt +2 -0
- createsonline-0.1.26.dist-info/licenses/LICENSE +21 -0
- createsonline-0.1.26.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# createsonline/auth/management.py
|
|
2
|
+
"""
|
|
3
|
+
CREATESONLINE User Management Commands
|
|
4
|
+
Provides Django-like utilities for user creation and management (Django-style interactive prompts)
|
|
5
|
+
"""
|
|
6
|
+
import getpass
|
|
7
|
+
import re
|
|
8
|
+
import sys
|
|
9
|
+
from typing import Optional, Tuple
|
|
10
|
+
from createsonline.auth.models import User, hash_password
|
|
11
|
+
from createsonline.database.abstraction import Database
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class UserManagement:
|
|
15
|
+
"""User management utility class"""
|
|
16
|
+
|
|
17
|
+
EMAIL_REGEX = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
|
|
18
|
+
MIN_PASSWORD_LENGTH = 8
|
|
19
|
+
|
|
20
|
+
@staticmethod
|
|
21
|
+
def create_superuser(
|
|
22
|
+
username: Optional[str] = None,
|
|
23
|
+
email: Optional[str] = None,
|
|
24
|
+
password: Optional[str] = None,
|
|
25
|
+
interactive: bool = True
|
|
26
|
+
) -> Tuple[bool, str]:
|
|
27
|
+
"""
|
|
28
|
+
Create a new superuser account
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
username: Superuser username (prompted if not provided and interactive=True)
|
|
32
|
+
email: Superuser email (prompted if not provided and interactive=True)
|
|
33
|
+
password: Superuser password (prompted if not provided and interactive=True)
|
|
34
|
+
interactive: Whether to prompt for missing values
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Tuple of (success: bool, message: str)
|
|
38
|
+
"""
|
|
39
|
+
try:
|
|
40
|
+
db = Database.get_instance()
|
|
41
|
+
|
|
42
|
+
# Get or prompt for username
|
|
43
|
+
if not username:
|
|
44
|
+
if not interactive:
|
|
45
|
+
return False, "Username is required"
|
|
46
|
+
username = UserManagement._prompt_username()
|
|
47
|
+
|
|
48
|
+
# Check if username already exists
|
|
49
|
+
with db.session() as session:
|
|
50
|
+
existing = session.query(User).filter(User.username == username).first()
|
|
51
|
+
if existing:
|
|
52
|
+
return False, f"Username '{username}' already exists"
|
|
53
|
+
|
|
54
|
+
# Get or prompt for email
|
|
55
|
+
if not email:
|
|
56
|
+
if not interactive:
|
|
57
|
+
return False, "Email is required"
|
|
58
|
+
email = UserManagement._prompt_email()
|
|
59
|
+
|
|
60
|
+
# Get or prompt for password
|
|
61
|
+
if not password:
|
|
62
|
+
if not interactive:
|
|
63
|
+
return False, "Password is required"
|
|
64
|
+
password = UserManagement._prompt_password()
|
|
65
|
+
|
|
66
|
+
# Validate password
|
|
67
|
+
if len(password) < UserManagement.MIN_PASSWORD_LENGTH:
|
|
68
|
+
return False, f"Password must be at least {UserManagement.MIN_PASSWORD_LENGTH} characters long"
|
|
69
|
+
|
|
70
|
+
# Hash password
|
|
71
|
+
hashed_password = hash_password(password)
|
|
72
|
+
|
|
73
|
+
# Create superuser
|
|
74
|
+
user = User(
|
|
75
|
+
username=username,
|
|
76
|
+
email=email,
|
|
77
|
+
password=hashed_password,
|
|
78
|
+
is_superuser=True,
|
|
79
|
+
is_staff=True,
|
|
80
|
+
is_active=True
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
with db.session() as session:
|
|
84
|
+
session.add(user)
|
|
85
|
+
session.commit()
|
|
86
|
+
|
|
87
|
+
return True, f"Superuser '{username}' created successfully!"
|
|
88
|
+
|
|
89
|
+
except Exception as e:
|
|
90
|
+
return False, f"Error creating superuser: {str(e)}"
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def _prompt_username() -> str:
|
|
94
|
+
"""Prompt user for username with validation"""
|
|
95
|
+
while True:
|
|
96
|
+
username = input("Username: ").strip()
|
|
97
|
+
|
|
98
|
+
if not username:
|
|
99
|
+
print("Username cannot be empty.")
|
|
100
|
+
continue
|
|
101
|
+
|
|
102
|
+
if len(username) < 3:
|
|
103
|
+
print("Username must be at least 3 characters long.")
|
|
104
|
+
continue
|
|
105
|
+
|
|
106
|
+
if not re.match(r'^[a-zA-Z0-9_-]+$', username):
|
|
107
|
+
print("Username can only contain letters, numbers, hyphens, and underscores.")
|
|
108
|
+
continue
|
|
109
|
+
|
|
110
|
+
# Check if already exists
|
|
111
|
+
try:
|
|
112
|
+
db = Database.get_instance()
|
|
113
|
+
with db.session() as session:
|
|
114
|
+
existing = session.query(User).filter(User.username == username).first()
|
|
115
|
+
if existing:
|
|
116
|
+
print(f"Username '{username}' already exists.")
|
|
117
|
+
continue
|
|
118
|
+
except Exception:
|
|
119
|
+
pass
|
|
120
|
+
|
|
121
|
+
return username
|
|
122
|
+
|
|
123
|
+
@staticmethod
|
|
124
|
+
def _prompt_email() -> str:
|
|
125
|
+
"""Prompt user for email with validation"""
|
|
126
|
+
while True:
|
|
127
|
+
email = input("Email address: ").strip()
|
|
128
|
+
|
|
129
|
+
if not email:
|
|
130
|
+
print("Email cannot be empty.")
|
|
131
|
+
continue
|
|
132
|
+
|
|
133
|
+
if not re.match(UserManagement.EMAIL_REGEX, email):
|
|
134
|
+
print("Enter a valid email address.")
|
|
135
|
+
continue
|
|
136
|
+
|
|
137
|
+
return email
|
|
138
|
+
|
|
139
|
+
@staticmethod
|
|
140
|
+
def _prompt_password() -> str:
|
|
141
|
+
"""Prompt user for password with confirmation"""
|
|
142
|
+
while True:
|
|
143
|
+
password = getpass.getpass("Password: ")
|
|
144
|
+
|
|
145
|
+
if len(password) < UserManagement.MIN_PASSWORD_LENGTH:
|
|
146
|
+
print(f"Password must be at least {UserManagement.MIN_PASSWORD_LENGTH} characters long.")
|
|
147
|
+
continue
|
|
148
|
+
|
|
149
|
+
# Check password strength (basic checks)
|
|
150
|
+
if not any(c.isupper() for c in password):
|
|
151
|
+
confirm = input("Password lacks uppercase letters. Continue anyway? [y/N]: ").strip().lower()
|
|
152
|
+
if confirm != 'y':
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
if not any(c.isdigit() for c in password):
|
|
156
|
+
confirm = input("Password lacks numeric characters. Continue anyway? [y/N]: ").strip().lower()
|
|
157
|
+
if confirm != 'y':
|
|
158
|
+
continue
|
|
159
|
+
|
|
160
|
+
# Confirm password
|
|
161
|
+
password_confirm = getpass.getpass("Password (again): ")
|
|
162
|
+
|
|
163
|
+
if password != password_confirm:
|
|
164
|
+
print("Passwords do not match.")
|
|
165
|
+
continue
|
|
166
|
+
|
|
167
|
+
return password
|
|
168
|
+
|
|
169
|
+
@staticmethod
|
|
170
|
+
def create_user(
|
|
171
|
+
username: str,
|
|
172
|
+
email: str,
|
|
173
|
+
password: str,
|
|
174
|
+
is_staff: bool = False,
|
|
175
|
+
is_superuser: bool = False,
|
|
176
|
+
is_active: bool = True
|
|
177
|
+
) -> Tuple[bool, str, Optional[User]]:
|
|
178
|
+
"""
|
|
179
|
+
Create a regular user
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
username: User username
|
|
183
|
+
email: User email
|
|
184
|
+
password: User password
|
|
185
|
+
is_staff: Whether user is staff
|
|
186
|
+
is_superuser: Whether user is superuser
|
|
187
|
+
is_active: Whether user is active
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
Tuple of (success: bool, message: str, user: Optional[User])
|
|
191
|
+
"""
|
|
192
|
+
try:
|
|
193
|
+
db = Database.get_instance()
|
|
194
|
+
|
|
195
|
+
# Validate email
|
|
196
|
+
if not re.match(UserManagement.EMAIL_REGEX, email):
|
|
197
|
+
return False, "Invalid email format", None
|
|
198
|
+
|
|
199
|
+
# Check if username exists
|
|
200
|
+
with db.session() as session:
|
|
201
|
+
existing = session.query(User).filter(User.username == username).first()
|
|
202
|
+
if existing:
|
|
203
|
+
return False, f"Username '{username}' already exists", None
|
|
204
|
+
|
|
205
|
+
# Hash password
|
|
206
|
+
hashed_password = hash_password(password)
|
|
207
|
+
|
|
208
|
+
# Create user
|
|
209
|
+
user = User(
|
|
210
|
+
username=username,
|
|
211
|
+
email=email,
|
|
212
|
+
password=hashed_password,
|
|
213
|
+
is_staff=is_staff,
|
|
214
|
+
is_superuser=is_superuser,
|
|
215
|
+
is_active=is_active
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
with db.session() as session:
|
|
219
|
+
session.add(user)
|
|
220
|
+
session.commit()
|
|
221
|
+
|
|
222
|
+
return True, f"User '{username}' created successfully!", user
|
|
223
|
+
|
|
224
|
+
except Exception as e:
|
|
225
|
+
return False, f"Error creating user: {str(e)}", None
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
__all__ = ['UserManagement']
|