Fakultas Ilmu Komputer UI

Commit 3801c8aa authored by Izzan Fakhril Islam's avatar Izzan Fakhril Islam
Browse files

Merge branch 'tutorial-7' into 'master'

Tutorial 7 PMPL

See merge request !9
parents 934dbaa4 591cfd83
Pipeline #25384 passed with stages
in 14 minutes and 37 seconds
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
import uuid
# Create your models here.
class TodoList(models.Model):
date = models.DateTimeField(blank=False)
todo_list = models.TextField(max_length=100, blank=False)
def __str__(self):
return "Todo at %s: %s" % (self.date.timestamp(), self.todo_list)
class TodoListCommentary(models.Model):
date = models.DateField(blank=False)
comment = models.TextField(max_length=100, blank=False)
def __str__(self):
return "Commentary at %s: %s" % (self.date.__str__, self.comment)
class Token(models.Model):
email = models.EmailField()
uid = models.CharField(default=uuid.uuid4, max_length=255)
class User(models.Model):
email = models.EmailField(primary_key=True)
REQUIRED_FIELDS = []
USERNAME_FIELD = 'email'
is_anonymous = False
is_authenticated = True
class ListUserManager(BaseUserManager):
def create_user(self, email):
ListUser.objects.create(email=email)
def create_superuser(self, email, password):
self.create_user(email)
class ListUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(primary_key=True)
USERNAME_FIELD = 'email'
objects = ListUserManager()
@property
def is_staff(self):
return self.email == 'izzan.fakhril@ui.ac.id'
@property
def is_active(self):
return True
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Tutorial 2 PMPL">
<meta name="author" content="{{ author }}">
<!-- bootstrap csss -->
<link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
<title>
{% block title %} Tutorial 7 PMPL by {{ author }} - {{ npm }}{% endblock %}
</title>
</head>
<style>
@import url(https://fonts.googleapis.com/css?family=Roboto|Roboto+Slab);
.container, .footer-down, .header-up{
font-family: "Roboto", "sans-serif";
font-weight: normal;
}
</style>
<body style="background-color: darkseagreen">
<header class="header-up">
{% include "tutorial_7/../partials/header.html" %}
</header>
<content>
<div class="container">
{% block content %}
{% endblock %}
</div>
</content>
<footer class="footer-down">
<!-- TODO Block Footer dan include footer.html -->
{% block footer %}
{% include "tutorial_7/../partials/footer.html" %}
{% endblock %}
</footer>
<!-- Jquery n Bootstrap Script -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="application/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>
{% extends "tutorial_7/../layout/base.html" %}
{% block content %}
<h1 align="center" style="font-weight: bold">Verification Email Sent.</h1>
<p>Check your email, you'll find a message with a link that will log you into the site.</p>
{% endblock %}
<p align="center">&copy; {{ author }}</p>
<!-- Fixed navbar -->
<style type = text/css>
.navbar-static-top{
background-color: darkgray;
font-size: 17px;
}
.navbar-brand{
font-size: 17px;
}
</style>
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{% url 'tutorial-7:index' %}" style="color: black">Tutorial 7 PMPL</a>
</div>
</div>
</nav>
{% extends "tutorial_7/../layout/base.html" %}
{% block content %}
<style>
.form-control {
@import url(https://fonts.googleapis.com/css?family=Droid+Sans+Mono);
margin-top: 3px;
margin-bottom: 3px;
font-family: "Droid Sans Mono";
}
table {
text-align: left;
padding: 8px;
width: 100%;
}
</style>
<div class="container" style="color: black; background-color: white; border-radius: 10px">
<br>
{% if user.is_authenticated %}
<p>You are currently logged in as: {{ user.email }}</p>
<button class="btn-danger"><a id="id_logout" style="color: white" href="{% url 'tutorial-7:logout' %}">Log out</a></button>
<br>
{% else %}
<form method="POST" action="{% url 'tutorial-7:send_login_email' %}">
Enter your email to log in: <input id="email" name="email" type="text"/>
{% csrf_token %}
</form>
{% endif %}
<br>
</div>
<br><br>
<h1 align="center" style="font-weight: bold">Your Personal Todo List</h1>
<br><br>
<div class="row">
<div class="col-md-6 col-xs-6">
<h4>Todo List Table</h4>
<br>
<table id="todo_table">
<tr>
<th><h5><b>Date/Time</b></h5></th>
<th><h5><b>Todo</b></h5></th>
</tr>
{% for todos in todos_dict %}
<tr>
<td>{{ todos.date }}</td>
<td>{{ todos.todo_list }}</td>
</tr>
{% endfor %}
</table>
<br>
<h4>Daily Todo List Comments</h4>
<br>
<table id="todo_comment_table">
<tr>
<th><h5><b>Date</b></h5></th>
<th><h5><b>Comment</b></h5></th>
</tr>
{% for commentary in todos_commentary_dict %}
<tr>
<td>{{ commentary.date }}</td>
<td>{{ commentary.comment }}</td>
</tr>
{% endfor %}
</table>
<br>
</div>
<div class="col-md-6 col-xs-6">
<h4><b>Add Todo</b></h4>
<form method="POST" action="{% url 'tutorial-7:add_todo' %}">
{% csrf_token %}
<table>
<tr>
<td>
Date/Time
</td>
<td>
<input type="datetime-local" name="date" id="todo_date" size="27"/>
</td>
</tr>
<tr>
<td>
Todo
</td>
<td>
<input type="text" name="activity" id="activity" size="27">
</td>
</tr>
</table>
<br>
<button type="submit" id="todo_submit" class="button btn-success">Submit</button>
</form>
<br>
<div class="errornote">
<p style="color: black; font-family: 'Roboto Slab'">{{ error_msg }}</p>
</div>
<h4><b>Add Daily Todo List Comment</b></h4>
<form method="POST" action="{% url 'tutorial-7:add_todo_commentary' %}">
{% csrf_token %}
<table>
<tr>
<td>
Date
</td>
<td>
<input type="date" name="date" id="comment_date" size="27"/>
</td>
</tr>
<tr>
<td>
Todo List Comment
</td>
<td>
<input type="text" name="comment" id="comment" size="27">
</td>
</tr>
</table>
<br>
<button type="submit" id="comment_submit" class="button btn-success">Submit</button>
</form>
<br>
<div class="errornote">
<p style="color: black; font-family: 'Roboto Slab'">{{ commentary_error_msg }}</p>
</div>
</div>
</div>
{% endblock %}
from django.conf.urls import url
from .views import index, login, logout, add_todo, add_todo_commentary, send_login_email
urlpatterns = [
url(r'^$', index, name='index'),
url(r'add_todo/$', add_todo, name='add_todo'),
url(r'add_todo_commentary/$', add_todo_commentary, name='add_todo_commentary'),
url(r'^send_email$', send_login_email, name='send_login_email'),
url(r'^login$', login, name='login'),
url(r'^logout$', logout, name='logout')
]
import uuid
import sys
from django.core.exceptions import ValidationError
from django.contrib.auth import authenticate
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout
from django.shortcuts import render, redirect
from .models import TodoList, TodoListCommentary, Token
from datetime import datetime
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.core.mail import send_mail
# Create your views here.
todo = {}
todo_commentary = {}
HTML_FILE = "tutorial_7.html"
EMAIL_SENT_HTML_FILE = "login_email_sent.html"
URL = "/tutorial-7/"
response = {
'author': 'Izzan Fakhril Islam',
'author_npm': '1606875806',
}
def index(request):
todo_dict = TodoList.objects.all().values()
todo_commentary_dict = TodoListCommentary.objects.all().values()
response['todos_dict'] = convert_queryset_into_json(todo_dict)
response['todos_commentary_dict'] = convert_queryset_into_json(todo_commentary_dict)
return render(request, HTML_FILE, response)
def login(request):
print('Login View', file=sys.stderr)
uid = request.GET.get('uid')
user = authenticate(uid=uid)
if user is not None:
auth_login(request, user)
return redirect('/tutorial-7/')
def logout(request):
auth_logout(request)
return redirect('/tutorial-7/')
def add_todo(request):
if request.method == 'POST':
try:
date = datetime.strptime(request.POST['date'], '%Y-%m-%dT%H:%M')
TodoList.objects.create(
todo_list=request.POST['activity'],
date=date
)
date_request = date.date()
todo_count_by_date = TodoList.objects.filter(date__date=date_request).count()
TodoListCommentary.objects.create(
comment=get_comment(todo_count_by_date),
date=date_request
)
return HttpResponseRedirect(reverse('tutorial-7:index'))
except (ValueError, ValidationError) as e:
todo = TodoList.objects.all().values()
response['error_msg'] = 'ERROR: Failed to add Todo List'
response['todos_dict'] = todo
return render(request, HTML_FILE, response)
def add_todo_commentary(request):
if request.method == 'POST':
try:
date = datetime.strptime(request.POST['date'], '%Y-%m-%d')
TodoListCommentary.objects.create(
comment=request.POST['comment'],
date=date
)
return HttpResponseRedirect(reverse('tutorial-2:index'))
except (ValueError, ValidationError) as e:
print(type(e))
todo_commentary = TodoListCommentary.objects.all().values()
response['commentary_error_msg'] = 'ERROR: Failed to add Todo List Commentary'
response['todos_commentary_dict'] = todo_commentary
return render(request, HTML_FILE, response)
def send_login_email(request):
email = request.POST['email']
uid = str(uuid.uuid4())
Token.objects.create(email=email, uid=uid)
url = request.build_absolute_uri(f'/tutorial-7/login?uid={uid}')
send_mail(
'Your Login Link for Tutorial 7 PMPL',
f'Use this link to log in:\n\n{url}',
'rvd.cena@gmail.com',
[email],
)
return render(request, EMAIL_SENT_HTML_FILE)
def convert_queryset_into_json(queryset_dict):
res = []
for data in queryset_dict:
res.append(data)
return res
def get_comment(count):
if count == 0:
comment = "yey, waktunya berlibur"
elif count < 5:
comment = "sibuk tapi santai"
else:
comment = "oh tidak"
return comment
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