Fakultas Ilmu Komputer UI

Commit 59d87955 authored by Samuel Dimas Partogi's avatar Samuel Dimas Partogi
Browse files

Merge branch 'PBI-9-Statistik_Akses_Materi' into 'staging'

Pbi 9 statistik akses materi

See merge request ppl-fasilkom-ui/2020/ppl-c/diskominfo-depok-digipus/marjinal-digipus!69
parents 84bb7a6b 32ef74e1
Pipeline #49691 passed with stages
in 5 minutes and 39 seconds
......@@ -7,6 +7,7 @@ LONG_MONTH = ['', 'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni',
BASE_PERIODE = [
("", "Pilih"),
('-----', (
("LAST_WEEK", "7 Hari Terakhir"),
("LAST_MONTH", "30 Hari Terakhir"),
......
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from crispy_forms.layout import Layout, Submit, Row, Column, Reset, ButtonHolder, Button
from crispy_forms.bootstrap import InlineCheckboxes
from django import forms
from administration.choices import genereatePeriodeChoices
......@@ -9,6 +9,12 @@ from app.models import Category
from authentication.models import User
def generate_category_choices():
categories = Category.objects.all()
category_choices = [(i.id, i.name) for i in categories]
return category_choices
class DateInput(forms.DateInput):
input_type = 'date'
......@@ -87,6 +93,8 @@ class PeriodForm(forms.Form):
widget=DateInput, label="Waktu mulai", required=False)
end_date = forms.DateField(
widget=DateInput, label="Waktu selesai", required=False)
categories = forms.MultipleChoiceField(
label="Kategori", required=False, choices=generate_category_choices)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
......@@ -95,7 +103,34 @@ class PeriodForm(forms.Form):
field.widget.attrs['class'] = 'form-control'
self.helper = FormHelper()
self.helper.attrs["name"] = "filter-form"
self.helper.form_method = 'get'
self.helper.add_input(Submit('submit', 'Filter'))
# def get_date(self):
self.helper.layout = Layout(
Row(
Column('period', css_class='form-group col-md-4 mb-0'),
Column('start_date', css_class='form-group col-md-4 mb-0'),
Column('end_date', css_class='form-group col-md-4 mb-0'),
css_class='form-row'
),
InlineCheckboxes('categories'),
Row(
ButtonHolder(Submit('submit', 'Filter')),
ButtonHolder(Button('reset_form', 'Hapus filter'), css_class ="btn-warning")
)
)
def clean(self):
cleaned_data = super().clean()
start_date = cleaned_data.get('start_date')
end_date = cleaned_data.get('end_date')
if start_date is not None and end_date is None:
self.add_error("end_date",
"masukan waktu selesai")
if start_date is None and end_date is not None:
self.add_error("start_date",
"masukan waktu mulai")
if start_date is not None and end_date is not None:
if start_date > end_date:
self.add_error("end_date",
"waktu selesai sebelum waktu mulai")
......@@ -2,48 +2,4 @@
// var canvas = document.getElementById("chart1");
// var heightRatio = 1.5;
// canvas.height = canvas.width * heightRatio;
// });
var ctx = document.getElementById("chart1").getContext("2d");
var myChart = new Chart(ctx, {
type: "bar",
responsive: true,
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: "# of Votes",
data: [12, 19, 3, 5, 2, 3],
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,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [
{
ticks: {
beginAtZero: true,
},
},
],
},
},
});
// });
\ No newline at end of file
from django.urls import path
from administration.views import (VerificationView, DetailVerificationView,
VerificationSettingView, CategorySettingView, KelolaKontributorView,
ProfileContributorAdminView, ProfileAdminAdministrationView,
KelolaAdminView, RegistrasiAdminView, EditVerificationView, EditCategoryView, StatisticsView, StatisticApiView,
delete_admin, delete_contributor, delete_verification, delete_category)
from administration.views import VerificationView, DetailVerificationView, VerificationSettingView, CategorySettingView, KelolaKontributorView, ProfileContributorAdminView, ProfileAdminAdministrationView, KelolaAdminView, RegistrasiAdminView, EditVerificationView, delete_admin, delete_contributor, delete_verification, StatisticsView, StatisticApiView, EditCategoryView, delete_category
app_name = "administration"
......
import random
import string
from django.utils import timezone, lorem_ipsum
from dateutil.relativedelta import relativedelta
def id_generator(size=6, chars=string.ascii_uppercase + string.digits): # pragma: no cover
def generate_time_step(s, e, step="DAILY"):
result = []
time = s.replace(hour=0, minute=0, second=0, microsecond=0)
while time < e:
result.append(time)
if step == "DAILY":
time = time + relativedelta(days=1)
result.append(e)
return result
def id_generator(size=6, chars=string.ascii_uppercase + string.digits): # pragma: no cover
return ''.join(random.choice(chars) for _ in range(size))
import json
from datetime import datetime, date
from django.core.exceptions import PermissionDenied
from django.contrib.auth.hashers import make_password
......@@ -6,14 +7,64 @@ from django.http import HttpResponseRedirect, JsonResponse
from django.shortcuts import get_object_or_404, render
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 administration.models import VerificationReport, VerificationSetting, DeletionHistory
from administration.forms import CategoryForm, VerificationSettingForm, RegistrasiAdminForm, PeriodForm
from app.models import Category, Materi
from app.models import Category, Materi, ViewStatistics, DownloadStatistics, Comment, Like, getRandomColor
from authentication.models import User
from datetime import datetime
from administration.utils import generate_time_step
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)
# Create your views here.
class VerificationView(TemplateView):
template_name = "verif.html"
......@@ -223,15 +274,120 @@ class ProfileContributorAdminView(TemplateView):
class StatisticsView(TemplateView):
template_name = "administration/data_statistik.html"
def dispatch(self, request, *args, **kwargs):
if not request.user.is_authenticated:
raise PermissionDenied(request)
return super(StatisticsView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(StatisticsView, self).get_context_data(**kwargs)
context["page_title"] = "Statistik"
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 = {
"charts": [],
"total": [],
"label": []
}
label = ["Dilihat", "Diunduh", "Komentar", "Disukai"]
colors = ["#4e73df", "#e74a3b", "#1cc88a", "#f6c23e"]
time_step = generate_time_step(start, end)
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)
return chart_data
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
form = context["periodForm"]
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)
data_sets = [view_set, download_set, like_set, comment_set]
chart_data = self.generate_chart_data(
filter_set["start"], filter_set["end"], data_sets)
context["chart_data"] = chart_data
return self.render_to_response(context=context)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment