Fix subsribtions

This commit is contained in:
dormantman 2019-12-30 18:06:50 +03:00 committed by Kuroshini
parent e33418dfe6
commit e772663f44
5 changed files with 151 additions and 72 deletions

View File

@ -1,43 +1,51 @@
from datetime import datetime
from smtplib import SMTPException
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 smtplib import SMTPException
from django.core.mail import send_mail
from django.core.validators import EMPTY_VALUES
from django.template.loader import get_template, render_to_string
from main.models import SiteSettings
from news import models
from notification.models import Subscriber
@shared_task
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)
htmly = get_template(settings.NEWS_EMAIL_TEMPLATE)
year = datetime.now().year
socials = list(SiteSettings.objects.with_country())
socials = dict(zip(map(lambda s: s.country.code, socials), socials))
for s in subscribers:
socials_for_subscriber = socials.get(s.country_code)
socials = dict(zip(map(lambda social: social.country.code, socials), socials))
for subscriber in subscribers:
socials_for_subscriber = socials.get(subscriber.country_code)
try:
for n in sent_news:
context = {"title": n.title.get(s.locale),
"subtitle": n.subtitle.get(s.locale),
"description": n.description.get(s.locale),
"code": s.update_code,
"image_url": n.image_url if n.image_url not in EMPTY_VALUES else None,
"domain_uri": settings.DOMAIN_URI,
"slug": n.slug,
"country_code": s.country_code,
"twitter_page_url": socials_for_subscriber.twitter_page_url if socials_for_subscriber else '#',
"instagram_page_url": socials_for_subscriber.instagram_page_url if socials_for_subscriber else '#',
"facebook_page_url": socials_for_subscriber.facebook_page_url if socials_for_subscriber else '#',
"send_to": s.send_to,
"year": year}
send_mail("G&M News", render_to_string(settings.NEWS_EMAIL_TEMPLATE, context),
settings.EMAIL_HOST_USER, [s.send_to], fail_silently=False,
html_message=htmly.render(context))
for new in sent_news:
context = {
"title": new.title.get(subscriber.locale),
"subtitle": new.subtitle.get(subscriber.locale),
"description": new.description.get(subscriber.locale),
"code": subscriber.update_code,
"image_url": new.image_url if new.image_url not in EMPTY_VALUES else None,
"domain_uri": settings.DOMAIN_URI,
"slug": new.slug,
"country_code": subscriber.country_code,
"twitter_page_url": socials_for_subscriber.twitter_page_url if socials_for_subscriber else '#',
"instagram_page_url": socials_for_subscriber.instagram_page_url if socials_for_subscriber else '#',
"facebook_page_url": socials_for_subscriber.facebook_page_url if socials_for_subscriber else '#',
"send_to": subscriber.send_to,
"year": year
}
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:
continue

View 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',
),
]

View File

@ -42,7 +42,6 @@ class SubscriberManager(models.Manager):
obj.ip_address = ip_address
obj.country_code = country_code
obj.locale = locale
obj.state = self.model.USABLE
obj.update_code = generate_string_code()
obj.subscription_types = subscription_types
obj.save()
@ -64,16 +63,6 @@ class SubscriberManager(models.Manager):
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):
"""Subscriber model."""
@ -102,7 +91,7 @@ class Subscriber(ProjectBaseMixin):
subscription_types = models.ManyToManyField(SubscriptionType, through='Subscribe')
objects = SubscriberManager.from_queryset(SubscriberQuerySet)()
objects = SubscriberManager()
class Meta:
"""Meta class."""
@ -121,9 +110,18 @@ class Subscriber(ProjectBaseMixin):
subscription_types = query.get('subscription_types')
old_subscribes = self.subscription_types.objects.all()
subscribes = self.subscription_types.objects.filter(pk__in=[subscription_types])
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()
@property
@ -148,17 +146,8 @@ class Subscriber(ProjectBaseMixin):
class Subscribe(ProjectBaseMixin):
"""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)
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)
subscription_type = models.ForeignKey(SubscriptionType, on_delete=models.CASCADE)

View File

@ -86,7 +86,7 @@ class SubscribeObjectSerializer(serializers.ModelSerializer):
model = models.Subscriber
fields = ()
read_only_fields = ('subscribe_date', 'unsubscribe_date', 'state',)
read_only_fields = ('subscribe_date', 'unsubscribe_date',)
class SubscribeSerializer(serializers.ModelSerializer):

View File

@ -1,11 +1,15 @@
from datetime import datetime, timedelta
from http.cookies import SimpleCookie
from django.test import TestCase
from rest_framework.test import APITestCase
from rest_framework import status
from rest_framework.test import APITestCase
from account.models import User
from notification.models import Subscriber
from account.models import User, Role, UserRole
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):
@ -17,23 +21,22 @@ class BaseTestCase(APITestCase):
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.client.cookies = SimpleCookie({
'access_token': tokens.get('access_token'),
'refresh_token': tokens.get('refresh_token')
})
class NotificationAnonSubscribeTestCase(APITestCase):
def test_subscribe(self):
test_data = {
"email": "test@email.com",
"state": 1
"email": "test@email.com"
}
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"])
self.assertEqual(response.json()["state"], test_data["state"])
class NotificationSubscribeTestCase(BaseTestCase):
@ -42,21 +45,17 @@ class NotificationSubscribeTestCase(BaseTestCase):
super().setUp()
self.test_data = {
"email": self.email,
"state": 1
"email": self.email
}
def test_subscribe(self):
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.json()["email"], self.email)
self.assertEqual(response.json()["state"], self.test_data["state"])
def test_subscribe_info_auth_user(self):
Subscriber.objects.create(user=self.user, email=self.email, state=1)
Subscriber.objects.create(user=self.user, email=self.email)
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):
def test_subscribe_info(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)
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}/")
@ -82,12 +80,10 @@ class NotificationSubscribeInfoTestCase(APITestCase):
class NotificationUnsubscribeAuthUserTestCase(BaseTestCase):
def test_unsubscribe_auth_user(self):
Subscriber.objects.create(user=self.user, email=self.email, state=1)
self.test_data = {
"email": self.email,
"state": 1
"email": self.email
}
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.test_data = {
"email": self.email,
"state": 1
"email": self.email
}
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}/",
data=self.test_data, format="json")
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"])