Use django-recurrence for recurrence fields

This commit is contained in:
Adam Goldsmith 2021-05-19 18:22:33 -04:00
parent 6918a3d497
commit 66c1ef629b
6 changed files with 74 additions and 20 deletions

View File

@ -4,7 +4,6 @@ verify_ssl = true
name = "pypi"
[packages]
python-dateutil = "*"
django = "*"
django-widget-tweaks = "*"
django-auth-ldap = "*"
@ -12,6 +11,7 @@ django-markdownx = "*"
django-markdownify = "*"
uvicorn = "*"
mysqlclient = "*"
django-recurrence = "*"
[dev-packages]

12
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "cf9669556a14beab13e75133255258d1c446c321e486d27def845667bfaec370"
"sha256": "909b6de0a11b2a6648f920e4bf5a8c191e482bc956a0c22965a0c65cb06a642b"
},
"pipfile-spec": 6,
"requires": {
@ -72,6 +72,14 @@
"index": "pypi",
"version": "==3.0.1"
},
"django-recurrence": {
"hashes": [
"sha256:715f681f6af029ff3a8d73c7b1460abd8cbc5d5a5001efcb127032e84d9cb963",
"sha256:9053b44b78b7fbfe3530673edfdd6d2f562105f8a192bc6a4b906a3df4f95f59"
],
"index": "pypi",
"version": "==1.10.3"
},
"django-widget-tweaks": {
"hashes": [
"sha256:9f91ca4217199b7671971d3c1f323a2bec71a0c27dec6260b3c006fa541bc489",
@ -203,7 +211,7 @@
"sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
"sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"
],
"index": "pypi",
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.8.1"
},
"python-ldap": {

View File

@ -26,6 +26,7 @@ INSTALLED_APPS = [
'widget_tweaks',
'markdownx',
'markdownify',
'recurrence',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',

View File

@ -0,0 +1,31 @@
# Generated by Django 3.2.3 on 2021-05-19 21:46
from django.db import migrations
import recurrence
import recurrence.fields
def transfer_recurrence(apps, schema_editor):
Task = apps.get_model('tasks', 'task')
for task in Task.objects.all():
task.recurrence = recurrence.deserialize('RRULE:' + task.recurrence_interval)
task.save(update_fields=['recurrence'])
class Migration(migrations.Migration):
dependencies = [
('tasks', '0002_tool_slug'),
]
operations = [
migrations.AddField(
model_name='task',
name='recurrence',
field=recurrence.fields.RecurrenceField(default=''),
preserve_default=False,
),
migrations.RunPython(transfer_recurrence),
migrations.RemoveField(
model_name='task',
name='recurrence_interval',
),
]

View File

@ -1,11 +1,11 @@
from datetime import datetime
import datetime
from dateutil.rrule import rrulestr
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.db import models
from django.urls import reverse
from markdownx.models import MarkdownxField
from recurrence.fields import RecurrenceField
class Tool(models.Model):
name = models.CharField(max_length=200)
@ -24,7 +24,7 @@ class Task(models.Model):
slug = models.SlugField()
tool = models.ForeignKey(Tool, on_delete=models.CASCADE)
description = MarkdownxField(blank=True)
recurrence_interval = models.CharField(max_length=200)
recurrence = RecurrenceField(include_dtstart=False)
recurrence_base = models.DateField(null=True, blank=True)
class Meta:
@ -42,18 +42,20 @@ class Task(models.Model):
@property
def next_recurrence(self):
def _date_to_datetime(date):
return datetime.datetime.combine(date, datetime.time.min)
if self.recurrence_base is None: # relative date
try:
rrule = rrulestr(self.recurrence_interval, dtstart=self.last_event.date)
return rrule[1]
return self.recurrence.after(
_date_to_datetime(self.last_event.date),
dtstart=_date_to_datetime(self.last_event.date))
except Event.DoesNotExist:
return None
else: # absolute date
rrule = rrulestr(self.recurrence_interval, dtstart=self.recurrence_base)
try:
return rrule.after(self.last_event.date)
return self.recurrence.after(_date_to_datetime(self.last_event.date))
except Event.DoesNotExist:
return rrule[1]
return self.recurrence.occurrences()[0]
@property
def is_overdue(self):
@ -61,7 +63,7 @@ class Task(models.Model):
if next_rec is None:
return False
else:
return next_rec < datetime.now()
return next_rec < datetime.datetime.now()
class SubscriptionSettings(models.Model):
@ -104,7 +106,7 @@ class GroupTaskSubscription(SubscriptionSettings):
next_recurrence = self.task.next_recurrence
if next_recurrence is None:
return False
time_until_overdue = next_recurrence - datetime.now()
time_until_overdue = next_recurrence - datetime.datetime.now()
return self.task.is_overdue or (time_until_overdue.days <= self.days_before)
def __str__(self):

View File

@ -14,14 +14,26 @@
</ol>
</nav>
<p> Next scheduled time: {{ task.next_recurrence|date }} </p>
{% if task.is_overdue %}
<div class="alert alert-danger">
Task is overdue!
</div>
{% endif %}
<section>
<h2> Recurrence </h2>
<ul>
{% for rule in task.recurrence.rrules %}
<li> {{ rule.to_text }} </li>
{% endfor %}
</ul>
{{ task.description|markdownify }}
<p> Next scheduled time: {{ task.next_recurrence|date|default:"never" }} </p>
{% if task.is_overdue %}
<div class="alert alert-danger">
Task is overdue!
</div>
{% endif %}
</section>
<section>
<h2> Description </h2>
{{ task.description|markdownify }}
</section>
{% if form.errors %}
<div class="alert alert-warning">