import mimetypes import os from io import BytesIO from register.services import MailService import django from decouple import config import pandas as pd from django.conf import settings from django.contrib import messages from django.contrib.auth.views import PasswordChangeForm from django.contrib.auth.views import PasswordChangeView from django.core.exceptions import PermissionDenied, FieldError from django.core.mail import send_mail from django.core.paginator import Paginator from django.db.models import Q, Avg, Count from django.http import (Http404, HttpResponse, HttpResponseRedirect, JsonResponse) from django.shortcuts import get_object_or_404, redirect from django.shortcuts import render from django.template import loader from django.urls import reverse from django.urls import reverse_lazy from django.views import defaults from django.views.generic import TemplateView from app.forms import SuntingProfilForm, UploadMateriForm, RatingContributorForm, GuestBookForm from app.models import ( Category, Comment, Review, Materi, LaporanMateri, ReqMaterial, Rating, RatingContributor, SubmitVisitor, GuestBook, ReadLater, NotifikasiKontributor, AdminNotification ) from authentication.models import User from .services import DafterKatalogService, DetailMateriService, LikeDislikeService, MateriFieldValidationHelperService, \ DownloadViewMateriHelperService, UploadMateriService, EditProfileService, RevisiMateriService, \ DownloadHistoryService, GoogleDriveUploadService, ReadLaterService 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/" def permission_denied(request, exception, template_name="error_403.html"): return defaults.permission_denied(request, exception, template_name) class DaftarKatalog(TemplateView): paginate_by = 2 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) context["kategori_list"] = Category.objects.all() lst_materi = Materi.objects.filter( status="APPROVE").order_by("date_modified") url = "" lst_materi, url = DafterKatalogService.apply_options( lst_materi, request, url) context["materi_list"] = lst_materi paginator = Paginator(context["materi_list"], 15) page_number = request.GET.get("page") page_obj = paginator.get_page(page_number) context["materi_list"] = page_obj context["url"] = url return self.render_to_response(context=context) class KatalogPerKontributorView(TemplateView): template_name = "app/katalog_kontri.html" 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) materi_list = Materi.objects.filter(status="APPROVE", uploader=context["contributor"]).order_by( "date_modified" ) paginator = Paginator(materi_list, 15) page_number = request.GET.get("page") materi_list_by_page = paginator.get_page(page_number) context["materi_list"] = materi_list_by_page contributor = context["contributor"] context["form_rating"] = RatingContributorForm(initial={ "contributor": contributor, "user": request.user }) context["avg_rating"] = User.objects.filter(email=kwargs["email"]) \ .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 return self.render_to_response(context=context) def post(self, request, *args, **kwargs): 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() return redirect("katalog-per-kontributor", email=kwargs["email"]) class DetailMateri(TemplateView): template_name = "app/detail_materi.html" def get_context_data(self, **kwargs): 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"]) 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) DetailMateriService.init_materi_download_count(context, materi) if self.request.user.is_authenticated: materi_rating = Rating.objects.filter( materi=materi, user=self.request.user).first() if materi_rating is not None: context['materi_rating_score'] = materi_rating.score 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 context['is_authenticated'] = self.request.user.is_authenticated return context def get(self, request, *args, **kwargs): context = self.get_context_data(**kwargs) query_set_for_comment = Comment.objects.filter( materi=context["materi_data"]) query_set_for_review = Review.objects.filter( materi=context["materi_data"]) has_disliked, has_liked = DetailMateriService.find_comment_like_dislike( query_set_for_comment, self.request.session) context["comment_data"] = query_set_for_comment context["review_data"] = query_set_for_review context["has_liked_comment"] = has_liked context["has_disliked_comment"] = has_disliked 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() return self.render_to_response(context=context) def post(self, request, *args, **kwargs): comment_text = request.POST.get("comment", None) review_text = request.POST.get("review", None) 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 == "")): context = self.get_context_data(*args, **kwargs) context["error_message"] = "Anda belum menuliskan komentar" context["materi_data"] = get_object_or_404(Materi, pk=kwargs["pk"]) query_set_for_comment = Comment.objects.filter( materi=context["materi_data"]) context["comment_data"] = query_set_for_comment query_set_for_review = Review.objects.filter( materi=context["materi_data"]) context["review_data"] = query_set_for_review return self.render_to_response(context=context) materi = get_object_or_404(Materi, pk=kwargs["pk"]) user_obj = request.user if request.user.is_authenticated else None if user_obj: if (comment_text != None): comment = Comment.objects.create( comment=comment_text, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj ) comment.save() 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.' MailService.send( subject='DIGIPUS: Komentar Baru pada Materi Anda', message=email_content, from_email=getattr(settings, 'EMAIL_HOST_USER'), recipient_list=[materi_uploader.email, ], ) elif (review_text != None): review = Review.objects.create( review=review_text, username=DetailMateriService.get_user_name(request), materi=materi, user=user_obj ) review.save() elif (report_text != None): laporan_materi = LaporanMateri.objects.create( materi=materi, laporan=report_text, user=user_obj ) laporan_materi.save() return HttpResponseRedirect(request.path) def toggle_like(request): if request.method == "POST": materi_id = request.POST.get("materi_id", None) session_id = request.POST.get("session_id", None) if materi_id is None or session_id is None: return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE}) return JsonResponse(LikeDislikeService.apply_like_materi(materi_id, session_id)) else: return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE}) def delete_comment(request, pk_materi, pk_comment): if not request.user.is_authenticated or not request.user.is_admin: raise PermissionDenied(request) comment = get_object_or_404(Comment, pk=pk_comment) url = "/materi/" + str(pk_materi) + "/" comment.delete() return HttpResponseRedirect(url) 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) def toggle_like_comment(request): comment_id = 0 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_MESSAGE, "comment_id": comment_id}) return JsonResponse(LikeDislikeService.apply_comment_like(comment_id, session_id)) else: return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE, "comment_id": comment_id}) def toggle_dislike_comment(request): comment_id = 0 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_MESSAGE, "comment_id": comment_id}) return JsonResponse(LikeDislikeService.apply_comment_dislike(comment_id, session_id)) else: return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE, "comment_id": comment_id}) def add_rating_materi(request): if request.method == "POST" and request.user.is_authenticated: materi_id = request.POST.get("materi_id", None) rating_score = request.POST.get("rating_score", None) is_valid_params, materi_id, \ rating_score, response, \ status_code = MateriFieldValidationHelperService.\ validate_materi_rating_params(materi_id, rating_score) if not is_valid_params: return JsonResponse(response, status=status_code) is_valid_rating, materi, \ response, status_code = MateriFieldValidationHelperService.\ validate_materi_rating(materi_id, request.user) if not is_valid_rating: return JsonResponse(response, status=status_code) Rating(materi=materi, user=request.user, score=rating_score).save() return JsonResponse( {"success": True, "msg": "Rating successfully created", "rating_score": rating_score}, status=201 ) return JsonResponse({"success": False, "msg": "Forbidden"}, status=403) 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): try: mimetype = mimetypes.guess_type(file_path) with open(file_path, "rb") as fh: return DownloadViewMateriHelperService.build_materi_response(fh, file_path, materi, mimetype, request, HttpResponse(fh.read(), content_type=mimetype[0])) except Exception: raise Http404(FILE_NOT_FOUND_MESSAGE) else: raise Http404(FILE_NOT_FOUND_MESSAGE) 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) try: with open(file_path, "rb") as fh: response = HttpResponse(fh.read(), content_type=mimetype[0]) DownloadViewMateriHelperService.build_view_materi_response( file_path, materi, response) return response except Exception: raise Http404(FILE_NOT_FOUND_MESSAGE) else: raise Http404(FILE_NOT_FOUND_MESSAGE) def delete_materi(request, pk): materi = get_object_or_404(Materi, pk=pk) if request.user.is_superuser or request.user.is_admin: materi.soft_delete() return HttpResponseRedirect("/administration/") materi.delete() return HttpResponseRedirect("/dashboard/") class UploadMateriView(TemplateView): template_name = UNGGAH_HTML context = {} redirect_path = "/unggah/" def get_context_data(self, **kwargs): context = super(UploadMateriView, self).get_context_data(**kwargs) return context def post(self, request, *args, **kwargs): if request.user.is_authenticated == False or not request.user.is_contributor: raise PermissionDenied(request) form = UploadMateriForm(request.POST, request.FILES) if form.is_valid(): materi = form.save(commit=False) materi.uploader = request.user konten = form.cleaned_data["content"] yt_url_id = form.cleaned_data['yt_video_id'] if not UploadMateriService.validate_file_extension(konten, request, yt_url_id): return HttpResponseRedirect(UNGGAH_URL) UploadMateriService.upload_materi(form, materi) messages.success( request, "Materi berhasil diunggah, periksa riwayat unggah anda") return HttpResponseRedirect(UNGGAH_URL) else: context = self.get_context_data(**kwargs) context["form"] = form messages.error(request, "Terjadi kesalahan pada pengisian data") return self.render_to_response(context) def get(self, request, *args, **kwargs): if request.user.is_authenticated == False or not request.user.is_contributor: raise PermissionDenied(request) context = self.get_context_data(**kwargs) context["form"] = UploadMateriForm return self.render_to_response(context) class UploadMateriHTML(TemplateView): template_name = UNGGAH_HTML context = {} class UploadMateriExcelView(TemplateView): template_name = "unggah_excel.html" context = {} def get_template_names(self): if self.request.path == UNGGAH_EXCEL_URL: template_name = "unggah_excel.html" return template_name def get(self, request, *args, **kwargs): if "template" in self.request.GET: data_frame = pd.DataFrame( {"Title": [], "Author": [], "Publisher": [], "Categories": [], "Description": [], } ) # pylint: disable=abstract-class-instantiated with BytesIO() as b: writer = pd.ExcelWriter( b, engine="xlsxwriter") data_frame.to_excel(writer, index=0) writer.save() response = HttpResponse( b.getvalue(), content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) 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): excel_file = request.FILES["excel"] excel = pd.read_excel(excel_file) row, lines = excel.shape categories = Category.objects.all() field_length = { "title": 50, "author": 30, "publisher": 30, } message = None # First pass, validate input for i in range(row): # Validate Categories message = UploadMateriService.validate_excel_categories( categories, excel, i, message) message = UploadMateriService.validate_excel_field_length( excel, field_length, i, message) if message != None: break if message != None: messages.error(request, message) return HttpResponseRedirect(UNGGAH_EXCEL_URL) # Second pass, save data with django.db.transaction.atomic(): UploadMateriService.upload_materi_excel( categories, excel, request, row) messages.success(request, "Materi berhasil diunggah") return HttpResponseRedirect(UNGGAH_EXCEL_URL) class DashboardKontributorView(TemplateView): template_name = "dashboard.html" 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): context = super(DashboardKontributorView, self).get_context_data(**kwargs) return context def get(self, request, *args, **kwargs): context = self.get_context_data(**kwargs) current_user = self.request.user materi_list = current_user.materi_set.all() context["materi_list"] = materi_list return self.render_to_response(context) class ProfilView(TemplateView): template_name = "profil.html" def dispatch(self, request, *args, **kwargs): if not request.user.is_authenticated: raise PermissionDenied(request) return super(ProfilView, self).dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): context = self.get_context_data(**kwargs) current_user = request.user context["user"] = current_user return self.render_to_response(context) class SuntingProfilView(TemplateView): template_name = "sunting.html" def dispatch(self, request, *args, **kwargs): if not request.user.is_authenticated: raise PermissionDenied(request) return super(SuntingProfilView, self).dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): current_user = self.request.user 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 form = SuntingProfilForm( request.POST, request.FILES, instance=current_user) if form.is_valid(): current_user.default_profile_picture = True # Removing exifdata from profile picture on upload if request.FILES: EditProfileService.update_profile_picture( current_user, request) else: form.save() return HttpResponseRedirect("/profil/") else: context = self.get_context_data(**kwargs) context["form"] = form return self.render_to_response(context) class ReqMateriView(TemplateView): template_name = "req_materi.html" def dispatch(self, request, *args, **kwargs): if request.user.is_authenticated == False: return HttpResponseRedirect(LOGIN_URL) return super(ReqMateriView, self).dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): context = super(ReqMateriView, self).get_context_data(**kwargs) return context def get(self, request, *args, **kwargs): context = self.get_context_data(**kwargs) context['requested_material'] = ReqMaterial.objects.all() return self.render_to_response(context) def post(self, request, *args, **kwargs): title = request.POST.get("title", None) if title is None: return JsonResponse({"success": False, "msg": MISSING_PARAMETER_MESSAGE}) ReqMaterial(title=title).save() return JsonResponse({"success": True, "msg": "Permintaan materi berhasil dikirimkan"}) 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) def get_context_data(self, **kwargs): context = super(SuksesLoginKontributorView, 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) class SuksesLoginAdminView(TemplateView): template_name = "sukses_admin.html" def getAdminNotification(self): notifications = AdminNotification.objects.all() return notifications def dispatch(self, request, *args, **kwargs): if not request.user.is_admin: raise PermissionDenied(request) return super(SuksesLoginAdminView, self).dispatch(request, *args, **kwargs) 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 notifications = self.getAdminNotification() context["notifications"] = notifications return self.render_to_response(context) class PostsView(TemplateView): template_name = "user_uploaded_posts.html" def dispatch(self, request, *args, **kwargs): if not request.user.is_authenticated: raise PermissionDenied(request) return super(PostsView, self).dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): context = super().get_context_data(**kwargs) user = self.request.user posts = Materi.objects.filter(uploader=user).order_by("-date_created") posts_data = {post.id: {"data": post, "comments": []} for post in posts} comments = Comment.objects.filter( materi__id__in=posts_data.keys()).order_by("-timestamp") for comment in comments: posts_data[comment.materi.id]["comments"].append(comment) context["user"] = user context["posts"] = posts_data return self.render_to_response(context=context) class RevisiMateriView(TemplateView): template_name = "revisi.html" def dispatch(self, request, *args, **kwargs): 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) def post(self, request, *args, **kwargs): if request.user.is_authenticated == False: raise PermissionDenied(request) current_materi = get_object_or_404(Materi, pk=kwargs["pk"]) if request.user.is_authenticated and request.user.is_contributor: opened_notif = NotifikasiKontributor.objects.filter(user=request.user, materi=current_materi) opened_notif.delete() form = UploadMateriForm( request.POST, request.FILES, instance=current_materi) if form.is_valid(): RevisiMateriService.revisi_materi(form, request) return HttpResponseRedirect("/dashboard/") else: context = self.get_context_data(**kwargs) context["form_revisi"] = form return self.render_to_response(context) def pages(request): context = {} # All resource paths end in .html. # Pick out the html file name from the url. And load that template. try: load_template = request.path.split("/")[-1] template = loader.get_template(load_template) return HttpResponse(template.render(context, request)) except Exception: template = loader.get_template("error-404.html") return HttpResponse(template.render(context, request)) class DownloadHistoryView(TemplateView): template_name = "download_history.html" def get_context_data(self, **kwargs): context = super(DownloadHistoryView, self).get_context_data(**kwargs) return context def get(self, request, *args, **kwargs): context = self.get_context_data(**kwargs) if request.user.is_authenticated: current_user = self.request.user DownloadHistoryService.init_data_authenticated_user( context, current_user) else: DownloadHistoryService.init_data_guest_user(context, request) return self.render_to_response(context) 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): GoogleDriveUploadService.upload_to_gdrive(file_path, materi.title) else: raise Http404(FILE_NOT_FOUND_MESSAGE) return HttpResponseRedirect(reverse('detail-materi', kwargs={'pk': pk})) 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) class PasswordChangeViews(PasswordChangeView): from_class = PasswordChangeForm success_url = reverse_lazy('password_success') def password_success(request): return render(request, 'password_success.html', {}) 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) class SubmitVisitorView(TemplateView): template_name = "submit_visitor.html" def dispatch(self, request, *args, **kwargs): if request.user.is_authenticated == False: return HttpResponseRedirect(LOGIN_URL) 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_MESSAGE}) SubmitVisitor(msg=title, user_id=user_id, email=email).save() return JsonResponse({"success": True, "msg": "Buku tamu berhasil ditambahkan"}) class GuestBookView(TemplateView): def get(self, request, *args, **kwargs): form = GuestBookForm() return render(request, 'guest_book.html', {'form': form}) def post(self, request, *args, **kwargs): name = request.POST.get('name') job = request.POST.get('job') gender = request.POST.get('gender') guestBook = GuestBook(name=name, job=job, gender=gender) guestBook.save() return redirect("daftar_katalog") 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_MESSAGE}) return JsonResponse(ReadLaterService.toggle_read_later(materi_id, request.user)) else: return JsonResponse({"success": False, "msg": UNSUPPORTED_MESSAGE}) class StatisticsView(TemplateView): template_name = "statistik.html" def dispatch(self, request, *args, **kwargs): if request.user.is_authenticated == False: return HttpResponseRedirect(LOGIN_URL) 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) 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