Skip to content

Commit d0006af

Browse files
Added documentation
1 parent 9920902 commit d0006af

File tree

4 files changed

+107
-19
lines changed

4 files changed

+107
-19
lines changed

certificate_generator/README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Certificate Generator
2+
3+
## Table of Contents
4+
5+
- [Folder Structure](#folder-structure)
6+
- [Requirements](#requirements)
7+
- [Approach](#approach)
8+
9+
## Folder Structure
10+
11+
```plain
12+
│ README.md
13+
│ requirements.txt
14+
│ run.py # To run the web app
15+
16+
└───app
17+
│ routes.py # Contains routes
18+
│ utils.py # Contains generate_certifcate() function
19+
│ __init__.py
20+
21+
├───static # Contains necessary static files
22+
│ └───certificates
23+
│ ├───generated # Stores generated certificates
24+
│ │ Shreyas Vedpathak.png # sample certificate
25+
│ │
26+
│ └───template # Contains neccesary required files
27+
│ Sanchez-Regular.ttf # Font
28+
│ template.png # Template for certificate
29+
30+
└───templates # HTML files for frontend
31+
certificate.html
32+
download.html
33+
home.html
34+
```
35+
36+
## Requirements
37+
38+
- Flask==1.1.2
39+
- Pillow==8.3.1
40+
41+
## Approach
42+
43+
1. We get the user name and pr number from the form in `certificate.html`.
44+
2. We use the received information to generate and save the certificate using `generate_certificate()` function in `app/utils.py`.
45+
3. Finally, we render that certificate using `download.html` and we provide the option of downloading, and generate again.

certificate_generator/app/routes.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,52 @@
1+
# External Imports
2+
import os
3+
from flask import render_template, request, send_file
4+
5+
# Internal Imports
16
from app import app
27
from app.utils import generate_certificate
3-
from flask import render_template, request, send_file
4-
import os
58

69

710
@app.after_request
811
def add_header(r):
912
"""
10-
Add headers to both force latest IE rendering engine or Chrome Frame,
11-
and also to cache the rendered page for 10 minutes.
13+
Prevents caching, which will make sure old files are not sent.
1214
"""
1315
r.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
1416
r.headers["Pragma"] = "no-cache"
1517
r.headers["Expires"] = "0"
1618
r.headers['Cache-Control'] = 'public, max-age=0'
1719
return r
1820

21+
1922
@app.route('/', methods=['GET', 'POST'])
2023
def home():
21-
return render_template("certificate.html")
24+
'''home
25+
Renders home page
26+
'''
27+
return render_template("certificate.html")
2228

2329

2430
@app.route('/render', methods=['POST'])
2531
def render_certificate():
32+
"""
33+
Get's information from user and generates
34+
the certificate using generate_certificate function
35+
"""
2636
if request.method == "POST":
27-
file_name = generate_certificate(request.form['name'], request.form['pr_num'])
37+
file_name = generate_certificate(
38+
request.form['name'],
39+
request.form['pr_num'])
2840
return render_template('download.html', file_name=file_name)
2941

42+
3043
@app.route('/download_certificate', methods=['GET'])
3144
def download():
45+
"""
46+
Download the generated certificate
47+
"""
3248
if request.method == "GET":
3349
filename = request.args.get("filename")
3450
filepath = os.path.join("static/certificates/generated", filename)
35-
return send_file(filepath, as_attachment=True, cache_timeout=0, attachment_filename=filename)
51+
return send_file(filepath, as_attachment=True, cache_timeout=0,
52+
attachment_filename=filename)

certificate_generator/app/utils.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,61 @@
1+
# External Imports
12
from PIL import Image, ImageFont, ImageDraw
2-
from app import app
33
import os
44

5+
# Internal Imports
6+
from app import app
7+
8+
59
def generate_certificate(name, pr_num):
10+
'''generate_certificate Generates certificate using base template
11+
12+
Args:
13+
name (string): Name to be displayed on certificate
14+
pr_num (integer): PR number to be displayed on certificate
15+
'''
16+
# Path to template certificate
617
template_dir = os.path.join(app.root_path, "static/certificates/template")
718
template_filename = "template.png"
8-
19+
20+
# Path to save the certificate
921
output_dir = os.path.join(app.root_path, "static",
1022
"certificates/generated/")
1123
output_filename = f"{name}.png"
12-
24+
25+
# Load the template file
1326
img = Image.open(os.path.join(template_dir, template_filename))
1427
draw = ImageDraw.Draw(img)
15-
28+
29+
# Text to put on the certificate
1630
event_name = "Hacktoberfest"
1731
contributed_at = "Automation scripts"
1832
msg = f"""for taking part in {event_name} and
1933
contribution in #{pr_num} at {contributed_at}.
2034
"""
21-
22-
name_font = ImageFont.truetype(os.path.join(template_dir, "Sanchez-Regular.ttf"), 150)
23-
msg_font = ImageFont.truetype(os.path.join(template_dir, "Sanchez-Regular.ttf"), 70)
24-
35+
# Load fonts
36+
name_font = ImageFont.truetype(os.path.join(
37+
template_dir, "Sanchez-Regular.ttf"), 150)
38+
msg_font = ImageFont.truetype(os.path.join(
39+
template_dir, "Sanchez-Regular.ttf"), 70)
40+
41+
# Insert text (Name)
2542
draw.text((1000, 1390), name, (51, 213, 172), font=name_font)
43+
# Insert text (Message)
2644
draw.text((1000, 1650), msg, (14, 69, 115), font=msg_font)
27-
45+
46+
# Calculate the width of the texts. We will need it to
47+
# draw the underline. As the pr number width can vary we cannot
48+
# hardcode the coordinates of the text to be underlined.
49+
# So we find the width of the pr_num and then calculate
50+
# the starting position of the underlined text.
2851
twidth, theight = draw.textsize(contributed_at, font=msg_font)
2952
prwidth, prheight = draw.textsize(pr_num, font=msg_font)
30-
53+
3154
lx = 1560 + prwidth + 120
3255
ly = 1810
3356
draw.line((lx, ly, lx + twidth, ly), fill=(14, 69, 115), width=5)
34-
57+
58+
# Save certificate
3559
img.save(os.path.join(output_dir, output_filename))
36-
60+
# Return filename, required for rendering the certificate
3761
return output_filename
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Flask==1.1.2
2+
Pillow==8.3.1

0 commit comments

Comments
 (0)