repos

blog.bythewood.me-wagtail

mirror archived upstream

Self-hostable blog for developers built on Wagtail and Django, with webpack, Bootstrap, and CodeMirror.

blogbootstrapdjangodockerhandcodedpythonself-hostedwagtailwebpack

2.3 KB · 60 lines · Python Raw History
 1from django.db import models
 2from django.utils import timezone
 3
 4
 5class ScheduledTask(models.Model):
 6    RUN_INTERVAL_CHOICES = (
 7        (300, "Every 5 minutes"),
 8        (900, "Every 15 minutes"),
 9        (1800, "Every 30 minutes"),
10        (3600, "Every hour"),
11        (86400, "Every day"),
12    )
13    MANAGEMENT_COMMAND_CHOICES = (
14        ("publish_scheduled_pages", "Publish scheduled pages (recommended every hour)"),
15        ("clearsessions", "Clear sessions (recommended every day)"),
16    )
17
18    management_command = models.CharField(
19        max_length=255, choices=MANAGEMENT_COMMAND_CHOICES, unique=True
20    )
21    run_interval = models.IntegerField(choices=RUN_INTERVAL_CHOICES)
22    last_run_at = models.DateTimeField(blank=True, null=True)
23    next_run_at = models.DateTimeField(blank=True, null=True)
24
25    def __str__(self):
26        return self.management_command
27
28    def should_run(self):
29        now = timezone.now()
30        if self.last_run_at is None:
31            return True
32        if self.next_run_at is None:
33            return True
34        return self.next_run_at <= now
35
36    def get_next_run_at(self, now):
37        """
38        Returns the next run datetime. Should be in whole increments of the run
39        interval.
40
41        Every 5 minutes should be rounded to the nearest 5 minutes.
42        Every 15 minutes should be rounded to the nearest 15 minutes.
43        Every 30 minutes should be rounded to the nearest 30 minutes.
44        Every hour should be rounded to the nearest hour.
45        Every day should be rounded to the nearest day.
46        """
47
48        if self.run_interval == 300:
49            return now.replace(minute=(now.minute // 5) * 5, second=0, microsecond=0) + timezone.timedelta(minutes=5)
50        elif self.run_interval == 900:
51            return now.replace(minute=(now.minute // 15) * 15, second=0, microsecond=0) + timezone.timedelta(minutes=15)
52        elif self.run_interval == 1800:
53            return now.replace(minute=(now.minute // 30) * 30, second=0, microsecond=0) + timezone.timedelta(minutes=30)
54        elif self.run_interval == 3600:
55            return now.replace(minute=0, second=0, microsecond=0) + timezone.timedelta(hours=1)
56        elif self.run_interval == 86400:
57            return now.replace(hour=0, minute=0, second=0, microsecond=0) + timezone.timedelta(days=1)
58        else:
59            raise ValueError("Invalid run interval")