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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
from django.core.exceptions import PermissionDenied
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from django.contrib import messages
from django.db import connection
from django.db.models import F
from django.apps import apps
from django.utils import timezone
from datetime import datetime, timedelta
from postgresqleu.util.pagination import simple_pagination
from postgresqleu.util.request import get_int_or_error
from .models import ScheduledJob, JobHistory, get_config
from .forms import ScheduledJobForm
from .util import reschedule_job, notify_job_change
def index(request):
if not request.user.is_superuser:
raise PermissionDenied("Access denied")
config = get_config()
if request.method == 'POST':
if request.POST.get('submit') == 'Hold all jobs':
config.hold_all_jobs = True
config.save()
notify_job_change()
return HttpResponseRedirect('.')
elif request.POST.get('submit') == 'Re-enable job execution':
what = get_int_or_error(request.POST, 'pending')
if what == 0:
messages.error(request, "Must decide what to do with pending jobs")
return HttpResponseRedirect(".")
elif what not in (1, 2):
messages.error(request, "Invalid choice for pending jobs")
return HttpResponseRedirect(".")
if what == 2:
# Re-schedule all pending jobs
for job in ScheduledJob.objects.filter(enabled=True, nextrun__lte=timezone.now()):
reschedule_job(job, save=True)
config.hold_all_jobs = False
config.save()
notify_job_change()
messages.info(request, "Job execution re-enabled")
return HttpResponseRedirect(".")
raise Http404("Unknown button")
jobs = ScheduledJob.objects.all().order_by(F('nextrun').asc(nulls_last=True))
try:
lastjob = ScheduledJob.objects.only('lastrun').filter(lastrun__isnull=False).order_by('-lastrun')[0]
lastjobtime = lastjob.lastrun
lastjob_recent = (timezone.now() - lastjobtime) < timedelta(hours=6)
except IndexError:
# No job has run yet, can happen on brand new installation
lastjobtime = None
lastjob_recent = False
history = JobHistory.objects.only('time', 'job__description', 'success', 'runtime').select_related('job').order_by('-time')[:20]
with connection.cursor() as curs:
curs.execute("SELECT count(1) FROM pg_stat_activity WHERE application_name='pgeu scheduled job runner' AND datname=current_database()")
n, = curs.fetchone()
runner_active = (n > 0)
return render(request, 'scheduler/index.html', {
'jobs': jobs,
'lastjob': lastjobtime,
'lastjob_recent': lastjob_recent,
'runner_active': runner_active,
'holdall': config.hold_all_jobs,
'history': history,
'apps': {a.name: a.verbose_name for a in apps.get_app_configs()},
'helplink': 'jobs',
})
def job(request, jobid):
if not request.user.is_superuser:
raise PermissionDenied("Access denied")
job = get_object_or_404(ScheduledJob, id=jobid)
if request.method == 'POST':
if request.POST.get('schedule-now', '') == '1':
job.nextrun = timezone.now()
job.save()
notify_job_change()
messages.info(request, "Scheduled immediate run of '{0}'".format(job.description))
return HttpResponseRedirect('../')
elif request.POST.get('reset-failure', '') == '1':
job.lastrun = None
job.lastrunsuccess = False
job.save()
messages.info(request, "Reset last run failure state of '{0}'".format(job.description))
return HttpResponseRedirect('../')
form = ScheduledJobForm(request, conference=None, instance=job, data=request.POST)
if form.is_valid():
form.save()
reschedule_job(job, notify=True)
return HttpResponseRedirect("../")
else:
form = ScheduledJobForm(request, conference=None, instance=job)
history_objects = JobHistory.objects.filter(job=job).order_by('-time')
(history, paginator, page_range) = simple_pagination(request, history_objects, 15)
return render(request, 'scheduler/job.html', {
'job': job,
'history': history,
'form': form,
'page_range': page_range,
'breadcrumbs': [('/admin/jobs/', 'Scheduled jobs'), ],
'helplink': 'jobs',
})
def history(request):
if not request.user.is_superuser:
raise PermissionDenied("Access denied")
history_objects = JobHistory.objects.only('time', 'job__description', 'success', 'runtime').select_related('job').order_by('-time')
(history, paginator, page_range) = simple_pagination(request, history_objects, 50)
return render(request, 'scheduler/history.html', {
'history': history,
'page_range': page_range,
'breadcrumbs': [('/admin/jobs/', 'Scheduled jobs'), ],
'helplink': 'jobs',
})
|