Fix subsribtions
This commit is contained in:
parent
d9f1da1e49
commit
13022ed476
|
|
@ -1,43 +1,51 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from smtplib import SMTPException
|
||||||
|
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from django.core.mail import send_mail
|
|
||||||
from notification.models import Subscriber
|
|
||||||
from news import models
|
|
||||||
from django.template.loader import render_to_string, get_template
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from smtplib import SMTPException
|
from django.core.mail import send_mail
|
||||||
from django.core.validators import EMPTY_VALUES
|
from django.core.validators import EMPTY_VALUES
|
||||||
|
from django.template.loader import get_template, render_to_string
|
||||||
|
|
||||||
from main.models import SiteSettings
|
from main.models import SiteSettings
|
||||||
|
from news import models
|
||||||
|
from notification.models import Subscriber
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def send_email_with_news(news_ids):
|
def send_email_with_news(news_ids):
|
||||||
subscribers = Subscriber.objects.filter(state=Subscriber.USABLE)
|
subscribers = Subscriber.objects.all()
|
||||||
sent_news = models.News.objects.filter(id__in=news_ids)
|
sent_news = models.News.objects.filter(id__in=news_ids)
|
||||||
|
|
||||||
htmly = get_template(settings.NEWS_EMAIL_TEMPLATE)
|
htmly = get_template(settings.NEWS_EMAIL_TEMPLATE)
|
||||||
year = datetime.now().year
|
year = datetime.now().year
|
||||||
|
|
||||||
socials = list(SiteSettings.objects.with_country())
|
socials = list(SiteSettings.objects.with_country())
|
||||||
socials = dict(zip(map(lambda s: s.country.code, socials), socials))
|
socials = dict(zip(map(lambda social: social.country.code, socials), socials))
|
||||||
for s in subscribers:
|
|
||||||
socials_for_subscriber = socials.get(s.country_code)
|
for subscriber in subscribers:
|
||||||
|
socials_for_subscriber = socials.get(subscriber.country_code)
|
||||||
try:
|
try:
|
||||||
for n in sent_news:
|
for new in sent_news:
|
||||||
context = {"title": n.title.get(s.locale),
|
context = {
|
||||||
"subtitle": n.subtitle.get(s.locale),
|
"title": new.title.get(subscriber.locale),
|
||||||
"description": n.description.get(s.locale),
|
"subtitle": new.subtitle.get(subscriber.locale),
|
||||||
"code": s.update_code,
|
"description": new.description.get(subscriber.locale),
|
||||||
"image_url": n.image_url if n.image_url not in EMPTY_VALUES else None,
|
"code": subscriber.update_code,
|
||||||
"domain_uri": settings.DOMAIN_URI,
|
"image_url": new.image_url if new.image_url not in EMPTY_VALUES else None,
|
||||||
"slug": n.slug,
|
"domain_uri": settings.DOMAIN_URI,
|
||||||
"country_code": s.country_code,
|
"slug": new.slug,
|
||||||
"twitter_page_url": socials_for_subscriber.twitter_page_url if socials_for_subscriber else '#',
|
"country_code": subscriber.country_code,
|
||||||
"instagram_page_url": socials_for_subscriber.instagram_page_url if socials_for_subscriber else '#',
|
"twitter_page_url": socials_for_subscriber.twitter_page_url if socials_for_subscriber else '#',
|
||||||
"facebook_page_url": socials_for_subscriber.facebook_page_url if socials_for_subscriber else '#',
|
"instagram_page_url": socials_for_subscriber.instagram_page_url if socials_for_subscriber else '#',
|
||||||
"send_to": s.send_to,
|
"facebook_page_url": socials_for_subscriber.facebook_page_url if socials_for_subscriber else '#',
|
||||||
"year": year}
|
"send_to": subscriber.send_to,
|
||||||
send_mail("G&M News", render_to_string(settings.NEWS_EMAIL_TEMPLATE, context),
|
"year": year
|
||||||
settings.EMAIL_HOST_USER, [s.send_to], fail_silently=False,
|
}
|
||||||
html_message=htmly.render(context))
|
send_mail(
|
||||||
|
"G&M News", render_to_string(settings.NEWS_EMAIL_TEMPLATE, context),
|
||||||
|
settings.EMAIL_HOST_USER, [subscriber.send_to], fail_silently=False,
|
||||||
|
html_message=htmly.render(context)
|
||||||
|
)
|
||||||
except SMTPException:
|
except SMTPException:
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
17
apps/notification/migrations/0008_remove_subscribe_state.py
Normal file
17
apps/notification/migrations/0008_remove_subscribe_state.py
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Generated by Django 2.2.7 on 2019-12-30 15:04
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('notification', '0007_auto_20191227_1426'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='subscribe',
|
||||||
|
name='state',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -42,7 +42,6 @@ class SubscriberManager(models.Manager):
|
||||||
obj.ip_address = ip_address
|
obj.ip_address = ip_address
|
||||||
obj.country_code = country_code
|
obj.country_code = country_code
|
||||||
obj.locale = locale
|
obj.locale = locale
|
||||||
obj.state = self.model.USABLE
|
|
||||||
obj.update_code = generate_string_code()
|
obj.update_code = generate_string_code()
|
||||||
obj.subscription_types = subscription_types
|
obj.subscription_types = subscription_types
|
||||||
obj.save()
|
obj.save()
|
||||||
|
|
@ -64,16 +63,6 @@ class SubscriberManager(models.Manager):
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
class SubscriberQuerySet(models.QuerySet):
|
|
||||||
"""Extended queryset for Subscriber model."""
|
|
||||||
|
|
||||||
def by_usable(self, switcher=True):
|
|
||||||
if switcher:
|
|
||||||
return self.filter(state=self.model.USABLE)
|
|
||||||
else:
|
|
||||||
return self.filter(state=self.model.UNUSABLE)
|
|
||||||
|
|
||||||
|
|
||||||
class Subscriber(ProjectBaseMixin):
|
class Subscriber(ProjectBaseMixin):
|
||||||
"""Subscriber model."""
|
"""Subscriber model."""
|
||||||
|
|
||||||
|
|
@ -102,7 +91,7 @@ class Subscriber(ProjectBaseMixin):
|
||||||
|
|
||||||
subscription_types = models.ManyToManyField(SubscriptionType, through='Subscribe')
|
subscription_types = models.ManyToManyField(SubscriptionType, through='Subscribe')
|
||||||
|
|
||||||
objects = SubscriberManager.from_queryset(SubscriberQuerySet)()
|
objects = SubscriberManager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Meta class."""
|
"""Meta class."""
|
||||||
|
|
@ -121,9 +110,18 @@ class Subscriber(ProjectBaseMixin):
|
||||||
|
|
||||||
subscription_types = query.get('subscription_types')
|
subscription_types = query.get('subscription_types')
|
||||||
|
|
||||||
|
old_subscribes = self.subscription_types.objects.all()
|
||||||
subscribes = self.subscription_types.objects.filter(pk__in=[subscription_types])
|
subscribes = self.subscription_types.objects.filter(pk__in=[subscription_types])
|
||||||
self.subscription_types = subscribes
|
self.subscription_types = subscribes
|
||||||
|
|
||||||
|
new_ids = set(existing_answer.answer.id for existing_answer in subscribes)
|
||||||
|
old_subscribes_types = [sub for sub in old_subscribes if sub.id not in new_ids]
|
||||||
|
old_subscribes = Subscribe.objects.filter(subscriber=self, subscription_types__in=[old_subscribes_types])
|
||||||
|
|
||||||
|
for sub in old_subscribes:
|
||||||
|
sub.unsubscribe_date = now()
|
||||||
|
sub.save()
|
||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
@ -148,17 +146,8 @@ class Subscriber(ProjectBaseMixin):
|
||||||
class Subscribe(ProjectBaseMixin):
|
class Subscribe(ProjectBaseMixin):
|
||||||
"""Subscribe model."""
|
"""Subscribe model."""
|
||||||
|
|
||||||
UNUSABLE = 0
|
|
||||||
USABLE = 1
|
|
||||||
|
|
||||||
STATE_CHOICES = (
|
|
||||||
(UNUSABLE, _('Unusable')),
|
|
||||||
(USABLE, _('Usable')),
|
|
||||||
)
|
|
||||||
|
|
||||||
subscribe_date = models.DateTimeField(_('Last subscribe date'), blank=True, null=True, default=now)
|
subscribe_date = models.DateTimeField(_('Last subscribe date'), blank=True, null=True, default=now)
|
||||||
unsubscribe_date = models.DateTimeField(_('Last unsubscribe date'), blank=True, null=True, default=None)
|
unsubscribe_date = models.DateTimeField(_('Last unsubscribe date'), blank=True, null=True, default=None)
|
||||||
state = models.PositiveIntegerField(choices=STATE_CHOICES, default=USABLE, verbose_name=_('State'))
|
|
||||||
|
|
||||||
subscriber = models.ForeignKey(Subscriber, on_delete=models.CASCADE)
|
subscriber = models.ForeignKey(Subscriber, on_delete=models.CASCADE)
|
||||||
subscription_type = models.ForeignKey(SubscriptionType, on_delete=models.CASCADE)
|
subscription_type = models.ForeignKey(SubscriptionType, on_delete=models.CASCADE)
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ class SubscribeObjectSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
model = models.Subscriber
|
model = models.Subscriber
|
||||||
fields = ()
|
fields = ()
|
||||||
read_only_fields = ('subscribe_date', 'unsubscribe_date', 'state',)
|
read_only_fields = ('subscribe_date', 'unsubscribe_date',)
|
||||||
|
|
||||||
|
|
||||||
class SubscribeSerializer(serializers.ModelSerializer):
|
class SubscribeSerializer(serializers.ModelSerializer):
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from http.cookies import SimpleCookie
|
from http.cookies import SimpleCookie
|
||||||
|
|
||||||
from django.test import TestCase
|
|
||||||
from rest_framework.test import APITestCase
|
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from account.models import User
|
from account.models import User, Role, UserRole
|
||||||
from notification.models import Subscriber
|
from location.models import Country
|
||||||
|
from main.models import SiteSettings
|
||||||
|
from news.models import News, NewsType
|
||||||
|
from notification.models import Subscriber, SubscriptionType
|
||||||
|
from translation.models import Language
|
||||||
|
|
||||||
|
|
||||||
class BaseTestCase(APITestCase):
|
class BaseTestCase(APITestCase):
|
||||||
|
|
@ -17,23 +21,22 @@ class BaseTestCase(APITestCase):
|
||||||
self.user = User.objects.create_user(username=self.username, email=self.email, password=self.password)
|
self.user = User.objects.create_user(username=self.username, email=self.email, password=self.password)
|
||||||
# get tokens
|
# get tokens
|
||||||
tokens = User.create_jwt_tokens(self.user)
|
tokens = User.create_jwt_tokens(self.user)
|
||||||
self.client.cookies = SimpleCookie({'access_token': tokens.get('access_token'),
|
self.client.cookies = SimpleCookie({
|
||||||
'refresh_token': tokens.get('refresh_token')})
|
'access_token': tokens.get('access_token'),
|
||||||
|
'refresh_token': tokens.get('refresh_token')
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class NotificationAnonSubscribeTestCase(APITestCase):
|
class NotificationAnonSubscribeTestCase(APITestCase):
|
||||||
|
|
||||||
def test_subscribe(self):
|
def test_subscribe(self):
|
||||||
|
|
||||||
test_data = {
|
test_data = {
|
||||||
"email": "test@email.com",
|
"email": "test@email.com"
|
||||||
"state": 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.post("/api/web/notifications/subscribe/", data=test_data, format="json")
|
response = self.client.post("/api/web/notifications/subscribe/", data=test_data, format="json")
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
self.assertEqual(response.json()["email"], test_data["email"])
|
self.assertEqual(response.json()["email"], test_data["email"])
|
||||||
self.assertEqual(response.json()["state"], test_data["state"])
|
|
||||||
|
|
||||||
|
|
||||||
class NotificationSubscribeTestCase(BaseTestCase):
|
class NotificationSubscribeTestCase(BaseTestCase):
|
||||||
|
|
@ -42,21 +45,17 @@ class NotificationSubscribeTestCase(BaseTestCase):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
||||||
self.test_data = {
|
self.test_data = {
|
||||||
"email": self.email,
|
"email": self.email
|
||||||
"state": 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def test_subscribe(self):
|
def test_subscribe(self):
|
||||||
|
|
||||||
response = self.client.post("/api/web/notifications/subscribe/", data=self.test_data, format="json")
|
response = self.client.post("/api/web/notifications/subscribe/", data=self.test_data, format="json")
|
||||||
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
self.assertEqual(response.json()["email"], self.email)
|
self.assertEqual(response.json()["email"], self.email)
|
||||||
self.assertEqual(response.json()["state"], self.test_data["state"])
|
|
||||||
|
|
||||||
def test_subscribe_info_auth_user(self):
|
def test_subscribe_info_auth_user(self):
|
||||||
|
Subscriber.objects.create(user=self.user, email=self.email)
|
||||||
Subscriber.objects.create(user=self.user, email=self.email, state=1)
|
|
||||||
|
|
||||||
response = self.client.get("/api/web/notifications/subscribe-info/", data=self.test_data, format="json")
|
response = self.client.get("/api/web/notifications/subscribe-info/", data=self.test_data, format="json")
|
||||||
|
|
||||||
|
|
@ -66,13 +65,12 @@ class NotificationSubscribeTestCase(BaseTestCase):
|
||||||
class NotificationSubscribeInfoTestCase(APITestCase):
|
class NotificationSubscribeInfoTestCase(APITestCase):
|
||||||
|
|
||||||
def test_subscribe_info(self):
|
def test_subscribe_info(self):
|
||||||
|
|
||||||
self.username = 'sedragurda'
|
self.username = 'sedragurda'
|
||||||
self.password = 'sedragurdaredips19'
|
self.password = 'sedragurdaredips19'
|
||||||
self.email = 'sedragurda@desoz.com'
|
self.email = 'sedragurda@desoz.com'
|
||||||
self.user = User.objects.create_user(username=self.username, email=self.email, password=self.password)
|
self.user = User.objects.create_user(username=self.username, email=self.email, password=self.password)
|
||||||
|
|
||||||
test_subscriber = Subscriber.objects.create(user=self.user, email=self.email, state=1)
|
test_subscriber = Subscriber.objects.create(user=self.user, email=self.email)
|
||||||
|
|
||||||
response = self.client.get(f"/api/web/notifications/subscribe-info/{test_subscriber.update_code}/")
|
response = self.client.get(f"/api/web/notifications/subscribe-info/{test_subscriber.update_code}/")
|
||||||
|
|
||||||
|
|
@ -82,12 +80,10 @@ class NotificationSubscribeInfoTestCase(APITestCase):
|
||||||
class NotificationUnsubscribeAuthUserTestCase(BaseTestCase):
|
class NotificationUnsubscribeAuthUserTestCase(BaseTestCase):
|
||||||
|
|
||||||
def test_unsubscribe_auth_user(self):
|
def test_unsubscribe_auth_user(self):
|
||||||
|
|
||||||
Subscriber.objects.create(user=self.user, email=self.email, state=1)
|
Subscriber.objects.create(user=self.user, email=self.email, state=1)
|
||||||
|
|
||||||
self.test_data = {
|
self.test_data = {
|
||||||
"email": self.email,
|
"email": self.email
|
||||||
"state": 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.patch("/api/web/notifications/unsubscribe/", data=self.test_data, format="json")
|
response = self.client.patch("/api/web/notifications/unsubscribe/", data=self.test_data, format="json")
|
||||||
|
|
@ -104,13 +100,82 @@ class NotificationUnsubscribeTestCase(APITestCase):
|
||||||
self.user = User.objects.create_user(username=self.username, email=self.email, password=self.password)
|
self.user = User.objects.create_user(username=self.username, email=self.email, password=self.password)
|
||||||
|
|
||||||
self.test_data = {
|
self.test_data = {
|
||||||
"email": self.email,
|
"email": self.email
|
||||||
"state": 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test_subscriber = Subscriber.objects.create(user=self.user, email=self.email, state=1)
|
test_subscriber = Subscriber.objects.create(user=self.user, email=self.email)
|
||||||
|
|
||||||
response = self.client.patch(f"/api/web/notifications/unsubscribe/{test_subscriber.update_code}/",
|
response = self.client.patch(f"/api/web/notifications/unsubscribe/{test_subscriber.update_code}/",
|
||||||
data=self.test_data, format="json")
|
data=self.test_data, format="json")
|
||||||
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class NotificationManySubscribeTestCase(APITestCase):
|
||||||
|
|
||||||
|
def test_unsubscribe(self):
|
||||||
|
self.username = 'sedragurda'
|
||||||
|
self.password = 'sedragurdaredips19'
|
||||||
|
self.email = 'sedragurda@desoz.com'
|
||||||
|
self.user = User.objects.create_user(
|
||||||
|
username=self.username, email=self.email, password=self.password)
|
||||||
|
|
||||||
|
# get tokens
|
||||||
|
tokens = User.create_jwt_tokens(self.user)
|
||||||
|
self.client.cookies = SimpleCookie(
|
||||||
|
{'access_token': tokens.get('access_token'),
|
||||||
|
'refresh_token': tokens.get('refresh_token')})
|
||||||
|
self.test_news_type = NewsType.objects.create(name="Test news type")
|
||||||
|
|
||||||
|
self.lang, created = Language.objects.get_or_create(
|
||||||
|
title='Russia',
|
||||||
|
locale='ru-RU'
|
||||||
|
)
|
||||||
|
|
||||||
|
self.country_ru, created = Country.objects.get_or_create(
|
||||||
|
name={"en-GB": "Russian"}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.site_ru, created = SiteSettings.objects.get_or_create(
|
||||||
|
subdomain='ru'
|
||||||
|
)
|
||||||
|
|
||||||
|
role = Role.objects.create(
|
||||||
|
role=Role.CONTENT_PAGE_MANAGER,
|
||||||
|
site_id=self.site_ru.id
|
||||||
|
)
|
||||||
|
role.save()
|
||||||
|
|
||||||
|
user_role = UserRole.objects.create(
|
||||||
|
user=self.user,
|
||||||
|
role=role
|
||||||
|
)
|
||||||
|
user_role.save()
|
||||||
|
|
||||||
|
self.test_news = News.objects.create(
|
||||||
|
created_by=self.user, modified_by=self.user,
|
||||||
|
title={"ru-RU": "Test news"},
|
||||||
|
news_type=self.test_news_type,
|
||||||
|
description={"ru-RU": "Description test news"},
|
||||||
|
end=datetime.now() + timedelta(hours=2),
|
||||||
|
state=News.PUBLISHED,
|
||||||
|
slugs={'en-GB': 'test-news-slug'},
|
||||||
|
country=self.country_ru,
|
||||||
|
site=self.site_ru
|
||||||
|
)
|
||||||
|
|
||||||
|
self.test_subscribe_type = SubscriptionType.objects.create(
|
||||||
|
index_name='test_index_name',
|
||||||
|
name={"ru-RU": "Test subscription type"}
|
||||||
|
)
|
||||||
|
|
||||||
|
test_data = {
|
||||||
|
'email': self.email,
|
||||||
|
'subscription_types_pk': [
|
||||||
|
self.test_subscribe_type
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self.client.post("/api/web/notifications/subscribe/", data=test_data, format="json")
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(response.json()["email"], test_data["email"])
|
||||||
Loading…
Reference in New Issue
Block a user