aipostify 1.0.1__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 (233) hide show
  1. aipostify/__init__.py +22 -0
  2. aipostify/cli.py +167 -0
  3. aipostify/project_template/.env.example +23 -0
  4. aipostify/project_template/.gitattributes +2 -0
  5. aipostify/project_template/.gitignore +73 -0
  6. aipostify/project_template/app/__init__.py +1 -0
  7. aipostify/project_template/app/apps.py +12 -0
  8. aipostify/project_template/app/http/controllers/__init__.py +4 -0
  9. aipostify/project_template/app/http/controllers/controller.py +11 -0
  10. aipostify/project_template/app/http/controllers/welcome_controller.py +10 -0
  11. aipostify/project_template/app/models/__init__.py +3 -0
  12. aipostify/project_template/app/models/user.py +22 -0
  13. aipostify/project_template/artisan +22 -0
  14. aipostify/project_template/config/app.py +11 -0
  15. aipostify/project_template/config/database.py +21 -0
  16. aipostify/project_template/config/mail.py +14 -0
  17. aipostify/project_template/config/queue.py +7 -0
  18. aipostify/project_template/database/migrations/0001_initial.py +29 -0
  19. aipostify/project_template/database/migrations/__init__.py +1 -0
  20. aipostify/project_template/database/seeders/database_seeder.py +10 -0
  21. aipostify/project_template/database/seeders/user_seeder.py +21 -0
  22. aipostify/project_template/framework/__init__.py +10 -0
  23. aipostify/project_template/framework/apps.py +6 -0
  24. aipostify/project_template/framework/auto_discovery.py +46 -0
  25. aipostify/project_template/framework/console/__init__.py +4 -0
  26. aipostify/project_template/framework/console/artisan.py +213 -0
  27. aipostify/project_template/framework/console/command.py +59 -0
  28. aipostify/project_template/framework/console/commands/cache_clear.py +35 -0
  29. aipostify/project_template/framework/console/commands/config_cache.py +36 -0
  30. aipostify/project_template/framework/console/commands/db_check.py +61 -0
  31. aipostify/project_template/framework/console/commands/db_create.py +36 -0
  32. aipostify/project_template/framework/console/commands/db_seed.py +34 -0
  33. aipostify/project_template/framework/console/commands/db_show.py +52 -0
  34. aipostify/project_template/framework/console/commands/db_transfer.py +37 -0
  35. aipostify/project_template/framework/console/commands/key_generate.py +36 -0
  36. aipostify/project_template/framework/console/commands/make_auth.py +268 -0
  37. aipostify/project_template/framework/console/commands/make_command.py +45 -0
  38. aipostify/project_template/framework/console/commands/make_component.py +39 -0
  39. aipostify/project_template/framework/console/commands/make_controller.py +77 -0
  40. aipostify/project_template/framework/console/commands/make_crud.py +236 -0
  41. aipostify/project_template/framework/console/commands/make_job.py +42 -0
  42. aipostify/project_template/framework/console/commands/make_layout.py +38 -0
  43. aipostify/project_template/framework/console/commands/make_middleware.py +39 -0
  44. aipostify/project_template/framework/console/commands/make_migration.py +32 -0
  45. aipostify/project_template/framework/console/commands/make_model.py +57 -0
  46. aipostify/project_template/framework/console/commands/make_request.py +39 -0
  47. aipostify/project_template/framework/console/commands/make_seeder.py +42 -0
  48. aipostify/project_template/framework/console/commands/make_service.py +39 -0
  49. aipostify/project_template/framework/console/commands/make_view.py +42 -0
  50. aipostify/project_template/framework/console/commands/migrate.py +30 -0
  51. aipostify/project_template/framework/console/commands/migrate_fresh.py +48 -0
  52. aipostify/project_template/framework/console/commands/migrate_refresh.py +19 -0
  53. aipostify/project_template/framework/console/commands/migrate_rollback.py +20 -0
  54. aipostify/project_template/framework/console/commands/migrate_status.py +33 -0
  55. aipostify/project_template/framework/console/commands/ptl_format.py +146 -0
  56. aipostify/project_template/framework/console/commands/ptl_install_vscode.py +106 -0
  57. aipostify/project_template/framework/console/commands/pypi_publish.py +93 -0
  58. aipostify/project_template/framework/console/commands/queue_work.py +38 -0
  59. aipostify/project_template/framework/console/commands/route_list.py +38 -0
  60. aipostify/project_template/framework/console/commands/schedule_run.py +38 -0
  61. aipostify/project_template/framework/console/commands/serve.py +39 -0
  62. aipostify/project_template/framework/console/commands/storage_link.py +41 -0
  63. aipostify/project_template/framework/console/commands/test_command.py +20 -0
  64. aipostify/project_template/framework/console/commands/tinker.py +48 -0
  65. aipostify/project_template/framework/console/commands/view_cache.py +33 -0
  66. aipostify/project_template/framework/console/commands/view_check.py +26 -0
  67. aipostify/project_template/framework/console/commands/view_clear.py +16 -0
  68. aipostify/project_template/framework/database/__init__.py +13 -0
  69. aipostify/project_template/framework/database/connector.py +90 -0
  70. aipostify/project_template/framework/database/fields.py +51 -0
  71. aipostify/project_template/framework/database/model.py +93 -0
  72. aipostify/project_template/framework/database/seeder.py +20 -0
  73. aipostify/project_template/framework/http/__init__.py +17 -0
  74. aipostify/project_template/framework/http/controller.py +39 -0
  75. aipostify/project_template/framework/http/middleware.py +50 -0
  76. aipostify/project_template/framework/http/request.py +61 -0
  77. aipostify/project_template/framework/http/response.py +76 -0
  78. aipostify/project_template/framework/http/validator.py +253 -0
  79. aipostify/project_template/framework/kernel.py +71 -0
  80. aipostify/project_template/framework/queue/__init__.py +3 -0
  81. aipostify/project_template/framework/queue/queue.py +111 -0
  82. aipostify/project_template/framework/routing/__init__.py +4 -0
  83. aipostify/project_template/framework/routing/resolver.py +149 -0
  84. aipostify/project_template/framework/routing/route.py +172 -0
  85. aipostify/project_template/framework/routing/templatetags/__init__.py +1 -0
  86. aipostify/project_template/framework/routing/templatetags/aipostify.py +69 -0
  87. aipostify/project_template/framework/routing/urls.py +45 -0
  88. aipostify/project_template/framework/schedule/__init__.py +3 -0
  89. aipostify/project_template/framework/schedule/schedule.py +101 -0
  90. aipostify/project_template/framework/settings.py +139 -0
  91. aipostify/project_template/framework/stubs/command.stub +8 -0
  92. aipostify/project_template/framework/stubs/component.stub +4 -0
  93. aipostify/project_template/framework/stubs/controller.resource.stub +40 -0
  94. aipostify/project_template/framework/stubs/controller.stub +5 -0
  95. aipostify/project_template/framework/stubs/job.stub +12 -0
  96. aipostify/project_template/framework/stubs/layout.stub +15 -0
  97. aipostify/project_template/framework/stubs/middleware.stub +7 -0
  98. aipostify/project_template/framework/stubs/model.stub +10 -0
  99. aipostify/project_template/framework/stubs/request.stub +12 -0
  100. aipostify/project_template/framework/stubs/seeder.stub +6 -0
  101. aipostify/project_template/framework/stubs/service.stub +5 -0
  102. aipostify/project_template/framework/stubs/view.stub +10 -0
  103. aipostify/project_template/framework/view/__init__.py +28 -0
  104. aipostify/project_template/framework/view/compiler.py +738 -0
  105. aipostify/project_template/framework/view/engine.py +403 -0
  106. aipostify/project_template/framework/view/exceptions.py +35 -0
  107. aipostify/project_template/framework/view/filters.py +145 -0
  108. aipostify/project_template/framework/view/formatter.py +222 -0
  109. aipostify/project_template/framework/view/helpers.py +114 -0
  110. aipostify/project_template/framework/view/sandbox.py +136 -0
  111. aipostify/project_template/public/css/app.css +234 -0
  112. aipostify/project_template/public/js/app.js +19 -0
  113. aipostify/project_template/pytest.ini +3 -0
  114. aipostify/project_template/requirements.txt +6 -0
  115. aipostify/project_template/resources/lang/en.json +14 -0
  116. aipostify/project_template/resources/lang/gu.json +14 -0
  117. aipostify/project_template/resources/lang/hi.json +14 -0
  118. aipostify/project_template/resources/views/components/alert.ptl +8 -0
  119. aipostify/project_template/resources/views/errors/404.html +16 -0
  120. aipostify/project_template/resources/views/errors/500.html +16 -0
  121. aipostify/project_template/resources/views/layouts/app.ptl +57 -0
  122. aipostify/project_template/resources/views/welcome.ptl +708 -0
  123. aipostify/project_template/routes/api.py +9 -0
  124. aipostify/project_template/routes/console.py +10 -0
  125. aipostify/project_template/routes/web.py +8 -0
  126. aipostify/project_template/storage/app/public/.gitkeep +1 -0
  127. aipostify/project_template/storage/framework/cache/.gitkeep +1 -0
  128. aipostify/project_template/storage/framework/sessions/.gitkeep +1 -0
  129. aipostify/project_template/storage/framework/views/521f046fdcb33fd1c337ff0e276264052596e53a7f71bde9b60b28eb339ca64f.py +43 -0
  130. aipostify/project_template/storage/logs/.gitkeep +1 -0
  131. aipostify/project_template/tools/vscode-postify/README.md +46 -0
  132. aipostify/project_template/tools/vscode-postify/extension.js +1171 -0
  133. aipostify/project_template/tools/vscode-postify/icons/icon-theme.json +13 -0
  134. aipostify/project_template/tools/vscode-postify/icons/ptl.svg +18 -0
  135. aipostify/project_template/tools/vscode-postify/language-configuration.json +26 -0
  136. aipostify/project_template/tools/vscode-postify/package.json +78 -0
  137. aipostify/project_template/tools/vscode-postify/snippets/postify.code-snippets +314 -0
  138. aipostify/project_template/tools/vscode-postify/syntaxes/postify.tmLanguage.json +54 -0
  139. aipostify-1.0.1.dist-info/METADATA +162 -0
  140. aipostify-1.0.1.dist-info/RECORD +233 -0
  141. aipostify-1.0.1.dist-info/WHEEL +5 -0
  142. aipostify-1.0.1.dist-info/entry_points.txt +4 -0
  143. aipostify-1.0.1.dist-info/licenses/LICENSE +21 -0
  144. aipostify-1.0.1.dist-info/top_level.txt +2 -0
  145. framework/__init__.py +10 -0
  146. framework/apps.py +6 -0
  147. framework/auto_discovery.py +46 -0
  148. framework/console/__init__.py +4 -0
  149. framework/console/artisan.py +213 -0
  150. framework/console/command.py +59 -0
  151. framework/console/commands/cache_clear.py +35 -0
  152. framework/console/commands/config_cache.py +36 -0
  153. framework/console/commands/db_check.py +61 -0
  154. framework/console/commands/db_create.py +36 -0
  155. framework/console/commands/db_seed.py +34 -0
  156. framework/console/commands/db_show.py +52 -0
  157. framework/console/commands/db_transfer.py +37 -0
  158. framework/console/commands/key_generate.py +36 -0
  159. framework/console/commands/make_auth.py +268 -0
  160. framework/console/commands/make_command.py +45 -0
  161. framework/console/commands/make_component.py +39 -0
  162. framework/console/commands/make_controller.py +77 -0
  163. framework/console/commands/make_crud.py +236 -0
  164. framework/console/commands/make_job.py +42 -0
  165. framework/console/commands/make_layout.py +38 -0
  166. framework/console/commands/make_middleware.py +39 -0
  167. framework/console/commands/make_migration.py +32 -0
  168. framework/console/commands/make_model.py +57 -0
  169. framework/console/commands/make_request.py +39 -0
  170. framework/console/commands/make_seeder.py +42 -0
  171. framework/console/commands/make_service.py +39 -0
  172. framework/console/commands/make_view.py +42 -0
  173. framework/console/commands/migrate.py +30 -0
  174. framework/console/commands/migrate_fresh.py +48 -0
  175. framework/console/commands/migrate_refresh.py +19 -0
  176. framework/console/commands/migrate_rollback.py +20 -0
  177. framework/console/commands/migrate_status.py +33 -0
  178. framework/console/commands/ptl_format.py +146 -0
  179. framework/console/commands/ptl_install_vscode.py +106 -0
  180. framework/console/commands/pypi_publish.py +93 -0
  181. framework/console/commands/queue_work.py +38 -0
  182. framework/console/commands/route_list.py +38 -0
  183. framework/console/commands/schedule_run.py +38 -0
  184. framework/console/commands/serve.py +39 -0
  185. framework/console/commands/storage_link.py +41 -0
  186. framework/console/commands/test_command.py +20 -0
  187. framework/console/commands/tinker.py +48 -0
  188. framework/console/commands/view_cache.py +33 -0
  189. framework/console/commands/view_check.py +26 -0
  190. framework/console/commands/view_clear.py +16 -0
  191. framework/database/__init__.py +13 -0
  192. framework/database/connector.py +90 -0
  193. framework/database/fields.py +51 -0
  194. framework/database/model.py +93 -0
  195. framework/database/seeder.py +20 -0
  196. framework/http/__init__.py +17 -0
  197. framework/http/controller.py +39 -0
  198. framework/http/middleware.py +50 -0
  199. framework/http/request.py +61 -0
  200. framework/http/response.py +76 -0
  201. framework/http/validator.py +253 -0
  202. framework/kernel.py +71 -0
  203. framework/queue/__init__.py +3 -0
  204. framework/queue/queue.py +111 -0
  205. framework/routing/__init__.py +4 -0
  206. framework/routing/resolver.py +149 -0
  207. framework/routing/route.py +172 -0
  208. framework/routing/templatetags/__init__.py +1 -0
  209. framework/routing/templatetags/aipostify.py +69 -0
  210. framework/routing/urls.py +45 -0
  211. framework/schedule/__init__.py +3 -0
  212. framework/schedule/schedule.py +101 -0
  213. framework/settings.py +139 -0
  214. framework/stubs/command.stub +8 -0
  215. framework/stubs/component.stub +4 -0
  216. framework/stubs/controller.resource.stub +40 -0
  217. framework/stubs/controller.stub +5 -0
  218. framework/stubs/job.stub +12 -0
  219. framework/stubs/layout.stub +15 -0
  220. framework/stubs/middleware.stub +7 -0
  221. framework/stubs/model.stub +10 -0
  222. framework/stubs/request.stub +12 -0
  223. framework/stubs/seeder.stub +6 -0
  224. framework/stubs/service.stub +5 -0
  225. framework/stubs/view.stub +10 -0
  226. framework/view/__init__.py +28 -0
  227. framework/view/compiler.py +738 -0
  228. framework/view/engine.py +403 -0
  229. framework/view/exceptions.py +35 -0
  230. framework/view/filters.py +145 -0
  231. framework/view/formatter.py +222 -0
  232. framework/view/helpers.py +114 -0
  233. framework/view/sandbox.py +136 -0
aipostify/__init__.py ADDED
@@ -0,0 +1,22 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ AIPostify
4
+ Laravel-Style Python MVC Framework with PTL (Postify Template Language).
5
+ """
6
+
7
+ __title__ = "aipostify"
8
+ __version__ = "1.0.1"
9
+ __author__ = "AIPostify Contributors"
10
+ __license__ = "MIT"
11
+ __description__ = "Laravel-Style Python MVC Starter Framework with PTL Template Engine"
12
+
13
+ from framework.kernel import bootstrap, get_wsgi_application, get_asgi_application
14
+
15
+ __all__ = [
16
+ "bootstrap",
17
+ "get_wsgi_application",
18
+ "get_asgi_application",
19
+ "__version__",
20
+ "__author__",
21
+ "__license__",
22
+ ]
aipostify/cli.py ADDED
@@ -0,0 +1,167 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ AIPostify CLI Entry Point
4
+ Provides global 'aipostify' and 'artisan' command-line tools.
5
+ """
6
+
7
+ import sys
8
+ import os
9
+ import shutil
10
+ from pathlib import Path
11
+
12
+
13
+ BANNER = r"""
14
+ ___ ____ ___ __ _ ____
15
+ / | / _/ / _ \___ ___ / /_ (_)/ __/__ __
16
+ / /| | / / / ___/ _ \ (_-< / __// // _/ / / / /
17
+ /_/ |_|_/___//_/ \___//___//_/ /_//_/ \__, /
18
+ /____/
19
+ Laravel-Style Python MVC Framework • v1.0.1
20
+ """
21
+
22
+
23
+ def _find_project_root():
24
+ """Look up directory tree for an artisan file to identify AIPostify project root."""
25
+ current = Path.cwd().resolve()
26
+ while current != current.parent:
27
+ if (current / "artisan").exists() and (current / "framework").exists():
28
+ return current
29
+ current = current.parent
30
+ return None
31
+
32
+
33
+ def _create_new_project(project_name: str):
34
+ """Scaffold a brand new AIPostify project in the specified directory."""
35
+ target_dir = Path.cwd() / project_name
36
+ if target_dir.exists() and any(target_dir.iterdir()):
37
+ print(f"\033[91m[Error]\033[0m Directory [{project_name}] already exists and is not empty.")
38
+ return 1
39
+
40
+ print(f"\033[95m{BANNER}\033[0m")
41
+ print(f"\033[96mCreating a new AIPostify application in:\033[0m {target_dir}\n")
42
+
43
+ # Locate package template / source directory
44
+ cli_dir = Path(__file__).resolve().parent
45
+ template_dir = cli_dir / "project_template"
46
+ if not template_dir.exists():
47
+ # Fall back to repository root during development
48
+ template_dir = cli_dir.parent
49
+
50
+ target_dir.mkdir(parents=True, exist_ok=True)
51
+
52
+ # 1. Copy complete project structure from template
53
+ if template_dir.exists():
54
+ shutil.copytree(
55
+ template_dir,
56
+ target_dir,
57
+ dirs_exist_ok=True,
58
+ ignore=shutil.ignore_patterns(
59
+ "__pycache__",
60
+ "*.pyc",
61
+ "*.sqlite",
62
+ "*.sqlite3",
63
+ "*.log",
64
+ ".tmp*",
65
+ "dist",
66
+ "build",
67
+ "*.egg-info",
68
+ ".pytest_cache",
69
+ ),
70
+ )
71
+ print(" \033[92m+\033[0m Created application core and directories (app, config, database, framework, resources, routes, storage, tools)")
72
+
73
+ # 2. Create .env from .env.example
74
+ env_example = target_dir / ".env.example"
75
+ env_file = target_dir / ".env"
76
+ if env_example.exists() and not env_file.exists():
77
+ shutil.copy2(env_example, env_file)
78
+ print(" \033[92m+\033[0m Generated .env configuration")
79
+
80
+ # 3. Ensure all storage subdirectories exist with .gitkeep
81
+ storage_dirs = [
82
+ "logs",
83
+ "app/public",
84
+ "framework/cache",
85
+ "framework/sessions",
86
+ "framework/views",
87
+ ]
88
+ for sub in storage_dirs:
89
+ sub_path = target_dir / "storage" / sub
90
+ sub_path.mkdir(parents=True, exist_ok=True)
91
+ gitkeep = sub_path / ".gitkeep"
92
+ if not gitkeep.exists():
93
+ gitkeep.touch()
94
+
95
+ print("\n\033[92m[Success] AIPostify application created successfully!\033[0m")
96
+ print("\n\033[93mNext Steps:\033[0m")
97
+ print(f" cd {project_name}")
98
+ print(" python artisan key:generate")
99
+ print(" python artisan migrate")
100
+ print(" python artisan serve\n")
101
+ return 0
102
+
103
+
104
+ def main():
105
+ """Main CLI handler for 'aipostify' command."""
106
+ args = sys.argv[1:]
107
+
108
+ if not args or args[0] in ["-h", "--help", "help"]:
109
+ print(f"\033[95m{BANNER}\033[0m")
110
+ print("Usage:")
111
+ print(" aipostify new <project_name> Create a new AIPostify project")
112
+ print(" aipostify --version, -v Display AIPostify version")
113
+ print(" aipostify <command> Run artisan command in current project")
114
+ print("\nExamples:")
115
+ print(" aipostify new myapp")
116
+ print(" aipostify serve")
117
+ print(" aipostify route:list")
118
+ return 0
119
+
120
+ if args[0] in ["-v", "--version", "version"]:
121
+ from . import __version__
122
+ print(f"AIPostify Framework v{__version__}")
123
+ return 0
124
+
125
+ if args[0] == "new":
126
+ if len(args) < 2:
127
+ print("\033[91m[Error]\033[0m Please provide a project name:")
128
+ print(" aipostify new <project_name>")
129
+ return 1
130
+ return _create_new_project(args[1])
131
+
132
+ # Check if we are inside an AIPostify project
133
+ project_root = _find_project_root()
134
+ if project_root:
135
+ artisan_path = project_root / "artisan"
136
+ cmd = [sys.executable, str(artisan_path)] + args
137
+ import subprocess
138
+ return subprocess.run(cmd).returncode
139
+ else:
140
+ print(f"\033[91m[Error]\033[0m Could not find an AIPostify project with an 'artisan' file.")
141
+ print("Run \033[96maipostify new <project_name>\033[0m to create a new application.")
142
+ return 1
143
+
144
+
145
+ def artisan_main():
146
+ """Entry point for standalone 'artisan' command."""
147
+ project_root = _find_project_root()
148
+ if not project_root:
149
+ # Fall back to current working directory
150
+ project_root = Path.cwd().resolve()
151
+
152
+ if str(project_root) not in sys.path:
153
+ sys.path.insert(0, str(project_root))
154
+
155
+ try:
156
+ from framework.kernel import bootstrap
157
+ bootstrap(project_root)
158
+ from framework.console import Artisan
159
+ exit_code = Artisan.handle(sys.argv[1:])
160
+ return exit_code or 0
161
+ except Exception as e:
162
+ print(f"\033[91m[Artisan Error]\033[0m {e}")
163
+ return 1
164
+
165
+
166
+ if __name__ == "__main__":
167
+ sys.exit(main())
@@ -0,0 +1,23 @@
1
+ APP_NAME=aipostify
2
+ APP_ENV=local
3
+ APP_DEBUG=true
4
+ APP_KEY=
5
+ APP_URL=http://127.0.0.1:8000
6
+ APP_LOCALE=en
7
+
8
+ # Database Connection: sqlite | mysql
9
+ DB_CONNECTION=sqlite
10
+
11
+ # --- SQLite (default) ---
12
+ DB_SQLITE_PATH=database/database.sqlite
13
+
14
+ # --- MySQL (Set DB_CONNECTION=mysql to use) ---
15
+ DB_HOST=127.0.0.1
16
+ DB_PORT=3306
17
+ DB_DATABASE=aipostify
18
+ DB_USERNAME=root
19
+ DB_PASSWORD=
20
+
21
+ QUEUE_CONNECTION=database
22
+ CACHE_DRIVER=file
23
+ SESSION_DRIVER=file
@@ -0,0 +1,2 @@
1
+ *.ptl linguist-language=HTML
2
+ *.ptl linguist-detectable=true
@@ -0,0 +1,73 @@
1
+ # AIPostify Git Ignore
2
+
3
+ # Environment & Secrets (Crucial: Never commit .env)
4
+ .env
5
+ .env.backup
6
+ .env.production
7
+
8
+ # Python & Bytecode
9
+ __pycache__/
10
+ *.py[cod]
11
+ *$py.class
12
+ *.so
13
+ .Python
14
+ build/
15
+ develop-eggs/
16
+ dist/
17
+ downloads/
18
+ eggs/
19
+ .eggs/
20
+ lib/
21
+ lib64/
22
+ parts/
23
+ sdist/
24
+ var/
25
+ wheels/
26
+ *.egg-info/
27
+ .installed.cfg
28
+ *.egg
29
+
30
+ # Virtual Environments
31
+ venv/
32
+ .venv/
33
+ env/
34
+ ENV/
35
+ env.bak/
36
+ venv.bak/
37
+
38
+ # Databases (Crucial: Keep local SQLite and transfer dumps out of git)
39
+ *.sqlite
40
+ *.sqlite3
41
+ *.db
42
+ database/*.sqlite
43
+ database/*.sqlite3
44
+ *.sql
45
+ storage/app/db_transfer_dump.json
46
+
47
+ # Storage Logs, Sessions, and Caches
48
+ storage/logs/*.log
49
+ storage/framework/cache/*
50
+ storage/framework/sessions/*
51
+ !storage/framework/cache/.gitkeep
52
+ !storage/framework/sessions/.gitkeep
53
+ !storage/logs/.gitkeep
54
+ !storage/app/public/.gitkeep
55
+
56
+ # Public Storage Symlink
57
+ public/storage
58
+
59
+ # Testing & Coverage
60
+ .pytest_cache/
61
+ .coverage
62
+ htmlcov/
63
+ .tox/
64
+ .nox/
65
+
66
+ # IDE & Editor specific
67
+ .idea/
68
+ .vscode/
69
+ *.swp
70
+ *.swo
71
+ *~
72
+ .DS_Store
73
+ Thumbs.db
@@ -0,0 +1 @@
1
+ default_app_config = "app.apps.UserAppConfig"
@@ -0,0 +1,12 @@
1
+ from django.apps import AppConfig
2
+ from pathlib import Path
3
+
4
+ class UserAppConfig(AppConfig):
5
+ default_auto_field = "django.db.models.BigAutoField"
6
+ name = "app"
7
+ verbose_name = "Application"
8
+
9
+ def ready(self):
10
+ from framework.auto_discovery import discover_models
11
+ from django.conf import settings
12
+ discover_models(settings.BASE_DIR)
@@ -0,0 +1,4 @@
1
+ from .controller import Controller
2
+ from .welcome_controller import WelcomeController
3
+
4
+ __all__ = ["Controller", "WelcomeController"]
@@ -0,0 +1,11 @@
1
+ """
2
+ Base Controller
3
+ """
4
+
5
+ from framework.http.controller import Controller as BaseController
6
+
7
+ class Controller(BaseController):
8
+ """
9
+ Base controller class from which all application controllers inherit.
10
+ """
11
+ pass
@@ -0,0 +1,10 @@
1
+ """
2
+ Welcome Controller
3
+ Serves default Laravel welcome landing page
4
+ """
5
+
6
+ from app.http.controllers.controller import Controller
7
+
8
+ class WelcomeController(Controller):
9
+ def index(self, request):
10
+ return self.render(request, "welcome")
@@ -0,0 +1,3 @@
1
+ from .user import User
2
+
3
+ __all__ = ["User"]
@@ -0,0 +1,22 @@
1
+ """
2
+ User Model
3
+ Default Laravel-style User Model
4
+ """
5
+
6
+ from framework.database.model import Model
7
+ from framework.database.fields import String, Email, DateTime
8
+
9
+ class User(Model):
10
+ name = String(max_length=255)
11
+ email = Email(unique=True)
12
+ password = String(max_length=255)
13
+ email_verified_at = DateTime(null=True, blank=True)
14
+ remember_token = String(max_length=100, null=True, blank=True)
15
+ created_at = DateTime(auto_now_add=True)
16
+ updated_at = DateTime(auto_now=True)
17
+
18
+ class Meta:
19
+ db_table = "users"
20
+
21
+ def __str__(self):
22
+ return self.name or self.email or f"User #{self.id}"
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ AIPostify - Laravel-style Python MVC Starter Framework CLI
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ # Ensure project root is in python path
11
+ ROOT_DIR = Path(__file__).resolve().parent
12
+ if str(ROOT_DIR) not in sys.path:
13
+ sys.path.insert(0, str(ROOT_DIR))
14
+
15
+ from framework.kernel import bootstrap
16
+ bootstrap(ROOT_DIR)
17
+
18
+ from framework.console import Artisan
19
+
20
+ if __name__ == "__main__":
21
+ exit_code = Artisan.handle(sys.argv[1:])
22
+ sys.exit(exit_code or 0)
@@ -0,0 +1,11 @@
1
+ """
2
+ Application Configuration
3
+ """
4
+
5
+ import os
6
+
7
+ APP_NAME = os.getenv("APP_NAME", "AIPostify")
8
+ APP_ENV = os.getenv("APP_ENV", "local")
9
+ APP_DEBUG = os.getenv("APP_DEBUG", "true").lower() in ("true", "1", "yes")
10
+ APP_URL = os.getenv("APP_URL", "http://127.0.0.1:8000")
11
+ APP_LOCALE = os.getenv("APP_LOCALE", "en")
@@ -0,0 +1,21 @@
1
+ """
2
+ Database Configuration
3
+ """
4
+
5
+ import os
6
+
7
+ DB_CONNECTION = os.getenv("DB_CONNECTION", "sqlite")
8
+
9
+ DATABASES = {
10
+ "sqlite": {
11
+ "database": os.getenv("DB_DATABASE", "database/database.sqlite"),
12
+ },
13
+ "mysql": {
14
+ "host": os.getenv("DB_HOST", "127.0.0.1"),
15
+ "port": int(os.getenv("DB_PORT", "3306")),
16
+ "database": os.getenv("DB_DATABASE", "aipostify"),
17
+ "username": os.getenv("DB_USERNAME", "root"),
18
+ "password": os.getenv("DB_PASSWORD", ""),
19
+ "charset": "utf8mb4",
20
+ },
21
+ }
@@ -0,0 +1,14 @@
1
+ """
2
+ Mail Configuration
3
+ """
4
+
5
+ import os
6
+
7
+ MAIL_MAILER = os.getenv("MAIL_MAILER", "smtp")
8
+ MAIL_HOST = os.getenv("MAIL_HOST", "127.0.0.1")
9
+ MAIL_PORT = int(os.getenv("MAIL_PORT", "1025"))
10
+ MAIL_USERNAME = os.getenv("MAIL_USERNAME", "")
11
+ MAIL_PASSWORD = os.getenv("MAIL_PASSWORD", "")
12
+ MAIL_ENCRYPTION = os.getenv("MAIL_ENCRYPTION", "tls")
13
+ MAIL_FROM_ADDRESS = os.getenv("MAIL_FROM_ADDRESS", "hello@aipostify.test")
14
+ MAIL_FROM_NAME = os.getenv("APP_NAME", "AIPostify")
@@ -0,0 +1,7 @@
1
+ """
2
+ Queue & Jobs Configuration
3
+ """
4
+
5
+ import os
6
+
7
+ QUEUE_CONNECTION = os.getenv("QUEUE_CONNECTION", "database")
@@ -0,0 +1,29 @@
1
+ # Generated for default Laravel database schema
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ initial = True
9
+
10
+ dependencies = []
11
+
12
+ operations = [
13
+ migrations.CreateModel(
14
+ name='User',
15
+ fields=[
16
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
17
+ ('name', models.CharField(max_length=255)),
18
+ ('email', models.EmailField(max_length=254, unique=True)),
19
+ ('password', models.CharField(max_length=255)),
20
+ ('email_verified_at', models.DateTimeField(blank=True, null=True)),
21
+ ('remember_token', models.CharField(blank=True, max_length=100, null=True)),
22
+ ('created_at', models.DateTimeField(auto_now_add=True)),
23
+ ('updated_at', models.DateTimeField(auto_now=True)),
24
+ ],
25
+ options={
26
+ 'db_table': 'users',
27
+ },
28
+ ),
29
+ ]
@@ -0,0 +1 @@
1
+ # Database Migrations
@@ -0,0 +1,10 @@
1
+ """
2
+ Database Seeder
3
+ """
4
+
5
+ from framework.database.seeder import Seeder
6
+ from database.seeders.user_seeder import UserSeeder
7
+
8
+ class DatabaseSeeder(Seeder):
9
+ def run(self):
10
+ self.call(UserSeeder)
@@ -0,0 +1,21 @@
1
+ """
2
+ User Seeder
3
+ """
4
+
5
+ import os
6
+ from framework.database import Seeder
7
+ from django.contrib.auth import get_user_model
8
+
9
+ class UserSeeder(Seeder):
10
+ def run(self):
11
+ env = os.getenv("APP_ENV", "local").lower()
12
+ if env in ("production", "prod"):
13
+ print("Skipping default demo/admin user creation in production environment.")
14
+ return
15
+
16
+ User = get_user_model()
17
+ if not User.objects.filter(username="admin").exists():
18
+ User.objects.create_superuser("admin", "admin@aipostify.test", "admin123")
19
+
20
+ if not User.objects.filter(username="demo").exists():
21
+ User.objects.create_user("demo", "demo@aipostify.test", "demo123")
@@ -0,0 +1,10 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ AIPostify Framework Core
4
+ Laravel-Style Python MVC Framework with PTL Template Engine.
5
+ """
6
+
7
+ from .kernel import bootstrap, get_wsgi_application, get_asgi_application
8
+
9
+ __version__ = "1.0.0"
10
+ __all__ = ["bootstrap", "get_wsgi_application", "get_asgi_application", "__version__"]
@@ -0,0 +1,6 @@
1
+ from django.apps import AppConfig
2
+
3
+ class FrameworkConfig(AppConfig):
4
+ default_auto_field = "django.db.models.BigAutoField"
5
+ name = "framework"
6
+ verbose_name = "AIPostify Framework"
@@ -0,0 +1,46 @@
1
+ """
2
+ AIPostify Auto-Discovery Engine
3
+ Discovers Models, Controllers, Commands, Seeders, and Middleware without manual registration
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import importlib
9
+ import pkgutil
10
+ from pathlib import Path
11
+
12
+ def discover_models(base_dir: Path):
13
+ """Import all model modules in app/models to register them with Django ORM."""
14
+ models_dir = base_dir / "app" / "models"
15
+ if not models_dir.exists():
16
+ return
17
+
18
+ for _, module_name, _ in pkgutil.iter_modules([str(models_dir)]):
19
+ if module_name.startswith("__"):
20
+ continue
21
+ try:
22
+ importlib.import_module(f"app.models.{module_name}")
23
+ except Exception as e:
24
+ # Silently catch or log during initial discovery
25
+ pass
26
+
27
+ def discover_commands(base_dir: Path) -> dict:
28
+ """Discover user custom commands in app/console/commands."""
29
+ commands_dir = base_dir / "app" / "console" / "commands"
30
+ commands = {}
31
+ if not commands_dir.exists():
32
+ return commands
33
+
34
+ for _, module_name, _ in pkgutil.iter_modules([str(commands_dir)]):
35
+ if module_name.startswith("__"):
36
+ continue
37
+ try:
38
+ mod = importlib.import_module(f"app.console.commands.{module_name}")
39
+ for attr_name in dir(mod):
40
+ attr = getattr(mod, attr_name)
41
+ if isinstance(attr, type) and hasattr(attr, "signature") and attr.signature:
42
+ commands[attr.signature] = attr
43
+ except Exception:
44
+ pass
45
+
46
+ return commands
@@ -0,0 +1,4 @@
1
+ from .artisan import Artisan
2
+ from .command import Command
3
+
4
+ __all__ = ["Artisan", "Command"]