Skip to content

Commit

Permalink
♻️ Rename FoiRequest.first_message to created_at
Browse files Browse the repository at this point in the history
  • Loading branch information
pajowu authored and stefanw committed Nov 15, 2022
1 parent 06826c6 commit 308364f
Show file tree
Hide file tree
Showing 20 changed files with 76 additions and 46 deletions.
4 changes: 2 additions & 2 deletions docker-compose.yml
Expand Up @@ -10,7 +10,7 @@ services:
POSTGRES_DB: froide
POSTGRES_PASSWORD: froide
ports:
- "127.0.0.1:5432:5432"
- "127.0.0.1:5433:5432"
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0
volumes:
Expand All @@ -23,7 +23,7 @@ services:
- "cluster.routing.allocation.disk.watermark.high=2gb"
- "cluster.routing.allocation.disk.watermark.flood_stage=1gb"
ports:
- "127.0.0.1:9200:9200"
- "127.0.0.1:9201:9200"

volumes:
es-data: {}
Expand Down
4 changes: 2 additions & 2 deletions froide/account/views.py
Expand Up @@ -198,7 +198,7 @@ def get_context_data(self, **kwargs):

aggregates = foirequests.aggregate(
count=models.Count("id"),
first_date=models.Min("first_message"),
first_date=models.Min("created_at"),
successful=models.Count(
"id",
filter=models.Q(
Expand Down Expand Up @@ -251,7 +251,7 @@ def get_context_data(self, **kwargs):

ctx.update(
{
"foirequests": foirequests.order_by("-first_message")[:10],
"foirequests": foirequests.order_by("-created_at")[:10],
"aggregates": aggregates,
"campaigns": campaigns,
"top_followers": top_followers,
Expand Down
8 changes: 4 additions & 4 deletions froide/foirequest/admin.py
Expand Up @@ -163,7 +163,7 @@ class FoiRequestAdmin(admin.ModelAdmin):
]
list_display = (
"title",
"first_message",
"created_at",
"secret_address",
"request_page",
"public_body",
Expand All @@ -173,7 +173,7 @@ class FoiRequestAdmin(admin.ModelAdmin):
)
list_filter = (
"jurisdiction",
"first_message",
"created_at",
"last_message",
"status",
"resolution",
Expand All @@ -195,7 +195,7 @@ class FoiRequestAdmin(admin.ModelAdmin):
)
search_fields = ["title", "description", "secret_address", "reference"]
ordering = ("-last_message",)
date_hierarchy = "first_message"
date_hierarchy = "created_at"

actions = [
"mark_checked",
Expand Down Expand Up @@ -409,7 +409,7 @@ def unblock_request(self, request, queryset):
mes.timestamp = timezone.now()
if req.law:
req.due_date = req.law.calculate_due_date()
req.first_message = mes.timestamp
req.created_at = mes.timestamp

req.is_blocked = False
req.save()
Expand Down
10 changes: 3 additions & 7 deletions froide/foirequest/api_views.py
Expand Up @@ -313,7 +313,7 @@ class Meta:
"due_date",
"resolved_on",
"last_message",
"first_message",
"created_at",
"status",
"public_body",
"resolution",
Expand Down Expand Up @@ -397,12 +397,8 @@ class FoiRequestFilter(filters.FilterSet):
lookup_expr="isnull",
method="campaign_filter",
)
first_message_after = filters.DateFilter(
field_name="first_message", lookup_expr="gte"
)
first_message_before = filters.DateFilter(
field_name="first_message", lookup_expr="lt"
)
created_at_after = filters.DateFilter(field_name="created_at", lookup_expr="gte")
created_at_before = filters.DateFilter(field_name="created_at", lookup_expr="lt")
has_same = filters.BooleanFilter(
field_name="same_as", lookup_expr="isnull", exclude=True
)
Expand Down
2 changes: 1 addition & 1 deletion froide/foirequest/documents.py
Expand Up @@ -40,7 +40,7 @@ class FoiRequestDocument(Document):
campaign = fields.IntegerField()

due_date = fields.DateField()
first_message = fields.DateField()
created_at = fields.DateField()
last_message = fields.DateField()

publicbody = fields.IntegerField(attr="public_body_id")
Expand Down
4 changes: 2 additions & 2 deletions froide/foirequest/feeds.py
Expand Up @@ -74,7 +74,7 @@ def link(self):
return self.make_url(self.url_name)

def items(self):
return self.items.order_by("-first_message")[:15]
return self.items.order_by("-created_at")[:15]

@clean_feed_output
def item_title(self, item):
Expand All @@ -92,7 +92,7 @@ def item_description(self, item):
return linebreaksbr(item.get_description())

def item_pubdate(self, item):
return item.first_message
return item.created_at


class LatestFoiRequestsFeedAtom(LatestFoiRequestsFeed):
Expand Down
14 changes: 7 additions & 7 deletions froide/foirequest/filters.py
Expand Up @@ -228,8 +228,8 @@ class BaseFoiRequestFilterSet(BaseSearchFilterSet):
widget=forms.HiddenInput(),
)

first = django_filters.DateFromToRangeFilter(
method="filter_first",
created = django_filters.DateFromToRangeFilter(
method="filter_created",
widget=DateRangeWidget,
)
last = django_filters.DateFromToRangeFilter(
Expand All @@ -239,8 +239,8 @@ class BaseFoiRequestFilterSet(BaseSearchFilterSet):
choices=[
("-last", _("last message (newest first)")),
("last", _("last message (oldest first)")),
("-first", _("request date (newest first)")),
("first", _("request date (oldest first)")),
("-created", _("request date (newest first)")),
("created", _("request date (oldest first)")),
],
label=_("sort"),
empty_label=_("default sort"),
Expand All @@ -259,7 +259,7 @@ class Meta:
"classification",
"tag",
"publicbody",
"first",
"created",
]

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -303,14 +303,14 @@ def filter_organization(self, qs, name, value):
filtered_qs = qs.filter(user=all_members)
return filtered_qs

def filter_first(self, qs, name, value):
def filter_created(self, qs, name, value):
range_kwargs = {}
if value.start is not None:
range_kwargs["gte"] = value.start
if value.stop is not None:
range_kwargs["lte"] = value.stop

return qs.filter(Q("range", first_message=range_kwargs))
return qs.filter(Q("range", created_at=range_kwargs))

def filter_last(self, qs, name, value):
range_kwargs = {}
Expand Down
2 changes: 1 addition & 1 deletion froide/foirequest/forms/message.py
Expand Up @@ -510,7 +510,7 @@ def clean_date(self):
raise forms.ValidationError(
_("Your reply date is in the future, that is not possible.")
)
if date < self.foirequest.first_message.date():
if date < self.foirequest.created_at.date():
raise forms.ValidationError(
_(
"Your reply date is before the request was made, "
Expand Down
@@ -0,0 +1,25 @@
# Generated by Django 4.0.7 on 2022-11-09 13:30

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("foirequest", "0057_foimessage_redacted_content_anon_and_more"),
]

operations = [
migrations.RenameField(
model_name="foirequest",
old_name="first_message",
new_name="created_at",
),
migrations.AlterField(
model_name="foirequest",
name="created_at",
field=models.DateTimeField(
blank=True, null=True, verbose_name="Created at"
),
),
]
21 changes: 15 additions & 6 deletions froide/foirequest/models/request.py
Expand Up @@ -2,6 +2,7 @@
import re
from collections import namedtuple
from datetime import timedelta
from typing import TYPE_CHECKING, Optional

import django.dispatch
from django.conf import settings
Expand All @@ -26,6 +27,9 @@

from .project import FoiProject

if TYPE_CHECKING:
from .message import FoiMessage

MODERATOR_CLASSIFICATION_OFFSET = timedelta(days=31)


Expand Down Expand Up @@ -76,7 +80,7 @@ def get_unclassified_for_moderation(self):

def get_throttle_filter(self, qs, user, extra_filters=None):
qs = qs.filter(user=user)
return qs, "first_message"
return qs, "created_at"

def delete_private_requests(self, user):
if not user:
Expand Down Expand Up @@ -320,9 +324,7 @@ class FoiRequest(models.Model):
Team, null=True, blank=True, on_delete=models.SET_NULL, verbose_name=_("Team")
)

first_message = models.DateTimeField(
_("Date of first message"), blank=True, null=True
)
created_at = models.DateTimeField(_("Created at"), blank=True, null=True)
last_message = models.DateTimeField(
_("Date of last message"), blank=True, null=True
)
Expand Down Expand Up @@ -856,14 +858,21 @@ def days_to_resolution(self):
break
if final is None or mes is None:
return None
return (mes.timestamp - self.first_message).days
return (mes.timestamp - self.created_at).days

@property
def first_outgoing_message(self):
def first_outgoing_message(self) -> Optional["FoiMessage"]:
sent_msg = self.sent_messages()
if sent_msg:
return sent_msg[0]

@property
def first_message(self):
if self.first_outgoing_message:
return self.first_outgoing_message.timestamp
else:
return self.created_at


def get_absolute_short_url(pk):
return reverse("foirequest-shortlink", kwargs={"obj_id": pk})
Expand Down
6 changes: 3 additions & 3 deletions froide/foirequest/services.py
Expand Up @@ -175,7 +175,7 @@ def create_request(self, publicbody, sequence=0):
language=data.get("language", ""),
site=Site.objects.get_current(),
reference=data.get("reference", ""),
first_message=now,
created_at=now,
last_message=now,
project=data.get("project"),
project_order=data.get("project_order"),
Expand Down Expand Up @@ -381,12 +381,12 @@ def process(self, request=None):
message.timestamp = timezone.now()
else:
if email.date < foirequest.first_message:
# Mail timestamp is earlier than first message due to bad time on mail server
# Mail timestamp is earlier than first outgoing message due to bad time on mail server
message.timestamp = timezone.now()
else:
message.timestamp = email.date

# if the message timestamp is still before or equal request start
# if the message timestamp is still before or equal first outgoing message
if message.timestamp <= foirequest.first_message:
# bump it by one second
message.timestamp = foirequest.first_message + timedelta(seconds=1)
Expand Down
@@ -1,4 +1,4 @@
{% load i18n %}{% autoescape off %}{% blocktrans with title=foirequest.title name=foirequest.user.get_full_name due=due date=foirequest.first_message|date:"SHORT_DATE_FORMAT" num=foirequest.pk %}Dear Sir or Madam,
{% load i18n %}{% autoescape off %}{% blocktrans with title=foirequest.title name=foirequest.user.get_full_name due=due date=foirequest.created_at|date:"SHORT_DATE_FORMAT" num=foirequest.pk %}Dear Sir or Madam,

My Freedom of Information request "{{ title }}" ({{ date }}, #{{ num }}) was not answered in the time defined by law and is now {{ due }} late.
Please update me on the status of my request as soon as possible.
Expand Down
Expand Up @@ -93,7 +93,7 @@ <h3 class="h5 info-box__title">{{ object.readable_status }}</h3>
{# date #}
<li class="info-box__list-item">
<div class="info-box__list-label">{% blocktrans %}Date{% endblocktrans %}</div>
<div class="info-box__list-value">{{ object.first_message|date:"j. F Y" }}</div>
<div class="info-box__list-value">{{ object.created_at|date:"j. F Y" }}</div>
</li>

{# due date #}
Expand Down
Expand Up @@ -46,7 +46,7 @@ <h3>
{% else %}
<dl>
<dt>{% trans "Request" %}</dt>
<dd>“{{ foirequest.title }}” [#{{ foirequest.id }}] ({{ foirequest.first_message|date:"SHORT_DATE_FORMAT" }})</dd>
<dd>“{{ foirequest.title }}” [#{{ foirequest.id }}] ({{ foirequest.created_at|date:"SHORT_DATE_FORMAT" }})</dd>
<dt>{% trans "Requester" %}</dt>
<dd>{{ foirequest.user.get_full_name }} &lt;{{ foirequest.secret_address }}&gt;</dd>
<dt>{% trans "File transfer" %}</dt>
Expand Down
2 changes: 1 addition & 1 deletion froide/foirequest/tests/factories.py
Expand Up @@ -54,7 +54,7 @@ class Meta:
status = ""
visibility = 2
user = factory.LazyAttribute(lambda o: UserFactory())
first_message = timezone.now() - timedelta(days=14)
created_at = timezone.now() - timedelta(days=14)
last_message = timezone.now() - timedelta(days=2)
resolved_on = None
due_date = timezone.now() + timedelta(days=14)
Expand Down
2 changes: 1 addition & 1 deletion froide/foirequest/tests/test_mail.py
Expand Up @@ -31,7 +31,7 @@ def foirequest_with_msg(world):
req = factories.FoiRequestFactory.create(
site=world,
secret_address=secret_address,
first_message=date,
created_at=date,
last_message=date,
)
factories.FoiMessageFactory.create(request=req, timestamp=date)
Expand Down
4 changes: 2 additions & 2 deletions froide/foirequest/tests/test_request.py
Expand Up @@ -647,7 +647,7 @@ def test_postal_reply(world, client, pb):
message = req.foimessage_set.all()[0]
message.timestamp = datetime(2011, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
message.save()
req.first_message = message.timestamp
req.created_at = message.timestamp
req.save()

file_size = os.path.getsize(factories.TEST_PDF_PATH)
Expand Down Expand Up @@ -1546,7 +1546,7 @@ def test_resolution(world, client):
assert req.costs == 0.0
assert req.status == FoiRequest.STATUS.RESOLVED
assert req.resolution == FoiRequest.RESOLUTION.SUCCESSFUL
assert req.days_to_resolution() == (mes.timestamp - req.first_message).days
assert req.days_to_resolution() == (mes.timestamp - req.created_at).days


@pytest.mark.django_db
Expand Down
2 changes: 1 addition & 1 deletion froide/foirequest/utils.py
Expand Up @@ -45,7 +45,7 @@ def get_label(self):
return self.label if self.label is not None else self.name


def throttle(qs, throttle_config, date_param="first_message"):
def throttle(qs, throttle_config, date_param="created_at"):
if throttle_config is None:
return False

Expand Down
2 changes: 1 addition & 1 deletion froide/organization/views.py
Expand Up @@ -53,7 +53,7 @@ def _get_last_foirequests(self, organization: Organization):
user__private=False
).values_list("user_id", flat=True)
foirequests = FoiRequest.published.filter(user__in=public_members)
return foirequests.order_by("-first_message")[:10]
return foirequests.order_by("-created_at")[:10]

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
Expand Down
4 changes: 2 additions & 2 deletions froide/tests/live/test_request.py
Expand Up @@ -162,7 +162,7 @@ def test_make_logged_in_request_too_many(
for _i in range(5):
req = foi_request_factory(
user=dummy_user,
first_message=timezone.now(),
created_at=timezone.now(),
)
foi_message_factory(request=req, is_response=False, sender_user=dummy_user)
do_login(page, live_server)
Expand Down Expand Up @@ -244,7 +244,7 @@ def test_set_status(
user = User.objects.get(username="dummy")
req = foi_request_factory(
user=user,
first_message=timezone.now(),
created_at=timezone.now(),
status="resolved",
resolution=from_resolution,
)
Expand Down

0 comments on commit 308364f

Please sign in to comment.