Update task creation

This commit is contained in:
Sonny Bakker 2020-09-26 18:51:40 +02:00
parent c830a42cc6
commit 8c69a22b32
9 changed files with 82 additions and 71 deletions

View file

@ -0,0 +1,10 @@
# Generated by Django 3.0.7 on 2020-09-26 15:34
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [("accounts", "0011_auto_20200913_2101")]
operations = [migrations.RemoveField(model_name="user", name="task")]

View file

@ -1,11 +1,10 @@
import json
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import UserManager as DjangoUserManager from django.contrib.auth.models import UserManager as DjangoUserManager
from django.db import models from django.db import models
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django_celery_beat.models import IntervalSchedule, PeriodicTask from django_celery_beat.models import PeriodicTask
class UserManager(DjangoUserManager): class UserManager(DjangoUserManager):
@ -41,15 +40,6 @@ class UserManager(DjangoUserManager):
class User(AbstractUser): class User(AbstractUser):
email = models.EmailField(_("email address"), unique=True) email = models.EmailField(_("email address"), unique=True)
task = models.OneToOneField(
PeriodicTask,
on_delete=models.CASCADE,
null=True,
blank=True,
editable=False,
verbose_name="collection task",
)
reddit_refresh_token = models.CharField(max_length=255, blank=True, null=True) reddit_refresh_token = models.CharField(max_length=255, blank=True, null=True)
reddit_access_token = models.CharField(max_length=255, blank=True, null=True) reddit_access_token = models.CharField(max_length=255, blank=True, null=True)
@ -63,26 +53,10 @@ class User(AbstractUser):
USERNAME_FIELD = "email" USERNAME_FIELD = "email"
REQUIRED_FIELDS = [] REQUIRED_FIELDS = []
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if not self.task:
task_interval, _ = IntervalSchedule.objects.get_or_create(
every=1, period=IntervalSchedule.HOURS
)
self.task, _ = PeriodicTask.objects.get_or_create(
enabled=True,
interval=task_interval,
name=f"{self.email}-collection-task",
task="FeedTask",
args=json.dumps([self.pk]),
)
self.save()
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
self.task.delete() tasks = PeriodicTask.objects.filter(name__contains=self.email)
tasks.delete()
return super().delete(*args, **kwargs) return super().delete(*args, **kwargs)
@property @property

View file

@ -1,22 +1,24 @@
from django.test import TestCase from django.test import TestCase
from django_celery_beat.models import PeriodicTask from django_celery_beat.models import IntervalSchedule, PeriodicTask
from newsreader.accounts.models import User from newsreader.accounts.tests.factories import UserFactory
class UserTestCase(TestCase): class UserTestCase(TestCase):
def test_task_is_created(self):
user = User.objects.create(email="durp@burp.nl", task=None)
task = PeriodicTask.objects.get(name=f"{user.email}-collection-task")
user.refresh_from_db()
self.assertEquals(task, user.task)
self.assertEquals(PeriodicTask.objects.count(), 1)
def test_task_is_deleted(self): def test_task_is_deleted(self):
user = User.objects.create(email="durp@burp.nl", task=None) user = UserFactory(email="durp@burp.nl")
interval = IntervalSchedule.objects.create(
every=1, period=IntervalSchedule.HOURS
)
PeriodicTask.objects.create(
name=f"{user.email}-feed", task="FeedTask", interval=interval
)
PeriodicTask.objects.create(
name=f"{user.email}-timeline", task="TwitterTimelineTask", interval=interval
)
user.delete() user.delete()
self.assertEquals(PeriodicTask.objects.count(), 0) self.assertEquals(PeriodicTask.objects.count(), 0)

View file

@ -290,7 +290,7 @@ class RedditClient(PostClient):
break break
except StreamException as e: except StreamException as e:
logger.exception( logger.exception(
"Stream failed reading content from {stream.rule.url}" f"Stream failed reading content from {stream.rule.url}"
) )
self.set_rule_error(stream.rule, e) self.set_rule_error(stream.rule, e)

View file

@ -3,6 +3,8 @@ from django.urls import reverse
import pytz import pytz
from django_celery_beat.models import PeriodicTask
from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.choices import RuleTypeChoices
from newsreader.news.collection.models import CollectionRule from newsreader.news.collection.models import CollectionRule
from newsreader.news.collection.tests.factories import FeedFactory from newsreader.news.collection.tests.factories import FeedFactory
@ -37,6 +39,12 @@ class FeedCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
self.assertEquals(rule.category.pk, self.category.pk) self.assertEquals(rule.category.pk, self.category.pk)
self.assertEquals(rule.user.pk, self.user.pk) self.assertEquals(rule.user.pk, self.user.pk)
self.assertTrue(
PeriodicTask.objects.get(
name=f"{self.user.email}-feed", task="FeedTask", enabled=True
)
)
class FeedUpdateViewTestCase(CollectionRuleViewTestCase, TestCase): class FeedUpdateViewTestCase(CollectionRuleViewTestCase, TestCase):
def setUp(self): def setUp(self):

View file

@ -41,7 +41,9 @@ class TwitterTimelineCreateViewTestCase(CollectionRuleViewTestCase, TestCase):
self.assertTrue( self.assertTrue(
PeriodicTask.objects.get( PeriodicTask.objects.get(
name=self.user.email, task="TwitterTimelineTask", enabled=True name=f"{self.user.email}-timeline",
task="TwitterTimelineTask",
enabled=True,
) )
) )

View file

@ -1,7 +1,11 @@
import json
from django.urls import reverse_lazy from django.urls import reverse_lazy
import pytz import pytz
from django_celery_beat.models import IntervalSchedule, PeriodicTask
from newsreader.news.collection.models import CollectionRule from newsreader.news.collection.models import CollectionRule
from newsreader.news.core.models import Category from newsreader.news.core.models import Category
@ -32,3 +36,25 @@ class CollectionRuleDetailMixin:
kwargs = super().get_form_kwargs() kwargs = super().get_form_kwargs()
kwargs["user"] = self.request.user kwargs["user"] = self.request.user
return kwargs return kwargs
class TaskCreationMixin:
def form_valid(self, form):
response = super().form_valid(form)
interval, period = self.task_interval
task_interval, _ = IntervalSchedule.objects.get_or_create(
every=interval, period=period
)
PeriodicTask.objects.get_or_create(
name=f"{self.request.user.email}-{self.task_name}",
task=self.task_type,
enabled=True,
defaults={
"args": json.dumps([self.request.user.pk]),
"interval": task_interval,
},
)
return response

View file

@ -3,6 +3,8 @@ from django.urls import reverse
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.views.generic.edit import CreateView, FormView, UpdateView from django.views.generic.edit import CreateView, FormView, UpdateView
from django_celery_beat.models import IntervalSchedule
from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.choices import RuleTypeChoices
from newsreader.news.collection.forms import ( from newsreader.news.collection.forms import (
CollectionRuleBulkForm, CollectionRuleBulkForm,
@ -13,12 +15,14 @@ from newsreader.news.collection.models import CollectionRule
from newsreader.news.collection.views.base import ( from newsreader.news.collection.views.base import (
CollectionRuleDetailMixin, CollectionRuleDetailMixin,
CollectionRuleViewMixin, CollectionRuleViewMixin,
TaskCreationMixin,
) )
from newsreader.utils.opml import parse_opml from newsreader.utils.opml import parse_opml
class FeedUpdateView(CollectionRuleViewMixin, CollectionRuleDetailMixin, UpdateView): class FeedUpdateView(CollectionRuleViewMixin, CollectionRuleDetailMixin, UpdateView):
template_name = "news/collection/views/feed-update.html" template_name = "news/collection/views/feed-update.html"
context_object_name = "feed"
form_class = FeedForm form_class = FeedForm
def get_queryset(self): def get_queryset(self):
@ -26,10 +30,14 @@ class FeedUpdateView(CollectionRuleViewMixin, CollectionRuleDetailMixin, UpdateV
return queryset.filter(type=RuleTypeChoices.feed) return queryset.filter(type=RuleTypeChoices.feed)
class FeedCreateView(CollectionRuleViewMixin, CollectionRuleDetailMixin, CreateView): class FeedCreateView(
CollectionRuleViewMixin, CollectionRuleDetailMixin, TaskCreationMixin, CreateView
):
template_name = "news/collection/views/feed-create.html" template_name = "news/collection/views/feed-create.html"
task_interval = (1, IntervalSchedule.HOURS)
task_name = "feed"
task_type = "FeedTask"
form_class = FeedForm form_class = FeedForm
context_object_name = "feed"
class OPMLImportView(FormView): class OPMLImportView(FormView):

View file

@ -1,44 +1,25 @@
import json
from django.views.generic.edit import CreateView, UpdateView from django.views.generic.edit import CreateView, UpdateView
from django_celery_beat.models import IntervalSchedule, PeriodicTask from django_celery_beat.models import IntervalSchedule
from newsreader.news.collection.choices import RuleTypeChoices from newsreader.news.collection.choices import RuleTypeChoices
from newsreader.news.collection.forms import TwitterTimelineForm from newsreader.news.collection.forms import TwitterTimelineForm
from newsreader.news.collection.views.base import ( from newsreader.news.collection.views.base import (
CollectionRuleDetailMixin, CollectionRuleDetailMixin,
CollectionRuleViewMixin, CollectionRuleViewMixin,
TaskCreationMixin,
) )
class TwitterTimelineCreateView( class TwitterTimelineCreateView(
CollectionRuleViewMixin, CollectionRuleDetailMixin, CreateView CollectionRuleViewMixin, CollectionRuleDetailMixin, TaskCreationMixin, CreateView
): ):
form_class = TwitterTimelineForm form_class = TwitterTimelineForm
template_name = "news/collection/views/twitter/timeline-create.html" template_name = "news/collection/views/twitter/timeline-create.html"
task_interval = (10, IntervalSchedule.MINUTES)
def form_valid(self, form): task_name = "timeline"
response = super().form_valid(form) task_type = "TwitterTimelineTask"
task_interval, _ = IntervalSchedule.objects.get_or_create(
every=1, period=IntervalSchedule.HOURS
)
task, _ = PeriodicTask.objects.get_or_create(
name=self.request.user.email,
task="TwitterTimelineTask",
enabled=True,
defaults={
"args": json.dumps([self.request.user.pk]),
"interval": task_interval,
},
)
self.request.user.task = task
self.request.user.save()
return response
class TwitterTimelineUpdateView( class TwitterTimelineUpdateView(