diff --git a/django_periodiq/management/commands/runperiodiq.py b/django_periodiq/management/commands/runperiodiq.py index f1cd3f8..94fd9f2 100644 --- a/django_periodiq/management/commands/runperiodiq.py +++ b/django_periodiq/management/commands/runperiodiq.py @@ -1,4 +1,6 @@ import os +import importlib +import pkgutil import sys from django.apps import apps @@ -40,7 +42,6 @@ def handle(self, path, verbosity, pid_file, log_file, **options): executable_name, # -v -v ... *verbosity_args, - # django_dramatiq.tasks app1.tasks app2.tasks ... *tasks_modules, "--path", *path, ] @@ -59,19 +60,67 @@ def handle(self, path, verbosity, pid_file, log_file, **options): os.execvp(executable_path, process_args) def discover_tasks_modules(self): + task_module_names = getattr(settings, "DRAMATIQ_AUTODISCOVER_MODULES", ("tasks",)) ignored_modules = set(getattr(settings, "DRAMATIQ_IGNORED_MODULES", [])) - app_configs = (c for c in apps.get_app_configs() if module_has_submodule(c.module, "tasks")) - tasks_modules = ["django_periodiq.setup"] # Broker module is first - for conf in app_configs: - module = conf.name + ".tasks" - if module in ignored_modules: + app_configs = [] + for conf in apps.get_app_configs(): + for task_module in task_module_names: + if module_has_submodule(conf.module, task_module): + app_configs.append((conf, task_module)) + tasks_modules = ["django_periodiq.setup"] + + def is_ignored_module(module_name): + if not ignored_modules: + return False + + if module_name in ignored_modules: + return True + + name_parts = module_name.split(".") + + for c in range(1, len(name_parts)): + part_name = ".".join(name_parts[:c]) + ".*" + if part_name in ignored_modules: + return True + + return False + + for conf, task_module in app_configs: + module = conf.name + "." + task_module + if is_ignored_module(module): self.stdout.write(" * Ignored tasks module: %r" % module) - else: + continue + + imported_module = importlib.import_module(module) + if not self._is_package(imported_module): self.stdout.write(" * Discovered tasks module: %r" % module) tasks_modules.append(module) + else: + submodules = self._get_submodules(imported_module) + + for submodule in submodules: + if is_ignored_module(submodule): + self.stdout.write(" * Ignored tasks module: %r" % submodule) + else: + self.stdout.write(" * Discovered tasks module: %r" % submodule) + tasks_modules.append(submodule) return tasks_modules + def _is_package(self, module): + return hasattr(module, "__path__") + + def _get_submodules(self, package): + submodules = [] + + package_path = package.__path__ + prefix = package.__name__ + "." + + for _, module_name, _ in pkgutil.walk_packages(package_path, prefix): + submodules.append(module_name) + + return submodules + def _resolve_executable(self, exec_name): bin_dir = os.path.dirname(sys.executable) if bin_dir: