Fakultas Ilmu Komputer UI

views.py 32.7 KB
Newer Older
1
2
import mimetypes
import os
3
from io import BytesIO
4

5
import django
6
from decouple import config
7
import pandas as pd
8
from django.conf import settings
9
from django.contrib import messages
10
11
12
from django.contrib.auth.views import PasswordChangeForm
from django.contrib.auth.views import PasswordChangeView
from django.core.exceptions import PermissionDenied, FieldError
13
from django.core.mail import send_mail
14
from django.core.paginator import Paginator
15
from django.db.models import Q, Avg, Count
16
17
from django.http import (Http404, HttpResponse, HttpResponseRedirect,
                         JsonResponse)
18
19
from django.shortcuts import get_object_or_404, redirect
from django.shortcuts import render
20
from django.template import loader
21
from django.urls import reverse
22
from django.urls import reverse_lazy
23
from django.views import defaults
24
from django.views.generic import TemplateView
25

26
from app.forms import SuntingProfilForm, UploadMateriForm, RatingContributorForm
27
28
29
from app.models import (
    Category,
    Comment,
30
    Review,
31
32
    Materi,
    ReqMaterial,
33
    Rating, RatingContributor,
Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
34
35
    SubmitVisitor,
    ReadLater
36
)
37
from authentication.models import User
38
39
from .services import DafterKatalogService, DetailMateriService, LikeDislikeService, MateriFieldValidationHelperService, \
    DownloadViewMateriHelperService, UploadMateriService, EditProfileService, RevisiMateriService, \
Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
40
    DownloadHistoryService, GoogleDriveUploadService, ReadLaterService
41

42

43
def permission_denied(request, exception, template_name="error_403.html"):
44
45
    return defaults.permission_denied(request, exception, template_name)

46

47
class DaftarKatalog(TemplateView):
igor lestin sianipar's avatar
igor lestin sianipar committed
48
    paginate_by = 2
49
50
51
52
53
54
55
    template_name = "app/katalog_materi.html"

    def get_context_data(self, **kwargs):
        return super().get_context_data(**kwargs)

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
56
        context["kategori_list"] = Category.objects.all()
57

Mika dabelza abi's avatar
Mika dabelza abi committed
58
        lstMateri = Materi.objects.filter(status="APPROVE").order_by("date_modified")
Mika dabelza abi's avatar
Mika dabelza abi committed
59
60
        url = ""

61
        lstMateri, url = DafterKatalogService.apply_options(lstMateri, request, url)
Saul Andre's avatar
Saul Andre committed
62

63

Mika dabelza abi's avatar
Mika dabelza abi committed
64
        context["materi_list"] = lstMateri
Mika dabelza abi's avatar
Mika dabelza abi committed
65
        paginator = Paginator(context["materi_list"], 15)
66
        page_number = request.GET.get("page")
Mika dabelza abi's avatar
Mika dabelza abi committed
67
68
69
70
        page_obj = paginator.get_page(page_number)
        context["materi_list"] = page_obj

        context["url"] = url
71
72
        return self.render_to_response(context=context)

73

74
75
class KatalogPerKontributorView(TemplateView):
    template_name = "app/katalog_kontri.html"
76

77
78
79
80
81
82
83
84
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        contributor = get_object_or_404(User, email=kwargs["email"])
        context["contributor"] = contributor
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
85
86
87
88
89

        materi_list = Materi.objects.filter(status="APPROVE", uploader=context["contributor"]).order_by(
            "date_modified"
        )

90
        paginator = Paginator(materi_list, 15)
91
        page_number = request.GET.get("page")
92
93
        materi_list_by_page = paginator.get_page(page_number)
        context["materi_list"] = materi_list_by_page
94
95
96
97
98
        contributor = context["contributor"]
        context["form_rating"] = RatingContributorForm(initial={
            "contributor": contributor,
            "user":request.user
        })
99
        context["avg_rating"] = User.objects.filter(email=kwargs["email"]) \
100
101
102
103
104
105
106
            .annotate(avg_rating=Avg("contributor__score"))[0]
        context["count_rating"] = RatingContributor.objects.filter(contributor=contributor).count()

        if request.user.is_authenticated:
            has_rated = RatingContributor.objects.filter(user=request.user, contributor=contributor).exists()
            context["has_rated"] = has_rated

107
        return self.render_to_response(context=context)
108

109
    def post(self, request, *args, **kwargs):
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
        context = self.get_context_data(**kwargs)
        if not request.user.is_authenticated:
            raise PermissionDenied(request)

        is_delete = request.POST.get('delete', None)
        is_update = request.POST.get('update', None)
        if is_delete:
            rating_contributor = get_object_or_404(
                RatingContributor, 
                user=request.user,
                contributor=context["contributor"]
            )
            rating_contributor.delete()
        elif is_update:
            score = request.POST.get('score', None)
            rating = RatingContributor.objects.filter(
                user=request.user,
                contributor=context["contributor"]
            ).first()
            
            if rating and score:
                rating.score = int(score)
                rating.save()
        else:
            data = RatingContributorForm(request.POST)
            if data.is_valid():
                data.save()
                
138
139
        return redirect("katalog-per-kontributor", email=kwargs["email"])

140
141
142
143
class DetailMateri(TemplateView):
    template_name = "app/detail_materi.html"

    def get_context_data(self, **kwargs):
144
145
146
147
        context = super(DetailMateri, self).get_context_data(**kwargs)
        if not self.request.session or not self.request.session.session_key:
            self.request.session.save()
        materi = get_object_or_404(Materi, pk=kwargs["pk"])
148
149
150
        DetailMateriService.init_context_data(context, materi, self.request.session)
        published_date = DetailMateriService.set_published_date(materi)
        DetailMateriService.init_citation_and_materi_rating(context, materi, published_date, self.request)
151
        DetailMateriService.init_materi_download_count(context, materi)
152
153
154
155

        if self.request.user.is_authenticated:
            materi_rating = Rating.objects.filter(materi=materi, user=self.request.user).first()
            if materi_rating is not None:
156
                context['materi_rating_score'] = materi_rating.score
157

Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
158
159
160
161
162
163
            materi_read_later = ReadLater.objects.filter(materi=materi, user=self.request.user).first()
            if materi_read_later is not None:
                context['is_in_read_later_list'] = True
            else:
                context['is_in_read_later_list'] = False

164
        context['is_authenticated'] = self.request.user.is_authenticated
165

166
        return context
167

168

169
170
    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
171
        query_set_for_comment = Comment.objects.filter(materi=context["materi_data"])
172
        query_set_for_review = Review.objects.filter(materi=context["materi_data"])
173
        has_disliked, has_liked = DetailMateriService.find_comment_like_dislike(query_set_for_comment, self.request.session)
174
        context["comment_data"] = query_set_for_comment
175
        context["review_data"] = query_set_for_review
176
177
        context["has_liked_comment"] = has_liked
        context["has_disliked_comment"] = has_disliked
178
179
        return self.render_to_response(context=context)

180

181

182
    def post(self, request, *args, **kwargs):
183
184
185
        comment_text = request.POST.get("comment", None)
        review_text  = request.POST.get("review", None)
        if ((comment_text == None or comment_text == "" )and (review_text == None or review_text == "")):
186
187
            context = self.get_context_data(*args, **kwargs)
            context["error_message"] = "Anda belum menuliskan komentar"
188
            context["materi_data"] = get_object_or_404(Materi, pk=kwargs["pk"])
189
            query_set_for_comment = Comment.objects.filter(materi=context["materi_data"])
190
            context["comment_data"] = query_set_for_comment
191
192
            query_set_for_review = Review.objects.filter(materi=context["materi_data"])
            context["review_data"] = query_set_for_review
193
            return self.render_to_response(context=context)
194

195
        materi = get_object_or_404(Materi, pk=kwargs["pk"])
196
        user_obj = request.user if request.user.is_authenticated else None
197
        if user_obj:
198
            if (comment_text != None ):
199
                comment = Comment.objects.create(
200
                    comment=comment_text, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj
201
202
                )
                comment.save()
203
204
205
206
207
208
209
210
211
212
213
214
                materi_uploader = materi.uploader
                if materi_uploader.is_subscribing_to_material_comments and user_obj.email != materi_uploader.email:
                    email_content =  f'User dengan email {user_obj.email} ' + \
                        f'menambahkan komentar pada materi Anda dengan judul "{materi.title}".' + \
                        f'\nKomentar: "{comment.comment}".\n' + \
                        f'Silahkan akses halaman detail materi untuk berinteraksi lebih lanjut.'
                    send_mail(
                        subject = 'DIGIPUS: Komentar Baru pada Materi Anda',
                        message = email_content,
                        from_email = getattr(settings, 'EMAIL_HOST_USER'),
                        recipient_list = [materi_uploader.email,],
                        fail_silently = False,
215
                    ) 
216
            elif (review_text != None):
217
                review = Review.objects.create(
218
                    review=review_text, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj
219
220
                )
                review.save()
221
222
        return HttpResponseRedirect(request.path)

223

224
def toggle_like(request):
225
226
227
    if request.method == "POST":
        materi_id = request.POST.get("materi_id", None)
        session_id = request.POST.get("session_id", None)
228
229
        if materi_id is None or session_id is None:
            return JsonResponse({"success": False, "msg": "Missing parameter"})
230
        return JsonResponse(LikeDislikeService.apply_like_materi(materi_id, session_id))
231
232
233
234
    else:
        return JsonResponse({"success": False, "msg": "Unsuported method"})


235
def delete_comment(request, pk_materi, pk_comment):
236
237
    if not request.user.is_authenticated or not request.user.is_admin:
        raise PermissionDenied(request)
238
    comment = get_object_or_404(Comment, pk=pk_comment)
239
    url = "/materi/" + str(pk_materi) + "/"
240
241
242
    comment.delete()
    return HttpResponseRedirect(url)

243
def toggle_like_comment(request):
244
    comment_id = 0
245
246
247
248
249
    if request.method == "POST":
        comment_id = request.POST.get("comment_id", None)
        session_id = request.POST.get("session_id", None)
        if comment_id is None or session_id is None:
            return JsonResponse({"success": False, "msg": "Missing parameter", "comment_id": comment_id})
250
        return JsonResponse(LikeDislikeService.apply_comment_like(comment_id, session_id))
251
252
253
    else:
        return JsonResponse({"success": False, "msg": "Unsuported method", "comment_id": comment_id})

254

255
def toggle_dislike_comment(request):
256
    comment_id = 0
257
258
259
260
261
    if request.method == "POST":
        comment_id = request.POST.get("comment_id", None)
        session_id = request.POST.get("session_id", None)
        if comment_id is None or session_id is None:
            return JsonResponse({"success": False, "msg": "Missing parameter", "comment_id": comment_id})
262
        return JsonResponse(LikeDislikeService.apply_comment_dislike(comment_id, session_id))
263
264
    else:
        return JsonResponse({"success": False, "msg": "Unsuported method", "comment_id": comment_id})
265
266


267
def add_rating_materi(request):
268
    if request.method == "POST" and request.user.is_authenticated:
269

270
271
        materi_id = request.POST.get("materi_id", None)
        rating_score = request.POST.get("rating_score", None)
272
273


274
275
276
277
        is_valid_params, materi_id, \
        rating_score, response, \
        status_code = MateriFieldValidationHelperService.\
            validate_materi_rating_params(materi_id,rating_score)
278

279
280
        if not is_valid_params:
            return JsonResponse(response, status=status_code)
281

282
283
284
        is_valid_rating, materi, \
        response, status_code = MateriFieldValidationHelperService.\
            validate_materi_rating(materi_id, request.user)
285

286
287
        if not is_valid_rating:
            return JsonResponse(response, status=status_code)
288
289

        Rating(materi=materi, user=request.user, score=rating_score).save()
290
291
292
        return JsonResponse(
            {"success": True, "msg": "Rating successfully created", "rating_score": rating_score}, status=201
        )
293
294
295
    return JsonResponse({"success": False, "msg": "Forbidden"}, status=403)


296

297
298
299
300
301
def download_materi(request, pk):
    materi = get_object_or_404(Materi, pk=pk)
    path = materi.content.path
    file_path = os.path.join(settings.MEDIA_ROOT, path)
    if os.path.exists(file_path):
302
303
304
        try:
            mimetype = mimetypes.guess_type(file_path)
            with open(file_path, "rb") as fh:
305
306
307
                return DownloadViewMateriHelperService.build_materi_response(fh, file_path,
                                                                             materi, mimetype, request,
                                                                             HttpResponse(fh.read(), content_type=mimetype[0]))
308
309
        except Exception as e:
            raise Http404("File tidak dapat ditemukan.")
310
311
312
    else:
        raise Http404("File tidak dapat ditemukan.")

igor lestin sianipar's avatar
igor lestin sianipar committed
313

314
315
316
317
318
319
def view_materi(request, pk):
    materi = get_object_or_404(Materi, pk=pk)
    path = materi.content.path
    file_path = os.path.join(settings.MEDIA_ROOT, path)
    if os.path.exists(file_path):
        mimetype = mimetypes.guess_type(file_path)
320
321
322
        try:
            with open(file_path, "rb") as fh:
                response = HttpResponse(fh.read(), content_type=mimetype[0])
323
                DownloadViewMateriHelperService.build_view_materi_response(file_path, materi, response)
324
325
326
                return response
        except Exception as e:
            raise Http404("File tidak dapat ditemukan.")
327
328
    else:
        raise Http404("File tidak dapat ditemukan.")
igor lestin sianipar's avatar
igor lestin sianipar committed
329

igor lestin sianipar's avatar
igor lestin sianipar committed
330

Selvy Fitriani's avatar
Selvy Fitriani committed
331
332
def delete_materi(request, pk):
    materi = get_object_or_404(Materi, pk=pk)
333
334
335
    if request.user.is_superuser or request.user.is_admin:
        materi.soft_delete()
        return HttpResponseRedirect("/administration/")
Selvy Fitriani's avatar
Selvy Fitriani committed
336
337
338
    materi.delete()
    return HttpResponseRedirect("/dashboard/")

igor lestin sianipar's avatar
igor lestin sianipar committed
339
class UploadMateriView(TemplateView):
340
    template_name = "unggah.html"
igor lestin sianipar's avatar
igor lestin sianipar committed
341
342
343
344
345
346
    context = {}

    def get_context_data(self, **kwargs):
        context = super(UploadMateriView, self).get_context_data(**kwargs)
        return context

Saul Andre's avatar
Saul Andre committed
347
    def post(self, request, *args, **kwargs):
Steven Kusuman's avatar
Steven Kusuman committed
348
        if request.user.is_authenticated == False or not request.user.is_contributor:
igor lestin sianipar's avatar
igor lestin sianipar committed
349
            raise PermissionDenied(request)
350
        form = UploadMateriForm(request.POST, request.FILES)
igor lestin sianipar's avatar
igor lestin sianipar committed
351
352
353
        if form.is_valid():
            materi = form.save(commit=False)
            materi.uploader = request.user
354
            konten = form.cleaned_data["content"]
355
356
            yt_url_id = form.cleaned_data['yt_video_id']
            if not UploadMateriService.validate_file_extension(konten, request, yt_url_id):
357
                return HttpResponseRedirect("/unggah/")
358
            UploadMateriService.upload_materi(form, materi)
359
            messages.success(request, "Materi berhasil diunggah, periksa riwayat unggah anda")
360
            return HttpResponseRedirect("/unggah/")
Saul Andre's avatar
Saul Andre committed
361
        else:
igor lestin sianipar's avatar
igor lestin sianipar committed
362
            context = self.get_context_data(**kwargs)
363
            context["form"] = form
364
            messages.error(request, "Terjadi kesalahan pada pengisian data")
igor lestin sianipar's avatar
igor lestin sianipar committed
365
366
            return self.render_to_response(context)

367
368


igor lestin sianipar's avatar
igor lestin sianipar committed
369
    def get(self, request, *args, **kwargs):
Steven Kusuman's avatar
Steven Kusuman committed
370
        if request.user.is_authenticated == False or not request.user.is_contributor:
igor lestin sianipar's avatar
igor lestin sianipar committed
371
            raise PermissionDenied(request)
372

igor lestin sianipar's avatar
igor lestin sianipar committed
373
        context = self.get_context_data(**kwargs)
374
        context["form"] = UploadMateriForm
igor lestin sianipar's avatar
igor lestin sianipar committed
375
        return self.render_to_response(context)
376

377

378
379
380
class UploadMateriHTML(TemplateView):
    template_name = "unggah.html"
    context = {}
igor lestin sianipar's avatar
igor lestin sianipar committed
381

382
383
384
385
386
387
    def get_template_names(self):
        if self.request.path == "/unggah/":
            template_name = "unggah.html"
        return template_name


388
389
390
391
392
393
394
395
396
397
398
class UploadMateriExcelView(TemplateView):
    template_name = "unggah_excel.html"
    context = {}

    def get_template_names(self):
        if self.request.path == "/unggah_excel/":
            template_name = "unggah_excel.html"
        return template_name

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

399
        if "template" in self.request.GET:
400

401
402
403
            data_frame = pd.DataFrame(
                {"Title": [], "Author": [], "Publisher": [], "Categories": [], "Description": [],}
            )
404
405

            with BytesIO() as b:
406
                writer = pd.ExcelWriter(b, engine="xlsxwriter")  # pylint: disable=abstract-class-instantiated
407
408
409
                data_frame.to_excel(writer, index=0)
                writer.save()
                response = HttpResponse(
410
411
                    b.getvalue(), content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                )
412
413
414
415
416
417
418
419
420
421

                response["Content-Disposition"] = "attachment; filename=template.xlsx"

                return response

        else:
            context = self.get_context_data(**kwargs)
            return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
422
423
        excel_file = request.FILES["excel"]
        excel = pd.read_excel(excel_file)
424

425
        row, lines = excel.shape
426
        categories = Category.objects.all()
427

428
        field_length = {
429
430
431
            "title": 50,
            "author": 30,
            "publisher": 30,
432
433
434
435
436
437
        }

        message = None

        # First pass, validate input
        for i in range(row):
438

439
            # Validate Categories
440
            message = UploadMateriService.validate_excel_categories(categories, excel, i, message)
441

442
            message = UploadMateriService.validate_excel_field_length(excel, field_length, i, message)
443
444
445

            if message != None:
                break
446

447
448
        if message != None:
            messages.error(request, message)
449
            return HttpResponseRedirect("/unggah_excel/")
450
451
452

        # Second pass, save data
        with django.db.transaction.atomic():
453
            UploadMateriService.upload_materi_excel(categories, excel, request, row)
454

455
        messages.success(request, "Materi berhasil diunggah")
456

457
        return HttpResponseRedirect("/unggah_excel/")
458
459


460
461


462
class DashboardKontributorView(TemplateView):
463
    template_name = "dashboard.html"
464
465
466
467
468
469
470

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated or not request.user.is_contributor:
            raise PermissionDenied(request)
        return super(DashboardKontributorView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
471
        context = super(DashboardKontributorView, self).get_context_data(**kwargs)
472
473
474
475
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
476
477
478
        current_user = self.request.user
        materi_list = current_user.materi_set.all()
        context["materi_list"] = materi_list
479
        return self.render_to_response(context)
480

481

482
class ProfilView(TemplateView):
483
484
485
    template_name = "profil.html"

    def dispatch(self, request, *args, **kwargs):
486
        if not request.user.is_authenticated:
487
            raise PermissionDenied(request)
488
        return super(ProfilView, self).dispatch(request, *args, **kwargs)
489
490
491

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
492
        current_user = request.user
493
494
495
        context["user"] = current_user
        return self.render_to_response(context)

496

497
498
499
500
class SuntingProfilView(TemplateView):
    template_name = "sunting.html"

    def dispatch(self, request, *args, **kwargs):
501
        if not request.user.is_authenticated:
502
503
504
505
            raise PermissionDenied(request)
        return super(SuntingProfilView, self).dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
Samuel Dimas Partogi's avatar
Samuel Dimas Partogi committed
506
        current_user = self.request.user
507
508
509
510
511
512
513
514
515
516
        context = self.get_context_data(**kwargs)
        context["user"] = current_user
        context["form"] = SuntingProfilForm(instance=current_user)
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
            raise PermissionDenied(request)

        current_user = self.request.user
517

518
        form = SuntingProfilForm(request.POST, request.FILES, instance=current_user)
519
520
        if form.is_valid():
            current_user.default_profile_picture = True
521
522
523

            # Removing exifdata from profile picture on upload
            if request.FILES:
524
                EditProfileService.update_profile_picture(current_user, request)
525
            else:
526
                form.save()
527
            return HttpResponseRedirect("/profil/")
528
529
        else:
            context = self.get_context_data(**kwargs)
530
531
            context["form"] = form
            return self.render_to_response(context)
532

533

534
535
536
537
538
539
540
541
542
class ReqMateriView(TemplateView):
    template_name = "req_materi.html"

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
            return HttpResponseRedirect("/login/")
        return super(ReqMateriView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
543
        context = super(ReqMateriView, self).get_context_data(**kwargs)
544
545
546
547
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
548
        context['requested_material'] = ReqMaterial.objects.all()
549
550
551
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
552
        title = request.POST.get("title", None)
553
554
555
556
557
        if title is None:
            return JsonResponse({"success": False, "msg": "Missing parameter"})
        ReqMaterial(title=title).save()
        return JsonResponse({"success": True, "msg": "Permintaan materi berhasil dikirimkan"})

558

559
560
561
562
563
564
565
class SuksesLoginKontributorView(TemplateView):
    template_name = "sukses_kontri.html"

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_contributor:
            raise PermissionDenied(request)
        return super(SuksesLoginKontributorView, self).dispatch(request, *args, **kwargs)
566

567
    def get_context_data(self, **kwargs):
568
        context = super(SuksesLoginKontributorView, self).get_context_data(**kwargs)
569
570
571
572
573
574
575
576
577
578
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)

        current_user = self.request.user
        context["user"] = current_user

        return self.render_to_response(context)

579

580
581
582
583
584
585
586
class SuksesLoginAdminView(TemplateView):
    template_name = "sukses_admin.html"

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_admin:
            raise PermissionDenied(request)
        return super(SuksesLoginAdminView, self).dispatch(request, *args, **kwargs)
587

588
589
590
591
592
593
594
595
596
597
598
599
    def get_context_data(self, **kwargs):
        context = super(SuksesLoginAdminView, self).get_context_data(**kwargs)
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)

        current_user = self.request.user
        context["user"] = current_user

        return self.render_to_response(context)

igor lestin sianipar's avatar
igor lestin sianipar committed
600

601
602
603
class PostsView(TemplateView):

    template_name = "user_uploaded_posts.html"
604
605

    def dispatch(self, request, *args, **kwargs):
606
        if not request.user.is_authenticated:
607
            raise PermissionDenied(request)
608
        return super(PostsView, self).dispatch(request, *args, **kwargs)
609
610

    def get(self, request, *args, **kwargs):
611
612
613
614
        context = super().get_context_data(**kwargs)
        user = self.request.user

        posts = Materi.objects.filter(uploader=user).order_by("-date_created")
615
        posts_data = {post.id: {"data": post, "comments": []} for post in posts}
616

617
        comments = Comment.objects.filter(materi__id__in=posts_data.keys()).order_by("-timestamp")
618
619
620
621
622
623
624

        for comment in comments:
            posts_data[comment.materi.id]["comments"].append(comment)

        context["user"] = user
        context["posts"] = posts_data

625
        return self.render_to_response(context=context)
626

627

628
629
630
class RevisiMateriView(TemplateView):
    template_name = "revisi.html"

631
    def dispatch(self, request, *args, **kwargs):
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
        if not request.user.is_contributor:
            raise PermissionDenied(request)
        return super(RevisiMateriView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(RevisiMateriView, self).get_context_data(**kwargs)
        current_materi = get_object_or_404(Materi, pk=kwargs["pk"])
        context["materi"] = current_materi
        context["revisi_form"] = UploadMateriForm(instance=current_materi)
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

647
    def post(self, request, *args, **kwargs):
648
649
650
651
        if request.user.is_authenticated == False:
            raise PermissionDenied(request)

        current_materi = get_object_or_404(Materi, pk=kwargs["pk"])
652
        form = UploadMateriForm(request.POST, request.FILES, instance=current_materi)
653
        if form.is_valid():
654
            RevisiMateriService.revisi_materi(form, request)
655
656
657
658
659
660
            return HttpResponseRedirect("/dashboard/")
        else:
            context = self.get_context_data(**kwargs)
            context["form_revisi"] = form
            return self.render_to_response(context)

661

Samuel Dimas's avatar
Samuel Dimas committed
662
663
664
665
666
667
def pages(request):
    context = {}
    # All resource paths end in .html.
    # Pick out the html file name from the url. And load that template.
    try:

668
        load_template = request.path.split("/")[-1]
Samuel Dimas's avatar
Samuel Dimas committed
669
670
671
        template = loader.get_template(load_template)
        return HttpResponse(template.render(context, request))

672
    except Exception as e:
Samuel Dimas's avatar
Samuel Dimas committed
673

674
        template = loader.get_template("error-404.html")
Samuel Dimas's avatar
Samuel Dimas committed
675
        return HttpResponse(template.render(context, request))
676
677


678
679
680
681
class DownloadHistoryView(TemplateView):
    template_name = "download_history.html"

    def get_context_data(self, **kwargs):
682
        context = super(DownloadHistoryView, self).get_context_data(**kwargs)
683
684
685
686
687
688
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        if request.user.is_authenticated:
            current_user = self.request.user
689
            DownloadHistoryService.init_data_authenticated_user(context, current_user)
690
        else:
691
            DownloadHistoryService.init_data_guest_user(context, request)
692
        return self.render_to_response(context)
693

694

695
696
697
698
699
def save_to_gdrive(request, pk):
    materi = get_object_or_404(Materi, pk=pk)
    path = materi.content.path
    file_path = os.path.join(settings.MEDIA_ROOT, path)
    if os.path.exists(file_path):
700
        GoogleDriveUploadService.upload_to_gdrive(file_path, materi.title)
701
702
703
    else:
        raise Http404("File tidak dapat ditemukan.")

Yaumi's avatar
Yaumi committed
704
705
    return HttpResponseRedirect(reverse('detail-materi', kwargs={'pk': pk}))

706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
class MateriFavorite(TemplateView):

    template_name = "user_favorite_materi.html"

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            raise PermissionDenied(request)
        return super(MateriFavorite, self).dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        context = super().get_context_data(**kwargs)
        user = self.request.user

        materi = Materi.objects.filter(like=True)
        likes_data = { mat.id: { "data": mat, "comments": [] } for mat in materi }

        comments = Comment.objects \
            .filter(materi__id__in=likes_data.keys()) \
            .order_by("-timestamp")

        for comment in comments:
            likes_data[comment.materi.id]["comments"].append(comment)

        context["user"] = user
        context["likes"] = likes_data

        return self.render_to_response(context=context)

Yaumi's avatar
Yaumi committed
734
class PasswordChangeViews(PasswordChangeView):
735

Yaumi's avatar
Yaumi committed
736
737
    from_class = PasswordChangeForm
    success_url = reverse_lazy('password_success')
Yaumi's avatar
Yaumi committed
738

Yaumi's avatar
Yaumi committed
739
def password_success(request):
740
    return render(request, 'password_success.html', {})
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764


def see_given_rating(request):
    if request.user.is_authenticated:
        order_by_key = request.GET.get('order_by_key', 'timestamp')

        if request.GET.get('order', '').lower() == 'asc':
            order_by = 'asc'
            query_order = ''
        else:
            order_by = 'dsc'
            query_order = '-'

        try:
            if order_by_key[0] == '-':
                order_by_key = order_by_key[1:]
            rating_list = Rating.objects.filter(user=request.user).order_by(query_order + order_by_key)
        except FieldError:
            order_by_key = 'timestamp'
            rating_list = Rating.objects.filter(user=request.user).order_by(query_order + order_by_key)

        return render(request, 'given-rating.html',
                      context={'rating_list': rating_list, 'order_by_key': order_by_key, 'order_by': order_by})
    return permission_denied(request, exception=None)
insan ramadhan's avatar
insan ramadhan committed
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789

class SubmitVisitorView(TemplateView):
    template_name = "submit_visitor.html"

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
            return HttpResponseRedirect("/login/")
        return super(SubmitVisitorView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(SubmitVisitorView, self).get_context_data(**kwargs)
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
        title = request.POST.get("title", None)
        email = request.POST.get("email", None)
        user_id = request.POST.get("user_id", None)
        if title is None:
            return JsonResponse({"success": False, "msg": "Missing parameter"})
        SubmitVisitor(msg=title, user_id=user_id, email=email).save()
        return JsonResponse({"success": True, "msg": "Buku tamu berhasil ditambahkan"})
790

Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
class ReadLaterView(TemplateView):
    template_name = 'baca-nanti.html'

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated:
            raise PermissionDenied(request)
        return super(ReadLaterView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(ReadLaterView, self).get_context_data(**kwargs)
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        user = self.request.user
        context["read_later_list"] = ReadLater.objects.filter(user=user).order_by('-timestamp')
        return self.render_to_response(context)

def toggle_readlater(request):
    if request.method == "POST":
        materi_id = request.POST.get("materi_id", None)
        if materi_id is None:
            return JsonResponse({"success": False, "msg": "Missing parameter"})
        
        return JsonResponse(ReadLaterService.toggle_read_later(materi_id, request.user))
    else:
        return JsonResponse({"success": False, "msg": "Unsuported method"})

819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
class StatisticsView(TemplateView):
    template_name = "statistik.html"

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
            return HttpResponseRedirect("/login/")
        return super(StatisticsView, self).dispatch(request, *args, **kwargs)

    def get_stat_json(self):
        query = Category.objects.annotate(num=Count('materi')).order_by('-num')

        # Take maximum 10 Category
        result = []
        for e in query:
            if len(result) >= 6:
                break
            else:
                result.append(e)

        chart_data = {
                'labels': [e.name for e in result],
                'datasets': [{
                    'label': 'Jumlah Materi per Kategori',
                    'data': [e.num for e in result],
                    'backgroundColor': [
                        'rgba(255, 99, 132, 0.2)',
                        'rgba(54, 162, 235, 0.2)',
                        'rgba(255, 206, 86, 0.2)',
                        'rgba(75, 192, 192, 0.2)',
                        'rgba(153, 102, 255, 0.2)',
                        'rgba(255, 159, 64, 0.2)'
                    ],
                    'borderColor': [
                        'rgba(255, 99, 132, 1)',
                        'rgba(54, 162, 235, 1)',
                        'rgba(255, 206, 86, 1)',
                        'rgba(75, 192, 192, 1)',
                        'rgba(153, 102, 255, 1)',
                        'rgba(255, 159, 64, 1)'
                    ],
                    'borderWidth': 1
                }]
            }
        return chart_data

    def get(self, request, *args, **kwargs):
        if request.GET.get('data') == 'json':
            return JsonResponse(self.get_stat_json())

        else:
            context = self.get_context_data(**kwargs)

            query = Category.objects.annotate(num=Count('materi'))
            context['stats'] = query

            return self.render_to_response(context)