mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-17 16:50:53 +00:00
104 lines
4.2 KiB
Python
104 lines
4.2 KiB
Python
from django.apps import AppConfig
|
|
import os
|
|
import sys
|
|
from django.db.models.signals import post_migrate
|
|
|
|
|
|
class PluginsConfig(AppConfig):
|
|
name = "apps.plugins"
|
|
verbose_name = "Plugins"
|
|
|
|
def ready(self):
|
|
"""Wire up plugin discovery without hitting the DB during app init.
|
|
|
|
- Skip during common management commands that don't need discovery.
|
|
- Register post_migrate handler to sync plugin registry to DB after migrations.
|
|
- Do an in-memory discovery (no DB) so registry is available early.
|
|
"""
|
|
try:
|
|
# Allow explicit opt-out via env var
|
|
if os.environ.get("DISPATCHARR_SKIP_PLUGIN_AUTODISCOVERY", "").lower() in ("1", "true", "yes"):
|
|
return
|
|
|
|
argv = sys.argv[1:] if len(sys.argv) > 1 else []
|
|
mgmt_cmds_to_skip = {
|
|
# Skip immediate discovery for these commands
|
|
"makemigrations", "collectstatic", "check", "test", "shell", "showmigrations",
|
|
}
|
|
if argv and argv[0] in mgmt_cmds_to_skip:
|
|
return
|
|
|
|
# Run discovery with DB sync after the plugins app has been migrated
|
|
def _post_migrate_discover(sender=None, app_config=None, **kwargs):
|
|
try:
|
|
if app_config and getattr(app_config, 'label', None) != 'plugins':
|
|
return
|
|
from .loader import PluginManager
|
|
PluginManager.get().discover_plugins(sync_db=True)
|
|
except Exception:
|
|
import logging
|
|
logging.getLogger(__name__).exception("Plugin discovery failed in post_migrate")
|
|
|
|
post_migrate.connect(
|
|
_post_migrate_discover,
|
|
dispatch_uid="apps.plugins.post_migrate_discover",
|
|
)
|
|
|
|
# Perform non-DB discovery now to populate in-memory registry.
|
|
from .loader import PluginManager
|
|
PluginManager.get().discover_plugins(sync_db=False)
|
|
except Exception:
|
|
# Avoid breaking startup due to plugin errors
|
|
import logging
|
|
|
|
logging.getLogger(__name__).exception("Plugin discovery wiring failed during app ready")
|
|
|
|
# Register periodic task for refreshing plugin repo manifests
|
|
self._setup_repo_refresh_schedule()
|
|
|
|
# Refresh repo manifests once at startup so the UI always has current data
|
|
self._enqueue_startup_refresh()
|
|
|
|
def _enqueue_startup_refresh(self):
|
|
from dispatcharr.app_initialization import should_skip_initialization
|
|
if should_skip_initialization():
|
|
return
|
|
try:
|
|
from .tasks import refresh_plugin_repos
|
|
refresh_plugin_repos.apply_async(countdown=10)
|
|
except Exception:
|
|
import logging
|
|
logging.getLogger(__name__).debug(
|
|
"Could not enqueue startup plugin repo refresh (Celery may not be ready yet)"
|
|
)
|
|
|
|
def _setup_repo_refresh_schedule(self):
|
|
from dispatcharr.app_initialization import should_skip_initialization
|
|
if should_skip_initialization():
|
|
return
|
|
try:
|
|
from core.scheduling import create_or_update_periodic_task, delete_periodic_task
|
|
from core.models import CoreSettings
|
|
from .tasks import PLUGIN_REPO_REFRESH_TASK_NAME
|
|
|
|
interval = 6
|
|
try:
|
|
obj = CoreSettings.objects.get(key="plugin_repo_settings")
|
|
interval = obj.value.get("refresh_interval_hours", 6)
|
|
except CoreSettings.DoesNotExist:
|
|
pass
|
|
|
|
if interval == 0:
|
|
delete_periodic_task(PLUGIN_REPO_REFRESH_TASK_NAME)
|
|
else:
|
|
create_or_update_periodic_task(
|
|
task_name=PLUGIN_REPO_REFRESH_TASK_NAME,
|
|
celery_task_path="apps.plugins.tasks.refresh_plugin_repos",
|
|
interval_hours=interval,
|
|
enabled=True,
|
|
)
|
|
except Exception:
|
|
import logging
|
|
logging.getLogger(__name__).debug(
|
|
"Could not set up plugin repo refresh schedule (migrations may not have run yet)"
|
|
)
|