Fakultas Ilmu Komputer UI
Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
PMPL
Class Project
DIGIPUS
Commits
bb5a2dfd
Commit
bb5a2dfd
authored
Oct 31, 2020
by
Anthony Dewa Priyasembada
Browse files
Merge branch '1706979171-82' into 'master'
[
#82
] Reading List See merge request
!88
parents
f7999a2f
599343b4
Pipeline
#60077
failed with stages
in 32 minutes and 15 seconds
Changes
9
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
app/migrations/0027_readlater.py
0 → 100644
View file @
bb5a2dfd
# Generated by Django 3.1 on 2020-10-30 13:26
from
django.conf
import
settings
from
django.db
import
migrations
,
models
import
django.db.models.deletion
import
django.utils.timezone
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
migrations
.
swappable_dependency
(
settings
.
AUTH_USER_MODEL
),
(
'app'
,
'0027_auto_20201030_1648'
),
]
operations
=
[
migrations
.
CreateModel
(
name
=
'ReadLater'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
auto_created
=
True
,
primary_key
=
True
,
serialize
=
False
,
verbose_name
=
'ID'
)),
(
'timestamp'
,
models
.
DateTimeField
(
default
=
django
.
utils
.
timezone
.
now
)),
(
'materi'
,
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
CASCADE
,
to
=
'app.materi'
)),
(
'user'
,
models
.
ForeignKey
(
on_delete
=
django
.
db
.
models
.
deletion
.
CASCADE
,
to
=
settings
.
AUTH_USER_MODEL
)),
],
options
=
{
'unique_together'
:
{(
'materi'
,
'user'
)},
},
),
]
app/models.py
View file @
bb5a2dfd
...
...
@@ -272,3 +272,11 @@ class LaporanMateri(models.Model):
laporan
=
models
.
TextField
(
validators
=
[
MinValueValidator
(
30
),
MaxValueValidator
(
120
)],
default
=
""
)
timestamp
=
models
.
DateTimeField
(
default
=
timezone
.
now
)
is_rejected
=
models
.
BooleanField
(
default
=
False
)
class
ReadLater
(
models
.
Model
):
materi
=
models
.
ForeignKey
(
Materi
,
on_delete
=
models
.
CASCADE
)
user
=
models
.
ForeignKey
(
User
,
on_delete
=
models
.
CASCADE
)
timestamp
=
models
.
DateTimeField
(
default
=
timezone
.
now
)
class
Meta
:
unique_together
=
[
"materi"
,
"user"
]
\ No newline at end of file
app/services.py
View file @
bb5a2dfd
...
...
@@ -15,7 +15,7 @@ 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
ViewStatistics
,
ReadLater
from
app.utils.fileManagementUtil
import
get_random_filename
,
remove_image_exifdata
from
digipus
import
settings
import
requests
...
...
@@ -470,3 +470,18 @@ class GoogleDriveUploadService:
file1
[
"title"
]
=
title
print
(
"title: %s, mimeType: %s"
%
(
file1
[
"title"
],
file1
[
"mimeType"
]))
file1
.
Upload
()
class
ReadLaterService
:
@
staticmethod
def
toggle_read_later
(
materi_id
,
current_user
):
materi
=
get_object_or_404
(
Materi
,
pk
=
materi_id
)
read_later_item_exist
=
ReadLater
.
objects
.
filter
(
materi
=
materi
,
user
=
current_user
).
exists
()
if
read_later_item_exist
:
read_later_item
=
get_object_or_404
(
ReadLater
,
materi
=
materi
,
user
=
current_user
)
read_later_item
.
delete
()
response
=
{
"success"
:
True
,
"read_later_checked"
:
False
}
else
:
ReadLater
(
materi
=
materi
,
user
=
current_user
).
save
()
response
=
{
"success"
:
True
,
"read_later_checked"
:
True
}
return
response
\ No newline at end of file
app/templates/app/detail_materi.html
View file @
bb5a2dfd
...
...
@@ -106,7 +106,7 @@ div.review {
<div
class=
"col col-3 cover"
>
<img
src=
{{materi_data.cover.url}}
alt=
"cover"
>
</div>
<div
class=
"col col-
6
ml-3 book"
>
<div
class=
"col col-
8
ml-3 book"
>
<h2>
{{materi_data.title}}
</h2>
<div
class=
"category-wrapper"
>
{% for category in materi_data.categories.all %}
...
...
@@ -256,12 +256,32 @@ div.review {
</div>
</div>
</div>
{% if is_in_read_later_list %}
<button
class=
"btn btn-book shadow-sm p-2 mr-2 bg-primary text-white rounded align-self-center"
type=
"button"
id=
"readLaterButton"
aria-haspopup=
"true"
aria-expanded=
"false"
onclick=
"postToggleReadLater()"
>
<em
class=
"align-self-center far fa-check-square"
id=
"readLaterText"
></em>
Baca Nanti
</button>
{% else %}
<button
class=
"btn btn-book shadow-sm p-2 mr-2 bg-white text-primary rounded align-self-center"
type=
"button"
id=
"readLaterButton"
aria-haspopup=
"true"
aria-expanded=
"false"
onclick=
"postToggleReadLater()"
>
<em
class=
"align-self-center far fa-square"
id=
"readLaterText"
></em>
Baca Nanti
</button>
{% endif %}
{% else %}
<button
class=
"btn dropdown-toggle btn-book shadow-sm p-2 mr-2 bg-white rounded align-self-center"
type=
"button"
id=
"dropdownMenuButton"
aria-haspopup=
"true"
aria-expanded=
"false"
data-toggle=
"modal"
data-target=
"#notLoggedInModal"
>
<em
class=
"align-self-center far fa-star"
></em>
Beri Rating
</button>
<button
class=
"btn btn-book shadow-sm p-2 mr-2 bg-white text-primary rounded align-self-center"
type=
"button"
id=
"readLaterButton"
aria-haspopup=
"true"
aria-expanded=
"false"
onclick=
"postToggleReadLater()"
>
<em
class=
"align-self-center far fa-square"
id=
"readLaterText"
></em>
Baca Nanti
</button>
{% endif %}
</div>
</div>
...
...
@@ -603,6 +623,37 @@ div.review {
});
}
function
postToggleReadLater
()
{
$
.
ajaxSetup
({
beforeSend
:
function
(
xhr
,
settings
)
{
if
(
!
csrfSafeMethod
(
settings
.
type
)
&&
!
this
.
crossDomain
)
{
xhr
.
setRequestHeader
(
"
X-CSRFToken
"
,
csrftoken
);
}
}
});
$
.
ajax
({
type
:
'
POST
'
,
url
:
"
{% url 'toggle-read-later' %}
"
,
data
:
{
'
materi_id
'
:
"
{{ materi_data.id }}
"
,
},
success
:
changeReadLaterButton
,
dataType
:
'
html
'
});
}
function
changeReadLaterButton
(
data
,
jqXHR
)
{
var
data
=
$
.
parseJSON
(
data
)
if
(
data
[
'
read_later_checked
'
])
{
$
(
'
#readLaterButton
'
).
removeClass
(
"
bg-white text-primary
"
).
addClass
(
"
bg-primary text-white
"
)
$
(
'
#readLaterText
'
).
removeClass
(
"
fa-square
"
).
addClass
(
"
fa-check-square
"
)
}
else
{
$
(
'
#readLaterButton
'
).
removeClass
(
"
bg-primary text-white
"
).
addClass
(
"
bg-white text-primary
"
)
$
(
'
#readLaterText
'
).
removeClass
(
"
fa-check-square
"
).
addClass
(
"
fa-square
"
)
}
}
function
LikePost
(
data
,
jqXHR
)
{
var
data
=
$
.
parseJSON
(
data
)
var
likeCount
=
parseInt
(
$
(
'
.info-content
'
)[
6
].
textContent
)
...
...
app/templates/app/includes/sidebar_profile.html
View file @
bb5a2dfd
...
...
@@ -27,4 +27,9 @@
<a
class=
"nav-link"
href=
"/given-rating/"
>
<span>
Rating Diberikan
</span></a>
</li>
<li
class=
"nav-item"
>
<a
class=
"nav-link"
href=
"/baca-nanti"
>
<span>
Baca Nanti
</span></a>
</li>
</ul>
\ No newline at end of file
app/templates/baca-nanti.html
0 → 100644
View file @
bb5a2dfd
{% extends 'app/base_profile.html' %}
{% load static %}
{% block title %}
<title>
Baca Nanti | Digipus
</title>
{% endblock %}
{% block stylesheets %}
<link
rel=
"stylesheet"
type=
"text/css"
href=
"{% static 'app/css/katalog_materi.css' %}"
>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script
src=
"https://code.jquery.com/jquery-3.5.1.min.js"
integrity=
"sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
crossorigin=
"anonymous"
></script>
<script
src=
"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity=
"sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin=
"anonymous"
></script>
<script
src=
"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity=
"sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin=
"anonymous"
></script>
<!-- Bootstrap core CSS -->
<link
href=
"../../static/app/vendor/bootstrap/css/bootstrap.min.css"
rel=
"stylesheet"
>
<!-- Custom styles for this template -->
<link
href=
"../../static/app/css/heroic-features.css"
rel=
"stylesheet"
>
<link
rel=
"icon"
type=
"image/png"
href=
"{% static 'images/icons/logo.ico' %}"
/>
<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' %}"
>
{% endblock %}
{% block content %}
<div
class=
"container"
>
<div
class=
"col-20"
>
<h1
class=
"mt-2"
>
Daftar Materi Yang Belum Dibaca
</h1>
<hr
class=
"mt-0 mb-4"
>
{% if read_later_list %}
<div
class=
"container row content"
>
<div
class=
"col-20 books"
>
{% for item in read_later_list %}
<div
class=
"card book"
>
<img
src=
{{item.materi.cover.url}}
class=
"card-img-top"
alt=
"cover"
style=
"height:200px; widows: 200px; overflow: hidden;"
></img>
<div
class=
"card-body"
>
<h5
class=
"card-title"
>
{{item.materi.title}}
</h5>
<p
class=
"card-text"
>
{{item.materi.author}}
</p>
<p
class=
"card-text"
>
Diunggah oleh
<a
class=
"card-link"
href=
"{% url 'katalog-per-kontributor' item.materi.uploader.email %}"
>
{{item.materi.uploader.name}}
</a>
</p>
<a
href=
"{% url 'view-materi' item.materi.id %}"
class=
"btn btn-book"
>
Baca
</a>
<a
href=
"{% url 'detail-materi' item.materi.id %}"
class=
"btn btn-book"
>
Detail
</a>
</div>
</div>
{% endfor %}
</div>
</div>
{% else %}
<h1>
Anda Tidak Memiliki Daftar Baca Nanti
</h1>
{% endif %}
</div>
</div>
{% endblock %}
app/tests.py
View file @
bb5a2dfd
...
...
@@ -42,6 +42,7 @@ from .models import (
ReqMaterial
,
RatingContributor
,
ViewStatistics
,
ReadLater
)
from
.services
import
(
...
...
@@ -3444,6 +3445,148 @@ class MateriRecommendationTest(TestCase):
list
=
[
int
(
id
)
for
id
in
re
.
findall
(
r
"Materi\s(\d+)[^\d]"
,
response
.
content
.
decode
())]
self
.
assertEqual
(
list
,
[
1
,
2
])
class
BacaNantiTest
(
TestCase
):
def
setUp
(
self
):
self
.
contributor_credential
=
{
"email"
:
"kontributor@gov.id"
,
"password"
:
id_generator
()
}
self
.
user_one_credential
=
{
"email"
:
"user_one@user.id"
,
"password"
:
id_generator
()
}
self
.
user_two_credential
=
{
"email"
:
"user_two@user.id"
,
"password"
:
id_generator
()
}
self
.
contributor
=
get_user_model
().
objects
.
create_user
(
**
self
.
contributor_credential
,
name
=
"Kontributor"
,
is_contributor
=
True
)
self
.
user_one
=
get_user_model
().
objects
.
create_user
(
**
self
.
user_one_credential
,
name
=
"User One"
)
self
.
user_two
=
get_user_model
().
objects
.
create_user
(
**
self
.
user_two_credential
,
name
=
"User Two"
)
self
.
cover
=
SimpleUploadedFile
(
"cover.jpg"
,
b
"Test file"
)
self
.
content
=
SimpleUploadedFile
(
"content.txt"
,
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
()
Materi
(
title
=
"Materi Dua"
,
author
=
"Author"
,
uploader
=
self
.
contributor
,
publisher
=
"Publisher"
,
descriptions
=
"Deskripsi Materi Dua"
,
status
=
"APPROVE"
,
cover
=
self
.
cover
,
content
=
self
.
content
).
save
()
self
.
materi1
=
Materi
.
objects
.
filter
(
title
=
'Materi 1'
).
get
()
self
.
materi2
=
Materi
.
objects
.
filter
(
title
=
'Materi Dua'
).
get
()
self
.
url
=
'/baca-nanti/'
self
.
toggle_url
=
'/baca-nanti-toggle/'
self
.
url_materi
=
'/materi/{}/'
.
format
(
self
.
materi1
.
id
)
def
test_readlater_object_can_be_created
(
self
):
ReadLater
(
materi
=
self
.
materi1
,
user
=
self
.
user_one
).
save
()
read_later
=
ReadLater
.
objects
.
first
()
self
.
assertEqual
(
read_later
.
materi
,
self
.
materi1
)
self
.
assertEqual
(
read_later
.
user
,
self
.
user_one
)
def
test_readlater_materi_must_not_unique
(
self
):
ReadLater
(
materi
=
self
.
materi1
,
user
=
self
.
user_one
).
save
()
ReadLater
(
materi
=
self
.
materi1
,
user
=
self
.
user_two
).
save
()
read_later_one
=
ReadLater
.
objects
.
get
(
user
=
self
.
user_one
)
read_later_two
=
ReadLater
.
objects
.
get
(
user
=
self
.
user_two
)
self
.
assertEqual
(
read_later_one
.
materi
,
self
.
materi1
)
self
.
assertEqual
(
read_later_one
.
user
,
self
.
user_one
)
self
.
assertEqual
(
read_later_two
.
materi
,
self
.
materi1
)
self
.
assertEqual
(
read_later_two
.
user
,
self
.
user_two
)
def
test_readlater_user_must_not_unique
(
self
):
ReadLater
(
materi
=
self
.
materi1
,
user
=
self
.
user_one
).
save
()
ReadLater
(
materi
=
self
.
materi2
,
user
=
self
.
user_one
).
save
()
read_later_one
=
ReadLater
.
objects
.
get
(
materi
=
self
.
materi1
)
read_later_two
=
ReadLater
.
objects
.
get
(
materi
=
self
.
materi2
)
self
.
assertEqual
(
read_later_one
.
materi
,
self
.
materi1
)
self
.
assertEqual
(
read_later_one
.
user
,
self
.
user_one
)
self
.
assertEqual
(
read_later_two
.
materi
,
self
.
materi2
)
self
.
assertEqual
(
read_later_two
.
user
,
self
.
user_one
)
def
test_readlater_materi_combined_with_user_must_be_unique
(
self
):
with
self
.
assertRaises
(
IntegrityError
)
as
context
:
ReadLater
(
materi
=
self
.
materi1
,
user
=
self
.
user_one
).
save
()
ReadLater
(
materi
=
self
.
materi1
,
user
=
self
.
user_one
).
save
()
self
.
assertTrue
(
'already exists'
in
str
(
context
.
exception
))
def
test_readlater_materi_cant_null
(
self
):
with
self
.
assertRaises
(
IntegrityError
):
ReadLater
(
user
=
self
.
user_one
).
save
()
def
test_readlater_user_cant_null
(
self
):
with
self
.
assertRaises
(
IntegrityError
):
ReadLater
(
materi
=
self
.
materi1
).
save
()
def
test_readlater_profile_page_url_exist
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
response
=
self
.
client
.
get
(
self
.
url
)
self
.
assertEqual
(
response
.
status_code
,
200
)
def
test_readlater_profile_page_using_template
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
response
=
self
.
client
.
get
(
self
.
url
)
self
.
assertTemplateUsed
(
response
=
response
,
template_name
=
"baca-nanti.html"
)
def
test_toggle_readlater_url_exist
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
response
=
self
.
client
.
post
(
self
.
toggle_url
,
{
'materi_id'
:
self
.
materi1
.
id
})
self
.
assertEqual
(
response
.
status_code
,
200
)
def
test_checking_readlater_in_materi_create_object
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
self
.
client
.
post
(
self
.
toggle_url
,
{
'materi_id'
:
self
.
materi1
.
id
})
read_later_exist
=
ReadLater
.
objects
.
filter
(
materi
=
self
.
materi1
,
user
=
self
.
user_one
).
exists
()
self
.
assertEqual
(
read_later_exist
,
True
)
def
test_unchecking_readlater_in_materi_delete_object
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
self
.
client
.
post
(
self
.
toggle_url
,
{
'materi_id'
:
self
.
materi1
.
id
})
sleep
(
1
)
self
.
client
.
post
(
self
.
toggle_url
,
{
'materi_id'
:
self
.
materi1
.
id
})
read_later_exist
=
ReadLater
.
objects
.
filter
(
materi
=
self
.
materi1
,
user
=
self
.
user_one
).
exists
()
self
.
assertEqual
(
read_later_exist
,
False
)
def
test_checking_readlater_in_materi_with_complete_paramater_return_success
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
response
=
self
.
client
.
post
(
self
.
toggle_url
,
{
'materi_id'
:
self
.
materi1
.
id
})
self
.
assertJSONEqual
(
str
(
response
.
content
,
encoding
=
'utf-8'
),
{
"success"
:
True
,
"read_later_checked"
:
True
}
)
def
test_unchecking_readlater_in_materi_with_complete_paramater_return_success
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
self
.
client
.
post
(
self
.
toggle_url
,
{
'materi_id'
:
self
.
materi1
.
id
})
sleep
(
1
)
response
=
self
.
client
.
post
(
self
.
toggle_url
,
{
'materi_id'
:
self
.
materi1
.
id
})
self
.
assertJSONEqual
(
str
(
response
.
content
,
encoding
=
'utf-8'
),
{
"success"
:
True
,
"read_later_checked"
:
False
}
)
def
test_toggle_readlater_return_if_method_snot_post
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
response
=
self
.
client
.
get
(
self
.
toggle_url
,
{
'materi_id'
:
self
.
materi1
.
id
})
self
.
assertJSONEqual
(
str
(
response
.
content
,
encoding
=
'utf-8'
),
{
"success"
:
False
,
"msg"
:
"Unsuported method"
}
)
def
test_toggle_readlater_return_if_paramater_materi_id_not_found
(
self
):
self
.
client
.
login
(
**
self
.
user_one_credential
)
response
=
self
.
client
.
post
(
self
.
toggle_url
)
self
.
assertJSONEqual
(
str
(
response
.
content
,
encoding
=
'utf-8'
),
{
"success"
:
False
,
"msg"
:
"Missing parameter"
}
)
class
MateriStatsTest
(
TestCase
):
def
setUp
(
self
):
...
...
app/urls.py
View file @
bb5a2dfd
...
...
@@ -5,7 +5,8 @@ from app import views
from
app.views
import
(
DashboardKontributorView
,
ProfilView
,
StatisticsView
,
SuksesLoginAdminView
,
SuksesLoginKontributorView
,
DownloadHistoryView
,
SuntingProfilView
,
UploadMateriHTML
,
UploadMateriView
,
UploadMateriExcelView
,
PostsView
,
ReqMateriView
,
KatalogPerKontributorView
,
MateriFavorite
,
PasswordChangeViews
,
password_success
,
SubmitVisitorView
)
ReqMateriView
,
KatalogPerKontributorView
,
MateriFavorite
,
PasswordChangeViews
,
password_success
,
SubmitVisitorView
,
ReadLaterView
)
urlpatterns
=
[
...
...
@@ -41,5 +42,7 @@ urlpatterns = [
path
(
"password_success/"
,
views
.
password_success
,
name
=
"password_success"
),
path
(
"given-rating/"
,
views
.
see_given_rating
,
name
=
"see_given_rating"
),
path
(
"submit-visitor/"
,
SubmitVisitorView
.
as_view
(),
name
=
"submit-visitor"
),
path
(
"baca-nanti/"
,
ReadLaterView
.
as_view
(),
name
=
"read-later"
),
path
(
"baca-nanti-toggle/"
,
views
.
toggle_readlater
,
name
=
"toggle-read-later"
),
path
(
"stats/"
,
StatisticsView
.
as_view
(),
name
=
"stats"
),
]
app/views.py
View file @
bb5a2dfd
...
...
@@ -31,12 +31,13 @@ from app.models import (
Materi
,
ReqMaterial
,
Rating
,
RatingContributor
,
SubmitVisitor
SubmitVisitor
,
ReadLater
)
from
authentication.models
import
User
from
.services
import
DafterKatalogService
,
DetailMateriService
,
LikeDislikeService
,
MateriFieldValidationHelperService
,
\
DownloadViewMateriHelperService
,
UploadMateriService
,
EditProfileService
,
RevisiMateriService
,
\
DownloadHistoryService
,
GoogleDriveUploadService
DownloadHistoryService
,
GoogleDriveUploadService
,
ReadLaterService
def
permission_denied
(
request
,
exception
,
template_name
=
"error_403.html"
):
...
...
@@ -154,6 +155,12 @@ class DetailMateri(TemplateView):
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
...
...
@@ -781,6 +788,34 @@ class SubmitVisitorView(TemplateView):
SubmitVisitor
(
msg
=
title
,
user_id
=
user_id
,
email
=
email
).
save
()
return
JsonResponse
({
"success"
:
True
,
"msg"
:
"Buku tamu berhasil ditambahkan"
})
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"
})
return
JsonResponse
(
ReadLaterService
.
toggle_read_later
(
materi_id
,
request
.
user
))
else
:
return
JsonResponse
({
"success"
:
False
,
"msg"
:
"Unsuported method"
})
class
StatisticsView
(
TemplateView
):
template_name
=
"statistik.html"
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment