Fakultas Ilmu Komputer UI

Commit f6eddb18 authored by Mutia Rahmatun Husna's avatar Mutia Rahmatun Husna
Browse files

Merge branch 'master' of...

Merge branch 'master' of https://gitlab.cs.ui.ac.id/pmpl/class-project/marjinal-digipus into 1706039622-23
parents 6cbbc0ce c1810816
Pipeline #60135 passed with stages
in 23 minutes and 22 seconds
{% extends 'administration/base_administrasi2.html' %}
{% load static %}
{% extends 'detail_kontri_admin_base.html' %}
{% block title %}
<title>Kelola Admin | Digipus</title>
{% endblock %}
{% block content %}
<div class="profile-content white-text">
<div>
{% if not user.default_profile_picture %}
<img class="img-profile rounded-circle" src="https://i.ibb.co/9wgPzyZ/default-image.png" alt="Photo" class="img-thumbnail"></img>
{% else %}
<img class="img-profile rounded-circle" src="{{ user.profile_picture.url }}" alt="Photo" class="img-thumbnail"></img>
{% endif %}
<div class="profile-margin"></div>
<h2>{{ user.name }}</h2>
<h4>{{ user.email }}</h4>
<h4>{{ user.biography }}</h4>
<div class="profile-margin"></div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
instansi
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
{{user.instansi}}
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
LinkedIn
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://linkedin.com">{{ user.linkedin }}</a>
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
Facebook
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://facebook.com">{{ user.facebook }}</a>
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
Twitter
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://twitter.com">{{ user.twitter }}</a>
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
Instagram
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://instagram.com">{{ user.instagram }}</a>
</div>
</div>
<a class="btn btn-primary btn-admin" href="/administration/kelola-admin/">Kembali ke Kelola Admin</a>
</div>
</div>
{% endblock%}
\ No newline at end of file
{% block return_link %}
<a class="btn btn-primary btn-admin" href="/administration/kelola-admin/">Kembali ke Kelola Admin</a>
{% endblock %}
{% extends 'administration/base_administrasi2.html' %}
{% load static %}
{% extends 'detail_kontri_admin_base.html' %}
{% block title %}
<title>Kelola Kontributor | Digipus</title>
{% endblock %}
{% block content %}
<div class="profile-content white-text">
<div>
{% if not user.default_profile_picture %}
<img class="img-profile rounded-circle" src="https://i.ibb.co/9wgPzyZ/default-image.png" alt="Photo" class="img-thumbnail"></img>
{% else %}
<img class="img-profile rounded-circle" src="{{ user.profile_picture.url }}" alt="Photo" class="img-thumbnail"></img>
{% endif %}
<div class="profile-margin"></div>
<h2>{{ user.name }}</h2>
<h4>{{ user.email }}</h4>
<h4>{{ user.biography }}</h4>
<div class="profile-margin"></div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
instansi
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
{{user.instansi}}
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
LinkedIn
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://linkedin.com">{{ user.linkedin }}</a>
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
Facebook
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://facebook.com">{{ user.facebook }}</a>
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
Twitter
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://twitter.com">{{ user.twitter }}</a>
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
Instagram
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://instagram.com">{{ user.instagram }}</a>
</div>
</div>
<a class="btn btn-primary btn-admin" href="/administration/kelola-kontributor/">Kembali ke Kelola Kontributor</a>
</div>
</div>
{% endblock %}
\ No newline at end of file
{% block return_link %}
<a class="btn btn-primary btn-admin" href="/administration/kelola-kontributor/">Kembali ke Kelola Kontributor</a>
{% endblock %}
{% extends 'administration/base_administrasi2.html' %}
{% block content %}
<div class="profile-content white-text">
<div>
{% if not user.default_profile_picture %}
<img class="img-profile rounded-circle" src="https://i.ibb.co/9wgPzyZ/default-image.png" alt="Photo" class="img-thumbnail"></img>
{% else %}
<img class="img-profile rounded-circle" src="{{ user.profile_picture.url }}" alt="Photo" class="img-thumbnail"></img>
{% endif %}
<div class="profile-margin"></div>
<h2>{{ user.name }}</h2>
<h4>{{ user.email }}</h4>
<h4>{{ user.biography }}</h4>
<div class="profile-margin"></div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
instansi
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
{{user.instansi}}
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
LinkedIn
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://linkedin.com">{{ user.linkedin }}</a>
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
Facebook
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://facebook.com">{{ user.facebook }}</a>
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
Twitter
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://twitter.com">{{ user.twitter }}</a>
</div>
</div>
<div class="row">
<div class="col-md-6 my-auto" style="font-size: 2rem;">
Instagram
</div>
<div class="col-md-6 my-auto" style="font-size: 1.2rem;">
<a href="https://instagram.com">{{ user.instagram }}</a>
</div>
</div>
{% block return_link %}
{% endblock %}
</div>
</div>
{% endblock %}
\ No newline at end of file
......@@ -52,25 +52,31 @@ Pratinjau Materi
{% if riwayat %}
<div class="info-wrapper">
<div class="info" id="1">
<dt class="col col-4">
<p class="info-name"><strong>Verifikatur</strong></p>
</dt>
<dl>
<dt class="col col-4">
<p class="info-name"><strong>Verifikatur</strong></p>
</dt>
</dl>
<dd>
<p class="info-content">{{verification_report.user.name}}</p>
</dd>
</div>
<div class="info" id="1">
<dt class="col col-4">
<p class="info-name"><strong>Waktu Verifikasi</strong></p>
</dt>
<dl>
<dt class="col col-4">
<p class="info-name"><strong>Waktu Verifikasi</strong></p>
</dt>
</dl>
<dd>
<p class="info-content">{{verification_report.timestamp}}</p>
</dd>
</div>
<div class="info" id="1">
<dt class="col col-4">
<p class="info-name"><strong>Status Materi</strong></p>
</dt>
<dl>
<dt class="col col-4">
<p class="info-name"><strong>Status Materi</strong></p>
</dt>
</dl>
<dd>
<p class="info-content">{{verification_report.status}}</p>
</dd>
......
......@@ -22,6 +22,7 @@
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered" id="dataTable">
<caption>Materi yang Dilaporkan</caption>
<thead>
<tr>
<th scope="col">Judul</th>
......
......@@ -67,6 +67,8 @@ class DafterKatalogService:
lst_materi = lst_materi.annotate(count=Count('unduh__id')).order_by('-count')
elif (get_sort == "jumlah_tampilan"):
lst_materi = lst_materi.annotate(count=Count('baca__id')).order_by('-count')
elif (get_sort == "jumlah_komentar"):
lst_materi = lst_materi.annotate(count=Count('comment__id')).order_by('-count')
return lst_materi, url
@staticmethod
......@@ -350,7 +352,7 @@ class UploadMateriService:
@staticmethod
def validate_yt_video_url(value):
r = requests.get('http://www.youtube.com/watch?v='+value)
r = requests.get('https://www.youtube.com/watch?v='+value)
if "\"playabilityStatus\":{\"status\":\"ERROR\"" in r.text:
raise ValidationError("Invalid Youtube video ID")
......
......@@ -312,7 +312,7 @@ div.review {
<div style="border-top:1px solid #d4d4d4;text-align:center">
<h3>Video</h3>
<iframe src="https://www.youtube.com/embed/{{ materi_data.yt_video_id }}"
allowfullscreen="allowfullscreen"
title="Video materi" allowfullscreen="allowfullscreen"
width="564" height="300">
invalid video url
</iframe>
......@@ -472,7 +472,7 @@ div.review {
{% endblock content %}
{% block extra_scripts %}
<script src="https://kit.fontawesome.com/bc2cedd6b2.js" crossorigin="anonymous"></script>
<script type="text/javascript">
<script>
// using jQuery
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
......
......@@ -149,6 +149,9 @@
<li>
<a href="?sort=jumlah_tampilan">jumlah tampilan</a>
</li>
<li>
<a href="?sort=jumlah_komentar">jumlah komentar</a>
</li>
</ul>
</div>
</div>
......
......@@ -2,7 +2,7 @@
{% load static %}
{% block title %}
<title>Unggah Materi dari Excel | Digipus</title>
<title>Statistik | Digipus</title>
{% endblock %}
{% block stylesheets %}
......@@ -24,9 +24,10 @@
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered">
<caption>Summary Materi per Kategori</caption>
<thead>
<th>Kategori</th>
<th>Jumlah Materi</th>
<th scope="col">Kategori</th>
<th scope="col">Jumlah Materi</th>
</thead>
<tbody>
{% for s in stats %}
......
......@@ -206,7 +206,48 @@ class DaftarKatalogSortingByJumlahTampilanTest(TestCase):
self.client.get(self.url)
response = self.client.get("/?sort=jumlah_tampilan")
self.assertRegex(str(response.content), rf'.*Materi 2.*Materi 1.*')
class DaftarKatalogSortingByJumlahKomentarTest(TestCase):
def setUp(self):
self.client = Client()
self.contributor_credential = {
"email": "kontributor@gov.id",
"password": "passwordtest"
}
self.contributor_credential_2 = {
"email": "kontributor2@gov.id",
"password": "passwordtest"
}
self.contributor = get_user_model().objects.create_user(
**self.contributor_credential, name="Kontributor 1", is_contributor=True)
self.contributor2 = get_user_model().objects.create_user(
**self.contributor_credential_2, name="Kontributor 2", is_contributor=True)
self.cover = SimpleUploadedFile(
"Cherprang_Areekul40_nJM9dGt.jpg", b"Test file")
self.content = SimpleUploadedFile("Bahan_PA_RKK.pdf", b"Test file")
Materi(title="Materi 1", author="Agas", uploader=self.contributor,
publisher="Kelas SC", descriptions="Deskripsi Materi 1",
status="APPROVE", cover=self.cover, content=self.content).save()
time.sleep(1)
Materi(title="Materi 2", author="Agas", uploader=self.contributor,
publisher="Kelas SC", descriptions="Deskripsi Materi 2",
status="APPROVE", cover=self.cover, content=self.content).save()
self.last_uploaded_material = Materi.objects.last()
url = f"/materi/{self.last_uploaded_material.id}/"
self.client.login(**self.contributor_credential_2)
self.client.post(url, {"comment": "This is new comment by Kontributor 2"})
def test_sorting_by_jumlah_komentar(self):
response = self.client.get("/?sort=jumlah_komentar")
self.assertRegex(str(response.content), rf'.*Materi 2.*Materi 1.*')
class DaftarKatalogPerKontributorTest(TestCase):
def setUp(self):
self.client = Client()
......@@ -970,6 +1011,7 @@ class PostsViewTest(TestCase):
materi=post,
session_id=("dummysession-" + str(i) + '-' + str(j))
)
time.sleep(0.1)
for i, post_id in enumerate(post_comment_group_dict):
post = post_comment_group_dict[post_id]["data"]
......@@ -1033,8 +1075,6 @@ class PostsViewTest(TestCase):
response = self._request_as_user()
posts = list(self.data.keys())
posts.sort()
comments = {
i: [comment.id for comment in self.data[post_id]["comments"]]
for i, post_id in enumerate(posts)
......
......@@ -4,7 +4,7 @@ import PIL.Image as Image
def get_random_filename(f_name):
ext = f_name.split(".")[-1]
name = ''.join(random.choices(string.ascii_lowercase , k=4))
name += hashlib.md5((datetime.datetime.now().isoformat() + f_name).encode()).hexdigest()
name += hashlib.md5((datetime.datetime.now().isoformat() + f_name).encode()).hexdigest() # Sensitive
name = name + "." + ext
return name
......
import mimetypes
import os
from io import BytesIO
from register.services import MailService
import django
from decouple import config
......@@ -213,12 +214,12 @@ class DetailMateri(TemplateView):
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(
MailService.send(
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,
)
elif (review_text != None):
review = Review.objects.create(
......@@ -387,11 +388,6 @@ class UploadMateriHTML(TemplateView):
template_name = UNGGAH_HTML
context = {}
def get_template_names(self):
if self.request.path == UNGGAH_URL:
template_name = UNGGAH_HTML
return template_name
class UploadMateriExcelView(TemplateView):
template_name = "unggah_excel.html"
......
......@@ -93,9 +93,20 @@ class RegistrationService:
Mohon verifikasi email Anda dengan klik pada link berikut: {url}
"""
send_mail(
MailService.send(
subject = 'DIGIPUS: Verifikasi Alamat Email',
message = email_content,
from_email = getattr(settings, 'EMAIL_HOST_USER'),
recipient_list = [user.email],
fail_silently = False)
recipient_list = [user.email])
class MailService:
@staticmethod
def send(subject, message, from_email, recipient_list):
send_mail(
subject,
message,
from_email,
recipient_list,
fail_silently = False) # Sensitive
{% load static %}
{% extends 'register_base.html' %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registrasi Kontributor</title>
<link rel="icon" type="image/png" href="{% static 'images/icons/logo.ico' %}" />
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="{% static 'vendor/bootstrap/css/bootstrap.min.css' %}">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="{% static 'fonts/font-awesome-4.7.0/css/font-awesome.min.css' %}">
<!--===============================================================================================-->
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="{% static 'vendor/animate/animate.css' %}">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="{% static 'vendor/css-hamburgers/hamburgers.min.css' %}">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="{% static 'vendor/animsition/css/animsition.min.css' %}">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="{% static 'vendor/select2/select2.min.css' %}">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="{% static 'vendor/daterangepicker/daterangepicker.css' %}">
<!--===============================================================================================-->
<link rel="stylesheet" type="text/css" href="{% static 'css/styles.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/util.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
<!--===============================================================================================-->
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital@1&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
</head>
<body style="background-color: #666666;">
<main>
<div class="limiter">
<div class="container-login100">
<div class="wrap-login100">
<form class="login100-form validate-form" method="POST" action="">
{% csrf_token %}
<div class="login100-form-title p-b-43">
Registrasi Kontributor
</div>
<div class="wrap-input100 validate-input" data-validate="Valid email is required: ex@abc.xyz">
{{ form.name }}
<span class="focus-input100"></span>
<span class="label-input100">Nama</span>
</div>
<div class="wrap-input100 validate-input" data-validate="Password is required">
{{ form.instansi }}
<span class="focus-input100"></span>
<span class="label-input100">Instansi/Pekerjaan</span>
</div>
<div class="wrap-input100 validate-input" data-validate="Valid email is required: ex@abc.xyz">
{{ form.nik.errors }}
{{ form.nik }}
<span class="focus-input100"></span>
<span class="label-input100">NIK</span>
</div>
<div class="wrap-input100 validate-input" data-validate="Valid email is required: ex@abc.xyz">
{{ form.alamat }}
<span class="focus-input100"></span>
<span class="label-input100">Alamat</span>
</div>
<div class="wrap-input100 validate-input" data-validate="Valid email is required: ex@abc.xyz">
{{ form.email.errors }}
{{ form.email }}
<span class="focus-input100"></span>
<span class="label-input100">Email</span>
</div>
<div class="wrap-input100 validate-input" data-validate="Valid email is required: ex@abc.xyz">
{{ form.nomor_telpon.errors}}
{{ form.nomor_telpon }}
<span class="focus-input100"></span>
<span class="label-input100">Nomor Telepon</span>
</div>
<div class="wrap-input100 validate-input" data-validate="Valid email is required: ex@abc.xyz">
{{ form.password.errors }}
{{ form.password }}
<span class="focus-input100"></span>
<span class="label-input100">Kata Sandi</span>
</div>
<div class="wrap-input100 validate-input" data-validate="Valid email is required: ex@abc.xyz">
{{ form.password2 }}
<span class="focus-input100"></span>
<span class="label-input100">Ketik Ulang Kata Sandi</span>
</div>
{% block title %} Registrasi Kontributor {% endblock %}
{% block form_title %} Registrasi Kontributor {% endblock %}
<div class="container-login100-form-btn">
<button class="login100-form-btn">
Daftar
</button>
</div>
<div class="flex-sb-m w-full p-t-3 p-b-32">
<div>
<a href="/login/" class="txt1">
Kembali ke halaman login
</a>
</div>
</div>
{% if message %}
<div class="text-success txt1" id="registrasi">{{ message }}</div>
<div class="txt1">Kembali ke <a href="/" class="txt1">halaman utama</a></div>
{% endif %}
</form>
<div class="login100-more" style="background-image: url('../static/images/bg-03.jpg'); z-index: 0;">
</div>
</div>
</div>
</div>
</main>
<!--===============================================================================================-->
<script src="../static/vendor/jquery/jquery-3.2.1.min.js"></script>
<!--===============================================================================================-->
<script src="../static/vendor/animsition/js/animsition.min.js"></script>
<!--===============================================================================================-->
<script src="../static/vendor/bootstrap/js/popper.js"></script>
<script
src="../static/../static/../static/../static/../static/../static/vendor/bootstrap/js/bootstrap.min.js"></script>
<!--===============================================================================================-->
<script src="../static/../static/../static/../static/../static/vendor/select2/select2.min.js"></script>
<!--===============================================================================================-->
<script src="../static/../static/../static/../static/vendor/daterangepicker/moment.min.js"></script>
<script src="../static/../static/../static/vendor/daterangepicker/daterangepicker.js"></script>
<!--===============================================================================================-->
<script src="../static/../static/vendor/countdowntime/countdowntime.js"></script>
<!--===============================================================================================-->
<script src="../static/js/login.js"></script>
<script src="../static/js/navbar.js"></script>
</body>
</html>
\ No newline at end of file
{% block footer %}
{% if message %}
<div class="text-success txt1" id="registrasi">{{ message }}</div>