Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#162949233 Article highlighting with comments #32

Merged
merged 1 commit into from
Feb 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions authors/apps/articles/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 2.1.4 on 2019-02-05 14:35
# Generated by Django 2.1.4 on 2019-02-05 15:50

from django.conf import settings
from django.db import migrations, models
Expand All @@ -12,8 +12,8 @@ class Migration(migrations.Migration):
initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('contenttypes', '0002_remove_content_type_name'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('taggit', '0002_auto_20150616_2121'),
]

Expand All @@ -29,6 +29,7 @@ class Migration(migrations.Migration):
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('read_time', models.TextField(default='null')),
('is_reported', models.BooleanField(default=False)),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='author', to=settings.AUTH_USER_MODEL)),
('tag_list', taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')),
],
Expand Down Expand Up @@ -61,6 +62,22 @@ class Migration(migrations.Migration):
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='HighlightArticleModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('body', models.TextField()),
('highlited_article', models.TextField(blank=True, null=True)),
('begin_index', models.IntegerField(blank=True, null=True)),
('end_index', models.IntegerField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True)),
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='highlight', to='articles.Article')),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='author_relate', to=settings.AUTH_USER_MODEL)),
],
options={
'ordering': ['-created_at'],
},
),
migrations.CreateModel(
name='HistoricalComments',
fields=[
Expand Down
18 changes: 0 additions & 18 deletions authors/apps/articles/migrations/0002_article_is_reported.py

This file was deleted.

18 changes: 18 additions & 0 deletions authors/apps/articles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ class Rating(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)



class BookmarkArticleModel(models.Model):
"""Bookmark Article model"""
article_id = models.ForeignKey(Article, on_delete=models.CASCADE)
Expand All @@ -137,3 +138,20 @@ class ReportArticle(models.Model):

def __str__(self):
return "{}".format(self.slug)

class HighlightArticleModel(models.Model):
body = models.TextField()
author = models.ForeignKey(User, related_name='author_relate',
on_delete=models.CASCADE)
article = models.ForeignKey(Article, related_name='highlight',
on_delete=models.CASCADE)
highlited_article = models.TextField(blank=True, null=True)
begin_index = models.IntegerField(blank=True, null=True)
end_index = models.IntegerField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return str(self.body)

class Meta:
ordering = ['-created_at']
39 changes: 33 additions & 6 deletions authors/apps/articles/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import readtime
from rest_framework import serializers
from .models import Article, Comments, LikeDislike, ReportArticle
from .models import (
Article, Comments,
LikeDislike, FavoriteArticle,
HighlightArticleModel,ReportArticle
)
from authors.apps.profiles.models import UserProfile
from taggit_serializer.serializers import (
TagListSerializerField,
Expand Down Expand Up @@ -34,8 +38,7 @@ def get_read_time(self, article):

class Meta:
model = Article
fields = ['slug', 'title', 'description', 'body', 'tag_list',
'created_at', 'updated_at', 'author', 'rating', 'read_time']
fields = '__all__'


class UpdateArticleSerializer(serializers.ModelSerializer):
Expand All @@ -60,8 +63,7 @@ def get_read_time(self, article):

class Meta:
model = Article
fields = ['slug', 'title', 'description', 'body', 'tag_list',
'created_at', 'updated_at', 'author', 'rating', 'read_time']
fields = '__all__'


class CommentSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -190,7 +192,6 @@ class CommentHistorySerializer(serializers.ModelSerializer):
"""
This class handles the history of the comment edited
"""

class Meta:
model = Comments
fields = ('id', 'body', 'created_at', 'updated_at')
Expand All @@ -202,3 +203,29 @@ class ReportArticleSerializer(serializers.ModelSerializer):
class Meta:
model = ReportArticle
fields = ('slug', 'author_id', 'message', 'reporter_id')


class HighlightArticleSerializer(serializers.ModelSerializer):
"""Serializer for creating a Comment"""

author = serializers.SerializerMethodField()
article = serializers.SerializerMethodField()
body = serializers.CharField()
highlited_article = serializers.CharField()
begin_index = serializers.CharField()
end_index = serializers.CharField()

def get_author(self, highlightcomment):
author = ProfileSerialiazer(highlightcomment.author.profiles)
return author.data

def get_article(self, highlightcomment):
article = ArticleSerializer(highlightcomment.article)
return article.data['id']

class Meta:
model = HighlightArticleModel
fields = "__all__"

def get_user_id(self, obj):
return obj.user_id.id
22 changes: 13 additions & 9 deletions authors/apps/articles/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
from django.urls import path

from authors.apps.articles.models import LikeDislike
from authors.apps.articles.views.articles import (GetUpdateDeleteArticle,
CreateArticleView,
LikeDislikeArticleView)
from authors.apps.articles.views.bookmark import (BookmarkArticle,
GetBookmarkedArticles)
from authors.apps.articles.views.comments import (
Expand All @@ -13,11 +10,12 @@
from authors.apps.articles.views.favorite import (FavouriteArticle,
GetFavouriteArticles)
from authors.apps.articles.views.articles import (
GetUpdateDeleteArticle,CreateArticleView,
SearchFilter,LikeDislikeArticleView,
ShareArticleViaEmail,ShareArticleViaFacebook,
ShareArticleViaTwitter
)
GetUpdateDeleteArticle, CreateArticleView,
SearchFilter, LikeDislikeArticleView,
ShareArticleViaEmail, ShareArticleViaFacebook,
ShareArticleViaTwitter, HighlightArticle,
RetrieveUpdateDeleteHighlight
)
from authors.apps.articles.views.report_article import (
ReportArticleApi, GetReportedArticles
)
Expand Down Expand Up @@ -73,5 +71,11 @@
path('/report/<slug>', ReportArticleApi.as_view(),
name='report_article'),
path('/reported/', GetReportedArticles.as_view(),
name='reported_articles')
name='reported_articles'),
path('/<slug>/highlight',
HighlightArticle.as_view(), name='highlight'
),
path('/<slug>/highlight/<int:id>',
RetrieveUpdateDeleteHighlight.as_view(), name='highlight_comment'
)
]
9 changes: 2 additions & 7 deletions authors/apps/articles/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ def get_unique_slug(model_instance, slugable_field_name, slug_field_name):
slug = slugify(getattr(model_instance, slugable_field_name))
unique_slug = slug
extension = ''.join(random.choices(
string.ascii_uppercase + string.digits, k=5))
model_class = model_instance.__class__

while model_class._default_manager.filter(
**{slug_field_name: unique_slug}
).exists():
unique_slug = '{}-{}'.format(slug, extension)
string.ascii_lowercase + string.digits, k=8))
unique_slug = '{}-{}'.format(slug, extension)
return unique_slug
129 changes: 123 additions & 6 deletions authors/apps/articles/views/articles.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from urllib.parse import quote
from rest_framework.generics import (
RetrieveUpdateDestroyAPIView, ListCreateAPIView,
ListAPIView,CreateAPIView
ListAPIView, CreateAPIView
)
from rest_framework.permissions import (
IsAuthenticatedOrReadOnly, IsAuthenticated
Expand All @@ -18,19 +18,26 @@
from taggit.models import Tag

# local imports
from authors.apps.articles.models import Article, LikeDislike
from authors.apps.articles.models import (
Article,
LikeDislike,
HighlightArticleModel
)
from authors.apps.articles.serializers import (
ArticleSerializer, UpdateArticleSerializer,
LikeDislikeSerializer, CustomTagSerializer
)
HighlightArticleSerializer, LikeDislikeSerializer,
CustomTagSerializer
)
from authors.apps.authentication.serializers import EmailCheckSerializer

from authors.apps.articles.renderers import (
ArticleJSONRenderer,
LikeArticleJSONRenderer,
TagJSONRenderer
)
)
from authors.apps.articles.response_messages import (error_messages,
success_messages)
success_messages
)
from authors.apps.core.pagination import CustomPagination
from django.core.mail import send_mail
from django.template.loader import render_to_string
Expand Down Expand Up @@ -333,3 +340,113 @@ def post(self, request, *args, **kwargs):
url_link = twitter_url + article_link
shared_post_url = {'link': url_link}
return Response(shared_post_url, status=status.HTTP_200_OK)


class HighlightArticle(ListCreateAPIView):
permission_classes = (IsAuthenticatedOrReadOnly, )
serializer_class = HighlightArticleSerializer
queryset = HighlightArticleModel.objects.all()

def highlight_index(self, begin_point, end_point):
"""
method picks the selected index values, stores them in a variable
"""
index_values = [begin_point, end_point]
return index_values

def create(self, request, slug):
"""Get an article to comment"""

article = get_object_or_404(Article, slug=slug)
comment = request.data.get('comment', {})

try:

if int(comment.get('begin_index')) > int(comment.get('end_index')):
return Response({
'message': "The begin index should be less than the end index"})

highlight_range = self.highlight_index(
int(comment.get('begin_index', 0)),
int(comment.get('end_index', 0)))

except ValueError:
return Response({
'error': 'Please enter integer values only',
}, status.HTTP_422_UNPROCESSABLE_ENTITY)
highlited_article = str(
article.body[highlight_range[0]:highlight_range[1]])

comment['highlited_article'] = highlited_article

serializer = HighlightArticleSerializer(data=comment, partial=True)
if serializer.is_valid():
serializer.save(author=self.request.user, article_id=article.pk)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

def get(self, request, slug, *args, **kwargs):

article = Article.objects.filter(slug=slug).first()
if not article:
message = {"error": "Article doesn't exist"}
return Response(message, status.HTTP_404_NOT_FOUND)
highlightcomment = article.highlight.filter()
serializer = self.serializer_class(highlightcomment, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)


class RetrieveUpdateDeleteHighlight(RetrieveUpdateDestroyAPIView):
permission_classes = (IsAuthenticatedOrReadOnly, )
serializer_class = HighlightArticleSerializer
queryset = HighlightArticleModel.objects.all()
lookup_field = 'id'

def get(self, request, slug, id):
sylviawanjiku marked this conversation as resolved.
Show resolved Hide resolved
article = Article.objects.filter(slug=slug).first()
if not article:
message = {"error": "Article doesn't exist"}
return Response(message, status.HTTP_404_NOT_FOUND)
try:
highlightcomment = article.highlight.filter(id=id).first().pk
return super().get(request, highlightcomment)
except:
message = {"error": "Highlight comment doesn't exist"}
return Response(message, status.HTTP_404_NOT_FOUND)

def update(self, request, slug, id):

article = Article.objects.filter(slug=slug).first()
if not article:
message = {"error": "Article doesn't exist"}
return Response(message, status.HTTP_404_NOT_FOUND)
highlightcomment = article.highlight.filter(id=id).first()
if not highlightcomment:
message = {"message": "Highlight comment does not exist"}
return Response(message, status=status.HTTP_404_NOT_FOUND)

update_comment = request.data.get('comment', {})['body']
data = {
'body': update_comment,
'article': article.pk,
}
serializer = self.serializer_class(
highlightcomment, data=data, partial=True)
serializer.is_valid(raise_exception=True)
serializer.save(author=request.user)
return Response(serializer.data, status=status.HTTP_200_OK)

def delete(self, request, slug, id):
article = Article.objects.filter(slug=slug).first()
if not article:
message = {"error": "Article doesn't exist"}
return Response(message, status.HTTP_404_NOT_FOUND)
try:
highlightcomment = article.highlight.filter(id=id).first().pk
except:
message = {"error": "Highlight comment doesn't exist"}
return Response(message, status.HTTP_404_NOT_FOUND)
super().delete(self, request, highlightcomment)
message = {"message": "Highlight Comment deleted successfully"}
return Response(
message, status.HTTP_200_OK)
Loading