# -*- 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()