From eb814cf1d31e83b027cbe33471f30f2194706e3a Mon Sep 17 00:00:00 2001 From: Muhammad Faraz Maqsood Date: Wed, 24 Jul 2024 18:32:49 +0500 Subject: [PATCH] feat: convert html template to pdf using pdfkit --- lms/djangoapps/certificates/views/webview.py | 24 +- .../sass/_sdaia-template_test.scss | 272 +++++++++++++++++ lms/templates/certificates/valid.html | 278 +++++++++++++++++- 3 files changed, 555 insertions(+), 19 deletions(-) create mode 100644 lms/static/certificates/sass/_sdaia-template_test.scss diff --git a/lms/djangoapps/certificates/views/webview.py b/lms/djangoapps/certificates/views/webview.py index ff2c665dd642..1b102f205e5b 100644 --- a/lms/djangoapps/certificates/views/webview.py +++ b/lms/djangoapps/certificates/views/webview.py @@ -8,11 +8,13 @@ from datetime import datetime from uuid import uuid4 +import pdfkit import pytz from django.conf import settings from django.contrib.auth.decorators import login_required from django.http import Http404, HttpResponse, HttpResponseRedirect from django.template import RequestContext +from django.template.loader import render_to_string from django.utils import translation from django.utils.encoding import smart_str from eventtracking import tracker @@ -755,7 +757,7 @@ def _render_invalid_certificate(request, course_id, platform_name, configuration def _render_valid_certificate(request, context, custom_template=None): """ - Renders certificate + Renders certificate as a PDF """ if custom_template: template = Template( @@ -766,6 +768,22 @@ def _render_valid_certificate(request, context, custom_template=None): encoding_errors='replace', ) context = RequestContext(request, context) - return HttpResponse(template.render(context)) + html_content = template.render(context) else: - return render_to_response("certificates/valid.html", context) + html_content = render_to_string("certificates/valid.html", context, request=request) + + path_wkhtmltopdf = '/usr/bin/wkhtmltopdf' + config = pdfkit.configuration(wkhtmltopdf=path_wkhtmltopdf) + + options = { + 'page-height': '200mm', + 'page-width': '297mm', + } + pdf = pdfkit.from_string(html_content, False, configuration=config, options=options) # Set output path to False to get a byte string + + response = HttpResponse(pdf, content_type='application/pdf') + response['Content-Disposition'] = 'attachment; filename="certificate.pdf"' + + ## TO-DO save it to GeneratedCertificate Model according to flow here or at the time of certificate creation + ## So that it can be sent to IBRAM - SDAIA + return response diff --git a/lms/static/certificates/sass/_sdaia-template_test.scss b/lms/static/certificates/sass/_sdaia-template_test.scss new file mode 100644 index 000000000000..6f1c7e47bc7f --- /dev/null +++ b/lms/static/certificates/sass/_sdaia-template_test.scss @@ -0,0 +1,272 @@ +html { + -webkit-text-size-adjust: 100%; /* 2 */ +} + +@font-face { + font-family: 'Diodrum'; + font-weight: 200; + src: url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicExtralight.ttf'); + src: + url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicExtralight.ttf') format('truetype'); +} + +@font-face { + font-family: 'Diodrum'; + font-weight: 300; + src: url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicLight.ttf'); + src: + url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicLight.ttf') format('truetype'); +} + +@font-face { + font-family: 'Diodrum'; + font-weight: 400; + src: url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicRegular.ttf'); + src: + url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicRegular.ttf') format('truetype'); +} + +@font-face { + font-family: 'Diodrum'; + font-weight: 500; + src: url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicMedium.ttf'); + src: + url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicMedium.ttf') format('truetype'); +} + +@font-face { + font-family: 'Diodrum'; + font-weight: 600; + src: url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicSemibold.ttf'); + src: + url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicSemibold.ttf') format('truetype'); +} + +@font-face { + font-family: 'Diodrum'; + font-weight: 700; + src: url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicBold.ttf'); + src: + url('http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@DiodrumArabicBold.ttf') format('truetype'); +} + +* { + margin: 0; + padding: 0; +} +.primary-color { + color: #32b994; +} +.black-color { + color: #1c355e; +} +.flex-small { + display: flex; + flex-shrink: 0; + gap: 4px; +} +.text-align{ + text-align: right; +} +.diodrumFontFamily{ + font-family: Diodrum; + font-weight: 500; +} +.stronger{ + font-weight: 700; +} +.certificateWrapper { + background: url("http://local.overhang.io:8000/asset-v1:Arbisoft+SE001+2024_S1+type@asset+block@certificatebg.png") no-repeat; + padding: 130px 12% 150px; + background-size: 100% 100%; + display: flex; + flex-direction: column; + gap: 60px; + + .sdaia-academy-logo { + width: 240px; + } + .sdaia-logo { + width: 190px; + } + + &__bodywraper { + width: 100%; + max-width: 1100px; + margin: 0 auto; + display: flex; + flex-direction: column; + gap: 30px; + } + &__header { + display: flex; + justify-content: space-between; + gap: 10px; + } + + &__mainTitleWrap { + text-align: center; + color: #32b994; + display: flex; + flex-direction: column; + font-size: 45px; + } + &__titleAr { + font-weight: 100; + } + &__title { + font-weight: bold; + } + + &__subTitleWrap { + display: flex; + justify-content: space-between; + font-size: 22px; + color: #1c355e; + font-weight: bold; + flex-direction: column; + } + &__personName { + font-size: 30px; + } + &__subTitleBody, + &__personWrap, + &__innerDetailWrap { + display: flex; + justify-content: space-between; + gap: 10px; + } + &__innerDetailWrap { + font-size: 18px; + } + &__topWrapper { + display: flex; + flex-direction: column; + gap: 50px; + } + &__list { + display: flex; + gap: 10px; + justify-content: space-between; + font-size: 20px; + color: #1c355e; + } + &__listWraper { + display: flex; + flex-direction: column; + } + + &__valueListWrap { + display: flex; + flex-direction: column; + } + @media only screen and (max-width: 1200px) { + gap: 20px; + .sdaia-academy-logo { + width: 200px; + } + .sdaia-logo { + width: 160px; + } + + &__list { + font-size: 18px; + } + + &__mainTitleWrap { + font-size: 25px; + } + &__bodywraper { + gap: 25px; + } + &__subTitleWrap { + font-size: 18px; + } + &__personName { + font-size: 26px; + } + } + + @media only screen and (max-width: 992px) { + padding: 100px 11%; + .sdaia-academy-logo { + width: 1700px; + } + .sdaia-logo { + width: 150px; + } + &__topWrapper { + gap: 30px; + } + &__bodywraper { + gap: 20px; + } + } + + @media only screen and (max-width: 768px) { + padding: 70px 11%; + &__topWrapper { + gap: 20px; + } + .sdaia-academy-logo { + width: 150px; + } + .sdaia-logo { + width: 120px; + } + + &__list { + font-size: 14px; + } + + &__mainTitleWrap { + font-size: 20px; + } + &__bodywraper { + gap: 20px; + } + &__subTitleWrap, + &__innerDetailWrap { + font-size: 15px; + } + } + + @media only screen and (max-width: 556px) { + padding: 60px 13%; + gap: 15px; + + .sdaia-academy-logo { + width: 100px; + } + .sdaia-logo { + width: 80px; + } + &__bodywraper, + &__topWrapper { + gap: 10px; + } + + &__mainTitleWrap { + font-size: 18px; + } + &__subTitleWrap, + &__list, + &__innerDetailWrap { + font-size: 12px; + } + &__list{ + gap: 5px; + } + &__personName { + font-size: 22px; + } + } +} + +[dir="rtl"] { + .certificateWrapper { + .text-align{ + text-align: left; + } + } +} diff --git a/lms/templates/certificates/valid.html b/lms/templates/certificates/valid.html index 4e89b0f25157..a43044972532 100644 --- a/lms/templates/certificates/valid.html +++ b/lms/templates/certificates/valid.html @@ -1,16 +1,262 @@ -<%page expression_filter="h"/> -<%inherit file="accomplishment-base.html" /> -<%! from django.utils.translation import ugettext as _ %> - -% if user.is_authenticated and user.id == int(accomplishment_user_id): -<%include file="_accomplishment-banner.html" /> -% endif -<%include file="_accomplishment-introduction.html" /> - -<%include file="_accomplishment-rendering.html" /> -
- -
+ + + + + + + + SDAIA Academy - Certificate of completion + + + + + + +
+
+ + +
+
+
+

+
شهادة إتمام دورة تدريبية +
+
Training Course Completion Certificate
+

+ +
+
+
+ Saudi Data and AI Authority (SDAIA) Certifies that +
+
+ الهيئة السعودية للبيانات والذكاء الاصطناعي ( سدايا ) تمنح +
+
+
+ + +
+
+
+
+
+
+
+ Has Completed the Training Course + شهادة إتمام الدورة التدريبية +
+
+ + +
+
+
+
+ + Consisting of + ({{course_duration}}) + hours + ساعة تدريبية({{arabic_course_duration}})بمعدل + +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file