ntc-dev-kit 1.0.0__tar.gz
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.
- ntc_dev_kit-1.0.0/LICENSE +21 -0
- ntc_dev_kit-1.0.0/MANIFEST.in +9 -0
- ntc_dev_kit-1.0.0/PKG-INFO +188 -0
- ntc_dev_kit-1.0.0/README.md +149 -0
- ntc_dev_kit-1.0.0/ntc/__init__.py +5 -0
- ntc_dev_kit-1.0.0/ntc/app_creator.py +296 -0
- ntc_dev_kit-1.0.0/ntc/cli.py +4 -0
- ntc_dev_kit-1.0.0/ntc/cli_enhanced.py +820 -0
- ntc_dev_kit-1.0.0/ntc/composer/__init__.py +0 -0
- ntc_dev_kit-1.0.0/ntc/composer/main.py +443 -0
- ntc_dev_kit-1.0.0/ntc/deployment/__init__.py +0 -0
- ntc_dev_kit-1.0.0/ntc/templates/__init__.py +2 -0
- ntc_dev_kit-1.0.0/ntc/templates/auth_app/__init__.py +0 -0
- ntc_dev_kit-1.0.0/ntc/templates/auth_app/admin.py +24 -0
- ntc_dev_kit-1.0.0/ntc/templates/auth_app/apps.py +6 -0
- ntc_dev_kit-1.0.0/ntc/templates/auth_app/models.py +30 -0
- ntc_dev_kit-1.0.0/ntc/templates/auth_app/serializers.py +101 -0
- ntc_dev_kit-1.0.0/ntc/templates/auth_app/urls.py +19 -0
- ntc_dev_kit-1.0.0/ntc/templates/auth_app/views.py +175 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/__init__.py +1 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/drf_structure.md +83 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/main.py +389 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/structure.json +126 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/.entry/start_core_backend.sh +37 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/.entry/start_tasks_backend.sh +30 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/CLAUDE.md +194 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/README.md +117 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/apps/app_admin.py +3 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/apps/app_apps.py +6 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/apps/app_models.py +4 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/apps/app_urls.py +8 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/apps/app_views.py +6 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/apps/common_apps.py +6 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/apps/common_models.py +8 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/config/gunicorn_config.py +9 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/config/http.conf +33 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/core/base_model.py +9 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/core/formatter.py +5 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/core/logger.py +8 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/core/pagination.py +6 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/core/response_wrapper.py +7 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/core/services/azure/email/backend.py +108 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/core/services/azure/email/client.py +296 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/core/services/azure/email/notifier.py +102 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/core/services/object_storage.py +285 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/django_project/asgi.py +5 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/django_project/celery.py +8 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/django_project/dev_settings.py +2 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/django_project/django_settings.txt +322 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/django_project/management_command.py +114 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/django_project/prod_settings.py +3 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/django_project/schema.py +7 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/django_project/urls.py +6 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/django_project/wsgi.py +5 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/docker/docker-compose.yml +11 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/knowledge/knowledge_description.md +201 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/knowledge/knowledge_design_pattern.md +722 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/knowledge/knowledge_structure.md +151 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/root/README.md +307 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/root/django_env.txt +98 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/root/django_requirements.txt +24 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/root/gitignore.txt +6 -0
- ntc_dev_kit-1.0.0/ntc/templates/drf_structure/templates/root/manage.py +11 -0
- ntc_dev_kit-1.0.0/ntc/templates/flutter/.gitignore +44 -0
- ntc_dev_kit-1.0.0/ntc/templates/flutter/.knowledge/knowledge_description.md +215 -0
- ntc_dev_kit-1.0.0/ntc/templates/flutter/.knowledge/knowledge_design_pattern.md +310 -0
- ntc_dev_kit-1.0.0/ntc/templates/flutter/.knowledge/knowledge_structure.md +83 -0
- ntc_dev_kit-1.0.0/ntc/templates/flutter/CLAUDE.md +190 -0
- ntc_dev_kit-1.0.0/ntc/templates/flutter/__init__.py +0 -0
- ntc_dev_kit-1.0.0/ntc/templates/flutter/analysis_options.yaml +9 -0
- ntc_dev_kit-1.0.0/ntc/templates/flutter/main.py +187 -0
- ntc_dev_kit-1.0.0/ntc/templates/flutter/pubspec.yaml +65 -0
- ntc_dev_kit-1.0.0/ntc/templates/flutter/structure.json +51 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/.env.example +10 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/.gitignore +36 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/CLAUDE.md +181 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/README.md +94 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/__init__.py +0 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/knowledge/knowledge_description.md +208 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/knowledge/knowledge_design_pattern.md +460 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/knowledge/knowledge_structure.md +75 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/main.py +224 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/package.json +25 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/src/app/globals.css +26 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/src/app/layout.tsx +59 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/src/app/page.tsx +21 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/src/components/Header.tsx +16 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/src/services/api.ts +81 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/src/utils/constants.ts +1 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/structure.json +32 -0
- ntc_dev_kit-1.0.0/ntc/templates/nextjs/tsconfig.json +27 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/.env.example +1 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/.gitignore +10 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/CLAUDE.md +210 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/README.md +72 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/__init__.py +0 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/index.html +13 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/knowledge/knowledge_description.md +202 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/knowledge/knowledge_design_pattern.md +448 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/knowledge/knowledge_structure.md +97 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/main.py +208 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/package.json +35 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/App.tsx +60 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/components/ProtectedRoute.tsx +16 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/components/Sidebar.tsx +90 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/components/TopNav.tsx +44 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/context/AuthContext.tsx +107 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/context/ThemeContext.tsx +34 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/context/WorkspaceContext.tsx +28 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/hooks/useApi.ts +39 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/index.css +34 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/layouts/AuthLayout.tsx +23 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/layouts/DashboardLayout.tsx +24 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/main.tsx +5 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/pages/DashboardPage.tsx +10 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/pages/auth/LoginPage.tsx +79 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/pages/auth/RegisterPage.tsx +93 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/services/api.service.ts +44 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/src/services/base.service.ts +193 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/structure.json +52 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/tsconfig.app.json +25 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/tsconfig.json +7 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/tsconfig.node.json +19 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_admin/vite.config.ts +13 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/CLAUDE.md +176 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/__init__.py +1 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/index.css +21 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/index.html +13 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/knowledge/knowledge_description.md +170 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/knowledge/knowledge_design_pattern.md +411 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/knowledge/knowledge_structure.md +74 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/main.py +217 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/package.json +32 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/src/App.tsx +63 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/src/components/Header.tsx +51 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/src/main.tsx +5 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/src/services/api.ts +90 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/src/utils/constants.ts +1 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/structure.json +65 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/tsconfig.app.json +25 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/tsconfig.json +7 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/tsconfig.node.json +19 -0
- ntc_dev_kit-1.0.0/ntc/templates/react_structure/vite.config.ts +12 -0
- ntc_dev_kit-1.0.0/ntc/utils/__init__.py +1 -0
- ntc_dev_kit-1.0.0/ntc/utils/environment.py +67 -0
- ntc_dev_kit-1.0.0/ntc/utils/output.py +41 -0
- ntc_dev_kit-1.0.0/ntc_dev_kit.egg-info/PKG-INFO +188 -0
- ntc_dev_kit-1.0.0/ntc_dev_kit.egg-info/SOURCES.txt +154 -0
- ntc_dev_kit-1.0.0/ntc_dev_kit.egg-info/dependency_links.txt +1 -0
- ntc_dev_kit-1.0.0/ntc_dev_kit.egg-info/entry_points.txt +2 -0
- ntc_dev_kit-1.0.0/ntc_dev_kit.egg-info/requires.txt +9 -0
- ntc_dev_kit-1.0.0/ntc_dev_kit.egg-info/top_level.txt +1 -0
- ntc_dev_kit-1.0.0/pyproject.toml +87 -0
- ntc_dev_kit-1.0.0/requirements.txt +2 -0
- ntc_dev_kit-1.0.0/setup.cfg +4 -0
- ntc_dev_kit-1.0.0/setup.py +44 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Nexent
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
include README.md
|
|
2
|
+
include LICENSE
|
|
3
|
+
include requirements.txt
|
|
4
|
+
recursive-include ntc/templates *.py *.json *.md *.txt *.html *.ts *.tsx *.css *.scss *.yml *.yaml *.sh *.conf *.cfg
|
|
5
|
+
recursive-include ntc/templates *.env.example *.gitignore
|
|
6
|
+
|
|
7
|
+
global-exclude __pycache__
|
|
8
|
+
global-exclude *.py[co]
|
|
9
|
+
global-exclude .DS_Store
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ntc-dev-kit
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Nexent Toolkit Console - A CLI tool for scaffolding Django REST Framework, React, Next.js, and Flutter projects
|
|
5
|
+
Home-page: https://github.com/nexent/ntc
|
|
6
|
+
Author: Nexent
|
|
7
|
+
Author-email: Nexent <dev@nexent.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/nexent/ntc
|
|
10
|
+
Project-URL: Repository, https://github.com/nexent/ntc
|
|
11
|
+
Project-URL: Issues, https://github.com/nexent/ntc/issues
|
|
12
|
+
Keywords: cli,scaffold,django,drf,react,nextjs,flutter,generator,boilerplate
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
23
|
+
Classifier: Topic :: Utilities
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: colorama>=0.4.6
|
|
28
|
+
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
31
|
+
Requires-Dist: twine>=4.0; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
33
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
34
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
35
|
+
Dynamic: author
|
|
36
|
+
Dynamic: home-page
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
Dynamic: requires-python
|
|
39
|
+
|
|
40
|
+
# NTC - Nexent Toolkit Console
|
|
41
|
+
|
|
42
|
+
A powerful CLI scaffolding tool for rapidly bootstrapping modern web and mobile projects.
|
|
43
|
+
|
|
44
|
+
## Overview
|
|
45
|
+
|
|
46
|
+
NTC (Nexent Toolkit Console) is a command-line interface that generates production-ready project boilerplates for:
|
|
47
|
+
|
|
48
|
+
- **Backend**: Django REST Framework with authentication, Celery, Docker support
|
|
49
|
+
- **Frontend**: React, React Admin, Next.js
|
|
50
|
+
- **Mobile**: Flutter
|
|
51
|
+
|
|
52
|
+
## Features
|
|
53
|
+
|
|
54
|
+
- **Interactive project initialization** with step-by-step prompts
|
|
55
|
+
- **Django REST Framework scaffolding** with JWT authentication, custom User models, and API documentation
|
|
56
|
+
- **Environment setup automation** (virtual environments, dependency installation)
|
|
57
|
+
- **Docker & Docker Compose** configuration included
|
|
58
|
+
- **Authentication app generator** with login, register, password reset endpoints
|
|
59
|
+
- **Modular app architecture** with pre-configured common utilities
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install ntc-dev-kit
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Quick Start
|
|
68
|
+
|
|
69
|
+
Create a new project interactively:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
ntc init
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Or specify technology directly:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Django REST API backend
|
|
79
|
+
ntc init --technology django
|
|
80
|
+
|
|
81
|
+
# React frontend
|
|
82
|
+
ntc init --technology react
|
|
83
|
+
|
|
84
|
+
# Next.js full-stack
|
|
85
|
+
ntc init --technology nextjs
|
|
86
|
+
|
|
87
|
+
# Flutter mobile
|
|
88
|
+
ntc init --technology flutter
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Usage
|
|
92
|
+
|
|
93
|
+
### Interactive Mode
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
ntc init
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Navigate menus with **arrow keys**, select with **Enter**, exit with **Escape**.
|
|
100
|
+
|
|
101
|
+
### Technology Options
|
|
102
|
+
|
|
103
|
+
| Technology | Description |
|
|
104
|
+
|-----------|-------------|
|
|
105
|
+
| `django` | Django REST Framework with JWT auth, Celery, Docker |
|
|
106
|
+
| `react` | React Vite project with TypeScript |
|
|
107
|
+
| `react-admin` | React Admin dashboard template |
|
|
108
|
+
| `nextjs` | Next.js full-stack application |
|
|
109
|
+
| `flutter` | Flutter mobile application |
|
|
110
|
+
|
|
111
|
+
### Additional Commands
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Create a new Django app within your project
|
|
115
|
+
ntc create app <app_name>
|
|
116
|
+
|
|
117
|
+
# Show help
|
|
118
|
+
ntc --help
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Django Project Structure
|
|
122
|
+
|
|
123
|
+
When you create a Django project, you get:
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
myproject/
|
|
127
|
+
├── .env # Environment variables
|
|
128
|
+
├── .gitignore
|
|
129
|
+
├── requirements.txt
|
|
130
|
+
├── manage.py
|
|
131
|
+
├── Dockerfile
|
|
132
|
+
├── docker-compose.yml
|
|
133
|
+
├── config/ # Gunicorn & nginx config
|
|
134
|
+
├── .entry/ # Startup scripts
|
|
135
|
+
├── .knowledge/ # AI documentation
|
|
136
|
+
├── apps/
|
|
137
|
+
│ ├── __init__.py
|
|
138
|
+
│ ├── common/ # Common utilities
|
|
139
|
+
│ └── authentication/ # (Optional) Auth app
|
|
140
|
+
├── core/ # Core utilities
|
|
141
|
+
│ ├── pagination.py
|
|
142
|
+
│ ├── base_model.py
|
|
143
|
+
│ ├── response_wrapper.py
|
|
144
|
+
│ └── services/ # Azure/AWS services
|
|
145
|
+
└── myproject/ # Django project settings
|
|
146
|
+
├── settings/
|
|
147
|
+
├── urls.py
|
|
148
|
+
├── asgi.py
|
|
149
|
+
├── wsgi.py
|
|
150
|
+
└── commands/ # Management commands
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Requirements
|
|
154
|
+
|
|
155
|
+
- **Python**: >= 3.10
|
|
156
|
+
- **Operating System**: Windows, macOS, Linux
|
|
157
|
+
|
|
158
|
+
## Dependencies
|
|
159
|
+
|
|
160
|
+
- `colorama` - Cross-platform colored terminal output
|
|
161
|
+
- `pyyaml` - YAML configuration parsing
|
|
162
|
+
|
|
163
|
+
## Development
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# Clone repository
|
|
167
|
+
git clone https://github.com/nexent/ntc.git
|
|
168
|
+
cd ntc
|
|
169
|
+
|
|
170
|
+
# Install in development mode
|
|
171
|
+
pip install -e ".[dev]"
|
|
172
|
+
|
|
173
|
+
# Run tests
|
|
174
|
+
pytest
|
|
175
|
+
|
|
176
|
+
# Code formatting
|
|
177
|
+
black ntc/
|
|
178
|
+
ruff check ntc/
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
184
|
+
|
|
185
|
+
## Support
|
|
186
|
+
|
|
187
|
+
- **Issues**: [GitHub Issues](https://github.com/nexent/ntc/issues)
|
|
188
|
+
- **Repository**: [GitHub](https://github.com/nexent/ntc)
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# NTC - Nexent Toolkit Console
|
|
2
|
+
|
|
3
|
+
A powerful CLI scaffolding tool for rapidly bootstrapping modern web and mobile projects.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
NTC (Nexent Toolkit Console) is a command-line interface that generates production-ready project boilerplates for:
|
|
8
|
+
|
|
9
|
+
- **Backend**: Django REST Framework with authentication, Celery, Docker support
|
|
10
|
+
- **Frontend**: React, React Admin, Next.js
|
|
11
|
+
- **Mobile**: Flutter
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Interactive project initialization** with step-by-step prompts
|
|
16
|
+
- **Django REST Framework scaffolding** with JWT authentication, custom User models, and API documentation
|
|
17
|
+
- **Environment setup automation** (virtual environments, dependency installation)
|
|
18
|
+
- **Docker & Docker Compose** configuration included
|
|
19
|
+
- **Authentication app generator** with login, register, password reset endpoints
|
|
20
|
+
- **Modular app architecture** with pre-configured common utilities
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install ntc-dev-kit
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
Create a new project interactively:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
ntc init
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or specify technology directly:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Django REST API backend
|
|
40
|
+
ntc init --technology django
|
|
41
|
+
|
|
42
|
+
# React frontend
|
|
43
|
+
ntc init --technology react
|
|
44
|
+
|
|
45
|
+
# Next.js full-stack
|
|
46
|
+
ntc init --technology nextjs
|
|
47
|
+
|
|
48
|
+
# Flutter mobile
|
|
49
|
+
ntc init --technology flutter
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
### Interactive Mode
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
ntc init
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Navigate menus with **arrow keys**, select with **Enter**, exit with **Escape**.
|
|
61
|
+
|
|
62
|
+
### Technology Options
|
|
63
|
+
|
|
64
|
+
| Technology | Description |
|
|
65
|
+
|-----------|-------------|
|
|
66
|
+
| `django` | Django REST Framework with JWT auth, Celery, Docker |
|
|
67
|
+
| `react` | React Vite project with TypeScript |
|
|
68
|
+
| `react-admin` | React Admin dashboard template |
|
|
69
|
+
| `nextjs` | Next.js full-stack application |
|
|
70
|
+
| `flutter` | Flutter mobile application |
|
|
71
|
+
|
|
72
|
+
### Additional Commands
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Create a new Django app within your project
|
|
76
|
+
ntc create app <app_name>
|
|
77
|
+
|
|
78
|
+
# Show help
|
|
79
|
+
ntc --help
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Django Project Structure
|
|
83
|
+
|
|
84
|
+
When you create a Django project, you get:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
myproject/
|
|
88
|
+
├── .env # Environment variables
|
|
89
|
+
├── .gitignore
|
|
90
|
+
├── requirements.txt
|
|
91
|
+
├── manage.py
|
|
92
|
+
├── Dockerfile
|
|
93
|
+
├── docker-compose.yml
|
|
94
|
+
├── config/ # Gunicorn & nginx config
|
|
95
|
+
├── .entry/ # Startup scripts
|
|
96
|
+
├── .knowledge/ # AI documentation
|
|
97
|
+
├── apps/
|
|
98
|
+
│ ├── __init__.py
|
|
99
|
+
│ ├── common/ # Common utilities
|
|
100
|
+
│ └── authentication/ # (Optional) Auth app
|
|
101
|
+
├── core/ # Core utilities
|
|
102
|
+
│ ├── pagination.py
|
|
103
|
+
│ ├── base_model.py
|
|
104
|
+
│ ├── response_wrapper.py
|
|
105
|
+
│ └── services/ # Azure/AWS services
|
|
106
|
+
└── myproject/ # Django project settings
|
|
107
|
+
├── settings/
|
|
108
|
+
├── urls.py
|
|
109
|
+
├── asgi.py
|
|
110
|
+
├── wsgi.py
|
|
111
|
+
└── commands/ # Management commands
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Requirements
|
|
115
|
+
|
|
116
|
+
- **Python**: >= 3.10
|
|
117
|
+
- **Operating System**: Windows, macOS, Linux
|
|
118
|
+
|
|
119
|
+
## Dependencies
|
|
120
|
+
|
|
121
|
+
- `colorama` - Cross-platform colored terminal output
|
|
122
|
+
- `pyyaml` - YAML configuration parsing
|
|
123
|
+
|
|
124
|
+
## Development
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Clone repository
|
|
128
|
+
git clone https://github.com/nexent/ntc.git
|
|
129
|
+
cd ntc
|
|
130
|
+
|
|
131
|
+
# Install in development mode
|
|
132
|
+
pip install -e ".[dev]"
|
|
133
|
+
|
|
134
|
+
# Run tests
|
|
135
|
+
pytest
|
|
136
|
+
|
|
137
|
+
# Code formatting
|
|
138
|
+
black ntc/
|
|
139
|
+
ruff check ntc/
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
145
|
+
|
|
146
|
+
## Support
|
|
147
|
+
|
|
148
|
+
- **Issues**: [GitHub Issues](https://github.com/nexent/ntc/issues)
|
|
149
|
+
- **Repository**: [GitHub](https://github.com/nexent/ntc)
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
from ntc.utils.output import print_success, print_error, print_info
|
|
4
|
+
from ntc.templates.drf_structure.main import sanitize_project_name
|
|
5
|
+
|
|
6
|
+
def get_app_template_content(template_name, app_name):
|
|
7
|
+
"""Load app template content and replace variables."""
|
|
8
|
+
template_path = os.path.join(
|
|
9
|
+
os.path.dirname(__file__),
|
|
10
|
+
'templates', 'drf_structure', 'templates', 'apps', template_name
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
if not os.path.exists(template_path):
|
|
14
|
+
# Fallback to inline content if template not found
|
|
15
|
+
return get_fallback_content(template_name, app_name)
|
|
16
|
+
|
|
17
|
+
with open(template_path, 'r', encoding='utf-8') as f:
|
|
18
|
+
content = f.read()
|
|
19
|
+
|
|
20
|
+
# Replace template variables
|
|
21
|
+
content = content.replace('{app_name}', app_name)
|
|
22
|
+
content = content.replace('{app_name_title}', app_name.replace('_', '').title())
|
|
23
|
+
|
|
24
|
+
return content
|
|
25
|
+
|
|
26
|
+
def get_fallback_content(template_name, app_name):
|
|
27
|
+
"""Fallback content if template files are not found."""
|
|
28
|
+
fallbacks = {
|
|
29
|
+
'app_admin.py': '''from django.contrib import admin
|
|
30
|
+
|
|
31
|
+
# Register your models here.
|
|
32
|
+
''',
|
|
33
|
+
'app_apps.py': f'''from django.apps import AppConfig
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class {app_name.replace('_', '').title()}Config(AppConfig):
|
|
37
|
+
default_auto_field = 'django.db.models.BigAutoField'
|
|
38
|
+
name = 'apps.{app_name}'
|
|
39
|
+
''',
|
|
40
|
+
'app_models.py': '''from django.db import models
|
|
41
|
+
from apps.common.models import TimeStampedModel
|
|
42
|
+
|
|
43
|
+
# Create your models here.
|
|
44
|
+
''',
|
|
45
|
+
'app_urls.py': f'''from django.urls import path
|
|
46
|
+
from . import views
|
|
47
|
+
|
|
48
|
+
app_name = '{app_name}'
|
|
49
|
+
|
|
50
|
+
urlpatterns = [
|
|
51
|
+
path('hello/', views.hello_world, name='hello_world'),
|
|
52
|
+
# Add your other URL patterns here
|
|
53
|
+
]
|
|
54
|
+
''',
|
|
55
|
+
'app_views.py': f'''from rest_framework import viewsets, status
|
|
56
|
+
from rest_framework.decorators import api_view
|
|
57
|
+
from rest_framework.response import Response
|
|
58
|
+
from core.response_wrapper import success_response, error_response
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@api_view(['GET'])
|
|
62
|
+
def hello_world(request):
|
|
63
|
+
"""Test view that returns Hello World message."""
|
|
64
|
+
return success_response(
|
|
65
|
+
data={{"message": "Hello World from {app_name} app!"}},
|
|
66
|
+
message="Welcome to {app_name} API"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Create your other views here.
|
|
71
|
+
''',
|
|
72
|
+
}
|
|
73
|
+
return fallbacks.get(template_name, '')
|
|
74
|
+
|
|
75
|
+
def create_app_structure(app_name):
|
|
76
|
+
"""Create the NTC app directory structure."""
|
|
77
|
+
# Sanitize app name using the same function as project names
|
|
78
|
+
original_name = app_name
|
|
79
|
+
app_name = sanitize_project_name(app_name)
|
|
80
|
+
|
|
81
|
+
if app_name != original_name:
|
|
82
|
+
print_info(f"App name sanitized: '{original_name}' -> '{app_name}'")
|
|
83
|
+
|
|
84
|
+
# Check if we're in a Django project root
|
|
85
|
+
if not os.path.exists('manage.py'):
|
|
86
|
+
print_error("Not in a Django project root directory. Please run this command from your project root.")
|
|
87
|
+
return False
|
|
88
|
+
|
|
89
|
+
# Check if apps directory exists
|
|
90
|
+
if not os.path.exists('apps'):
|
|
91
|
+
print_info("Creating apps directory...")
|
|
92
|
+
os.makedirs('apps', exist_ok=True)
|
|
93
|
+
# Create apps/__init__.py
|
|
94
|
+
with open('apps/__init__.py', 'w') as f:
|
|
95
|
+
f.write('')
|
|
96
|
+
|
|
97
|
+
base_path = os.path.join('apps', app_name)
|
|
98
|
+
|
|
99
|
+
# Check if app already exists
|
|
100
|
+
if os.path.exists(base_path):
|
|
101
|
+
print_error(f"App '{app_name}' already exists in apps/{app_name}/")
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
print_info(f"Creating app structure for '{app_name}'...")
|
|
105
|
+
|
|
106
|
+
# Create directories
|
|
107
|
+
directories = [
|
|
108
|
+
base_path,
|
|
109
|
+
os.path.join(base_path, 'permissions'),
|
|
110
|
+
os.path.join(base_path, 'serializers'),
|
|
111
|
+
os.path.join(base_path, 'selectors'),
|
|
112
|
+
os.path.join(base_path, 'services'),
|
|
113
|
+
os.path.join(base_path, 'socket'),
|
|
114
|
+
os.path.join(base_path, 'tasks'),
|
|
115
|
+
os.path.join(base_path, 'tests'),
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
for directory in directories:
|
|
119
|
+
os.makedirs(directory, exist_ok=True)
|
|
120
|
+
# Create __init__.py in each directory
|
|
121
|
+
init_file = os.path.join(directory, '__init__.py')
|
|
122
|
+
with open(init_file, 'w') as f:
|
|
123
|
+
f.write('')
|
|
124
|
+
|
|
125
|
+
# Create main app files
|
|
126
|
+
files_content = {
|
|
127
|
+
'admin.py': get_app_template_content('app_admin.py', app_name),
|
|
128
|
+
'apps.py': get_app_template_content('app_apps.py', app_name),
|
|
129
|
+
'models.py': get_app_template_content('app_models.py', app_name),
|
|
130
|
+
'urls.py': get_app_template_content('app_urls.py', app_name),
|
|
131
|
+
'views.py': get_app_template_content('app_views.py', app_name),
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
for filename, content in files_content.items():
|
|
135
|
+
file_path = os.path.join(base_path, filename)
|
|
136
|
+
with open(file_path, 'w') as f:
|
|
137
|
+
f.write(content)
|
|
138
|
+
|
|
139
|
+
print_success(f"App '{app_name}' created successfully!")
|
|
140
|
+
|
|
141
|
+
# Add to INSTALLED_APPS
|
|
142
|
+
if add_to_installed_apps(app_name):
|
|
143
|
+
print_success(f"Added 'apps.{app_name}' to INSTALLED_APPS")
|
|
144
|
+
else:
|
|
145
|
+
print_info(f"Please manually add 'apps.{app_name}' to INSTALLED_APPS in your settings")
|
|
146
|
+
|
|
147
|
+
# Add to main URLs
|
|
148
|
+
if add_to_main_urls(app_name):
|
|
149
|
+
print_success(f"Added app URLs to main urls.py")
|
|
150
|
+
else:
|
|
151
|
+
print_info(f"Please manually add: path('{app_name}/', include('apps.{app_name}.urls')) to your main urls.py")
|
|
152
|
+
|
|
153
|
+
print_info("Next steps:")
|
|
154
|
+
print_info(f" 1. Test the app: GET /{app_name}/hello/ (returns Hello World)")
|
|
155
|
+
print_info(f" 2. Run 'python manage.py makemigrations {app_name}' after creating models")
|
|
156
|
+
print_info(f" 3. Start building your API endpoints in apps/{app_name}/views.py")
|
|
157
|
+
|
|
158
|
+
return True
|
|
159
|
+
|
|
160
|
+
def add_to_installed_apps(app_name):
|
|
161
|
+
"""Add the new app to INSTALLED_APPS in settings."""
|
|
162
|
+
# Find settings files
|
|
163
|
+
settings_files = []
|
|
164
|
+
|
|
165
|
+
# Look for settings in common locations
|
|
166
|
+
possible_settings = [
|
|
167
|
+
'settings.py',
|
|
168
|
+
'settings/base.py',
|
|
169
|
+
'settings/dev.py',
|
|
170
|
+
]
|
|
171
|
+
|
|
172
|
+
# Find project directory (should contain settings)
|
|
173
|
+
for root, dirs, files in os.walk('.'):
|
|
174
|
+
if 'settings.py' in files or 'settings' in dirs:
|
|
175
|
+
for settings_file in possible_settings:
|
|
176
|
+
settings_path = os.path.join(root, settings_file)
|
|
177
|
+
if os.path.exists(settings_path):
|
|
178
|
+
settings_files.append(settings_path)
|
|
179
|
+
break
|
|
180
|
+
|
|
181
|
+
if not settings_files:
|
|
182
|
+
return False
|
|
183
|
+
|
|
184
|
+
# Use the first settings file found (usually base.py or settings.py)
|
|
185
|
+
settings_file = settings_files[0]
|
|
186
|
+
|
|
187
|
+
try:
|
|
188
|
+
with open(settings_file, 'r', encoding='utf-8') as f:
|
|
189
|
+
content = f.read()
|
|
190
|
+
|
|
191
|
+
# Check if app is already in INSTALLED_APPS
|
|
192
|
+
if f"'apps.{app_name}'" in content or f'"apps.{app_name}"' in content:
|
|
193
|
+
return True # Already added
|
|
194
|
+
|
|
195
|
+
# Find INSTALLED_APPS and add the new app
|
|
196
|
+
import re
|
|
197
|
+
|
|
198
|
+
# Pattern to match INSTALLED_APPS
|
|
199
|
+
pattern = r'(INSTALLED_APPS\s*=\s*\[)(.*?)(\])'
|
|
200
|
+
match = re.search(pattern, content, re.DOTALL)
|
|
201
|
+
|
|
202
|
+
if match:
|
|
203
|
+
start, apps_content, end = match.groups()
|
|
204
|
+
|
|
205
|
+
# Add the new app to the end of the list
|
|
206
|
+
new_app_line = f" 'apps.{app_name}',\n"
|
|
207
|
+
|
|
208
|
+
# Insert before the closing bracket
|
|
209
|
+
new_content = content.replace(
|
|
210
|
+
match.group(0),
|
|
211
|
+
f"{start}{apps_content.rstrip()}\n{new_app_line}{end}"
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
with open(settings_file, 'w', encoding='utf-8') as f:
|
|
215
|
+
f.write(new_content)
|
|
216
|
+
|
|
217
|
+
return True
|
|
218
|
+
|
|
219
|
+
except Exception as e:
|
|
220
|
+
print_error(f"Failed to update INSTALLED_APPS: {e}")
|
|
221
|
+
return False
|
|
222
|
+
|
|
223
|
+
return False
|
|
224
|
+
|
|
225
|
+
def add_to_main_urls(app_name):
|
|
226
|
+
"""Add the new app URLs to the main urls.py file."""
|
|
227
|
+
# Find main urls.py
|
|
228
|
+
urls_files = []
|
|
229
|
+
|
|
230
|
+
# Look for main urls.py (usually in project root or project directory)
|
|
231
|
+
for root, dirs, files in os.walk('.'):
|
|
232
|
+
if 'urls.py' in files:
|
|
233
|
+
urls_path = os.path.join(root, 'urls.py')
|
|
234
|
+
# Skip app-specific urls.py files
|
|
235
|
+
if 'apps' not in root:
|
|
236
|
+
urls_files.append(urls_path)
|
|
237
|
+
|
|
238
|
+
if not urls_files:
|
|
239
|
+
return False
|
|
240
|
+
|
|
241
|
+
# Use the first main urls.py found
|
|
242
|
+
urls_file = urls_files[0]
|
|
243
|
+
|
|
244
|
+
try:
|
|
245
|
+
with open(urls_file, 'r', encoding='utf-8') as f:
|
|
246
|
+
content = f.read()
|
|
247
|
+
|
|
248
|
+
# Check if app URLs are already included
|
|
249
|
+
if f"'{app_name}/'" in content or f'"{app_name}/"' in content:
|
|
250
|
+
return True # Already added
|
|
251
|
+
|
|
252
|
+
# Check if include is imported
|
|
253
|
+
if 'from django.urls import' in content:
|
|
254
|
+
if 'include' not in content:
|
|
255
|
+
# Add include to existing import
|
|
256
|
+
content = content.replace(
|
|
257
|
+
'from django.urls import',
|
|
258
|
+
'from django.urls import include,'
|
|
259
|
+
).replace('include,', 'include, ')
|
|
260
|
+
else:
|
|
261
|
+
# Add the import at the top
|
|
262
|
+
lines = content.split('\n')
|
|
263
|
+
for i, line in enumerate(lines):
|
|
264
|
+
if line.startswith('from django.'):
|
|
265
|
+
lines.insert(i + 1, 'from django.urls import path, include')
|
|
266
|
+
break
|
|
267
|
+
content = '\n'.join(lines)
|
|
268
|
+
|
|
269
|
+
# Find urlpatterns and add the new app
|
|
270
|
+
import re
|
|
271
|
+
|
|
272
|
+
pattern = r'(urlpatterns\s*=\s*\[)(.*?)(\])'
|
|
273
|
+
match = re.search(pattern, content, re.DOTALL)
|
|
274
|
+
|
|
275
|
+
if match:
|
|
276
|
+
start, urls_content, end = match.groups()
|
|
277
|
+
|
|
278
|
+
# Add the new app URL pattern
|
|
279
|
+
new_url_line = f" path('{app_name}/', include('apps.{app_name}.urls')),\n"
|
|
280
|
+
|
|
281
|
+
# Insert before the closing bracket
|
|
282
|
+
new_content = content.replace(
|
|
283
|
+
match.group(0),
|
|
284
|
+
f"{start}{urls_content.rstrip()}\n{new_url_line}{end}"
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
with open(urls_file, 'w', encoding='utf-8') as f:
|
|
288
|
+
f.write(new_content)
|
|
289
|
+
|
|
290
|
+
return True
|
|
291
|
+
|
|
292
|
+
except Exception as e:
|
|
293
|
+
print_error(f"Failed to update main urls.py: {e}")
|
|
294
|
+
return False
|
|
295
|
+
|
|
296
|
+
return False
|