Fakultas Ilmu Komputer UI

views.py 32.9 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
44
45
46
47
48
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/"
49

50
def permission_denied(request, exception, template_name="error_403.html"):
51
52
    return defaults.permission_denied(request, exception, template_name)

53

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

65
        lst_materi = Materi.objects.filter(status="APPROVE").order_by("date_modified")
Mika dabelza abi's avatar
Mika dabelza abi committed
66
67
        url = ""

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

70

71
        context["materi_list"] = lst_materi
Mika dabelza abi's avatar
Mika dabelza abi committed
72
        paginator = Paginator(context["materi_list"], 15)
73
        page_number = request.GET.get("page")
Mika dabelza abi's avatar
Mika dabelza abi committed
74
75
76
77
        page_obj = paginator.get_page(page_number)
        context["materi_list"] = page_obj

        context["url"] = url
78
79
        return self.render_to_response(context=context)

80

81
82
class KatalogPerKontributorView(TemplateView):
    template_name = "app/katalog_kontri.html"
83

84
85
86
87
88
89
90
91
    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)
92
93
94
95
96

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

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

114
        return self.render_to_response(context=context)
115

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

147
148
149
150
class DetailMateri(TemplateView):
    template_name = "app/detail_materi.html"

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

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

Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
165
166
167
168
169
170
            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

171
        context['is_authenticated'] = self.request.user.is_authenticated
172

173
        return context
174

175

176
177
    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
178
        query_set_for_comment = Comment.objects.filter(materi=context["materi_data"])
179
        query_set_for_review = Review.objects.filter(materi=context["materi_data"])
180
        has_disliked, has_liked = DetailMateriService.find_comment_like_dislike(query_set_for_comment, self.request.session)
181
        context["comment_data"] = query_set_for_comment
182
        context["review_data"] = query_set_for_review
183
184
        context["has_liked_comment"] = has_liked
        context["has_disliked_comment"] = has_disliked
185
186
        return self.render_to_response(context=context)

187

188

189
    def post(self, request, *args, **kwargs):
190
191
192
        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 == "")):
193
194
            context = self.get_context_data(*args, **kwargs)
            context["error_message"] = "Anda belum menuliskan komentar"
195
            context["materi_data"] = get_object_or_404(Materi, pk=kwargs["pk"])
196
            query_set_for_comment = Comment.objects.filter(materi=context["materi_data"])
197
            context["comment_data"] = query_set_for_comment
198
199
            query_set_for_review = Review.objects.filter(materi=context["materi_data"])
            context["review_data"] = query_set_for_review
200
            return self.render_to_response(context=context)
201

202
        materi = get_object_or_404(Materi, pk=kwargs["pk"])
203
        user_obj = request.user if request.user.is_authenticated else None
204
        if user_obj:
205
            if (comment_text != None ):
206
                comment = Comment.objects.create(
207
                    comment=comment_text, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj
208
209
                )
                comment.save()
210
211
212
213
214
215
216
217
218
219
220
221
                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,
222
                    ) 
223
            elif (review_text != None):
224
                review = Review.objects.create(
225
                    review=review_text, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj
226
227
                )
                review.save()
228
229
        return HttpResponseRedirect(request.path)

230

231
def toggle_like(request):
232
233
234
    if request.method == "POST":
        materi_id = request.POST.get("materi_id", None)
        session_id = request.POST.get("session_id", None)
235
        if materi_id is None or session_id is None:
236
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE})
237
        return JsonResponse(LikeDislikeService.apply_like_materi(materi_id, session_id))
238
    else:
239
        return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE})
240
241


242
def delete_comment(request, pk_materi, pk_comment):
243
244
    if not request.user.is_authenticated or not request.user.is_admin:
        raise PermissionDenied(request)
245
    comment = get_object_or_404(Comment, pk=pk_comment)
246
    url = "/materi/" + str(pk_materi) + "/"
247
248
249
    comment.delete()
    return HttpResponseRedirect(url)

250
def toggle_like_comment(request):
251
    comment_id = 0
252
253
254
255
    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:
256
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE, "comment_id": comment_id})
257
        return JsonResponse(LikeDislikeService.apply_comment_like(comment_id, session_id))
258
    else:
259
        return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE, "comment_id": comment_id})
260

261

262
def toggle_dislike_comment(request):
263
    comment_id = 0
264
265
266
267
    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:
268
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE, "comment_id": comment_id})
269
        return JsonResponse(LikeDislikeService.apply_comment_dislike(comment_id, session_id))
270
    else:
271
        return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE, "comment_id": comment_id})
272
273


274
def add_rating_materi(request):
275
    if request.method == "POST" and request.user.is_authenticated:
276

277
278
        materi_id = request.POST.get("materi_id", None)
        rating_score = request.POST.get("rating_score", None)
279
280


281
282
283
284
        is_valid_params, materi_id, \
        rating_score, response, \
        status_code = MateriFieldValidationHelperService.\
            validate_materi_rating_params(materi_id,rating_score)
285

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

289
290
291
        is_valid_rating, materi, \
        response, status_code = MateriFieldValidationHelperService.\
            validate_materi_rating(materi_id, request.user)
292

293
294
        if not is_valid_rating:
            return JsonResponse(response, status=status_code)
295
296

        Rating(materi=materi, user=request.user, score=rating_score).save()
297
298
299
        return JsonResponse(
            {"success": True, "msg": "Rating successfully created", "rating_score": rating_score}, status=201
        )
300
301
302
    return JsonResponse({"success": False, "msg": "Forbidden"}, status=403)


303

304
305
306
307
308
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):
309
310
311
        try:
            mimetype = mimetypes.guess_type(file_path)
            with open(file_path, "rb") as fh:
312
313
314
                return DownloadViewMateriHelperService.build_materi_response(fh, file_path,
                                                                             materi, mimetype, request,
                                                                             HttpResponse(fh.read(), content_type=mimetype[0]))
315
316
        except Exception:
            raise Http404(FILE_NOT_FOUND_MESSAGE)
317
    else:
318
        raise Http404(FILE_NOT_FOUND_MESSAGE)
319

igor lestin sianipar's avatar
igor lestin sianipar committed
320

321
322
323
324
325
326
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)
327
328
329
        try:
            with open(file_path, "rb") as fh:
                response = HttpResponse(fh.read(), content_type=mimetype[0])
330
                DownloadViewMateriHelperService.build_view_materi_response(file_path, materi, response)
331
                return response
332
333
        except Exception:
            raise Http404(FILE_NOT_FOUND_MESSAGE)
334
    else:
335
        raise Http404(FILE_NOT_FOUND_MESSAGE)
igor lestin sianipar's avatar
igor lestin sianipar committed
336

igor lestin sianipar's avatar
igor lestin sianipar committed
337

Selvy Fitriani's avatar
Selvy Fitriani committed
338
339
def delete_materi(request, pk):
    materi = get_object_or_404(Materi, pk=pk)
340
341
342
    if request.user.is_superuser or request.user.is_admin:
        materi.soft_delete()
        return HttpResponseRedirect("/administration/")
Selvy Fitriani's avatar
Selvy Fitriani committed
343
344
345
    materi.delete()
    return HttpResponseRedirect("/dashboard/")

igor lestin sianipar's avatar
igor lestin sianipar committed
346
class UploadMateriView(TemplateView):
347
    template_name = UNGGAH_HTML
igor lestin sianipar's avatar
igor lestin sianipar committed
348
349
350
351
352
353
    context = {}

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

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

374
375


igor lestin sianipar's avatar
igor lestin sianipar committed
376
    def get(self, request, *args, **kwargs):
Steven Kusuman's avatar
Steven Kusuman committed
377
        if request.user.is_authenticated == False or not request.user.is_contributor:
igor lestin sianipar's avatar
igor lestin sianipar committed
378
            raise PermissionDenied(request)
379

igor lestin sianipar's avatar
igor lestin sianipar committed
380
        context = self.get_context_data(**kwargs)
381
        context["form"] = UploadMateriForm
igor lestin sianipar's avatar
igor lestin sianipar committed
382
        return self.render_to_response(context)
383

384

385
class UploadMateriHTML(TemplateView):
386
    template_name = UNGGAH_HTML
387
    context = {}
igor lestin sianipar's avatar
igor lestin sianipar committed
388

389
    def get_template_names(self):
390
391
        if self.request.path == UNGGAH_URL:
            template_name = UNGGAH_HTML
392
393
394
        return template_name


395
396
397
398
399
class UploadMateriExcelView(TemplateView):
    template_name = "unggah_excel.html"
    context = {}

    def get_template_names(self):
400
        if self.request.path == UNGGAH_EXCEL_URL:
401
402
403
404
405
            template_name = "unggah_excel.html"
        return template_name

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

406
        if "template" in self.request.GET:
407

408
409
410
            data_frame = pd.DataFrame(
                {"Title": [], "Author": [], "Publisher": [], "Categories": [], "Description": [],}
            )
411
412

            with BytesIO() as b:
413
                writer = pd.ExcelWriter(b, engine="xlsxwriter")  # pylint: disable=abstract-class-instantiated
414
415
416
                data_frame.to_excel(writer, index=0)
                writer.save()
                response = HttpResponse(
417
418
                    b.getvalue(), content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                )
419
420
421
422
423
424
425
426
427
428

                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):
429
430
        excel_file = request.FILES["excel"]
        excel = pd.read_excel(excel_file)
431

432
        row, lines = excel.shape
433
        categories = Category.objects.all()
434

435
        field_length = {
436
437
438
            "title": 50,
            "author": 30,
            "publisher": 30,
439
440
441
442
443
444
        }

        message = None

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

446
            # Validate Categories
447
            message = UploadMateriService.validate_excel_categories(categories, excel, i, message)
448

449
            message = UploadMateriService.validate_excel_field_length(excel, field_length, i, message)
450
451
452

            if message != None:
                break
453

454
455
        if message != None:
            messages.error(request, message)
456
            return HttpResponseRedirect(UNGGAH_EXCEL_URL)
457
458
459

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

462
        messages.success(request, "Materi berhasil diunggah")
463

464
        return HttpResponseRedirect(UNGGAH_EXCEL_URL)
465
466


467
468


469
class DashboardKontributorView(TemplateView):
470
    template_name = "dashboard.html"
471
472
473
474
475
476
477

    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):
478
        context = super(DashboardKontributorView, self).get_context_data(**kwargs)
479
480
481
482
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
483
484
485
        current_user = self.request.user
        materi_list = current_user.materi_set.all()
        context["materi_list"] = materi_list
486
        return self.render_to_response(context)
487

488

489
class ProfilView(TemplateView):
490
491
492
    template_name = "profil.html"

    def dispatch(self, request, *args, **kwargs):
493
        if not request.user.is_authenticated:
494
            raise PermissionDenied(request)
495
        return super(ProfilView, self).dispatch(request, *args, **kwargs)
496
497
498

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
499
        current_user = request.user
500
501
502
        context["user"] = current_user
        return self.render_to_response(context)

503

504
505
506
507
class SuntingProfilView(TemplateView):
    template_name = "sunting.html"

    def dispatch(self, request, *args, **kwargs):
508
        if not request.user.is_authenticated:
509
510
511
512
            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
513
        current_user = self.request.user
514
515
516
517
518
519
520
521
522
523
        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
524

525
        form = SuntingProfilForm(request.POST, request.FILES, instance=current_user)
526
527
        if form.is_valid():
            current_user.default_profile_picture = True
528
529
530

            # Removing exifdata from profile picture on upload
            if request.FILES:
531
                EditProfileService.update_profile_picture(current_user, request)
532
            else:
533
                form.save()
534
            return HttpResponseRedirect("/profil/")
535
536
        else:
            context = self.get_context_data(**kwargs)
537
538
            context["form"] = form
            return self.render_to_response(context)
539

540

541
542
543
544
545
class ReqMateriView(TemplateView):
    template_name = "req_materi.html"

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
546
            return HttpResponseRedirect(LOGIN_URL)
547
548
549
        return super(ReqMateriView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
550
        context = super(ReqMateriView, self).get_context_data(**kwargs)
551
552
553
554
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
555
        context['requested_material'] = ReqMaterial.objects.all()
556
557
558
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
559
        title = request.POST.get("title", None)
560
        if title is None:
561
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE})
562
563
564
        ReqMaterial(title=title).save()
        return JsonResponse({"success": True, "msg": "Permintaan materi berhasil dikirimkan"})

565

566
567
568
569
570
571
572
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)
573

574
    def get_context_data(self, **kwargs):
575
        context = super(SuksesLoginKontributorView, self).get_context_data(**kwargs)
576
577
578
579
580
581
582
583
584
585
        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)

586

587
588
589
590
591
592
593
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)
594

595
596
597
598
599
600
601
602
603
604
605
606
    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
607

608
609
610
class PostsView(TemplateView):

    template_name = "user_uploaded_posts.html"
611
612

    def dispatch(self, request, *args, **kwargs):
613
        if not request.user.is_authenticated:
614
            raise PermissionDenied(request)
615
        return super(PostsView, self).dispatch(request, *args, **kwargs)
616
617

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

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

624
        comments = Comment.objects.filter(materi__id__in=posts_data.keys()).order_by("-timestamp")
625
626
627
628
629
630
631

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

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

632
        return self.render_to_response(context=context)
633

634

635
636
637
class RevisiMateriView(TemplateView):
    template_name = "revisi.html"

638
    def dispatch(self, request, *args, **kwargs):
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
        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)

654
    def post(self, request, *args, **kwargs):
655
656
657
658
        if request.user.is_authenticated == False:
            raise PermissionDenied(request)

        current_materi = get_object_or_404(Materi, pk=kwargs["pk"])
659
        form = UploadMateriForm(request.POST, request.FILES, instance=current_materi)
660
        if form.is_valid():
661
            RevisiMateriService.revisi_materi(form, request)
662
663
664
665
666
667
            return HttpResponseRedirect("/dashboard/")
        else:
            context = self.get_context_data(**kwargs)
            context["form_revisi"] = form
            return self.render_to_response(context)

668

Samuel Dimas's avatar
Samuel Dimas committed
669
670
671
672
673
674
def pages(request):
    context = {}
    # All resource paths end in .html.
    # Pick out the html file name from the url. And load that template.
    try:

675
        load_template = request.path.split("/")[-1]
Samuel Dimas's avatar
Samuel Dimas committed
676
677
678
        template = loader.get_template(load_template)
        return HttpResponse(template.render(context, request))

679
    except Exception:
Samuel Dimas's avatar
Samuel Dimas committed
680

681
        template = loader.get_template("error-404.html")
Samuel Dimas's avatar
Samuel Dimas committed
682
        return HttpResponse(template.render(context, request))
683
684


685
686
687
688
class DownloadHistoryView(TemplateView):
    template_name = "download_history.html"

    def get_context_data(self, **kwargs):
689
        context = super(DownloadHistoryView, self).get_context_data(**kwargs)
690
691
692
693
694
695
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        if request.user.is_authenticated:
            current_user = self.request.user
696
            DownloadHistoryService.init_data_authenticated_user(context, current_user)
697
        else:
698
            DownloadHistoryService.init_data_guest_user(context, request)
699
        return self.render_to_response(context)
700

701

702
703
704
705
706
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):
707
        GoogleDriveUploadService.upload_to_gdrive(file_path, materi.title)
708
    else:
709
        raise Http404(FILE_NOT_FOUND_MESSAGE)
710

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

713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
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
741
class PasswordChangeViews(PasswordChangeView):
742

Yaumi's avatar
Yaumi committed
743
744
    from_class = PasswordChangeForm
    success_url = reverse_lazy('password_success')
Yaumi's avatar
Yaumi committed
745

Yaumi's avatar
Yaumi committed
746
def password_success(request):
747
    return render(request, 'password_success.html', {})
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771


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
772
773
774
775
776
777

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

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
778
            return HttpResponseRedirect(LOGIN_URL)
insan ramadhan's avatar
insan ramadhan committed
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
        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:
794
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE})
insan ramadhan's avatar
insan ramadhan committed
795
796
        SubmitVisitor(msg=title, user_id=user_id, email=email).save()
        return JsonResponse({"success": True, "msg": "Buku tamu berhasil ditambahkan"})
797

Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
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:
820
            return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE})
Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
821
822
823
        
        return JsonResponse(ReadLaterService.toggle_read_later(materi_id, request.user))
    else:
824
        return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE})
Anthony Dewa Priyasembada's avatar
Anthony Dewa Priyasembada committed
825

826
827
828
829
830
class StatisticsView(TemplateView):
    template_name = "statistik.html"

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
831
            return HttpResponseRedirect(LOGIN_URL)
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
875
876
877
878
879
880
881
        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)