Skip to content

Commit

Permalink
feat(push notification):send notification
Browse files Browse the repository at this point in the history
 - add follow model for user follower
 - add notification app
 - add notifications on installed apps
 - add notifications view

[finishes #161254670]
  • Loading branch information
Gidraf committed Nov 19, 2018
1 parent 615ace6 commit 3a4debe
Show file tree
Hide file tree
Showing 23 changed files with 667 additions and 76 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ script:
- python3 manage.py migrate profiles
- python3 manage.py makemigrations article
- python3 manage.py migrate article
- python3 manage.py makemigrations notifications
- python3 manage.py migrate notifications
- python3 manage.py makemigrations report
- python3 manage.py migrate report
- python3 manage.py makemigrations
Expand Down
40 changes: 38 additions & 2 deletions authors/apps/article/likes_dislike_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from ..authentication.renderers import UserJSONRenderer
from rest_framework.permissions import IsAuthenticated

from authors.apps.article.renderers import FavoriteJSONRenderer
from authors.apps.article.serializers import FavoriteSerializer,\
ArticleSerializer
from .serializers import RateArticleSerializer
from .models import RateArticle
from .models import (Article,
LikeDislikeArticle, Favorite)
from rest_framework.generics import CreateAPIView


LOOKUP_FIELD = 'slug'
Expand Down Expand Up @@ -141,7 +144,7 @@ def post(self, request, **kwargs):
return Response(
{"response": disliked_article_response},
status=status.HTTP_200_OK)
except Exception as e:
except Exception:
LikeDislikeArticle(
liker=disliker,
article=disliked_article,
Expand All @@ -151,6 +154,39 @@ def post(self, request, **kwargs):
status=status.HTTP_200_OK)


class Rate(CreateAPIView):
permission_classes = (IsAuthenticated,)
renderer_classes = (UserJSONRenderer,)
serializer_class = RateArticleSerializer

def post(self, request, **kwargs):
"""
rate user view
"""
data = request.data.get('user', {})
serializer = self.serializer_class(data=data)
serializer.validate(data=data)
serializer.is_valid(raise_exception=True)
rate_article = None
try:
article = Article.objects.get(slug=data['slug'])
except Exception:
return Response({"response": "Article not found"},
status=status.HTTP_204_NO_CONTENT)
rater = request.user
try:
rate_article = RateArticle.objects.get(
rater=rater, article=article)
rate_article.rate = data["rate"]
rate_article.save()
return Response({"response": "successfully rated"},
status=status.HTTP_200_OK)
except Exception:
RateArticle(
rater=rater, article=article, rate=data["rate"]).save()
return Response(data={"response": "sucessfully rated"},
status=status.HTTP_200_OK)

class FavoriteAPIView(APIView):
serializer_class = FavoriteSerializer
permission_classes = (IsAuthenticated,)
Expand Down
69 changes: 69 additions & 0 deletions authors/apps/article/send_notifiactions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from ..profiles.models import UserProfile, Follow
from django.template.loader import render_to_string
from django.core.mail import send_mail
from .models import Article, Favorite
from authors.settings import DEFAULT_DOMAIN, EMAIL_HOST_USER

from ..notifications.models import NotificationsFollower, NotificationsArticle


def send_article_notification(slug, data, request):
"""
send email to article favourites
"""
try:
article = Article.objects.get(slug=slug)
subscribers = Favorite.objects.filter(article=article)
for subscriber in subscribers:
message = request.user.username + " commented on this article "
link = DEFAULT_DOMAIN + '/api/article/detail/' + \
article.slug
msg = render_to_string('article_alert.html', {
'user': subscriber.user.username,
"link": link,
"message": message,
"comment": data["body"]
})
send_mail('Authors Heaven New Article!',
'New Comment!!!!',
EMAIL_HOST_USER,
[subscriber.user.email],
html_message=msg,
fail_silently=False)
NotificationsArticle(
subscriber_id=subscriber.pk,
article_id=article.pk).save()
except Exception as error:
print(str(error))


def send_followers_notification(instance, request, user):
"""
send email to user following the author
"""
try:
profile = UserProfile.objects.get(user=user)
followers = Follow.objects.filter(follower=profile)
article = Article.objects.get(title=instance["title"])
for follower in followers:
message = article.user.username + " published new article "
link = DEFAULT_DOMAIN + '/api/article/detail/' + \
article.slug
follower_message = render_to_string('followee_alert.html', {
'user': follower.followee.user.username,
"link": link,
"message": message,
"title": instance["title"]
})
send_mail('Authors Heaven New Article!',
'New Article!!!!',
EMAIL_HOST_USER,
[follower.followee.user.email],
html_message=follower_message,
fail_silently=False)
NotificationsFollower(
follower=profile,
followee=follower.followee,
article=article).save()
except Exception as error:
print(str(error))
12 changes: 6 additions & 6 deletions authors/apps/article/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@
native Python datatypes that can then
be easily rendered into JSON, XML or other content types.'''
import math

from rest_framework import serializers
from django.apps import apps
from rest_framework.validators import UniqueTogetherValidator

from authors.apps.profiles.models import UserProfile

from .models import RateArticle, Comments, CommentHistory, Favorite
from authors.apps.profiles.serializers import ProfileListSerializer
from authors.apps.profiles.models import UserProfile


TABLE = apps.get_model('article', 'Article')
Profile = apps.get_model('profiles', 'UserProfile')
Expand Down Expand Up @@ -137,7 +135,9 @@ def get_time_to_read(self, body, images):
image_view_time = 0
if images:
image_view_time = (len(images) * 0.25)
time_taken = math.ceil((len(list(body)) / 250) + image_view_time)
time_taken = 0
if body:
time_taken = math.ceil((len(list(body)) / 250) + image_view_time)
if time_taken <= 1:
return str(time_taken) + 'min'
return str(time_taken) + 'mins'
Expand All @@ -146,7 +146,7 @@ def create(self, validated_data):
instance = TABLE.objects.create(**validated_data)
validated_data['slug'] = instance.slug
validated_data['time_to_read'] = self.get_time_to_read(
instance.body, validated_data.get('images'),)
instance.body, validated_data.get('images'))

return validated_data

Expand Down
56 changes: 56 additions & 0 deletions authors/apps/article/templates/article_alert.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<style>
.card {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
max-width: 600px;
margin: auto;
text-align: center;
font-family: arial;
}

.title {
color: grey;
font-size: 13px;
text-align: left;
}

button {
border: none;
outline: 0;
display: inline-block;
padding: 8px;
color: #000;;
background-color: #000;
text-align: center;
cursor: pointer;
width: 100%;
font-size: 18px;
}

a {
text-decoration: none;
font-size: 13px;
color: black;
}

button:hover, a:hover {
opacity: 0.7;
}
</style>
</head>
<body>

<div class="card">
<p class="title">
Hi {{user}},<br></p>
<p class="title"> New Comment!!!! <a href={{ENVIRONMENT}}>
Authors Heaven</a>, the platform for
people with expressive ideas.</p>
<p class="title">{{message}}<a href={{link}}> {{comment}} </a>view it on Authors Haven</p>
<p><button></button>Authors Heavens. All Rights Reserved</p>
</div>

</body>
</html>
56 changes: 56 additions & 0 deletions authors/apps/article/templates/followee_alert.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<style>
.card {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
max-width: 600px;
margin: auto;
text-align: center;
font-family: arial;
}

.title {
color: grey;
font-size: 13px;
text-align: left;
}

button {
border: none;
outline: 0;
display: inline-block;
padding: 8px;
color: #000;;
background-color: #000;
text-align: center;
cursor: pointer;
width: 100%;
font-size: 18px;
}

a {
text-decoration: none;
font-size: 13px;
color: black;
}

button:hover, a:hover {
opacity: 0.7;
}
</style>
</head>
<body>

<div class="card">
<p class="title">
Hi {{user}},<br></p>
<p class="title"> New Article!!!! <a href={{ENVIRONMENT}}>
Authors Heaven</a>, the platform for
people with expressive ideas.</p>
<p class="title">{{message}}<a href={{link}}> {{title}} </a>view it on Authors Haven</p>
<p><button></button>Authors Heavens. All Rights Reserved</p>
</div>

</body>
</html>
7 changes: 6 additions & 1 deletion authors/apps/article/tests/base_like_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def setUp(self):
self.email = "test_user@gmail.com"
self.name = "test"
self.user = User(username=self.name, email=self.email)
self.user.set_password("@Winners11")
self.user.set_password("@Winffners11")
self.user.save()
self.user_id = User.objects.get(email=self.email).pk
self.slug = "this-is-a-question"
Expand Down Expand Up @@ -78,3 +78,8 @@ def setUp(self):
self.view_likes_url = os.environ["URL"] + "api/article/rate/"
self.articles_url = os.environ["URL"] + "api/article/"
self.create_articles_url = os.environ["URL"] + "api/article/create"
self.get_notifications = os.environ["URL"] + "api/notifications"
self.edit_notifications = os.environ["URL"] + "api/notifications" +\
"1" + "follower"
self.edit_notifications_2 = os.environ["URL"] + "api/notifications" +\
"1" + "unfollower"
4 changes: 2 additions & 2 deletions authors/apps/article/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
ArticleDeleteAPIView,
ArticleDetailAPIView,
ArticleUpdateAPIView,
Rate,
ArticleRate,
CommentsListCreateView,
CommentsUpdateDeleteAPIView,
ArticleTags, CommentHistoryAPIView)
from .likes_dislike_views import (
Like,
Dislike,
FavoriteAPIView
FavoriteAPIView,
Rate
)

schema_view = get_swagger_view(title="Article Comments")
Expand Down
Loading

0 comments on commit 3a4debe

Please sign in to comment.