added plugin architecture

This commit is contained in:
vabene1111 2023-04-06 17:22:02 +02:00
parent 0ba2fa296a
commit 2552d27f6f
4 changed files with 58 additions and 2 deletions

1
.gitignore vendored
View File

@ -78,6 +78,7 @@ postgresql/
/docker-compose.override.yml
vue/node_modules
plugins
.vscode/
vetur.config.js
cookbook/static/vue

View File

@ -18,7 +18,7 @@
<excludeFolder url="file://$MODULE_DIR$/staticfiles" />
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.11 (recipes)" jdkType="Python SDK" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TemplatesService">

View File

@ -13,6 +13,8 @@ import ast
import json
import os
import re
import sys
import traceback
from django.contrib import messages
from django.utils.translation import gettext_lazy as _
@ -117,6 +119,34 @@ INSTALLED_APPS = [
'treebeard',
]
PLUGINS = []
try:
for d in os.listdir(os.path.join(BASE_DIR, 'recipes', 'plugins')):
if d != '__pycache__':
try:
apps_path = f'recipes.plugins.{d}.apps'
__import__(apps_path)
app_config_classname = dir(sys.modules[apps_path])[1]
plugin_module = f'recipes.plugins.{d}.apps.{app_config_classname}'
if plugin_module not in INSTALLED_APPS:
INSTALLED_APPS.append(plugin_module)
plugin_class = getattr(sys.modules[apps_path], app_config_classname)
plugin_config = {
'name': plugin_class.verbose_name if hasattr(plugin_class, 'verbose_name') else plugin_class.name,
'module': f'recipes.plugins.{d}',
'base_path': os.path.join(BASE_DIR, 'recipes', 'plugins', d),
'base_url': plugin_class.base_url,
'bundle_name': plugin_class.bundle_name if hasattr(plugin_class, 'bundle_name') else '',
}
PLUGINS.append(plugin_config)
except Exception:
if DEBUG:
traceback.print_exc()
print(f'ERROR failed to initialize plugin {d}')
except Exception:
if DEBUG:
print('ERROR failed to initialize plugins')
SOCIAL_PROVIDERS = os.getenv('SOCIAL_PROVIDERS').split(',') if os.getenv('SOCIAL_PROVIDERS') else []
SOCIALACCOUNT_EMAIL_VERIFICATION = 'none'
INSTALLED_APPS = INSTALLED_APPS + SOCIAL_PROVIDERS
@ -362,9 +392,20 @@ WEBPACK_LOADER = {
'POLL_INTERVAL': 0.1,
'TIMEOUT': None,
'IGNORE': [r'.+\.hot-update.js', r'.+\.map'],
}
},
}
for p in PLUGINS:
if p['bundle_name'] != '':
WEBPACK_LOADER[p['bundle_name']] = {
'CACHE': not DEBUG,
'BUNDLE_DIR_NAME': f'{p["base_path"]}/vue/', # must end with slash
'STATS_FILE': os.path.join(p["base_path"], 'vue', 'webpack-stats.json'),
'POLL_INTERVAL': 0.1,
'TIMEOUT': None,
'IGNORE': [r'.+\.hot-update.js', r'.+\.map'],
}
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/

View File

@ -14,6 +14,8 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
import traceback
from django.conf import settings
from django.contrib import admin
from django.urls import include, path, re_path
@ -42,3 +44,15 @@ if settings.ENABLE_METRICS:
if settings.GUNICORN_MEDIA or settings.DEBUG:
urlpatterns += re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
urlpatterns += re_path(r'^jsreverse.json$', reverse_views.urls_js, name='js_reverse'),
for p in settings.PLUGINS:
try:
urlpatterns += path(p['base_url'], include(f'{p["module"]}.urls')),
except ModuleNotFoundError as e:
if settings.DEBUG:
print(e.msg)
print(f'ERROR failed loading plugin <{p["name"]}> urls, did you forget creating urls.py in your plugin?')
except Exception as e:
if settings.DEBUG:
print(f'ERROR failed loading urls for plugin <{p["name"]}>')
traceback.format_exc()