runjobs.py 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. # -*- coding: utf-8 -*-
  2. import logging
  3. from django.apps import apps
  4. from django.core.management.base import BaseCommand
  5. from django_extensions.management.jobs import get_jobs, print_jobs
  6. from django_extensions.management.utils import setup_logger, signalcommand
  7. logger = logging.getLogger(__name__)
  8. class Command(BaseCommand):
  9. help = "Runs scheduled maintenance jobs."
  10. when_options = ['minutely', 'quarter_hourly', 'hourly', 'daily', 'weekly', 'monthly', 'yearly']
  11. def add_arguments(self, parser):
  12. super().add_arguments(parser)
  13. parser.add_argument(
  14. 'when', nargs='?',
  15. help="options: %s" % ', '.join(self.when_options)
  16. )
  17. parser.add_argument(
  18. '--list', '-l', action="store_true", dest="list_jobs",
  19. default=False, help="List all jobs with their description"
  20. )
  21. def usage_msg(self):
  22. print("%s Please specify: %s" % (self.help, ', '.join(self.when_options)))
  23. def runjobs(self, when, options):
  24. verbosity = options["verbosity"]
  25. jobs = get_jobs(when, only_scheduled=True)
  26. for app_name, job_name in sorted(jobs.keys()):
  27. job = jobs[(app_name, job_name)]
  28. if verbosity > 1:
  29. logger.info("Executing %s job: %s (app: %s)", when, job_name, app_name)
  30. try:
  31. job().execute()
  32. except Exception:
  33. logger.exception("ERROR OCCURED IN JOB: %s (APP: %s)", job_name, app_name)
  34. def runjobs_by_signals(self, when, options):
  35. """ Run jobs from the signals """
  36. # Thanks for Ian Holsman for the idea and code
  37. from django_extensions.management import signals
  38. from django.conf import settings
  39. verbosity = options["verbosity"]
  40. for app_name in settings.INSTALLED_APPS:
  41. try:
  42. __import__(app_name + '.management', '', '', [''])
  43. except ImportError:
  44. pass
  45. for app in (app.models_module for app in apps.get_app_configs() if app.models_module):
  46. if verbosity > 1:
  47. app_name = '.'.join(app.__name__.rsplit('.')[:-1])
  48. print("Sending %s job signal for: %s" % (when, app_name))
  49. if when == 'minutely':
  50. signals.run_minutely_jobs.send(sender=app, app=app)
  51. elif when == 'quarter_hourly':
  52. signals.run_quarter_hourly_jobs.send(sender=app, app=app)
  53. elif when == 'hourly':
  54. signals.run_hourly_jobs.send(sender=app, app=app)
  55. elif when == 'daily':
  56. signals.run_daily_jobs.send(sender=app, app=app)
  57. elif when == 'weekly':
  58. signals.run_weekly_jobs.send(sender=app, app=app)
  59. elif when == 'monthly':
  60. signals.run_monthly_jobs.send(sender=app, app=app)
  61. elif when == 'yearly':
  62. signals.run_yearly_jobs.send(sender=app, app=app)
  63. @signalcommand
  64. def handle(self, *args, **options):
  65. when = options['when']
  66. setup_logger(logger, self.stdout)
  67. if options['list_jobs']:
  68. print_jobs(when, only_scheduled=True, show_when=True, show_appname=True)
  69. elif when in self.when_options:
  70. self.runjobs(when, options)
  71. self.runjobs_by_signals(when, options)
  72. else:
  73. self.usage_msg()