Fakultas Ilmu Komputer UI

views.py 34.5 KB
Newer Older
1
2
import mimetypes
import os
3
from io import BytesIO
4
from register.services import MailService
5

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

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

46
47
48
49
50
51
52
MISSING_PARAMETER_MESSAGE = "Missing parameter"
UNSUPPORTED_MESSAGE = "Unsuported method"
FILE_NOT_FOUND_MESSAGE = "File tidak dapat ditemukan."
UNGGAH_HTML = "unggah.html"
UNGGAH_URL = "/unggah/"
UNGGAH_EXCEL_URL = "/unggah_excel/"
LOGIN_URL = "/login/"
53

54
def permission_denied(request, exception, template_name="error_403.html"):
55
56
    return defaults.permission_denied(request, exception, template_name)

57

58
class DaftarKatalog(TemplateView):
igor lestin sianipar's avatar
igor lestin sianipar committed
59
    paginate_by = 2
60
61
62
63
64
65
66
    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)
67
        context["kategori_list"] = Category.objects.all()
68

69
        lst_materi = Materi.objects.filter(status="APPROVE").order_by("date_modified")
Mika dabelza abi's avatar
Mika dabelza abi committed
70
71
        url = ""

72
        lst_materi, url = DafterKatalogService.apply_options(lst_materi, request, url)
Saul Andre's avatar
Saul Andre committed
73

74

75
        context["materi_list"] = lst_materi
Mika dabelza abi's avatar
Mika dabelza abi committed
76
        paginator = Paginator(context["materi_list"], 15)
77
        page_number = request.GET.get("page")
Mika dabelza abi's avatar
Mika dabelza abi committed
78
79
80
81
        page_obj = paginator.get_page(page_number)
        context["materi_list"] = page_obj

        context["url"] = url
82
83
        return self.render_to_response(context=context)

84

85
86
class KatalogPerKontributorView(TemplateView):
    template_name = "app/katalog_kontri.html"
87

88
89
90
91
92
93
94
95
    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)
96
97
98
99
100

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

101
        paginator = Paginator(materi_list, 15)
102
        page_number = request.GET.get("page")
103
104
        materi_list_by_page = paginator.get_page(page_number)
        context["materi_list"] = materi_list_by_page
105
106
107
108
109
        contributor = context["contributor"]
        context["form_rating"] = RatingContributorForm(initial={
            "contributor": contributor,
            "user":request.user
        })
110
        context["avg_rating"] = User.objects.filter(email=kwargs["email"]) \
111
112
113
114
115
116
117
            .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

118
        return self.render_to_response(context=context)
119

120
    def post(self, request, *args, **kwargs):
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
        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()
                
149
150
        return redirect("katalog-per-kontributor", email=kwargs["email"])

151
152
153
154
class DetailMateri(TemplateView):
    template_name = "app/detail_materi.html"

    def get_context_data(self, **kwargs):
155
156
157
158
        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"])
159
160
161
        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)
162
        DetailMateriService.init_materi_download_count(context, materi)
163
164
165
166

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

Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
169
170
171
172
173
174
            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

175
        context['is_authenticated'] = self.request.user.is_authenticated
176

177
        return context
178

179

180
181
    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
182
        query_set_for_comment = Comment.objects.filter(materi=context["materi_data"])
183
        query_set_for_review = Review.objects.filter(materi=context["materi_data"])
184
        has_disliked, has_liked = DetailMateriService.find_comment_like_dislike(query_set_for_comment, self.request.session)
185
        context["comment_data"] = query_set_for_comment
186
        context["review_data"] = query_set_for_review
187
188
        context["has_liked_comment"] = has_liked
        context["has_disliked_comment"] = has_disliked
189
190
191
        if request.user.is_authenticated and request.user.is_contributor:
            opened_notif = NotifikasiKontributor.objects.filter(user=request.user, materi=context["materi_data"])
            opened_notif.delete()
192
193
        return self.render_to_response(context=context)

194

195

196
    def post(self, request, *args, **kwargs):
197
198
        comment_text = request.POST.get("comment", None)
        review_text  = request.POST.get("review", None)
Yusuf T Ardho's avatar
Yusuf T Ardho committed
199
200
201
202
        report_text = request.POST.get("report", None)
        if ((comment_text == None or comment_text == "" ) and \
            (review_text == None or review_text == "") and \
            (report_text == None or report_text == "")):
203
204
            context = self.get_context_data(*args, **kwargs)
            context["error_message"] = "Anda belum menuliskan komentar"
205
            context["materi_data"] = get_object_or_404(Materi, pk=kwargs["pk"])
206
            query_set_for_comment = Comment.objects.filter(materi=context["materi_data"])
207
            context["comment_data"] = query_set_for_comment
208
209
            query_set_for_review = Review.objects.filter(materi=context["materi_data"])
            context["review_data"] = query_set_for_review
210
            return self.render_to_response(context=context)
211

212
        materi = get_object_or_404(Materi, pk=kwargs["pk"])
213
        user_obj = request.user if request.user.is_authenticated else None
214
        if user_obj:
215
            if (comment_text != None ):
216
                comment = Comment.objects.create(
217
                    comment=comment_text, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj
218
219
                )
                comment.save()
220
221
222
223
224
225
                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.'
226
227

                    MailService.send(
228
229
230
231
                        subject = 'DIGIPUS: Komentar Baru pada Materi Anda',
                        message = email_content,
                        from_email = getattr(settings, 'EMAIL_HOST_USER'),
                        recipient_list = [materi_uploader.email,],
232
                    ) 
233
            elif (review_text != None):
234
                review = Review.objects.create(
235
                    review=review_text, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj
236
237
                )
                review.save()
Yusuf T Ardho's avatar
Yusuf T Ardho committed
238
239
240
241
242
            elif (report_text != None):
                laporan_materi = LaporanMateri.objects.create(
                    materi=materi, laporan=report_text, user=user_obj
                )
                laporan_materi.save()
243
244
        return HttpResponseRedirect(request.path)

245

246
def toggle_like(request):
247
248
249
    if request.method == "POST":
        materi_id = request.POST.get("materi_id", None)
        session_id = request.POST.get("session_id", None)
250
        if materi_id is None or session_id is None:
251
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE})
252
        return JsonResponse(LikeDislikeService.apply_like_materi(materi_id, session_id))
253
    else:
254
        return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE})
255
256


257
def delete_comment(request, pk_materi, pk_comment):
258
259
    if not request.user.is_authenticated or not request.user.is_admin:
        raise PermissionDenied(request)
260
    comment = get_object_or_404(Comment, pk=pk_comment)
261
    url = "/materi/" + str(pk_materi) + "/"
262
263
264
    comment.delete()
    return HttpResponseRedirect(url)

265
266
267
268
269
270
271
272
def delete_review(request, pk_materi, pk_review):
    if not request.user.is_authenticated or not request.user.is_admin:
        raise PermissionDenied(request)
    review = get_object_or_404(Review, pk=pk_review)
    url_materi = "/materi/" + str(pk_materi) + "/"
    review.delete()
    return HttpResponseRedirect(url_materi)

273
def toggle_like_comment(request):
274
    comment_id = 0
275
276
277
278
    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:
279
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE, "comment_id": comment_id})
280
        return JsonResponse(LikeDislikeService.apply_comment_like(comment_id, session_id))
281
    else:
282
        return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE, "comment_id": comment_id})
283

284

285
def toggle_dislike_comment(request):
286
    comment_id = 0
287
288
289
290
    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:
291
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE, "comment_id": comment_id})
292
        return JsonResponse(LikeDislikeService.apply_comment_dislike(comment_id, session_id))
293
    else:
294
        return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE, "comment_id": comment_id})
295

296
def add_rating_materi(request):
297
    if request.method == "POST" and request.user.is_authenticated:
298

299
300
        materi_id = request.POST.get("materi_id", None)
        rating_score = request.POST.get("rating_score", None)
301
302


303
304
305
306
        is_valid_params, materi_id, \
        rating_score, response, \
        status_code = MateriFieldValidationHelperService.\
            validate_materi_rating_params(materi_id,rating_score)
307

308
309
        if not is_valid_params:
            return JsonResponse(response, status=status_code)
310

311
312
313
        is_valid_rating, materi, \
        response, status_code = MateriFieldValidationHelperService.\
            validate_materi_rating(materi_id, request.user)
314

315
316
        if not is_valid_rating:
            return JsonResponse(response, status=status_code)
317
318

        Rating(materi=materi, user=request.user, score=rating_score).save()
319
320
321
        return JsonResponse(
            {"success": True, "msg": "Rating successfully created", "rating_score": rating_score}, status=201
        )
322
323
324
    return JsonResponse({"success": False, "msg": "Forbidden"}, status=403)


325

326
327
328
329
330
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):
331
332
333
        try:
            mimetype = mimetypes.guess_type(file_path)
            with open(file_path, "rb") as fh:
334
335
336
                return DownloadViewMateriHelperService.build_materi_response(fh, file_path,
                                                                             materi, mimetype, request,
                                                                             HttpResponse(fh.read(), content_type=mimetype[0]))
337
338
        except Exception:
            raise Http404(FILE_NOT_FOUND_MESSAGE)
339
    else:
340
        raise Http404(FILE_NOT_FOUND_MESSAGE)
341

igor lestin sianipar's avatar
igor lestin sianipar committed
342

343
344
345
346
347
348
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)
349
350
351
        try:
            with open(file_path, "rb") as fh:
                response = HttpResponse(fh.read(), content_type=mimetype[0])
352
                DownloadViewMateriHelperService.build_view_materi_response(file_path, materi, response)
353
                return response
354
355
        except Exception:
            raise Http404(FILE_NOT_FOUND_MESSAGE)
356
    else:
357
        raise Http404(FILE_NOT_FOUND_MESSAGE)
igor lestin sianipar's avatar
igor lestin sianipar committed
358

igor lestin sianipar's avatar
igor lestin sianipar committed
359

Selvy Fitriani's avatar
Selvy Fitriani committed
360
361
def delete_materi(request, pk):
    materi = get_object_or_404(Materi, pk=pk)
362
363
364
    if request.user.is_superuser or request.user.is_admin:
        materi.soft_delete()
        return HttpResponseRedirect("/administration/")
Selvy Fitriani's avatar
Selvy Fitriani committed
365
366
367
    materi.delete()
    return HttpResponseRedirect("/dashboard/")

igor lestin sianipar's avatar
igor lestin sianipar committed
368
class UploadMateriView(TemplateView):
369
    template_name = UNGGAH_HTML
igor lestin sianipar's avatar
igor lestin sianipar committed
370
    context = {}
371
    redirect_path = "/unggah/"
igor lestin sianipar's avatar
igor lestin sianipar committed
372
373
374
375
376

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

Saul Andre's avatar
Saul Andre committed
377
    def post(self, request, *args, **kwargs):
Steven Kusuman's avatar
Steven Kusuman committed
378
        if request.user.is_authenticated == False or not request.user.is_contributor:
igor lestin sianipar's avatar
igor lestin sianipar committed
379
            raise PermissionDenied(request)
380
        form = UploadMateriForm(request.POST, request.FILES)
igor lestin sianipar's avatar
igor lestin sianipar committed
381
382
383
        if form.is_valid():
            materi = form.save(commit=False)
            materi.uploader = request.user
384
            konten = form.cleaned_data["content"]
385
386
            yt_url_id = form.cleaned_data['yt_video_id']
            if not UploadMateriService.validate_file_extension(konten, request, yt_url_id):
387
                return HttpResponseRedirect(UNGGAH_URL)
388
            UploadMateriService.upload_materi(form, materi)
389
            messages.success(request, "Materi berhasil diunggah, periksa riwayat unggah anda")
390
            return HttpResponseRedirect(UNGGAH_URL)
Saul Andre's avatar
Saul Andre committed
391
        else:
igor lestin sianipar's avatar
igor lestin sianipar committed
392
            context = self.get_context_data(**kwargs)
393
            context["form"] = form
394
            messages.error(request, "Terjadi kesalahan pada pengisian data")
igor lestin sianipar's avatar
igor lestin sianipar committed
395
396
            return self.render_to_response(context)

397
398


igor lestin sianipar's avatar
igor lestin sianipar committed
399
    def get(self, request, *args, **kwargs):
Steven Kusuman's avatar
Steven Kusuman committed
400
        if request.user.is_authenticated == False or not request.user.is_contributor:
igor lestin sianipar's avatar
igor lestin sianipar committed
401
            raise PermissionDenied(request)
402

igor lestin sianipar's avatar
igor lestin sianipar committed
403
        context = self.get_context_data(**kwargs)
404
        context["form"] = UploadMateriForm
igor lestin sianipar's avatar
igor lestin sianipar committed
405
        return self.render_to_response(context)
406

407

408
class UploadMateriHTML(TemplateView):
409
    template_name = UNGGAH_HTML
410
    context = {}
igor lestin sianipar's avatar
igor lestin sianipar committed
411

412

413
414
415
416
417
class UploadMateriExcelView(TemplateView):
    template_name = "unggah_excel.html"
    context = {}

    def get_template_names(self):
418
        if self.request.path == UNGGAH_EXCEL_URL:
419
420
421
422
423
            template_name = "unggah_excel.html"
        return template_name

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

424
        if "template" in self.request.GET:
425

426
427
428
            data_frame = pd.DataFrame(
                {"Title": [], "Author": [], "Publisher": [], "Categories": [], "Description": [],}
            )
429
430

            with BytesIO() as b:
431
                writer = pd.ExcelWriter(b, engine="xlsxwriter")  # pylint: disable=abstract-class-instantiated
432
433
434
                data_frame.to_excel(writer, index=0)
                writer.save()
                response = HttpResponse(
435
436
                    b.getvalue(), content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                )
437
438
439
440
441
442
443
444
445
446

                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):
447
448
        excel_file = request.FILES["excel"]
        excel = pd.read_excel(excel_file)
449

450
        row, lines = excel.shape
451
        categories = Category.objects.all()
452

453
        field_length = {
454
455
456
            "title": 50,
            "author": 30,
            "publisher": 30,
457
458
459
460
461
462
        }

        message = None

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

464
            # Validate Categories
465
            message = UploadMateriService.validate_excel_categories(categories, excel, i, message)
466

467
            message = UploadMateriService.validate_excel_field_length(excel, field_length, i, message)
468
469
470

            if message != None:
                break
471

472
473
        if message != None:
            messages.error(request, message)
474
            return HttpResponseRedirect(UNGGAH_EXCEL_URL)
475
476
477

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

480
        messages.success(request, "Materi berhasil diunggah")
481

482
        return HttpResponseRedirect(UNGGAH_EXCEL_URL)
483
484


485
486


487
class DashboardKontributorView(TemplateView):
488
    template_name = "dashboard.html"
489
490
491
492
493
494
495

    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):
496
        context = super(DashboardKontributorView, self).get_context_data(**kwargs)
497
498
499
500
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
501
502
503
        current_user = self.request.user
        materi_list = current_user.materi_set.all()
        context["materi_list"] = materi_list
504
        return self.render_to_response(context)
505

506

507
class ProfilView(TemplateView):
508
509
510
    template_name = "profil.html"

    def dispatch(self, request, *args, **kwargs):
511
        if not request.user.is_authenticated:
512
            raise PermissionDenied(request)
513
        return super(ProfilView, self).dispatch(request, *args, **kwargs)
514
515
516

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
517
        current_user = request.user
518
519
520
        context["user"] = current_user
        return self.render_to_response(context)

521

522
523
524
525
class SuntingProfilView(TemplateView):
    template_name = "sunting.html"

    def dispatch(self, request, *args, **kwargs):
526
        if not request.user.is_authenticated:
527
528
529
530
            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
531
        current_user = self.request.user
532
533
534
535
536
537
538
539
540
541
        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
542

543
        form = SuntingProfilForm(request.POST, request.FILES, instance=current_user)
544
545
        if form.is_valid():
            current_user.default_profile_picture = True
546
547
548

            # Removing exifdata from profile picture on upload
            if request.FILES:
549
                EditProfileService.update_profile_picture(current_user, request)
550
            else:
551
                form.save()
552
            return HttpResponseRedirect("/profil/")
553
554
        else:
            context = self.get_context_data(**kwargs)
555
556
            context["form"] = form
            return self.render_to_response(context)
557

558

559
560
561
562
563
class ReqMateriView(TemplateView):
    template_name = "req_materi.html"

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
564
            return HttpResponseRedirect(LOGIN_URL)
565
566
567
        return super(ReqMateriView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
568
        context = super(ReqMateriView, self).get_context_data(**kwargs)
569
570
571
572
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
573
        context['requested_material'] = ReqMaterial.objects.all()
574
575
576
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
577
        title = request.POST.get("title", None)
578
        if title is None:
579
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE})
580
581
582
        ReqMaterial(title=title).save()
        return JsonResponse({"success": True, "msg": "Permintaan materi berhasil dikirimkan"})

583

584
585
586
587
588
589
590
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)
591

592
    def get_context_data(self, **kwargs):
593
        context = super(SuksesLoginKontributorView, self).get_context_data(**kwargs)
594
595
596
597
598
599
600
601
602
603
        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)

604

605
606
607
class SuksesLoginAdminView(TemplateView):
    template_name = "sukses_admin.html"

608
609
610
611
    def getAdminNotification(self):
        notifications = AdminNotification.objects.all()
        return notifications

612
613
614
615
    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_admin:
            raise PermissionDenied(request)
        return super(SuksesLoginAdminView, self).dispatch(request, *args, **kwargs)
616

617
618
619
620
621
622
623
624
625
626
    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

627
628
        notifications = self.getAdminNotification()
        context["notifications"] = notifications
629

630
        return self.render_to_response(context)
igor lestin sianipar's avatar
igor lestin sianipar committed
631

632
633
634
class PostsView(TemplateView):

    template_name = "user_uploaded_posts.html"
635
636

    def dispatch(self, request, *args, **kwargs):
637
        if not request.user.is_authenticated:
638
            raise PermissionDenied(request)
639
        return super(PostsView, self).dispatch(request, *args, **kwargs)
640
641

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

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

648
        comments = Comment.objects.filter(materi__id__in=posts_data.keys()).order_by("-timestamp")
649
650
651
652
653
654
655

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

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

656
        return self.render_to_response(context=context)
657

658

659
660
661
class RevisiMateriView(TemplateView):
    template_name = "revisi.html"

662
    def dispatch(self, request, *args, **kwargs):
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
        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)

678
    def post(self, request, *args, **kwargs):
679
680
681
682
        if request.user.is_authenticated == False:
            raise PermissionDenied(request)

        current_materi = get_object_or_404(Materi, pk=kwargs["pk"])
683
        form = UploadMateriForm(request.POST, request.FILES, instance=current_materi)
684
        if form.is_valid():
685
            RevisiMateriService.revisi_materi(form, request)
686
687
688
689
690
691
            return HttpResponseRedirect("/dashboard/")
        else:
            context = self.get_context_data(**kwargs)
            context["form_revisi"] = form
            return self.render_to_response(context)

692

Samuel Dimas's avatar
Samuel Dimas committed
693
694
695
696
697
698
def pages(request):
    context = {}
    # All resource paths end in .html.
    # Pick out the html file name from the url. And load that template.
    try:

699
        load_template = request.path.split("/")[-1]
Samuel Dimas's avatar
Samuel Dimas committed
700
701
702
        template = loader.get_template(load_template)
        return HttpResponse(template.render(context, request))

703
    except Exception:
Samuel Dimas's avatar
Samuel Dimas committed
704

705
        template = loader.get_template("error-404.html")
Samuel Dimas's avatar
Samuel Dimas committed
706
        return HttpResponse(template.render(context, request))
707
708


709
710
711
712
class DownloadHistoryView(TemplateView):
    template_name = "download_history.html"

    def get_context_data(self, **kwargs):
713
        context = super(DownloadHistoryView, self).get_context_data(**kwargs)
714
715
716
717
718
719
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        if request.user.is_authenticated:
            current_user = self.request.user
720
            DownloadHistoryService.init_data_authenticated_user(context, current_user)
721
        else:
722
            DownloadHistoryService.init_data_guest_user(context, request)
723
        return self.render_to_response(context)
724

725

726
727
728
729
730
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):
731
        GoogleDriveUploadService.upload_to_gdrive(file_path, materi.title)
732
    else:
733
        raise Http404(FILE_NOT_FOUND_MESSAGE)
734

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

737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
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
765
class PasswordChangeViews(PasswordChangeView):
766

Yaumi's avatar
Yaumi committed
767
768
    from_class = PasswordChangeForm
    success_url = reverse_lazy('password_success')
Yaumi's avatar
Yaumi committed
769

Yaumi's avatar
Yaumi committed
770
def password_success(request):
771
    return render(request, 'password_success.html', {})
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795


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
796
797
798
799
800
801

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

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
802
            return HttpResponseRedirect(LOGIN_URL)
insan ramadhan's avatar
insan ramadhan committed
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
        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:
818
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE})
insan ramadhan's avatar
insan ramadhan committed
819
820
        SubmitVisitor(msg=title, user_id=user_id, email=email).save()
        return JsonResponse({"success": True, "msg": "Buku tamu berhasil ditambahkan"})
821

Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
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:
844
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE})
Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
845
846
847
        
        return JsonResponse(ReadLaterService.toggle_read_later(materi_id, request.user))
    else:
848
        return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE})
Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
849

850
851
852
853
854
class StatisticsView(TemplateView):
    template_name = "statistik.html"

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
855
            return HttpResponseRedirect(LOGIN_URL)
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
        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)
906
907
908
909
910
911
912
913
914
915
916
917
918
919

class MostContributor(TemplateView):
    template_name = "most-contributor.html"

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

    def count_contributor(self):
        count_materi = Materi.objects.all.count()
        content = {'count_materi':count_materi}
        print(content)
        return content