Fakultas Ilmu Komputer UI

Commit 2d43f764 authored by Adrika Novrialdi's avatar Adrika Novrialdi
Browse files

Merge branch '2006560806-80' into 'master'

Refactor Views to Service Layer

Closes #80

See merge request !29
parents 61ce89fb 6c3f899c
Pipeline #58896 passed with stages
in 14 minutes and 33 seconds
from dateutil.relativedelta import relativedelta
from django.db.models import Count
from django.utils import timezone
from datetime import datetime
from administration.forms import PeriodForm
from administration.models import VerificationSetting
from app.models import LaporanMateri, Materi
class DateHelperService:
@staticmethod
def get_start_end_date(period):
if period == 'ALL_TIME':
return (None, None)
elif period.split("_")[0] == "LAST":
end, start = DateHelperService.handle_last(period)
return (start, end)
elif period.split("_")[0] == "CURRENT":
end, start = DateHelperService.handle_current(period)
return (start, end)
elif period.split("_")[0] == "MINUS":
end, start = DateHelperService.handle_minus(period)
return (start, end)
else:
return (None, None)
@staticmethod
def handle_minus(period):
start = timezone.now()
end = None
delta = int(period.split("_")[1])
if period.split("_")[2] == "MONTH":
start = start.replace(day=1, hour=0, minute=0,
second=0, microsecond=0)
start = start - relativedelta(months=delta)
end = start + relativedelta(months=1)
elif period.split("_")[2] == "YEAR":
start = start.replace(month=1, day=1, hour=0,
minute=0, second=0, microsecond=0)
start = start - relativedelta(years=delta)
end = start + relativedelta(years=1)
return end, start
@staticmethod
def handle_current(period):
start = timezone.now()
end = None
if period.split("_")[1] == "MONTH":
start = start.replace(day=1, hour=0, minute=0,
second=0, microsecond=0)
end = start + relativedelta(months=1)
elif period.split("_")[1] == "YEAR":
start = start.replace(month=1, day=1, hour=0,
minute=0, second=0, microsecond=0)
end = start + relativedelta(years=1)
return end, start
@staticmethod
def handle_last(period):
end = timezone.now()
delta = 7
if period.split("_")[1] == "WEEK":
delta = 7
if period.split("_")[1] == "MONTH":
delta = 30
if period.split("_")[1] == "QUARTER":
delta = 90
if period.split("_")[1] == "YEAR":
delta = 365
start = end - relativedelta(days=delta)
return end, start
class DetailVerificationService:
@staticmethod
def init_data(context, materi):
context["materi_data"] = materi
context["kriteria_list"] = VerificationSetting.objects.filter(
archived=False)
if materi.status == "PENDING" or materi.status == "REVISION":
riwayat = False
else:
riwayat = True
context["riwayat"] = riwayat
context["verification_report"] = materi.verificationreport_set.first()
@staticmethod
def initilize_kriteria(items) -> list:
kriteria = []
for item in items:
if "kriteria" in item[0]:
verification_item_id = item[0].split("-")[1]
verif_obj = VerificationSetting.objects.get(
id=int(verification_item_id))
kriteria_value = {
"title": verif_obj.title,
"status": True if item[1] == "1" else False
}
kriteria.append(kriteria_value)
return kriteria
@staticmethod
def action_approve(materi):
DetailVerificationService.save_materi_status(materi, "APPROVE")
@staticmethod
def action_disapprove(materi):
DetailVerificationService.save_materi_status(materi, "DISAPPROVE")
@staticmethod
def save_materi_status(materi, status: str):
materi.status = status
materi.save()
class StatisticService:
@staticmethod
def get_filter_set(period, kwargs):
filter_set = {}
form = PeriodForm()
DEFAULT_PERIOD = "LAST_MONTH"
if form.is_valid():
form_data = form.cleaned_data
if len(form_data["categories"]) == 0:
form_data["categories"] = None
if form_data["period"] == "":
form_data["period"] = DEFAULT_PERIOD
# check if using custom date range
end, start = StatisticService.init_date(DEFAULT_PERIOD, form_data)
filter_set["start"] = start
filter_set["end"] = end
filter_set["categories"] = form_data["categories"]
return filter_set
@staticmethod
def init_date(default_period, form_data):
if form_data["start_date"] is not None and form_data["end_date"] is not None:
start = timezone.make_aware(datetime.combine(
form_data["start_date"], datetime.min.time()))
end = timezone.make_aware(datetime.combine(
form_data["end_date"], datetime.min.time()))
elif form_data["period"] is not None:
start, end = DateHelperService.get_start_end_date(form_data["period"])
else:
start, end = DateHelperService.get_start_end_date(default_period)
return end, start
@staticmethod
def generate_view_stat(chart_data, colors, data_sets, label, time_step):
for label, color, dataset in zip(label, colors, data_sets):
result = {
"label": label,
"backgroundColor": color,
"borderColor": color,
"borderWidth": 1
}
data = []
total = 0
s = 0
e = 1
while e < len(time_step):
todays = dataset.filter(
timestamp__gte=time_step[s], timestamp__lt=time_step[e]).count()
data.append(todays)
total += todays
s += 1
e += 1
result["data"] = data
chart_data["charts"].append(result)
chart_data["total"].append(total)
@staticmethod
def get_query_set(user, object_statistic, **kwargs):
if user.is_admin:
return object_statistic.objects.filter(materi__status="APPROVE")
else:
return object_statistic.objects.filter(materi__status="APPROVE", materi__uploader=user.id)
@staticmethod
def filter_qs(qs, filter_set):
if filter_set.get("categories", None) is not None:
qs = qs.filter(materi__categories__in=filter_set.get("categories"))
if filter_set.get("start") is not None and filter_set.get("end") is not None:
s = filter_set.get("start")
e = filter_set.get("end")
qs = qs.filter(timestamp__gte=s, timestamp__lt=e)
return qs.distinct()
class LaporanMateriService:
@staticmethod
def initilize_report():
laporan_materi = LaporanMateri.objects.filter(is_rejected=False)
materi_dilaporkan = Materi.objects \
.filter(laporanmateri__id__in=laporan_materi, status="APPROVE") \
.annotate(jumlah_laporan=Count('laporanmateri__materi_id')) \
.order_by('-jumlah_laporan') \
.distinct()
materi_diblokir = Materi.objects.filter(status="BLOCKED")
return laporan_materi, materi_dilaporkan, materi_diblokir
import json
from datetime import datetime, date
from django.core.exceptions import PermissionDenied
from django.contrib.auth.hashers import make_password
from django.db.models import Count
from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import get_object_or_404, render
from django.shortcuts import get_object_or_404
from django.views.generic import TemplateView, View
from django.contrib import messages
from django.utils import timezone, lorem_ipsum
from dateutil.relativedelta import relativedelta
from django.utils import timezone
from administration.models import VerificationReport, VerificationSetting, DeletionHistory
from administration.forms import CategoryForm, VerificationSettingForm, RegistrasiAdminForm, PeriodForm, EditAdminStatusForm
from app.models import Category, Materi, ViewStatistics, DownloadStatistics, Comment, Like, getRandomColor, LaporanMateri
from app.views import permission_denied
from administration.services import StatisticService, DetailVerificationService, LaporanMateriService
from app.models import Category, Materi, ViewStatistics, DownloadStatistics, Comment, Like, LaporanMateri
from authentication.models import User
from datetime import datetime
......@@ -24,52 +20,6 @@ from django.core import management
ADMINISTRATION_MANAGEMENT = "/administration/kelola-admin/"
ADMINISTRATION_REPORT = "/administration/laporan-materi/"
def get_start_end_date(period):
if period == 'ALL_TIME':
return (None, None)
elif period.split("_")[0] == "LAST":
end = timezone.now()
delta = 7
if period.split("_")[1] == "WEEK":
delta = 7
if period.split("_")[1] == "MONTH":
delta = 30
if period.split("_")[1] == "QUARTER":
delta = 90
if period.split("_")[1] == "YEAR":
delta = 365
start = end - relativedelta(days=delta)
return (start, end)
elif period.split("_")[0] == "CURRENT":
start = timezone.now()
if period.split("_")[1] == "MONTH":
start = start.replace(day=1, hour=0, minute=0,
second=0, microsecond=0)
end = start + relativedelta(months=1)
return (start, end)
elif period.split("_")[1] == "YEAR":
start = start.replace(month=1, day=1, hour=0,
minute=0, second=0, microsecond=0)
end = start + relativedelta(years=1)
return (start, end)
elif period.split("_")[0] == "MINUS":
start = timezone.now()
delta = int(period.split("_")[1])
if period.split("_")[2] == "MONTH":
start = start.replace(day=1, hour=0, minute=0,
second=0, microsecond=0)
start = start - relativedelta(months=delta)
end = start + relativedelta(months=1)
return (start, end)
elif period.split("_")[2] == "YEAR":
start = start.replace(month=1, day=1, hour=0,
minute=0, second=0, microsecond=0)
start = start - relativedelta(years=delta)
end = start + relativedelta(years=1)
return (start, end)
else:
return (None, None)
class VerificationView(TemplateView):
template_name = "verif.html"
......@@ -104,44 +54,25 @@ class DetailVerificationView(TemplateView):
context = super(DetailVerificationView,
self).get_context_data(**kwargs)
materi = get_object_or_404(Materi, pk=kwargs["pk"])
context["materi_data"] = materi
context["kriteria_list"] = VerificationSetting.objects.filter(
archived=False)
if materi.status == "PENDING" or materi.status == "REVISION":
riwayat = False
else:
riwayat = True
context["riwayat"] = riwayat
context["verification_report"] = materi.verificationreport_set.first()
DetailVerificationService.init_data(context, materi)
return context
def post(self, request, *args, **kwargs):
materi = get_object_or_404(Materi, pk=kwargs["pk"])
feedback = request.POST.get("feedback", "")
action = request.POST.get("action", None)
report = {}
kriteria = []
for item in request.POST.items():
if "kriteria" in item[0]:
verification_item_id = item[0].split("-")[1]
verif_obj = VerificationSetting.objects.get(
id=int(verification_item_id))
kriteria_value = {
"title": verif_obj.title,
"status": True if item[1] == "1" else False
}
kriteria.append(kriteria_value)
report["kriteria"] = kriteria
items = request.POST.items()
report["kriteria"] = DetailVerificationService.initilize_kriteria(items)
report["feedback"] = feedback
if action == "approve" and feedback != "":
materi.status = "APPROVE"
materi.save()
DetailVerificationService.action_approve(materi)
elif action == "disapprove" and feedback != "":
materi.status = "DISAPPROVE"
materi.save()
DetailVerificationService.action_disapprove(materi)
else:
context = self.get_context_data(**kwargs)
context["error"] = True
......@@ -151,6 +82,7 @@ class DetailVerificationView(TemplateView):
verif_report.save()
return HttpResponseRedirect("/administration/")
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context=context)
......@@ -291,56 +223,9 @@ class StatisticsView(TemplateView):
context["periodForm"] = PeriodForm(self.request.GET)
return context
def get_filter_set(self, **kwargs):
filter_set = {}
form = PeriodForm(self.request.GET)
DEFAULT_PERIOD = "LAST_MONTH"
if form.is_valid():
form_data = form.cleaned_data
if len(form_data["categories"]) == 0:
form_data["categories"] = None
if form_data["period"] == "":
form_data["period"] = DEFAULT_PERIOD
# check if using custom date range
if form_data["start_date"] is not None and form_data["end_date"] is not None:
start = timezone.make_aware(datetime.combine(
form_data["start_date"], datetime.min.time()))
end = timezone.make_aware(datetime.combine(
form_data["end_date"], datetime.min.time()))
elif form_data["period"] is not None:
start, end = get_start_end_date(form_data["period"])
else:
start, end = get_start_end_date(DEFAULT_PERIOD)
filter_set["start"] = start
filter_set["end"] = end
filter_set["categories"] = form_data["categories"]
return filter_set
def get_query_set(self, object_statistic, **kwargs):
if self.request.user.is_admin:
return object_statistic.objects.filter(materi__status="APPROVE")
else:
return object_statistic.objects.filter(materi__status="APPROVE", materi__uploader=self.request.user.id)
def filter_qs(self, qs, filter_set):
if filter_set.get("categories", None) is not None:
qs = qs.filter(materi__categories__in=filter_set.get("categories"))
if filter_set.get("start") is not None and filter_set.get("end") is not None:
s = filter_set.get("start")
e = filter_set.get("end")
qs = qs.filter(timestamp__gte=s, timestamp__lt=e)
return qs.distinct()
# def generate_table_data(self, data_sets):
# table_data = {}
# counter = 1
# row_materi_table = []
# for item in data_sets:
# # return res
def generate_chart_data(self, start, end, data_sets):
chart_data = {
......@@ -354,41 +239,21 @@ class StatisticsView(TemplateView):
for i in time_step:
chart_data["label"].append(i.strftime("%d/%m/%Y"))
# generate view stat
for label, color, dataset in zip(label, colors, data_sets):
result = {
"label": label,
"backgroundColor": color,
"borderColor": color,
"borderWidth": 1
}
data = []
total = 0
s = 0
e = 1
while e < len(time_step):
todays = dataset.filter(
timestamp__gte=time_step[s], timestamp__lt=time_step[e]).count()
data.append(todays)
total += todays
s += 1
e += 1
result["data"] = data
chart_data["charts"].append(result)
chart_data["total"].append(total)
StatisticService.generate_view_stat(chart_data, colors, data_sets, label, time_step)
return chart_data
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
filter_set = self.get_filter_set(**kwargs)
view_set = self.get_query_set(ViewStatistics, **kwargs)
view_set = self.filter_qs(view_set, filter_set)
download_set = self.get_query_set(DownloadStatistics, **kwargs)
download_set = self.filter_qs(download_set, filter_set)
like_set = self.get_query_set(Like, **kwargs)
like_set = self.filter_qs(like_set, filter_set)
comment_set = self.get_query_set(Comment, **kwargs)
comment_set = self.filter_qs(comment_set, filter_set)
filter_set = StatisticService.get_filter_set(self.request.GET,**kwargs)
view_set = StatisticService.get_query_set(self.request.user,ViewStatistics, **kwargs)
view_set = StatisticService.filter_qs(view_set, filter_set)
download_set = StatisticService.get_query_set(self.request.user, DownloadStatistics, **kwargs)
download_set = StatisticService.filter_qs(download_set, filter_set)
like_set = StatisticService.get_query_set(self.request.user, Like, **kwargs)
like_set = StatisticService.filter_qs(like_set, filter_set)
comment_set = StatisticService.get_query_set(self.request.user, Comment, **kwargs)
comment_set = StatisticService.filter_qs(comment_set, filter_set)
data_sets = [view_set, download_set, like_set, comment_set]
chart_data = self.generate_chart_data(
......@@ -657,13 +522,11 @@ class LaporanMateriView(TemplateView):
def get(self, request, *args, **kwargs):
context = super(LaporanMateriView, self).get_context_data(**kwargs)
context["laporan_materi"] = LaporanMateri.objects.filter(is_rejected=False)
context["materi_dilaporkan"] = Materi.objects \
.filter(laporanmateri__id__in=context["laporan_materi"], status="APPROVE") \
.annotate(jumlah_laporan=Count('laporanmateri__materi_id')) \
.order_by('-jumlah_laporan') \
.distinct()
context["materi_diblokir"] = Materi.objects.filter(status="BLOCKED")
laporan_materi, materi_dilaporkan, \
materi_diblokir = LaporanMateriService.initilize_report()
context["laporan_materi"] = laporan_materi
context["materi_dilaporkan"] = materi_dilaporkan
context["materi_diblokir"] = materi_diblokir
return self.render_to_response(context=context)
class LaporanMateriDetailView(TemplateView):
......@@ -700,4 +563,3 @@ def tolak_laporan(request, *args, **kwargs):
laporan.save()
return HttpResponseRedirect(ADMINISTRATION_REPORT + str(laporan.materi_id))
import datetime
import os
import random
from django.contrib import messages
from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ValidationError
from django.db.models import Count, Q
from django.shortcuts import get_object_or_404
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from administration.models import VerificationReport
from app.forms import SuntingProfilForm
from app.models import Category, Like, LikeComment, DislikeComment, Materi, Comment, Rating, DownloadStatistics, \
ViewStatistics
from app.utils.fileManagementUtil import get_random_filename, remove_image_exifdata
from digipus import settings
class DafterKatalogService:
@staticmethod
def search_materi(get_search, lst_materi, url):
url = url + "&search={0}".format(get_search)
lst_materi = (
lst_materi.search(get_search)
.filter(
Q(author__icontains=get_search)
| Q(uploader__name__icontains=get_search)
| Q(descriptions__icontains=get_search)
| Q(publisher__icontains=get_search)
)
.distinct()
)
return lst_materi, url
@staticmethod
def filter_materi_by_kategori(get_kategori, lst_materi, url):
url = url + "&kategori={0}".format(get_kategori)
kategori = Category.objects.get(pk=get_kategori)
lst_materi = lst_materi.filter(categories=kategori.pk)
return lst_materi, url
@staticmethod
def apply_sort(get_sort, lst_materi, url):
url = url + "&sort={0}".format(get_sort)
if (get_sort == "judul"):
lst_materi = lst_materi.order_by('title')
elif (get_sort == "penulis"):
lst_materi = lst_materi.order_by('author')
elif (get_sort == "pengunggah"):
lst_materi = lst_materi.order_by('uploader')
elif (get_sort == "terbaru"):
lst_materi = lst_materi.order_by('-date_created')
elif (get_sort == "terlama"):
lst_materi = lst_materi.order_by('date_created')
elif (get_sort == "terpopuler"):
lst_materi = lst_materi.annotate(count=Count('like__id')).order_by('-count')
elif (get_sort == "jumlah_unduh"):
lst_materi = lst_materi.annotate(count=Count('unduh__id')).order_by('-count')
return lst_materi, url
@staticmethod
def apply_options(lst_materi, request, url):
should_random = bool(request.GET.get("random"))
get_search = request.GET.get("search")
if get_search:
lst_materi, url = DafterKatalogService.search_materi(get_search, lst_materi, url)
get_kategori = request.GET.get("kategori")
if get_kategori:
lst_materi, url = DafterKatalogService.filter_materi_by_kategori(get_kategori, lst_materi, url)
get_sort = request.GET.get("sort")
if get_sort:
lst_materi, url = DafterKatalogService.apply_sort(get_sort, lst_materi, url)
if should_random:
lst_materi = DafterKatalogService.apply_random(lst_materi)
return lst_materi, url
@staticmethod
def apply_random(lst_materi):
return random.sample(list(lst_materi), len(lst_materi))
class DetailMateriService:
@staticmethod
def init_context_data(context, materi, session):
context["session_id"] = session.session_key
context["materi_data"] = materi
context["report"] = VerificationReport.objects.filter(materi=materi)
context["has_liked"] = Like.objects.filter(materi=materi, session_id=session.session_key).exists()
@staticmethod
def set_published_date(materi):
published_date = ""
if materi.published_date == None:
published_date = "n.d"
else:
published_date = materi.published_date.strftime("%Y-%m-%d %H:%M")
return published_date
@staticmethod
def init_citation_and_materi_rating(context, materi, published_date, request):
citation_apa = materi.author + " . (" + published_date + ") . " + materi.title + " . " + materi.publisher
context["citationAPA"] = citation_apa
context["citationIEEE"] = CitationService.get_citation_ieee(request, materi)
context["materi_rating_score"] = 0
@staticmethod