Skip to content

Commit

Permalink
Merge 0f9fadb into 6b793ee
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewhingah authored Feb 3, 2019
2 parents 6b793ee + 0f9fadb commit 746d427
Show file tree
Hide file tree
Showing 22 changed files with 632 additions and 2 deletions.
4 changes: 4 additions & 0 deletions authors/apps/articles/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""
set default app config
"""
default_app_config = 'authors.apps.articles.apps.ArticlesConfig'
5 changes: 4 additions & 1 deletion authors/apps/articles/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@


class ArticlesConfig(AppConfig):
name = 'articles'
name = 'authors.apps.articles'

def ready(self):
from authors.apps.usernotifications import handlers
23 changes: 23 additions & 0 deletions authors/apps/authentication/migrations/0004_auto_20190129_2002.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 2.1.5 on 2019-01-29 20:02

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('authentication', '0003_merge_20190121_1209'),
]

operations = [
migrations.AddField(
model_name='user',
name='app_notification_subscription',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='user',
name='email_notification_subscription',
field=models.BooleanField(default=True),
),
]
4 changes: 4 additions & 0 deletions authors/apps/authentication/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ class User(AbstractBaseUser, PermissionsMixin):

# More fields required by Django when specifying a custom user model.

# fields to specify if a user has subscribed to notifications
email_notification_subscription = models.BooleanField(default=True)
app_notification_subscription = models.BooleanField(default=True)

# The `USERNAME_FIELD` property tells us which field we will use to log in.
# In this case, we want that to be the email field.
USERNAME_FIELD = 'email'
Expand Down
4 changes: 4 additions & 0 deletions authors/apps/friends/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""
set default app config
"""
default_app_config = 'authors.apps.friends.apps.FriendsConfig'
5 changes: 4 additions & 1 deletion authors/apps/friends/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@


class FriendsConfig(AppConfig):
name = 'friends'
name = 'authors.apps.friends'

def ready(self):
from authors.apps.usernotifications import handlers
Empty file.
3 changes: 3 additions & 0 deletions authors/apps/usernotifications/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
5 changes: 5 additions & 0 deletions authors/apps/usernotifications/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class UsernotificationsConfig(AppConfig):
name = 'usernotifications'
95 changes: 95 additions & 0 deletions authors/apps/usernotifications/handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from django.conf import settings
from django.template.loader import render_to_string
from django.db.models.signals import post_save
from django.core.mail import send_mail
from notifications.signals import notify
from notifications.models import Notification
from authors.apps.friends.models import Friend
from authors.apps.authentication.models import User
from authors.apps.articles.models import Article
from . import verbs


def follow_handler(sender, instance, created, **kwargs):
"""
notification handler for friends
"""
# get the user that has been followed
follower = instance.user_from
followed = instance.user_to
recipient = followed
if recipient.email_notification_subscription is False:
return
url = 'api/profiles/{}'.format(followed.username)
notify.send(
follower,
recipient=recipient,
description="{} followed you on {}".format(follower.username, instance.created_at.strftime('%d-%B-%Y %H:%M')),
verb=verbs.USER_FOLLOWING,
action_object=instance,
target=followed,
resource_url=url
)


def article_handler(sender, instance, created, **kwargs):
"""
notification handler for articles
"""
article_author = instance.author
followers = Friend.objects.select_related(
'user_from').filter(user_to=article_author.id).all()
# add the author's followers to the recipients list
recipients = [User.objects.get(id=u.user_from_id) for u in followers]
# add only the subscribed followers to the recipients list
subsribed_users = [user for user in recipients if user.app_notification_subscription is True]
if not subsribed_users:
return
for user in subsribed_users:
url = "api/articles/"
notify.send(
article_author,
recipient=user,
description="{} posted an article on {}".format(
article_author.username,
instance.created.strftime('%d-%B-%Y %H:%M')),
verb=verbs.ARTICLE_CREATION,
action_object=instance,
resource_url=url
)


def email_notification_handler(sender, instance, created, **kwargs):
"""
notification handler for emails
"""
user = instance.recipient
recipient = User.objects.get(email=user)
if recipient.email_notification_subscription is False:
return
description = instance.description
token = recipient.token
opt_out_link = '{}/api/notifications/unsubscribe/{}'.format(
settings.DOMAIN, token
)
try:
resource_url = instance.data['resource_url']
except TypeError:
resource_url = "api/articles/"
html_content = render_to_string('email_notification.html', context={
"opt_out_link": opt_out_link,
"username": recipient.username,
"description": description,
"resource_url": resource_url
})
send_mail(
"User Notification",
'',
'django_unchained@gmail.com',
[recipient.email],
html_message=html_content)


post_save.connect(follow_handler, sender=Friend, weak=False)
post_save.connect(article_handler, sender=Article, weak=False)
post_save.connect(email_notification_handler, sender=Notification)
Empty file.
3 changes: 3 additions & 0 deletions authors/apps/usernotifications/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.db import models

# Create your models here.
56 changes: 56 additions & 0 deletions authors/apps/usernotifications/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from rest_framework import serializers

from notifications.models import Notification

from authors.apps.articles.models import Article
from authors.apps.authentication.models import User


class UnsubscribeSerializer(serializers.Serializer):
"""
serializer class for unsubscribing from email notifications
"""
class Meta:
fields = ('message', 'email', 'app')


class ActorTargetField(serializers.RelatedField):
"""
class to represent an actor/target
"""
def to_representation(self, value):
actor_type = None
data = []
if isinstance(value, Article):
actor_type = "article"
data = value.slug

elif isinstance(value, User):
actor_type = "user"
data = value.username

return {"type": actor_type, "data": data}

def to_internal_value(self, data):
return Notification(data)


class NotificationSerializer(serializers.ModelSerializer):
"""
serializer class for notification objects
"""
actor = ActorTargetField(read_only=True)
target = ActorTargetField(read_only=True)

class Meta:
model = Notification
fields = (
'id',
'actor',
'verb',
'target',
'level',
'unread',
'timestamp',
'description',
'emailed')
34 changes: 34 additions & 0 deletions authors/apps/usernotifications/templates/email_notification.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Authors Haven Notifications</title>
<meta name="description" content="email notifications">
<meta name="keywords" content="keywords">
</head>


<body>
<div id="div-page" style="border: 2px solid #86C232;border-radius: 25px;width: 30em;padding: 25px;margin: 5em;text-align: justify; border-width: thick">

<h1 style="line-height: 35px;text-align: center; color: #86C232;">
Authors Haven Notifications
</h1>
<h1 style="line-height: 35px;text-align: center;">
Hello <span id="username" style="color: #23bebe;">{{username}}</span>
</h1>

<div id="div-content" style="line-height: 26px;">
<p style="text-align: center;">This is an auto generated notification.</p>
<p>{{description}}</p>
<p><a href={{resource_url}}><button>See Here</button></a></p>
<p>To opt out of these notifications, click below</p>
<p></p><a href={{opt_out_link}}>Unsubscribe</a></p>
<p style="text-align: center;">Thank you for being an active user.</p>

</div>
</div>


</body>

</html>
Empty file.
Loading

0 comments on commit 746d427

Please sign in to comment.