-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #345 from FJNR-inc/develop
new release
- Loading branch information
Showing
37 changed files
with
1,110 additions
and
1,002 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import json | ||
import traceback | ||
from django.utils import timezone | ||
|
||
import requests | ||
from django.core.mail import mail_admins | ||
from django.urls import reverse | ||
|
||
from blitz_api import settings | ||
from cron_manager.models import Task | ||
|
||
|
||
class CronManager: | ||
|
||
def __init__(self): | ||
self.url_to_call = settings.EXTERNAL_SCHEDULER['URL_TO_CALL'] | ||
|
||
def create_task(self, data): | ||
Task.objects.create(**data) | ||
|
||
def create_wait_queue_place_notification(self, wait_queue_place_id): | ||
wait_queue_place_url = self.url_to_call + reverse( | ||
'retreat:waitqueueplace-notify', | ||
args=[wait_queue_place_id] | ||
) | ||
|
||
data = { | ||
"execution_datetime": timezone.now(), | ||
"execution_interval": 1000 * 60 * 60 * 24, | ||
"url": wait_queue_place_url, | ||
"description": "Retreat wait queue notification" | ||
} | ||
|
||
self.create_task(data) | ||
|
||
def create_remind_user(self, retreat_id, reminder_date): | ||
remind_users_url = self.url_to_call + reverse( | ||
'retreat:retreat-detail', | ||
args=[retreat_id] | ||
) + "/remind_users" | ||
data = { | ||
"execution_datetime": reminder_date, | ||
"url": remind_users_url, | ||
"description": "Retreat 7-days reminder notification" | ||
} | ||
|
||
self.create_task(data) | ||
|
||
def create_recap(self, retreat_id, throwback_date): | ||
remind_users_url = self.url_to_call + reverse( | ||
'retreat:retreat-detail', | ||
args=[retreat_id] | ||
) + "/recap" | ||
data = { | ||
"execution_datetime": throwback_date, | ||
"url": remind_users_url, | ||
"description": "Retreat post-event notification" | ||
} | ||
|
||
self.create_task(data) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from django.contrib import admin | ||
|
||
from . import models | ||
from django.utils.translation import ugettext_lazy as _ | ||
|
||
|
||
class ExecutionInline(admin.StackedInline): | ||
model = models.Execution | ||
can_delete = True | ||
show_change_link = True | ||
verbose_name_plural = _('Executions') | ||
fk_name = 'task' | ||
|
||
|
||
class TaskAdmin(admin.ModelAdmin): | ||
inlines = (ExecutionInline,) | ||
list_display = ( | ||
'id', | ||
'description', | ||
'execution_datetime', | ||
'execution_interval', | ||
'active', | ||
'created_at' | ||
) | ||
list_filter = ( | ||
'description', | ||
'active' | ||
) | ||
search_fields = ( | ||
'description', | ||
'id', | ||
) | ||
|
||
|
||
class ExecutionAdmin(admin.ModelAdmin): | ||
list_display = ( | ||
'id', | ||
'task', | ||
'created_at', | ||
'executed_at', | ||
'success', | ||
'http_code' | ||
) | ||
list_filter = ( | ||
'success', | ||
'task', | ||
'http_code' | ||
) | ||
autocomplete_fields = ('task',) | ||
|
||
|
||
admin.site.register(models.Task, TaskAdmin) | ||
admin.site.register(models.Execution, ExecutionAdmin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class CronManagerConfig(AppConfig): | ||
name = 'cron_manager' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from cron_manager.models import Task | ||
|
||
|
||
def execute_tasks(): | ||
|
||
task_actives = Task.objects.filter( | ||
active=True | ||
) | ||
|
||
for task in task_actives: | ||
if task.can_be_execute: | ||
task.execute() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Generated by Django 2.2.7 on 2020-01-08 19:49 | ||
|
||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='Task', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('url', models.URLField(verbose_name='URL to execute')), | ||
('description', models.CharField(max_length=150, verbose_name='Description')), | ||
('execution_datetime', models.DateTimeField(verbose_name='Execution datetime')), | ||
('execution_interval', models.BigIntegerField(blank=True, null=True, verbose_name='Execution intervals ms')), | ||
('active', models.BooleanField(default=True, verbose_name='Active')), | ||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created_at')), | ||
], | ||
), | ||
migrations.CreateModel( | ||
name='Execution', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), | ||
('executed_at', models.DateTimeField(verbose_name='Executed at')), | ||
('success', models.BooleanField(blank=True, default=False, null=True, verbose_name='Succeded ?')), | ||
('http_code', models.CharField(blank=True, max_length=100, null=True, verbose_name='HTTP code')), | ||
('http_response', models.TextField(blank=True, null=True, verbose_name='HTTP response')), | ||
('task', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='executions', to='cron_manager.Task', verbose_name='Task')), | ||
], | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import requests | ||
from django.db import models | ||
from django.utils import timezone | ||
|
||
from django.utils.translation import ugettext_lazy as _ | ||
|
||
|
||
class Task(models.Model): | ||
"""Model for tasks""" | ||
|
||
url = models.URLField( | ||
verbose_name=_("URL to execute"), | ||
) | ||
|
||
description = models.CharField( | ||
max_length=150, | ||
verbose_name=_("Description"), | ||
) | ||
|
||
execution_datetime = models.DateTimeField( | ||
verbose_name=_("Execution datetime"), | ||
) | ||
|
||
execution_interval = models.BigIntegerField( | ||
blank=True, | ||
null=True, | ||
verbose_name=_("Execution intervals ms"), | ||
) | ||
|
||
active = models.BooleanField( | ||
default=True, | ||
verbose_name=_("Active"), | ||
) | ||
|
||
created_at = models.DateTimeField( | ||
auto_now_add=True, | ||
verbose_name=_("Created_at"), | ||
) | ||
|
||
def __str__(self): | ||
return self.description | ||
|
||
@property | ||
def last_execution(self): | ||
return self.executions.order_by('-executed_at').first() | ||
|
||
@property | ||
def can_be_execute(self): | ||
|
||
if self.active: | ||
if self.execution_interval: | ||
now_less_intervals = timezone.now() - timezone.timedelta( | ||
milliseconds=self.execution_interval) | ||
else: | ||
now_less_intervals = timezone.now() | ||
|
||
last_execution = self.last_execution | ||
|
||
if last_execution: | ||
return now_less_intervals > last_execution.executed_at | ||
else: | ||
return now_less_intervals > self.execution_datetime | ||
else: | ||
return False | ||
|
||
def execute(self): | ||
|
||
last_execution = self.last_execution | ||
if last_execution: | ||
if self.execution_interval: | ||
executed_at = last_execution.executed_at - timezone.timedelta( | ||
milliseconds=self.execution_interval) | ||
else: | ||
executed_at = last_execution.executed_at | ||
else: | ||
executed_at = self.execution_datetime | ||
|
||
execution = Execution.objects.create( | ||
task=self, | ||
executed_at=executed_at | ||
) | ||
|
||
response = requests.get(self.url) | ||
|
||
success = False | ||
if 200 <= response.status_code < 300: | ||
success = True | ||
try: | ||
content = response.json() | ||
stop_cron_task = content.get('stop', False) | ||
if stop_cron_task or not self.execution_interval: | ||
self.active = False | ||
self.save() | ||
except Exception: | ||
success = False | ||
execution.success = success | ||
execution.http_code = response.status_code | ||
execution.http_response = response.text | ||
execution.save() | ||
|
||
|
||
class Execution(models.Model): | ||
"""Model to log execution of tasks""" | ||
|
||
task = models.ForeignKey( | ||
'Task', | ||
related_name='executions', | ||
on_delete=models.CASCADE, | ||
verbose_name="Task" | ||
) | ||
|
||
created_at = models.DateTimeField( | ||
auto_now_add=True, | ||
verbose_name=_("Created at"), | ||
) | ||
|
||
executed_at = models.DateTimeField( | ||
verbose_name=_("Executed at"), | ||
) | ||
|
||
success = models.BooleanField( | ||
default=False, | ||
blank=True, | ||
null=True, | ||
verbose_name=_("Succeded ?"), | ||
) | ||
|
||
http_code = models.CharField( | ||
max_length=100, | ||
blank=True, | ||
null=True, | ||
verbose_name=_("HTTP code"), | ||
) | ||
|
||
http_response = models.TextField( | ||
verbose_name=_("HTTP response"), | ||
blank=True, | ||
null=True, | ||
) | ||
|
||
def __str__(self): | ||
return f'{self.task} - {self.success}' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from rest_framework import serializers | ||
|
||
from .models import ( | ||
Task | ||
) | ||
|
||
|
||
class TaskSerializer(serializers.HyperlinkedModelSerializer): | ||
id = serializers.ReadOnlyField() | ||
|
||
class Meta: | ||
model = Task | ||
fields = '__all__' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
|
||
from rest_framework.routers import SimpleRouter | ||
from django.urls import path | ||
from django.conf.urls import include | ||
|
||
from . import views | ||
|
||
|
||
class OptionalSlashSimpleRouter(SimpleRouter): | ||
""" Subclass of SimpleRouter to make the trailing slash optional """ | ||
|
||
def __init__(self, *args, **kwargs): | ||
super(SimpleRouter, self).__init__(*args, **kwargs) | ||
self.trailing_slash = '/?' | ||
|
||
|
||
app_name = "cron_manager" | ||
|
||
router = OptionalSlashSimpleRouter() | ||
router.register('tasks', views.TaskViewSet) | ||
|
||
urlpatterns = [ | ||
path('', include(router.urls)), # includes router generated URL | ||
] |
Oops, something went wrong.