Add plan follower model and configuration
This commit is contained in:
parent
829315c1dc
commit
7792674ed7
4 changed files with 150 additions and 0 deletions
|
|
@ -5,3 +5,10 @@ from django.utils.translation import gettext_lazy as _
|
||||||
class FroideGovPlanConfig(AppConfig):
|
class FroideGovPlanConfig(AppConfig):
|
||||||
name = "froide_govplan"
|
name = "froide_govplan"
|
||||||
verbose_name = _("GovPlan App")
|
verbose_name = _("GovPlan App")
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from froide.follow.configuration import follow_registry
|
||||||
|
|
||||||
|
from .configuration import GovernmentPlanFollowConfiguration
|
||||||
|
|
||||||
|
follow_registry.register(GovernmentPlanFollowConfiguration())
|
||||||
|
|
|
||||||
80
froide_govplan/configuration.py
Normal file
80
froide_govplan/configuration.py
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Iterator
|
||||||
|
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from froide.follow.configuration import FollowConfiguration
|
||||||
|
from froide.helper.notifications import Notification, TemplatedEvent
|
||||||
|
|
||||||
|
from .admin import get_allowed_plans
|
||||||
|
from .models import GovernmentPlanFollower, GovernmentPlanUpdate
|
||||||
|
|
||||||
|
|
||||||
|
class GovernmentPlanFollowConfiguration(FollowConfiguration):
|
||||||
|
model = GovernmentPlanFollower
|
||||||
|
title: str = _("Government plans")
|
||||||
|
slug: str = "govplan"
|
||||||
|
follow_message: str = _("You are now following this plan.")
|
||||||
|
unfollow_message: str = _("You are not following this plan anymore.")
|
||||||
|
confirm_email_message: str = _(
|
||||||
|
"Check your emails and click the confirmation link in order to follow this government plan."
|
||||||
|
)
|
||||||
|
action_labels = {
|
||||||
|
"follow": _("Follow plan"),
|
||||||
|
"follow_q": _("Follow plan?"),
|
||||||
|
"unfollow": _("Unfollow plan"),
|
||||||
|
"following": _("Following plan"),
|
||||||
|
"follow_description": _(
|
||||||
|
"You will get notifications via email when something new happens with this plan. You can unsubscribe anytime."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_content_object_queryset(self, request):
|
||||||
|
return get_allowed_plans(request)
|
||||||
|
|
||||||
|
def can_follow(self, content_object, user, request=None):
|
||||||
|
if request:
|
||||||
|
get_allowed_plans(request)
|
||||||
|
|
||||||
|
return super().can_follow(content_object, user)
|
||||||
|
|
||||||
|
def get_batch_updates(
|
||||||
|
self, start: datetime, end: datetime
|
||||||
|
) -> Iterator[Notification]:
|
||||||
|
yield from get_plan_updates(start, end)
|
||||||
|
|
||||||
|
def get_confirm_follow_message(self, content_object):
|
||||||
|
return _(
|
||||||
|
"please confirm that you want to follow the plan “{title}” by clicking this link:"
|
||||||
|
).format(title=content_object.title)
|
||||||
|
|
||||||
|
def email_changed(self, user):
|
||||||
|
# Move all confirmed email subscriptions of new email
|
||||||
|
# to user except own requests
|
||||||
|
self.model.objects.filter(email=user.email, confirmed=True).update(
|
||||||
|
email="", user=user
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_plan_updates(start: datetime, end: datetime):
|
||||||
|
plan_updates = GovernmentPlanUpdate.objects.filter(
|
||||||
|
public=True, timestamp__gte=start, timestamp__lt=end
|
||||||
|
).select_related("plan")
|
||||||
|
|
||||||
|
for plan_update in plan_updates:
|
||||||
|
yield Notification(
|
||||||
|
section=_("Government Plans"),
|
||||||
|
event_type="planupdate",
|
||||||
|
object=plan_update.plan,
|
||||||
|
object_label=plan_update.plan.title,
|
||||||
|
timestamp=plan_update.timestamp,
|
||||||
|
event=make_plan_event(plan_update.plan),
|
||||||
|
user_id=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def make_plan_event(plan):
|
||||||
|
return TemplatedEvent(
|
||||||
|
_("An update was posted for the government plan “{title}”."),
|
||||||
|
title=plan.title,
|
||||||
|
)
|
||||||
49
froide_govplan/migrations/0004_auto_20220311_2330.py
Normal file
49
froide_govplan/migrations/0004_auto_20220311_2330.py
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
# Generated by Django 3.2.12 on 2022-03-11 22:30
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('froide_govplan', '0003_auto_20220228_1051'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='governmentplanscmsplugin',
|
||||||
|
name='template',
|
||||||
|
field=models.CharField(blank=True, choices=[('froide_govplan/plugins/default.html', 'Normal'), ('froide_govplan/plugins/progress.html', 'Progress'), ('froide_govplan/plugins/card_cols.html', 'Card columns')], help_text='template used to display the plugin', max_length=250, verbose_name='template'),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='GovernmentPlanFollower',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('email', models.CharField(blank=True, max_length=255)),
|
||||||
|
('confirmed', models.BooleanField(default=False)),
|
||||||
|
('timestamp', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Timestamp of Following')),
|
||||||
|
('context', models.JSONField(blank=True, null=True)),
|
||||||
|
('content_object', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='followers', to='froide_govplan.governmentplan', verbose_name='Government plan')),
|
||||||
|
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Government plan follower',
|
||||||
|
'verbose_name_plural': 'Government plan followers',
|
||||||
|
'ordering': ('-timestamp',),
|
||||||
|
'get_latest_by': 'timestamp',
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddConstraint(
|
||||||
|
model_name='governmentplanfollower',
|
||||||
|
constraint=models.UniqueConstraint(condition=models.Q(('user__isnull', False)), fields=('content_object', 'user'), name='unique_user_follower_froide_govplan_governmentplanfollower'),
|
||||||
|
),
|
||||||
|
migrations.AddConstraint(
|
||||||
|
model_name='governmentplanfollower',
|
||||||
|
constraint=models.UniqueConstraint(condition=models.Q(('user__isnull', True)), fields=('content_object', 'email'), name='unique_email_follower_froide_govplan_governmentplanfollower'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -10,6 +10,7 @@ from taggit.managers import TaggableManager
|
||||||
from taggit.models import TaggedItemBase
|
from taggit.models import TaggedItemBase
|
||||||
|
|
||||||
from froide.foirequest.models import FoiRequest
|
from froide.foirequest.models import FoiRequest
|
||||||
|
from froide.follow.models import Follower
|
||||||
from froide.organization.models import Organization
|
from froide.organization.models import Organization
|
||||||
from froide.publicbody.models import Category, Jurisdiction, PublicBody
|
from froide.publicbody.models import Category, Jurisdiction, PublicBody
|
||||||
|
|
||||||
|
|
@ -237,6 +238,19 @@ class GovernmentPlanUpdate(models.Model):
|
||||||
return "{} - {} ({})".format(self.title, self.timestamp, self.plan)
|
return "{} - {} ({})".format(self.title, self.timestamp, self.plan)
|
||||||
|
|
||||||
|
|
||||||
|
class GovernmentPlanFollower(Follower):
|
||||||
|
content_object = models.ForeignKey(
|
||||||
|
GovernmentPlan,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name="followers",
|
||||||
|
verbose_name=_("Government plan"),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta(Follower.Meta):
|
||||||
|
verbose_name = _("Government plan follower")
|
||||||
|
verbose_name_plural = _("Government plan followers")
|
||||||
|
|
||||||
|
|
||||||
if CMSPlugin:
|
if CMSPlugin:
|
||||||
|
|
||||||
PLUGIN_TEMPLATES = [
|
PLUGIN_TEMPLATES = [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue