Skip to content

Commit

Permalink
Merge pull request #85 from mnqrt/feat/adrian/tanyateman
Browse files Browse the repository at this point in the history
  • Loading branch information
mnqrt authored Aug 25, 2024
2 parents e77c886 + 927f3ee commit 5b492c7
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 12 deletions.
27 changes: 27 additions & 0 deletions main/migrations/0024_likepost.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 3.1.2 on 2024-08-22 14:10

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('main', '0023_auto_20240818_1418'),
]

operations = [
migrations.CreateModel(
name='LikePost',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('object_id', models.PositiveIntegerField()),
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.profile')),
],
options={
'unique_together': {('user', 'content_type', 'object_id')},
},
),
]
19 changes: 18 additions & 1 deletion main/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from django.db import models
from django.db.models.deletion import CASCADE
from django.db.models import UniqueConstraint
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
import boto3
import environ

Expand Down Expand Up @@ -243,4 +245,19 @@ def get_attachment_presigned_url(attachment, expires_in=expires_in):
},
ExpiresIn=expires_in
)
return url
return url

class LikePost(models.Model):
"""
This class That a user like a Post (Could be Question/Answer)
"""
user = models.ForeignKey(Profile, on_delete=models.CASCADE)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')

class Meta:
unique_together = ('user', 'content_type', 'object_id')

def __str__(self):
return f'{self.user.username} liked {self.content_object}: {self.content_type} {self.object_id}'
116 changes: 105 additions & 11 deletions main/views_tanyateman.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
from main.views_calculator import score_component
from .serializers import AddQuestionSerializer, CalculatorSerializer, QuestionSerializer, ScoreComponentSerializer, TanyaTemanProfileSerializer, UserCumulativeGPASerializer, UserGPASerializer, CourseForSemesterSerializer, SemesterWithCourseSerializer, HideVerificationQuestionSerializer, AnswerQuestionSerializer, AnswerSerializer
from .utils import get_recommended_score, get_score, response, response_paged, update_course_score, validate_body, check_notexist_and_create_user_cumulative_gpa, validate_body_minimum, add_semester_gpa, delete_semester_gpa, update_semester_gpa, update_cumulative_gpa, get_fasilkom_courses, add_course_to_semester, validate_params, delete_course_to_semester, get_paged_questions
from .models import Calculator, Course, Profile, Question, Answer
from .models import Calculator, Course, LikePost, Profile, Question, Answer
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
import boto3
import environ
Expand Down Expand Up @@ -71,8 +72,41 @@ def tanya_teman(request):
if not id.isnumeric():
return response(error="id should be a number", status=status.HTTP_400_BAD_REQUEST)
return tanya_teman_with_id(request, id)

if request.method == 'PUT':
is_like = request.query_params.get("is_like")
if is_like is None:
return response(error="The only allowed PUT request for /tanya-teman is to like/unlike a Question.", status=status.HTTP_400_BAD_REQUEST)

id = request.query_params.get('id')
if id is None:
return response(error="id is required", status=status.HTTP_400_BAD_REQUEST)
if not id.isnumeric():
return response(error="id should be a number", status=status.HTTP_400_BAD_REQUEST)

question = Question.objects.filter(pk=id).first()
if question is None:
return response(error="No matching question", status=status.HTTP_404_NOT_FOUND)

content_type = ContentType.objects.get_for_model(Question)
question_like = LikePost.objects.filter(content_type=content_type, object_id=id, user=user).first()
if question_like is None:
LikePost.objects.create(
user=user,
content_type=content_type,
object_id=id
)
question.like_count += 1
question.save()
else:
question_like.delete()
question.like_count -= 1
question.save()

return response(status=status.HTTP_200_OK)

@api_view(['GET', 'POST'])

@api_view(['GET', 'POST', 'PUT'])
def jawab_teman(request):
user = Profile.objects.get(username=str(request.user))

Expand Down Expand Up @@ -125,6 +159,39 @@ def jawab_teman(request):
Q(question=question),
Q(verification_status=Answer.VerificationStatus.APPROVED) | Q(user=user))
return jawab_teman_paged(request, all_replies)

if request.method == 'PUT':
is_like = request.query_params.get("is_like")
if is_like is None:
return response(error="The only allowed PUT request for /jawab-teman is to like/unlike an Answer.", status=status.HTTP_400_BAD_REQUEST)

id = request.query_params.get('id')
if id is None:
return response(error="id is required", status=status.HTTP_400_BAD_REQUEST)
if not id.isnumeric():
return response(error="id should be a number", status=status.HTTP_400_BAD_REQUEST)

answer = Answer.objects.filter(pk=id).first()
if answer is None:
return response(error="No matching answer", status=status.HTTP_404_NOT_FOUND)

content_type = ContentType.objects.get_for_model(Answer)
answer_like = LikePost.objects.filter(content_type=content_type, object_id=id, user=user).first()
if answer_like is None:
LikePost.objects.create(
user=user,
content_type=content_type,
object_id=id
)
answer.like_count += 1
answer.save()
else:
answer_like.delete()
answer.like_count -= 1
answer.save()

return response(status=status.HTTP_200_OK)


def tanya_teman_with_id(request, id):
user = Profile.objects.get(username=str(request.user))
Expand All @@ -146,24 +213,39 @@ def tanya_teman_with_id(request, id):

def tanya_teman_paged(request, questions, is_history):
page = request.query_params.get('page')
user = Profile.objects.get(username=str(request.user))
if page is None:
return response(error='page is required', status=status.HTTP_400_BAD_REQUEST)

questions, total_page = get_paged_questions(questions, page)

list_questions = None
if is_history:
list_questions = QuestionSerializer(questions, many=True).data
else:
list_questions = HideVerificationQuestionSerializer(questions, many=True).data
list_questions = add_is_liked(user, list_questions, is_question=True)

return response_paged(data={
'questions': QuestionSerializer(questions, many=True).data
if is_history else
HideVerificationQuestionSerializer(questions, many=True).data
'questions': list_questions
}, total_page=total_page)

def jawab_teman_paged(request, answers):
page = request.query_params.get('page')
user = Profile.objects.get(username=str(request.user))
question = answers[0].question if len(answers) > 0 else None
like_count = question.like_count if question != None else 0
reply_count = question.reply_count if question != None else 0
if page is None:
return response(error='page is required', status=status.HTTP_400_BAD_REQUEST)

answers, total_page = get_paged_questions(answers, page)
list_answers = AnswerSerializer(answers, many=True).data
list_answers = add_is_liked(user, list_answers, is_question=False)
return response_paged(data={
'answers': AnswerSerializer(answers, many=True).data
'answers': list_answers,
'like_count': like_count,
'reply_count': reply_count
}, total_page=total_page)


Expand All @@ -190,12 +272,12 @@ def filtered_question(request):
questions = questions.filter(Q(question_text__icontains=keyword))

if is_paling_banyak_disukai:
return questions.order_by('like_count')
return questions.order_by('-like_count')
if is_terverifikasi:
return questions.filter(verification_status=Question.VerificationStatus.APPROVED).order_by('created_at')
return questions.filter(verification_status=Question.VerificationStatus.APPROVED).order_by('-created_at')
if is_menunggu_verifikasi:
return questions.filter(verification_status=Question.VerificationStatus.WAITING).order_by('created_at')
return questions.order_by('created_at')
return questions.filter(verification_status=Question.VerificationStatus.WAITING).order_by('-created_at')
return questions.order_by('-created_at')

'''
upload_attachment returns ('error', response) if the attachment file is not valid
Expand Down Expand Up @@ -232,4 +314,16 @@ def upload_attachment(attachment_file):
s3.upload_fileobj(attachment_file, bucket_name, key)
return "success", key
except Exception as e:
return "error", response(error=str(e), status=status.HTTP_400_BAD_REQUEST)
return "error", response(error=str(e), status=status.HTTP_400_BAD_REQUEST)

def add_is_liked(user, posts, is_question):
list_posts = []
if is_question:
content_type = ContentType.objects.get_for_model(Question)
else:
content_type = ContentType.objects.get_for_model(Answer)
for post in posts:
post_like = LikePost.objects.filter(content_type=content_type, object_id=post['id'], user=user).first()
post['liked_by_user'] = 1 if post_like != None else 0
list_posts.append(post)
return list_posts

0 comments on commit 5b492c7

Please sign in to comment.