Use django-recurrence for recurrence fields
This commit is contained in:
parent
6918a3d497
commit
66c1ef629b
2
Pipfile
2
Pipfile
@ -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
12
Pipfile.lock
generated
@ -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": {
|
||||
|
@ -26,6 +26,7 @@ INSTALLED_APPS = [
|
||||
'widget_tweaks',
|
||||
'markdownx',
|
||||
'markdownify',
|
||||
'recurrence',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
|
31
tasks/migrations/0003_task_recurrence.py
Normal file
31
tasks/migrations/0003_task_recurrence.py
Normal 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',
|
||||
),
|
||||
]
|
@ -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):
|
||||
|
@ -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">
|
||||
|
Loading…
Reference in New Issue
Block a user