summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrathamesh2023-12-27 14:44:20 +0530
committerPrathamesh2023-12-27 14:45:06 +0530
commitfa1e7cf9320d8124efe70a9f4ab093d314acf178 (patch)
tree1f84320ba3d5382cffab71db6bdeaaea3da62c7a
parent7e6b8ebb54f3921f1aa28cbea69904b9737a8d69 (diff)
downloadcertificate-generation-fa1e7cf9320d8124efe70a9f4ab093d314acf178.tar.gz
certificate-generation-fa1e7cf9320d8124efe70a9f4ab093d314acf178.tar.bz2
certificate-generation-fa1e7cf9320d8124efe70a9f4ab093d314acf178.zip
Change UI
-rw-r--r--.gitignore1
-rw-r--r--website/cgen/generator.py2
-rw-r--r--website/cgen/models.py9
-rw-r--r--[-rwxr-xr-x]website/cgen/templates/base.html157
-rw-r--r--website/cgen/templates/download.html53
-rw-r--r--website/cgen/templates/index.html90
-rwxr-xr-xwebsite/cgen/templates/verification.html55
-rw-r--r--website/cgen/verification.py3
-rw-r--r--website/cgen/views.py10
-rw-r--r--website/website/settings.py5
10 files changed, 274 insertions, 111 deletions
diff --git a/.gitignore b/.gitignore
index a0c9ca2..c1036fe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ __pycache__
local.py
*.pyc
*.swp
+certificates
diff --git a/website/cgen/generator.py b/website/cgen/generator.py
index cd55f7f..b894c93 100644
--- a/website/cgen/generator.py
+++ b/website/cgen/generator.py
@@ -36,7 +36,7 @@ def get_details(certificate_id, email):
info['serial_key'] = key
info['qr_code'] = f'{DOMAIN}/certificates/verify/{key}/'
certificate_details['info'] = info
- path = f'{settings.BASE_DIR}/{certificate.id}'
+ path = f'{settings.BASE_DIR}/certificates/{certificate.id}'
certificate_details['path'] = path
if not os.path.exists(f"path/{{Makefile}}"):
shutil.copy2(f'{settings.BASE_DIR}/Makefile', path)
diff --git a/website/cgen/models.py b/website/cgen/models.py
index 30bb762..e367ae3 100644
--- a/website/cgen/models.py
+++ b/website/cgen/models.py
@@ -1,6 +1,7 @@
from django.db import models, IntegrityError
from django.utils import timezone
from django.contrib.auth.models import User
+from django.conf import settings
import os
import hashlib
@@ -11,13 +12,13 @@ types = (
)
# Create your models here.
-
-
def get_file_dir(instance, filename):
- return os.sep.join((str(instance.id), filename))
+ if not os.path.exists(settings.CERTIFICATES_PATH):
+ os.mkdir(settings.CERTIFICATES_PATH)
+ return os.sep.join(('certificates', str(instance.id), filename))
def get_certificate_dir(instance, filename):
- return os.sep.join((str(instance.participant.certificate.id), str(instance.id), filename))
+ return os.sep.join(('certificates', str(instance.participant.certificate.id), str(instance.id), filename))
class Event(models.Model):
"""
diff --git a/website/cgen/templates/base.html b/website/cgen/templates/base.html
index 69190e8..4e6bd11 100755..100644
--- a/website/cgen/templates/base.html
+++ b/website/cgen/templates/base.html
@@ -1,57 +1,104 @@
-<html>
-<link rel="icon" href="https://fossee.in/sites/all/themes/software_responsive_theme/favicon.ico" type="image/vnd.microsoft.icon"/>
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
- <head>
- <title>
- {% block title %}
- Certificates
- {% endblock %}
- </title>
- {% block css %}
- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
- {% endblock %}
- {% block js %}
- <script src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
- {% endblock %}
- {% block javascript %}
- <!-- overide with custom javascript -->
+<!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">
+ <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
+ <meta name="description" content="">
+ <meta name="author" content="">
+ <link rel="icon" href="../../favicon.ico">
+
+ <title>
+ {% block title %}
+ Certificates
{% endblock %}
- </head>
- <body>
- <div class="container-full">
-<nav class="navbar navbar-dark bg-dark">
- <a class="navbar-brand" href="{% url 'events' %}">Events</a>
-</nav>
- <div class="row">
-
- <div class="col-lg-12 text-center v-center">
- {% block header%}
-
- {% endblock %}
- {% block content %}
- {% endblock %}
- </div>
-
- </div> <!-- /row -->
- <hr>
- <br>
- <div id="footer-wrapper" class="container">
- <div id="footer-inner" class="col-lg-12 col-md-12 col-sm-12">
- <div class="pull-left">
- <!--[if lte IE 8]><span style="filter: FlipH; -ms-filter: "FlipH"; display: inline-block;"><![endif]-->
- <span style="-moz-transform: scaleX(-1); -o-transform: scaleX(-1); -webkit-transform: scaleX(-1); transform: scaleX(-1); display: inline-block;">
- <!--<a href="http://www.gnu.org/copyleft/" target="_blank">&copy;</a>-->
- </span>
- <!--[if lte IE 8]></span><![endif]-->
- <!--2013 <a href="http://fossee.in" target="_blank">fossee.in</a>-->
- </div>
- <div class="pull-right">
- Developed at IIT Bombay
- </div>
- </div> <!-- /#footer-inner -->
- </div> <!-- /#footer-wrapper -->
- </div> <!-- /container full -->
- </body>
-</html>
+ </title>
+
+ <!-- Bootstrap core CSS -->
+ {% block css %}
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
+ {% endblock %}
+ {% block js %}
+ <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
+<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" integrity="sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+" crossorigin="anonymous"></script>
+ <script src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
+ {% endblock %}
+ {% block javascript %}
+ <!-- overide with custom javascript -->
+ {% endblock %}
+
+ {% block head %}
+ {% endblock %}
+ </head>
+
+ <body>
+
+<header>
+ <div class="collapse bg-dark" id="navbarHeader">
+ <div class="container">
+ <div class="row">
+ <div class="col-sm-8 col-md-7 py-4">
+ <h4 class="text-white">About</h4>
+ <p class="text-muted"> Cgen is a certificate generator.<br>It allows you to download your certificates. </p>
+ </div>
+ <div class="col-sm-4 offset-md-1 py-4">
+ <h4 class="text-white">Contact</h4>
+ <ul class="list-unstyled">
+ <li><a href="#" class="text-white">Email me</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="navbar navbar-dark bg-dark shadow-sm">
+ <div class="container">
+ <a href="{% url 'events' %}" class="navbar-brand d-flex align-items-center">
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true" class="me-2" viewBox="0 0 24 24"><circle cx="12" cy="13" r="4"/></svg>
+ <strong>Cgen</strong>
+ </a>
+ <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarHeader" aria-controls="navbarHeader" aria-expanded="false" aria-label="Toggle navigation">
+ <span class="navbar-toggler-icon"></span>
+ </button>
+ </div>
+ </div>
+</header>
+
+<main>
+ <section class="py-5 text-center container">
+ <div class="row py-lg-5">
+ <div class="col-lg-6 col-md-8 mx-auto">
+ <h1 class="fw-light">{% block header %} {% endblock %}</h1>
+ <p class="lead text-muted">{% block header_content %} {% endblock %}</p>
+ </p>
+ </div>
+ </div>
+ </section>
+
+ <div class="album py-5 bg-light">
+ <div class="container">
+ {% block content %}
+ {% endblock %}
+ </div>
+ </div>
+ </div>
+
+</main>
+
+<footer class="text-muted py-5">
+ <div class="container">
+ <p class="float-end mb-1">
+ <a href="#">Back to top</a>
+ </p>
+ <p class="mb-1">Cgen created at &copy; FOSSEE, IIT BOMBAY 2023</p>
+ </div>
+ <p></p>
+</footer>
+
+
+
+
+ </body>
+</html>
diff --git a/website/cgen/templates/download.html b/website/cgen/templates/download.html
index 11f3c2a..afa8117 100644
--- a/website/cgen/templates/download.html
+++ b/website/cgen/templates/download.html
@@ -1,30 +1,39 @@
{% extends 'base.html' %}
{% block header%}
- <h1>{{ certificate.event.name }} Certificates</h1>
+ {{ certificate.event.name }} Certificates
{% endblock %}
{% block content %}
- <div class="modal fade" id="invalidModal" tabindex="-1" role="dialog" aria-labelledby="invalidModalLabel" aria-hidden="true">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
- <h4 class="modal-title" id="invalidModalLabel">Invalid Email</h4>
- </div>
- <div class="modal-body">
+
+ <form style="margin-right:200px; margin-left:200px" action="{% url 'certificate_download' certificate.id %}" method="post">
+ {% csrf_token %}
+ <div class="mb-3">
+ <label for="inputemail" class="form-label">Email address</label>
+ <input type="email" name="email" id="email" class="form-control" id="inputemail" aria-describedby="emailHelp">
+ <div id="emailHelp" class="form-text"> Enter the registered email address.</div>
+ </div>
+ <button type="submit" class="btn btn-primary">Download</button>
+ </form>
+
+
+ <div class="modal" id="invalidModal" tabindex="-1">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title">Invalid Email</h5>
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onClick="$('#invalidModal').hide()"></button>
+ </div>
+ <div class="modal-body">
+ <p>
The requested certificate is unavailable for your email address. Please enter proper email and retry.
- </div>
- </div>
+ </p>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" onClick="$('#invalidModal').hide()">Close</button>
</div>
- </div>
- <form class="col-lg-12" action="{% url 'certificate_download' certificate.id %}" method="post">
- {% csrf_token %}
- {{ message }}
- <div class="input-group" style="width:340px;text-align:center;margin:0 auto;">
- <input style="width:450;" class="form-control input-lg" placeholder="Enter the email address you used for registration" type="text" id="email" name=email>
- <span class="input-group-btn"><button class="btn btn-lg btn-primary" type="submit">Download Certificate</button></span>
</div>
- </form>
- <center><h4>Problem in downloading the certificate? Write to us at <a href="mailto:certificates@fossee.in">certificates[at]fossee[dot]in</a></h4>
+ </div>
+ </div>
+ <!--<center><h4>Problem in downloading the certificate? Write to us at <a href="mailto:certificates@fossee.in">certificates[at]fossee[dot]in</a></h4>-->
{% endblock %}
{% block javascript %}
@@ -34,7 +43,7 @@
email = ""
error = "{{ error }}"
if(error == "True"){
- $("#invalidModal").modal();
+ $("#invalidModal").show();
}
if(value == "paper"){
$('#A').prop('checked', true)
@@ -43,7 +52,7 @@
$('#email').val(email);
notreg = "{{ notregistered }}";
if(notreg == "1"){
- $("#invalidModal").modal();
+ $("#invalidModal").show();
}
$("[name=type]").change(function(){
$("#paper").remove();
diff --git a/website/cgen/templates/index.html b/website/cgen/templates/index.html
new file mode 100644
index 0000000..5dfdbf7
--- /dev/null
+++ b/website/cgen/templates/index.html
@@ -0,0 +1,90 @@
+{% extends 'base.html' %}
+ {% block head %}
+
+ <style>
+ .bd-placeholder-img {
+ font-size: 1.125rem;
+ text-anchor: middle;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ }
+
+ @media (min-width: 768px) {
+ .bd-placeholder-img-lg {
+ font-size: 3.5rem;
+ }
+ }
+
+ .b-example-divider {
+ height: 3rem;
+ background-color: rgba(0, 0, 0, .1);
+ border: solid rgba(0, 0, 0, .15);
+ border-width: 1px 0;
+ box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
+ }
+
+ .b-example-vr {
+ flex-shrink: 0;
+ width: 1.5rem;
+ height: 100vh;
+ }
+
+ .bi {
+ vertical-align: -.125em;
+ fill: currentColor;
+ }
+
+ .nav-scroller {
+ position: relative;
+ z-index: 2;
+ height: 2.75rem;
+ overflow-y: hidden;
+ }
+
+ .nav-scroller .nav {
+ display: flex;
+ flex-wrap: nowrap;
+ padding-bottom: 1rem;
+ margin-top: -1px;
+ overflow-x: auto;
+ text-align: center;
+ white-space: nowrap;
+ -webkit-overflow-scrolling: touch;
+ }
+ </style>
+ {% endblock %}
+
+{% block header %}
+ Certificates available for download.
+{% endblock %}
+
+{% block header_content %}
+ Certificates for the following events and courses are available.
+{% endblock %}
+
+{% block content %}
+ <div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">
+ {% for event in events %}
+ <div class="col">
+ <div class="card shadow-sm">
+ <svg class="bd-placeholder-img card-img-top" width="100%" height="225" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Placeholder: Thumbnail" preserveAspectRatio="xMidYMid slice" focusable="false"><title>Placeholder</title><rect width="100%" height="100%" fill="#55595c"/><text x="50%" y="50%" fill="#eceeef" dy=".3em">{{ event.name }}</text></svg>
+
+ <div class="card-body">
+ <p class="card-text">{{ event.name }}</p>
+ {% for certificate in event.certificate_set.all %}
+ <div class="d-flex justify-content-between align-items-center">
+ <p>{{ certificate.description }}
+ <div class="btn-group">
+ <a type="button" href="{% url 'certificate_download' certificate.id %}" class="btn btn-sm btn-outline-secondary">Download</a>
+ <a type="button" href="{% url 'verify' %}" class="btn btn-sm btn-outline-secondary">Verify</a>
+ </div>
+ </div>
+ <small class="text-muted">9 Downloads</small>
+ {% endfor %}
+ </div>
+ </div>
+ </div>
+ {% endfor %}
+ </div>
+{% endblock %}
diff --git a/website/cgen/templates/verification.html b/website/cgen/templates/verification.html
index df33779..ad834a1 100755
--- a/website/cgen/templates/verification.html
+++ b/website/cgen/templates/verification.html
@@ -1,54 +1,57 @@
{% extends 'base.html' %}
{% block header%}
- <h1> Certificate Verification </h1>
+ Certificate Verification
{% endblock %}
{% block content %}
- <div class="modal fade" id="invalidModal" tabindex="-1" role="dialog" aria-labelledby="invalidModalLabel" aria-hidden="true">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
- <h4 class="modal-title" id="invalidModalLabel">Invalid Serial Number</h4>
- </div>
- <div class="modal-body">
+ <div class="modal" id="invalidModal" tabindex="-1">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title">Invalid Serial Key</h5>
+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onClick="$('#invalidModal').hide()"></button>
+ </div>
+ <div class="modal-body">
+ <p>
Sorry ! The serial number you entered seems to be invalid. Please try again !
- </div>
- </div>
+ </p>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" onClick="$('#invalidModal').hide()">Close</button>
</div>
+ </div>
</div>
- <p><b> Enter the alphanumeric characters below the QR code<br> OR <br>Enter the serial number you received while scanning the QR code on certificate</p>
- <hr>
- <form action="{% url 'verify' %}" method="post">
+ </div>
+ <div style="margin-right:200px; margin-left:200px">
+ <p> Enter the alphanumeric characters below the QR code<br> OR <br>Enter the serial number you received while scanning the QR code on certificate</p>
+ <form style="margin-right:200px; margin-left:200px"action="{% url 'verify' %}" method="post">
{% csrf_token %}
- <div class="input-group" style="width:340px;text-align:center;margin:0 auto;">
+ <div class="input-group" >
<input class="form-control input-lg" placeholder="Enter the serial number" type="text" name="key">
<span class="input-group-btn"><button class="btn btn-lg btn-primary" type="submit">Verify</button></span>
</div>
</form>
- <hr>
{% if has_details %}
+ <br>
<div>
- <table class="table table-bordered" align="center" style="width:50%">
- <caption>Details</caption>
+ <caption> Following are the details</caption>
+ <table class="table table-primary table-bordered" >
<tbody>
{% for key, value in details.items %}
<tr>
- <td>{{ key }}</td>
+ <td>{{ key | title }}</td>
<td>{{ value }}</td>
</tr>
{% endfor %}
</tbody>
</table>
- <div style="width:40%"><a href="{% url 'verify' %}" >&lt Back</a></div>
- </div>
-
- <div align="left" style="width:50%" >
+ <div class="bg-white">
{{ description | safe }}
+ </div>
</div>
+
{% endif %}
- <hr>
- <!--<center><h4>Problem in verifying the details ? write to us at <a href="mailto:certificates@fossee.in">certificates[at]fossee[dot]in</a></h4>-->
+ </div>
{% endblock %}
@@ -58,7 +61,7 @@ invalid_serial = {{ invalidserial }}
$( document ).ready(function() {
if(invalid_serial == 1)
{
- $("#invalidModal").modal();
+ $("#invalidModal").show();
}
});
</script>
diff --git a/website/cgen/verification.py b/website/cgen/verification.py
index 2cf026d..bc35078 100644
--- a/website/cgen/verification.py
+++ b/website/cgen/verification.py
@@ -4,7 +4,8 @@ from cgen.models import CertificateManager
def verify(key):
- details = OrderedDict()
+ details = OrderedDict()
+ description = None
try:
cm = CertificateManager.objects.get(serial_key_short=key)
details['Authentic'] = True
diff --git a/website/cgen/views.py b/website/cgen/views.py
index f988e80..1343312 100644
--- a/website/cgen/views.py
+++ b/website/cgen/views.py
@@ -13,7 +13,7 @@ import csv
def events(request):
events = Event.objects.filter(is_published=True)
context = {'events': events}
- return render(request, 'events.html', context)
+ return render(request, 'index.html', context)
# Create your views here.
def certificate_download(request, certificate_id):
@@ -36,13 +36,19 @@ def certificate_download(request, certificate_id):
def verify(request, key=None):
context = {}
+ if key is None and request.method == 'GET':
+ return render(request, 'verification.html', context)
if key is not None:
skey = key
elif request.method == 'POST':
skey = request.POST.get('key').strip()
+
details, description = verification.verify(skey)
+ if not details['Authentic']:
+ context['invalidserial'] = 1
+ return render(request, 'verification.html', context)
+
context['details'] = details
- context['has_details'] = True
context['has_details'] = details['Authentic']
context['description'] = description
return render(request, 'verification.html', context)
diff --git a/website/website/settings.py b/website/website/settings.py
index 1976128..d54ca4d 100644
--- a/website/website/settings.py
+++ b/website/website/settings.py
@@ -124,3 +124,8 @@ TIME_OUT = 15
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
+
+LOGO = "https://www.cep.iitb.ac.in/assets/img/IIT-Logo.png"
+
+CERTIFICATES_PATH = f"settings.BASE_DIR/certificates"
+