summaryrefslogtreecommitdiff
path: root/postgresqleu/scheduler/apps.py
blob: 4e01f4ad48c3f9091b3c9210bd6a26807313b1ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from django.apps import AppConfig
from django.db.models.signals import post_migrate
from django.db import transaction, connection
from django.core.management import get_commands, load_command_class

from .util import reschedule_job


def handle_post_migrate(sender, **kwargs):
    ScheduledJob = sender.get_model('ScheduledJob')

    with transaction.atomic():
        # Check that our own app has actually been migrated. If it has not, just don't
        # do anything -- it might be part of an initial migration of just some apps.
        curs = connection.cursor()
        curs.execute("SELECT id FROM django_migrations WHERE app='scheduler'")
        if curs.rowcount == 0:
            print("Job scheduler not yet installed, not triggering migration")
            return

        jobs = []
        for name, app in get_commands().items():
            if app.startswith('django'):
                continue
            cmd = load_command_class(app, name)
            if hasattr(cmd, 'ScheduledJob'):
                job, created = ScheduledJob.objects.get_or_create(app=app, command=name)

                dirty = False

                def _update_field(jobfield, cmdfield, obj=cmd.ScheduledJob, default=None):
                    if getattr(job, jobfield) != getattr(obj, cmdfield, default):
                        setattr(job, jobfield, getattr(obj, cmdfield, default))
                        return True
                    return False

                dirty += _update_field('description', 'help', obj=cmd)
                dirty += _update_field('scheduled_interval', 'scheduled_interval')
                dirty += _update_field('scheduled_times', 'scheduled_times')
                if dirty:
                    job.full_clean()
                    if created:
                        if getattr(cmd.ScheduledJob, 'default_notify_on_success', None):
                            job.notifyonsuccess = True
                        reschedule_job(job, save=False)
                    job.save()
                    if created:
                        print("Created scheduled job for {}".format(job.description))
                    else:
                        print("Updated scheduled job for {}".format(job.description))
                jobs.append(job.pk)

        for dj in ScheduledJob.objects.exclude(pk__in=jobs):
            print("Deleted scheduled job for {}".format(dj.description))
            dj.delete()


class SchedulerAppConfig(AppConfig):
    name = 'postgresqleu.scheduler'

    def ready(self):
        post_migrate.connect(handle_post_migrate, sender=self)