• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gcivil-nyu-org / INT2-Monday-Spring2024-Team-3 / #620096607

03 Apr 2024 11:07PM UTC coverage: 90.241%. First build
#620096607

Pull #155

travis-ci

Pull Request #155: Ml review filter

2 of 3 new or added lines in 1 file covered. (66.67%)

1313 of 1455 relevant lines covered (90.24%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

49.33
/backend/views/review_handlers.py
1
import json
1✔
2
import logging
1✔
3
from django.http import JsonResponse, HttpResponseServerError
1✔
4
from django.views.decorators.http import require_POST
1✔
5
from django.contrib.auth.decorators import login_required
1✔
6
from backend.models import (
1✔
7
    Event,
1✔
8
    Review,
1✔
9
    SuspendedUser,
10
    ReplyToReview,
11
    Report,
1✔
12
    ReportReply,
1✔
13
)
1✔
14
from django.shortcuts import get_object_or_404, redirect
1✔
15
from django.db.models import Avg
1✔
16
from django.db.models import F
1✔
17
from django.core.paginator import Paginator
×
18
from django.shortcuts import render
19

20
from backend.huggingface import censorbot
21
from datetime import datetime, timedelta
22
from backend.admin import send_notification_email
23

1✔
24
logger = logging.getLogger(__name__)
1✔
25

1✔
NEW
26

×
27
@login_required
28
@require_POST
29
def post_review(request, event_id):
30
    event = get_object_or_404(Event, pk=event_id)
31
    user = request.user
32
    if SuspendedUser.objects.filter(user=user, is_suspended=True).exists():
1✔
33
        return JsonResponse(
1✔
34
            {
35
                "success": False,
1✔
36
                "message": "Your account is suspended. You cannot post a review.",
1✔
37
            }
38
        )
1✔
39
    rating = request.POST.get("rating")
1✔
40
    review_text = request.POST.get("review_text")
1✔
41
    # if censorbot.detect_hate_speech(review_text)[0]["label"] == "hate":
1✔
42
    #     return JsonResponse(
43
    #         {
1✔
44
    #             "success": False,
45
    #             "message": "Your review contains hate speech. Please remove it and try again.",
46
    #         }
47
    #     )
48
    review = Review(event=event, user=user, rating=rating, review_text=review_text)
49
    review.likes_count = 0
50
    review.save()
51

52
    liked_by_users = review.liked_by.all()
53

54
    avg_rating_result = Review.objects.filter(event=event).aggregate(Avg("rating"))
55
    new_avg_rating = avg_rating_result["rating__avg"] or 0
56
    new_avg_rating = round(new_avg_rating, 2)
57
    event.avg_rating = new_avg_rating
58
    event.save()
59

60
    return JsonResponse(
61
        {
62
            "success": True,
63
            "review_id": review.id,
64
            "new_avg_rating": new_avg_rating,
65
            "user": {
66
                "username": user.username,
67
                "profile": {
1✔
68
                    "avatar": (user.profile.avatar.url if user.profile.avatar else None)
×
69
                },
×
70
            },
×
71
            "rating": review.rating,
×
72
            "review_text": review.review_text,
73
            "timestamp": review.timestamp.isoformat(),
×
74
            "likes_count": review.likes_count,
75
            "liked_by": [user.username for user in liked_by_users],
76
            "reply_count": review.reply_count,
1✔
77
        }
×
78
    )
×
79

×
80

81
def get_average_rating(request, event_id):
×
82
    reviews = Review.objects.filter(event__id=event_id)
83
    average_rating = reviews.aggregate(Avg("rating"))["rating__avg"]
×
84
    if average_rating is not None:
×
85
        return JsonResponse({"avg_rating": average_rating})
86
    else:
×
87
        return JsonResponse({"avg_rating": None})
×
88

×
89

90
def get_reviews_for_event(request, event_id):
91
    try:
92
        page_number = request.GET.get("page", 1)
93
        reviews_per_page = 100
94

95
        reviews = Review.objects.filter(event__id=event_id).order_by("timestamp")
96

97
        paginator = Paginator(reviews, reviews_per_page)
98
        page_obj = paginator.get_page(page_number)
99

100
        reviews_data = []
101
        for review in page_obj:
102
            reviews_data.append(
103
                {
104
                    "id": review.id,
105
                    "user": {
106
                        "username": review.user.username,
107
                        "profile": {
108
                            "avatar": (
109
                                review.user.profile.avatar.url
110
                                if review.user.profile.avatar
111
                                else None
×
112
                            )
113
                        },
114
                    },
115
                    "rating": review.rating,
116
                    "review_text": review.review_text,
117
                    "timestamp": review.timestamp.isoformat(),
118
                    "likes_count": review.likes_count,
119
                    "liked_by": list(
120
                        review.liked_by.values_list("username", flat=True)
×
121
                    ),
×
122
                    "reply_count": review.reply_count,
×
123
                }
124
            )
125

1✔
126
        return JsonResponse(
1✔
127
            {
1✔
128
                "reviews": reviews_data,
×
129
                "has_next": page_obj.has_next(),
×
130
                "next_page_number": (
×
131
                    page_obj.next_page_number() if page_obj.has_next() else None
×
132
                ),
×
133
            }
×
134
        )
135
    except Exception as e:
136
        print(e)
1✔
137
        return HttpResponseServerError("Server Error: {}".format(e))
1✔
138

1✔
139

×
140
@login_required
×
141
@require_POST
×
142
def like_review(request, event_id, review_id):
×
143
    review = get_object_or_404(Review, pk=review_id)
×
144
    user = request.user
×
145
    if review.liked_by.filter(pk=user.pk).exists():
146
        return JsonResponse(
147
            {"error": "You have already liked this review."}, status=400
1✔
148
        )
1✔
149
    review.liked_by.add(user)
1✔
150
    review.likes_count += 1
×
151
    review.save()
×
152
    return JsonResponse({"success": True, "likes_count": review.likes_count})
×
153

×
154

×
155
@login_required
×
156
@require_POST
157
def unlike_review(request, event_id, review_id):
158
    review = get_object_or_404(Review, pk=review_id)
159
    user = request.user
160
    if not review.liked_by.filter(pk=user.pk).exists():
161
        return JsonResponse({"error": "You did not like this review."}, status=400)
162
    review.liked_by.remove(user)
163
    review.likes_count = max(review.likes_count - 1, 0)
164
    review.save()
165
    return JsonResponse({"success": True, "likes_count": review.likes_count})
166

167

168
@login_required
169
@require_POST
170
def delete_review(request, event_id, review_id):
171
    try:
172
        review = get_object_or_404(Review, pk=review_id)
173
        review.delete()
174
        return JsonResponse({"success": True})
175
    except Exception as e:
176
        return JsonResponse({"success": False, "message": str(e)}, status=500)
177

178

179
@login_required
180
def get_user_reviews(request, username):
181
    user = request.user
182
    reviews = Review.objects.filter(user=user).order_by("-timestamp")
183
    reviews_data = []
184
    for review in reviews:
185
        reviews_data.append(
186
            {
187
                "id": review.id,
188
                "event": {
189
                    "title": review.event.title,
190
                    "location": review.event.location,
191
                    "id": review.event.id,
192
                },
193
                "rating": review.rating,
194
                "review_text": review.review_text,
195
                "timestamp": review.timestamp.isoformat(),
196
                "likes_count": review.likes_count,
197
                "liked_by": list(review.liked_by.values_list("username", flat=True)),
198
            }
199
        )
200
    return render(request, "review_history.html", {"reviews": reviews_data})
201

202

203
@login_required
204
@require_POST
205
def delete_reviewhistory(request, review_id, username):
206
    try:
207
        review = get_object_or_404(Review, pk=review_id)
208
        review.delete()
209
        return JsonResponse({"success": True})
210
    except Exception as e:
211
        return JsonResponse({"success": False, "message": str(e)}, status=500)
212

213

214
@require_POST
215
def reply_to_review(request, event_id, review_id):
216
    user = request.user
217
    if SuspendedUser.objects.filter(user=user, is_suspended=True).exists():
218
        return JsonResponse(
219
            {
220
                "success": False,
221
                "message": "Your account is suspended. You cannot post a reply.",
222
            }
223
        )
224
    review = get_object_or_404(Review, pk=review_id)
225
    reply_text = request.POST.get("reply_text")
226

227
    if not reply_text:
228
        return JsonResponse(
229
            {"success": False, "message": "Reply text is required."}, status=400
230
        )
231

232
    reply = ReplyToReview.objects.create(
233
        review=review, fromUser=user, toUser=review.user, reply_text=reply_text
234
    )
235
    liked_by_users = reply.liked_by.all()
236
    review.reply_count = F("reply_count") + 1
237
    review.save()
238
    review.refresh_from_db(fields=["reply_count"])
239

240
    return JsonResponse(
241
        {
242
            "success": True,
243
            "reply_id": reply.id,
244
            "reply_text": reply.reply_text,
245
            "from_user": {
246
                "username": reply.fromUser.username,
247
                "profile": {
248
                    "avatar": (
249
                        reply.fromUser.profile.avatar.url
250
                        if reply.fromUser.profile.avatar
251
                        else None
252
                    )
253
                },
254
            },
255
            "to_user": review.user.username,
256
            "timestamp": reply.timestamp.strftime("%Y-%m-%d %H:%M:%S"),
257
            "reply_count": review.reply_count,
258
            "likes_count": reply.likes_count,
259
            "likes_by": [user.username for user in liked_by_users],
260
        }
261
    )
262

263

264
def get_replies_for_review(request, event_id, review_id):
265
    try:
266
        replies = ReplyToReview.objects.filter(review__id=review_id).order_by(
267
            "-timestamp"
268
        )
269
        replies_data = []
270

271
        for reply in replies:
272
            replies_data.append(
273
                {
274
                    "id": reply.id,
275
                    "from_user": {
276
                        "username": reply.fromUser.username,
277
                        "profile": {
278
                            "avatar": (
279
                                reply.fromUser.profile.avatar.url
280
                                if reply.fromUser.profile.avatar
281
                                else None
282
                            )
283
                        },
284
                    },
285
                    "to_user": reply.toUser.username,
286
                    "reply_text": reply.reply_text,
287
                    "timestamp": reply.timestamp.isoformat(),
288
                    "likes_count": reply.likes_count,
289
                    "liked_by": list(reply.liked_by.values_list("username", flat=True)),
290
                }
291
            )
292
        return JsonResponse({"replies": replies_data})
293

294
    except Exception as e:
295
        print(e)
296
        return HttpResponseServerError("Server Error: {}".format(e))
297

298

299
@login_required
300
@require_POST
301
def like_reply(request, event_id, review_id, reply_id):
302
    replies = ReplyToReview.objects.filter(review__id=review_id)
303
    reply = get_object_or_404(replies, pk=reply_id)
304
    user = request.user
305
    if reply.liked_by.filter(pk=user.pk).exists():
306
        return JsonResponse(
307
            {"error": "You have already liked this review."}, status=400
308
        )
309

310
    reply.liked_by.add(user)
311
    reply.likes_count += 1
312
    reply.save()
313
    return JsonResponse({"success": True, "likes_count": reply.likes_count})
314

315

316
@login_required
317
@require_POST
318
def unlike_reply(request, event_id, review_id, reply_id):
319
    replies = ReplyToReview.objects.filter(review__id=review_id)
320
    reply = get_object_or_404(replies, pk=reply_id)
321
    user = request.user
322
    if not reply.liked_by.filter(pk=user.pk).exists():
323
        return JsonResponse({"error": "You did not like this review."}, status=400)
324

325
    reply.liked_by.remove(user)
326
    reply.likes_count = max(reply.likes_count - 1, 0)
327
    reply.save()
328
    return JsonResponse({"success": True, "likes_count": reply.likes_count})
329

330

331
@login_required
332
@require_POST
333
def delete_reply(request, event_id, review_id, reply_id):
334
    try:
335
        review = get_object_or_404(Review, pk=review_id)
336
        review.reply_count = review.reply_count - 1
337
        review.save()
338
        replies = ReplyToReview.objects.filter(review__id=review_id)
339
        reply = get_object_or_404(replies, pk=reply_id)
340
        reply.delete()
341
        return JsonResponse({"success": True})
342
    except Exception as e:
343
        return JsonResponse({"success": False, "message": str(e)}, status=500)
344

345

346
@login_required
347
@require_POST
348
def report_review(request, review_id, event_id=None):
349
    try:
350
        # Parse JSON data from request body
351
        print(review_id)
352

353
        data = json.loads(request.body)
354
        print(request.body)
355
        review = get_object_or_404(Review, pk=review_id)
356

357
        # Check if the review has already been reported by this user
358
        if Report.objects.filter(review=review, reported_by=request.user).exists():
359
            return JsonResponse(
360
                {"success": False, "message": "You have already reported this review."}
361
            )
362

363
        # Extract title and description from the JSON data
364
        title = data.get("title")
365
        description = data.get("description")
366

367
        # Create a new report
368
        Report.objects.create(
369
            title=title,
370
            description=description,
371
            review=review,
372
            reported_by=request.user,
373
            reported_user=review.user,
374
        )
375
        review.is_reported = True
376
        review.save()
377

378
        subject = "Report Received"
379
        message = "Your report has been received. An admin will review your report and take appropriate action. Thank you for your patience."
380
        send_notification_email(request.user, subject, message)
381

382
        return JsonResponse(
383
            {"success": True, "message": "Report submitted successfully."}
384
        )
385
    except Exception as e:
386
        # Log the error for better debugging
387
        print(f"Error reporting review: {e}")
388
        return JsonResponse({"success": False, "message": str(e)})
389

390

391
@login_required
392
@require_POST
393
def reply_report(request, review_id, reply_id, event_id=None):
394
    try:
395
        # Parse JSON data from request body
396
        print(review_id)
397

398
        data = json.loads(request.body)
399
        print(request.body)
400
        review = get_object_or_404(Review, pk=review_id)
401
        reply = get_object_or_404(ReplyToReview, pk=reply_id)
402
        print(reply)
403

404
        # Check if the reply has already been reported by this user
405
        if ReportReply.objects.filter(reply=reply, reported_by=request.user).exists():
406
            return JsonResponse(
407
                {"success": False, "message": "You have already reported this reply."}
408
            )
409

410
        # Extract title and description from the JSON data
411
        title = data.get("title")
412
        description = data.get("description")
413

414
        # Create a new report
415
        ReportReply.objects.create(
416
            title=title,
417
            description=description,
418
            review=review,
419
            reply=reply,
420
            reported_by=request.user,
421
            reported_user=reply.fromUser,  # assuming reply.user is the one who made the reply
422
        )
423
        reply.is_reported = True
424
        reply.save()
425

426
        subject = "Report Received"
427
        message = "Your report has been received. An admin will review your report and take appropriate action. Thank you for your patience."
428
        send_notification_email(request.user, subject, message)
429

430
        return JsonResponse(
431
            {"success": True, "message": "Report submitted successfully."}
432
        )
433
    except Exception as e:
434
        # Log the error for better debugging
435
        print(f"Error reporting reply: {e}")
436
        return JsonResponse({"success": False, "message": str(e)})
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc