2025-11-10 20:06:38 +03:00

104 lines
3.5 KiB
Python

# -*- coding: utf-8 -*-
import logging
from django.apps import apps
from django.core.management.base import BaseCommand
from django_extensions.management.jobs import get_jobs, print_jobs
from django_extensions.management.utils import setup_logger, signalcommand
logger = logging.getLogger(__name__)
class Command(BaseCommand):
help = "Runs scheduled maintenance jobs."
when_options = [
"minutely",
"quarter_hourly",
"hourly",
"daily",
"weekly",
"monthly",
"yearly",
]
def add_arguments(self, parser):
super().add_arguments(parser)
parser.add_argument(
"when", nargs="?", help="options: %s" % ", ".join(self.when_options)
)
parser.add_argument(
"--list",
"-l",
action="store_true",
dest="list_jobs",
default=False,
help="List all jobs with their description",
)
def usage_msg(self):
print("%s Please specify: %s" % (self.help, ", ".join(self.when_options)))
def runjobs(self, when, options):
verbosity = options["verbosity"]
jobs = get_jobs(when, only_scheduled=True)
for app_name, job_name in sorted(jobs.keys()):
job = jobs[(app_name, job_name)]
if verbosity > 1:
logger.info("Executing %s job: %s (app: %s)", when, job_name, app_name)
try:
job().execute()
except Exception:
logger.exception(
"ERROR OCCURED IN JOB: %s (APP: %s)", job_name, app_name
)
def runjobs_by_signals(self, when, options):
"""Run jobs from the signals"""
# Thanks for Ian Holsman for the idea and code
from django_extensions.management import signals
from django.conf import settings
verbosity = options["verbosity"]
for app_name in settings.INSTALLED_APPS:
try:
__import__(app_name + ".management", "", "", [""])
except ImportError:
pass
for app in (
app.models_module for app in apps.get_app_configs() if app.models_module
):
if verbosity > 1:
app_name = ".".join(app.__name__.rsplit(".")[:-1])
print("Sending %s job signal for: %s" % (when, app_name))
if when == "minutely":
signals.run_minutely_jobs.send(sender=app, app=app)
elif when == "quarter_hourly":
signals.run_quarter_hourly_jobs.send(sender=app, app=app)
elif when == "hourly":
signals.run_hourly_jobs.send(sender=app, app=app)
elif when == "daily":
signals.run_daily_jobs.send(sender=app, app=app)
elif when == "weekly":
signals.run_weekly_jobs.send(sender=app, app=app)
elif when == "monthly":
signals.run_monthly_jobs.send(sender=app, app=app)
elif when == "yearly":
signals.run_yearly_jobs.send(sender=app, app=app)
@signalcommand
def handle(self, *args, **options):
when = options["when"]
setup_logger(logger, self.stdout)
if options["list_jobs"]:
print_jobs(when, only_scheduled=True, show_when=True, show_appname=True)
elif when in self.when_options:
self.runjobs(when, options)
self.runjobs_by_signals(when, options)
else:
self.usage_msg()