We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
When issuing a certificate, the person being certified should be sent an email with a link to their cert


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `django_project/certification/views/certificate.py`
Content:
```
1 # coding=utf-8
2 from django.http import Http404, HttpResponse
3 from django.views.generic import CreateView, DetailView
4 from django.core.urlresolvers import reverse
5 from braces.views import LoginRequiredMixin
6 from reportlab.pdfgen import canvas
7 from reportlab.lib.pagesizes import A4, landscape
8 from reportlab.lib.utils import ImageReader
9 from ..models import Certificate, Course, Attendee
10 from ..forms import CertificateForm
11 from base.models.project import Project
12 
13 
14 class CertificateMixin(object):
15     """Mixin class to provide standard settings for Certificate."""
16 
17     model = Certificate
18     form_class = CertificateForm
19 
20 
21 class CertificateCreateView(
22         LoginRequiredMixin, CertificateMixin, CreateView):
23     """Create view for Certificate."""
24 
25     context_object_name = 'certificate'
26     template_name = 'certificate/create.html'
27 
28     def get_success_url(self):
29         """Define the redirect URL.
30 
31         After successful creation of the object, the User will be redirected
32         to the Course detail page.
33 
34        :returns: URL
35        :rtype: HttpResponse
36        """
37 
38         return reverse('course-detail', kwargs={
39             'project_slug': self.project_slug,
40             'organisation_slug': self.organisation_slug,
41             'slug': self.course_slug
42         })
43 
44     def get_context_data(self, **kwargs):
45         """Get the context data which is passed to a template.
46 
47         :param kwargs: Any arguments to pass to the superclass.
48         :type kwargs: dict
49 
50         :returns: Context data which will be passed to the template.
51         :rtype: dict
52         """
53 
54         context = super(
55             CertificateCreateView, self).get_context_data(**kwargs)
56         context['course'] = Course.objects.get(slug=self.course_slug)
57         context['attendee'] = Attendee.objects.get(pk=self.pk)
58         return context
59 
60     def get_form_kwargs(self):
61         """Get keyword arguments from form.
62 
63         :returns keyword argument from the form
64         :rtype: dict
65         """
66 
67         kwargs = super(CertificateCreateView, self).get_form_kwargs()
68         self.project_slug = self.kwargs.get('project_slug', None)
69         self.organisation_slug = self.kwargs.get('organisation_slug', None)
70         self.course_slug = self.kwargs.get('course_slug', None)
71         self.pk = self.kwargs.get('pk', None)
72         self.course = Course.objects.get(slug=self.course_slug)
73         self.attendee = Attendee.objects.get(pk=self.pk)
74         kwargs.update({
75             'user': self.request.user,
76             'course': self.course,
77             'attendee': self.attendee,
78         })
79         return kwargs
80 
81 
82 class CertificateDetailView(DetailView):
83     """Detail view for Certificate."""
84 
85     model = Certificate
86     context_object_name = 'certificate'
87     template_name = 'certificate/detail.html'
88 
89     def get_context_data(self, **kwargs):
90         """Get the context data which is passed to a template.
91 
92         :param kwargs: Any arguments to pass to the superclass.
93         :type kwargs: dict
94 
95         :returns: Context data which will be passed to the template.
96         :rtype: dict
97         """
98 
99         self.certificateID = self.kwargs.get('id', None)
100         self.project_slug = self.kwargs.get('project_slug', None)
101         context = super(
102             CertificateDetailView, self).get_context_data(**kwargs)
103         issued_id = \
104             Certificate.objects.all().values_list('certificateID', flat=True)
105         if self.certificateID in issued_id:
106             context['certificate'] = \
107                 Certificate.objects.get(certificateID=self.certificateID)
108         context['project_slug'] = self.project_slug
109         return context
110 
111     def get_queryset(self):
112         """Get the queryset for this view.
113 
114         :returns: Queryset which is all certificate in the
115             corresponding organisation.
116         :rtype: QuerySet
117         """
118 
119         qs = Certificate.objects.all()
120         return qs
121 
122     def get_object(self, queryset=None):
123         """Get the object for this view.
124 
125         :param queryset: A query set
126         :type queryset: QuerySet
127 
128         :returns: Queryset which is filtered to only show a certificate
129             depends on the input certificate ID.
130         :rtype: QuerySet
131         :raises: Http404
132         """
133 
134         if queryset is None:
135             queryset = self.get_queryset()
136             certificateID = self.kwargs.get('id', None)
137             if certificateID:
138                 try:
139                     obj = queryset.get(certificateID=certificateID)
140                     return obj
141                 except Certificate.DoesNotExist:
142                     return None
143             else:
144                 raise Http404('Sorry! Certificate by this ID is not exist.')
145 
146 
147 def certificate_pdf_view(request, **kwargs):
148 
149     project_slug = kwargs.pop('project_slug')
150     course_slug = kwargs.pop('course_slug')
151     pk = kwargs.pop('pk')
152     project = Project.objects.get(slug=project_slug)
153     course = Course.objects.get(slug=course_slug)
154     attendee = Attendee.objects.get(pk=pk)
155     certificate = Certificate.objects.get(course=course, attendee=attendee)
156     current_site = request.META['HTTP_HOST']
157 
158     # Create the HttpResponse object with the appropriate PDF headers.
159     response = HttpResponse(content_type='application/pdf')
160     response['Content-Disposition'] = 'filename="certificate.pdf"'
161 
162     # Create the PDF object, using the response object as its "file."
163     page = canvas.Canvas(response, pagesize=landscape(A4))
164     width, height = A4
165     center = height * 0.5
166 
167     if project.image_file:
168         project_logo = ImageReader(project.image_file)
169     else:
170         project_logo = None
171 
172     if course.certifying_organisation.logo:
173         organisation_logo = ImageReader(course.certifying_organisation.logo)
174     else:
175         organisation_logo = None
176 
177     if project.signature:
178         project_owner_signature = ImageReader(project.signature)
179     else:
180         project_owner_signature = None
181 
182     if course.course_convener.signature:
183         convener_signature = ImageReader(course.course_convener.signature)
184     else:
185         convener_signature = None
186 
187     if course.template_certificate:
188         background = ImageReader(course.template_certificate)
189     else:
190         background = None
191 
192     # Certificate margin.
193     margin_right = height - 50
194     margin_left = 50
195     margin_bottom = 50
196     max_left = margin_right - 100
197 
198     # Draw things on the PDF. Here's where the PDF generation happens.
199     # See the ReportLab documentation for the full list of functionality.
200     if background is not None:
201         page.drawImage(
202             background, 0, 0, height=width, width=height,
203             preserveAspectRatio=True, mask='auto')
204     page.setFillColorRGB(0.1, 0.1, 0.1)
205     page.setFont('Times-Roman', 18)
206     # page.drawString(margin_left, 480, project.name)
207     # page.drawRightString(
208     #     (margin_right), 480, course.certifying_organisation.name)
209 
210     if project_logo is not None:
211         page.drawImage(
212             project_logo, 50, 450, width=100, height=100,
213             preserveAspectRatio=True, mask='auto')
214 
215     if organisation_logo is not None:
216         page.drawImage(
217             organisation_logo, max_left, 450, height=100, width=100,
218             preserveAspectRatio=True, anchor='c', mask='auto')
219 
220     page.setFont('Times-Bold', 26)
221     page.drawCentredString(center, 480, 'Certificate of Completion')
222     page.drawCentredString(
223         center, 400, '%s %s' % (attendee.firstname, attendee.surname))
224     page.setFont('Times-Roman', 16)
225     page.drawCentredString(
226         center, 360, 'Has attended and completed the course:')
227     page.setFont('Times-Bold', 20)
228     page.drawCentredString(center, 300, course.course_type.name)
229     page.setFont('Times-Roman', 16)
230     page.drawCentredString(
231         center, 270,
232         'From %s %s %s to %s %s %s'
233         % (course.start_date.day, course.start_date.strftime('%B'),
234            course.start_date.year, course.end_date.day,
235            course.end_date.strftime('%B'), course.end_date.year))
236     page.setFillColorRGB(0.1, 0.1, 0.1)
237     page.drawCentredString(
238         center, 220, 'Convened by %s %s at %s' % (
239             course.course_convener.user.first_name,
240             course.course_convener.user.last_name, course.training_center))
241 
242     if project_owner_signature is not None:
243         page.drawImage(
244             project_owner_signature,
245             (margin_left + 100), (margin_bottom + 70), width=100, height=70,
246             preserveAspectRatio=True, anchor='s', mask='auto')
247 
248     if convener_signature is not None:
249         page.drawImage(
250             convener_signature, (margin_right - 200), (margin_bottom + 70),
251             width=100, height=70, preserveAspectRatio=True, anchor='s',
252             mask='auto')
253 
254     page.setFont('Times-Italic', 12)
255     page.drawCentredString(
256         (margin_left + 150), (margin_bottom + 60),
257         '%s %s' % (project.owner.first_name, project.owner.last_name))
258     page.drawCentredString(
259         (margin_right - 150), (margin_bottom + 60),
260         '%s %s' % (
261             course.course_convener.user.first_name,
262             course.course_convener.user.last_name))
263     page.line(
264         (margin_left + 70), (margin_bottom + 55),
265         (margin_left + 230), (margin_bottom + 55))
266     page.line(
267         (margin_right - 70), (margin_bottom + 55),
268         (margin_right - 230), (margin_bottom + 55))
269     page.setFont('Times-Roman', 13)
270     page.drawCentredString(
271         (margin_left + 150), (margin_bottom + 40), 'Project Owner')
272     page.drawCentredString(
273         (margin_right - 150), (margin_bottom + 40), 'Convener')
274 
275     # Footnotes.
276     page.setFont('Times-Roman', 14)
277     page.drawString(
278         margin_left, margin_bottom - 10, 'ID: %s' % certificate.certificateID)
279     page.setFont('Times-Roman', 8)
280     page.drawString(
281         margin_left, (margin_bottom - 20),
282         'You can verify this certificate by visiting '
283         'http://%s/en/%s/certificate/%s/.'
284         % (current_site, project.slug, certificate.certificateID))
285 
286     # Close the PDF object cleanly.
287     page.showPage()
288     page.save()
289     return response
290
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/django_project/certification/views/certificate.py b/django_project/certification/views/certificate.py
--- a/django_project/certification/views/certificate.py
+++ b/django_project/certification/views/certificate.py
@@ -1,7 +1,11 @@
 # coding=utf-8
-from django.http import Http404, HttpResponse
+from django.http import Http404, HttpResponse, HttpResponseRedirect
 from django.views.generic import CreateView, DetailView
+from django.contrib.sites.models import Site
+from django.core.mail import send_mail
 from django.core.urlresolvers import reverse
+from django.db import IntegrityError
+from django.core.exceptions import ValidationError
 from braces.views import LoginRequiredMixin
 from reportlab.pdfgen import canvas
 from reportlab.lib.pagesizes import A4, landscape
@@ -78,6 +82,60 @@
         })
         return kwargs
 
+    def form_valid(self, form):
+        """Save new created certificate
+
+        :param form
+        :type form
+
+        :returns HttpResponseRedirect object to success_url
+        :rtype: HttpResponseRedirect
+
+        We check that there is no referential integrity error when saving."""
+
+        try:
+            super(CertificateCreateView, self).form_valid(form)
+            certificate_id = form.instance.certificateID
+
+            # Send email to the attendee when the certificate is issued.
+            if Site._meta.installed:
+                site = Site.objects.get_current().domain
+
+            send_mail(
+                'Certificate from %s Course' % self.course.course_type,
+                'Dear %s %s,\n\n' % (
+                    self.attendee.firstname, self.attendee.surname) +
+                'Congratulations!\n'
+                'Your certificate from the following course '
+                'has been issued.\n\n' +
+                'Course type: %s\n' % self.course.course_type +
+                'Course date: %s to %s\n' % (
+                    self.course.start_date.strftime('%d %B %Y'),
+                    self.course.end_date.strftime('%d %B %Y')) +
+                'Training center: %s\n' % self.course.training_center +
+                'Certifying organisation: %s\n\n'
+                % self.course.certifying_organisation +
+                'You may check the full details of the certificate '
+                'by visiting:\n'
+                'http://%s/en/%s/certificate/%s/\n\n' % (
+                    site,
+                    self.course.certifying_organisation.project.slug,
+                    certificate_id
+                ) +
+                'Sincerely,\n%s %s' % (
+                    self.course.course_convener.user.first_name,
+                    self.course.course_convener.user.last_name
+                ),
+                self.course.course_convener.user.email,
+                [self.attendee.email],
+                fail_silently=False,
+            )
+
+            return HttpResponseRedirect(self.get_success_url())
+        except IntegrityError:
+            return ValidationError(
+                'ERROR: Certificate already exists!')
+
 
 class CertificateDetailView(DetailView):
     """Detail view for Certificate."""

{"golden_diff": "diff --git a/django_project/certification/views/certificate.py b/django_project/certification/views/certificate.py\n--- a/django_project/certification/views/certificate.py\n+++ b/django_project/certification/views/certificate.py\n@@ -1,7 +1,11 @@\n # coding=utf-8\n-from django.http import Http404, HttpResponse\n+from django.http import Http404, HttpResponse, HttpResponseRedirect\n from django.views.generic import CreateView, DetailView\n+from django.contrib.sites.models import Site\n+from django.core.mail import send_mail\n from django.core.urlresolvers import reverse\n+from django.db import IntegrityError\n+from django.core.exceptions import ValidationError\n from braces.views import LoginRequiredMixin\n from reportlab.pdfgen import canvas\n from reportlab.lib.pagesizes import A4, landscape\n@@ -78,6 +82,60 @@\n         })\n         return kwargs\n \n+    def form_valid(self, form):\n+        \"\"\"Save new created certificate\n+\n+        :param form\n+        :type form\n+\n+        :returns HttpResponseRedirect object to success_url\n+        :rtype: HttpResponseRedirect\n+\n+        We check that there is no referential integrity error when saving.\"\"\"\n+\n+        try:\n+            super(CertificateCreateView, self).form_valid(form)\n+            certificate_id = form.instance.certificateID\n+\n+            # Send email to the attendee when the certificate is issued.\n+            if Site._meta.installed:\n+                site = Site.objects.get_current().domain\n+\n+            send_mail(\n+                'Certificate from %s Course' % self.course.course_type,\n+                'Dear %s %s,\\n\\n' % (\n+                    self.attendee.firstname, self.attendee.surname) +\n+                'Congratulations!\\n'\n+                'Your certificate from the following course '\n+                'has been issued.\\n\\n' +\n+                'Course type: %s\\n' % self.course.course_type +\n+                'Course date: %s to %s\\n' % (\n+                    self.course.start_date.strftime('%d %B %Y'),\n+                    self.course.end_date.strftime('%d %B %Y')) +\n+                'Training center: %s\\n' % self.course.training_center +\n+                'Certifying organisation: %s\\n\\n'\n+                % self.course.certifying_organisation +\n+                'You may check the full details of the certificate '\n+                'by visiting:\\n'\n+                'http://%s/en/%s/certificate/%s/\\n\\n' % (\n+                    site,\n+                    self.course.certifying_organisation.project.slug,\n+                    certificate_id\n+                ) +\n+                'Sincerely,\\n%s %s' % (\n+                    self.course.course_convener.user.first_name,\n+                    self.course.course_convener.user.last_name\n+                ),\n+                self.course.course_convener.user.email,\n+                [self.attendee.email],\n+                fail_silently=False,\n+            )\n+\n+            return HttpResponseRedirect(self.get_success_url())\n+        except IntegrityError:\n+            return ValidationError(\n+                'ERROR: Certificate already exists!')\n+\n \n class CertificateDetailView(DetailView):\n     \"\"\"Detail view for Certificate.\"\"\"\n", "issue": "When issuing a certificate, the person being certified should be sent an email with a link to their cert\n\n", "before_files": [{"content": "# coding=utf-8\nfrom django.http import Http404, HttpResponse\nfrom django.views.generic import CreateView, DetailView\nfrom django.core.urlresolvers import reverse\nfrom braces.views import LoginRequiredMixin\nfrom reportlab.pdfgen import canvas\nfrom reportlab.lib.pagesizes import A4, landscape\nfrom reportlab.lib.utils import ImageReader\nfrom ..models import Certificate, Course, Attendee\nfrom ..forms import CertificateForm\nfrom base.models.project import Project\n\n\nclass CertificateMixin(object):\n    \"\"\"Mixin class to provide standard settings for Certificate.\"\"\"\n\n    model = Certificate\n    form_class = CertificateForm\n\n\nclass CertificateCreateView(\n        LoginRequiredMixin, CertificateMixin, CreateView):\n    \"\"\"Create view for Certificate.\"\"\"\n\n    context_object_name = 'certificate'\n    template_name = 'certificate/create.html'\n\n    def get_success_url(self):\n        \"\"\"Define the redirect URL.\n\n        After successful creation of the object, the User will be redirected\n        to the Course detail page.\n\n       :returns: URL\n       :rtype: HttpResponse\n       \"\"\"\n\n        return reverse('course-detail', kwargs={\n            'project_slug': self.project_slug,\n            'organisation_slug': self.organisation_slug,\n            'slug': self.course_slug\n        })\n\n    def get_context_data(self, **kwargs):\n        \"\"\"Get the context data which is passed to a template.\n\n        :param kwargs: Any arguments to pass to the superclass.\n        :type kwargs: dict\n\n        :returns: Context data which will be passed to the template.\n        :rtype: dict\n        \"\"\"\n\n        context = super(\n            CertificateCreateView, self).get_context_data(**kwargs)\n        context['course'] = Course.objects.get(slug=self.course_slug)\n        context['attendee'] = Attendee.objects.get(pk=self.pk)\n        return context\n\n    def get_form_kwargs(self):\n        \"\"\"Get keyword arguments from form.\n\n        :returns keyword argument from the form\n        :rtype: dict\n        \"\"\"\n\n        kwargs = super(CertificateCreateView, self).get_form_kwargs()\n        self.project_slug = self.kwargs.get('project_slug', None)\n        self.organisation_slug = self.kwargs.get('organisation_slug', None)\n        self.course_slug = self.kwargs.get('course_slug', None)\n        self.pk = self.kwargs.get('pk', None)\n        self.course = Course.objects.get(slug=self.course_slug)\n        self.attendee = Attendee.objects.get(pk=self.pk)\n        kwargs.update({\n            'user': self.request.user,\n            'course': self.course,\n            'attendee': self.attendee,\n        })\n        return kwargs\n\n\nclass CertificateDetailView(DetailView):\n    \"\"\"Detail view for Certificate.\"\"\"\n\n    model = Certificate\n    context_object_name = 'certificate'\n    template_name = 'certificate/detail.html'\n\n    def get_context_data(self, **kwargs):\n        \"\"\"Get the context data which is passed to a template.\n\n        :param kwargs: Any arguments to pass to the superclass.\n        :type kwargs: dict\n\n        :returns: Context data which will be passed to the template.\n        :rtype: dict\n        \"\"\"\n\n        self.certificateID = self.kwargs.get('id', None)\n        self.project_slug = self.kwargs.get('project_slug', None)\n        context = super(\n            CertificateDetailView, self).get_context_data(**kwargs)\n        issued_id = \\\n            Certificate.objects.all().values_list('certificateID', flat=True)\n        if self.certificateID in issued_id:\n            context['certificate'] = \\\n                Certificate.objects.get(certificateID=self.certificateID)\n        context['project_slug'] = self.project_slug\n        return context\n\n    def get_queryset(self):\n        \"\"\"Get the queryset for this view.\n\n        :returns: Queryset which is all certificate in the\n            corresponding organisation.\n        :rtype: QuerySet\n        \"\"\"\n\n        qs = Certificate.objects.all()\n        return qs\n\n    def get_object(self, queryset=None):\n        \"\"\"Get the object for this view.\n\n        :param queryset: A query set\n        :type queryset: QuerySet\n\n        :returns: Queryset which is filtered to only show a certificate\n            depends on the input certificate ID.\n        :rtype: QuerySet\n        :raises: Http404\n        \"\"\"\n\n        if queryset is None:\n            queryset = self.get_queryset()\n            certificateID = self.kwargs.get('id', None)\n            if certificateID:\n                try:\n                    obj = queryset.get(certificateID=certificateID)\n                    return obj\n                except Certificate.DoesNotExist:\n                    return None\n            else:\n                raise Http404('Sorry! Certificate by this ID is not exist.')\n\n\ndef certificate_pdf_view(request, **kwargs):\n\n    project_slug = kwargs.pop('project_slug')\n    course_slug = kwargs.pop('course_slug')\n    pk = kwargs.pop('pk')\n    project = Project.objects.get(slug=project_slug)\n    course = Course.objects.get(slug=course_slug)\n    attendee = Attendee.objects.get(pk=pk)\n    certificate = Certificate.objects.get(course=course, attendee=attendee)\n    current_site = request.META['HTTP_HOST']\n\n    # Create the HttpResponse object with the appropriate PDF headers.\n    response = HttpResponse(content_type='application/pdf')\n    response['Content-Disposition'] = 'filename=\"certificate.pdf\"'\n\n    # Create the PDF object, using the response object as its \"file.\"\n    page = canvas.Canvas(response, pagesize=landscape(A4))\n    width, height = A4\n    center = height * 0.5\n\n    if project.image_file:\n        project_logo = ImageReader(project.image_file)\n    else:\n        project_logo = None\n\n    if course.certifying_organisation.logo:\n        organisation_logo = ImageReader(course.certifying_organisation.logo)\n    else:\n        organisation_logo = None\n\n    if project.signature:\n        project_owner_signature = ImageReader(project.signature)\n    else:\n        project_owner_signature = None\n\n    if course.course_convener.signature:\n        convener_signature = ImageReader(course.course_convener.signature)\n    else:\n        convener_signature = None\n\n    if course.template_certificate:\n        background = ImageReader(course.template_certificate)\n    else:\n        background = None\n\n    # Certificate margin.\n    margin_right = height - 50\n    margin_left = 50\n    margin_bottom = 50\n    max_left = margin_right - 100\n\n    # Draw things on the PDF. Here's where the PDF generation happens.\n    # See the ReportLab documentation for the full list of functionality.\n    if background is not None:\n        page.drawImage(\n            background, 0, 0, height=width, width=height,\n            preserveAspectRatio=True, mask='auto')\n    page.setFillColorRGB(0.1, 0.1, 0.1)\n    page.setFont('Times-Roman', 18)\n    # page.drawString(margin_left, 480, project.name)\n    # page.drawRightString(\n    #     (margin_right), 480, course.certifying_organisation.name)\n\n    if project_logo is not None:\n        page.drawImage(\n            project_logo, 50, 450, width=100, height=100,\n            preserveAspectRatio=True, mask='auto')\n\n    if organisation_logo is not None:\n        page.drawImage(\n            organisation_logo, max_left, 450, height=100, width=100,\n            preserveAspectRatio=True, anchor='c', mask='auto')\n\n    page.setFont('Times-Bold', 26)\n    page.drawCentredString(center, 480, 'Certificate of Completion')\n    page.drawCentredString(\n        center, 400, '%s %s' % (attendee.firstname, attendee.surname))\n    page.setFont('Times-Roman', 16)\n    page.drawCentredString(\n        center, 360, 'Has attended and completed the course:')\n    page.setFont('Times-Bold', 20)\n    page.drawCentredString(center, 300, course.course_type.name)\n    page.setFont('Times-Roman', 16)\n    page.drawCentredString(\n        center, 270,\n        'From %s %s %s to %s %s %s'\n        % (course.start_date.day, course.start_date.strftime('%B'),\n           course.start_date.year, course.end_date.day,\n           course.end_date.strftime('%B'), course.end_date.year))\n    page.setFillColorRGB(0.1, 0.1, 0.1)\n    page.drawCentredString(\n        center, 220, 'Convened by %s %s at %s' % (\n            course.course_convener.user.first_name,\n            course.course_convener.user.last_name, course.training_center))\n\n    if project_owner_signature is not None:\n        page.drawImage(\n            project_owner_signature,\n            (margin_left + 100), (margin_bottom + 70), width=100, height=70,\n            preserveAspectRatio=True, anchor='s', mask='auto')\n\n    if convener_signature is not None:\n        page.drawImage(\n            convener_signature, (margin_right - 200), (margin_bottom + 70),\n            width=100, height=70, preserveAspectRatio=True, anchor='s',\n            mask='auto')\n\n    page.setFont('Times-Italic', 12)\n    page.drawCentredString(\n        (margin_left + 150), (margin_bottom + 60),\n        '%s %s' % (project.owner.first_name, project.owner.last_name))\n    page.drawCentredString(\n        (margin_right - 150), (margin_bottom + 60),\n        '%s %s' % (\n            course.course_convener.user.first_name,\n            course.course_convener.user.last_name))\n    page.line(\n        (margin_left + 70), (margin_bottom + 55),\n        (margin_left + 230), (margin_bottom + 55))\n    page.line(\n        (margin_right - 70), (margin_bottom + 55),\n        (margin_right - 230), (margin_bottom + 55))\n    page.setFont('Times-Roman', 13)\n    page.drawCentredString(\n        (margin_left + 150), (margin_bottom + 40), 'Project Owner')\n    page.drawCentredString(\n        (margin_right - 150), (margin_bottom + 40), 'Convener')\n\n    # Footnotes.\n    page.setFont('Times-Roman', 14)\n    page.drawString(\n        margin_left, margin_bottom - 10, 'ID: %s' % certificate.certificateID)\n    page.setFont('Times-Roman', 8)\n    page.drawString(\n        margin_left, (margin_bottom - 20),\n        'You can verify this certificate by visiting '\n        'http://%s/en/%s/certificate/%s/.'\n        % (current_site, project.slug, certificate.certificateID))\n\n    # Close the PDF object cleanly.\n    page.showPage()\n    page.save()\n    return response\n", "path": "django_project/certification/views/certificate.py"}], "after_files": [{"content": "# coding=utf-8\nfrom django.http import Http404, HttpResponse, HttpResponseRedirect\nfrom django.views.generic import CreateView, DetailView\nfrom django.contrib.sites.models import Site\nfrom django.core.mail import send_mail\nfrom django.core.urlresolvers import reverse\nfrom django.db import IntegrityError\nfrom django.core.exceptions import ValidationError\nfrom braces.views import LoginRequiredMixin\nfrom reportlab.pdfgen import canvas\nfrom reportlab.lib.pagesizes import A4, landscape\nfrom reportlab.lib.utils import ImageReader\nfrom ..models import Certificate, Course, Attendee\nfrom ..forms import CertificateForm\nfrom base.models.project import Project\n\n\nclass CertificateMixin(object):\n    \"\"\"Mixin class to provide standard settings for Certificate.\"\"\"\n\n    model = Certificate\n    form_class = CertificateForm\n\n\nclass CertificateCreateView(\n        LoginRequiredMixin, CertificateMixin, CreateView):\n    \"\"\"Create view for Certificate.\"\"\"\n\n    context_object_name = 'certificate'\n    template_name = 'certificate/create.html'\n\n    def get_success_url(self):\n        \"\"\"Define the redirect URL.\n\n        After successful creation of the object, the User will be redirected\n        to the Course detail page.\n\n       :returns: URL\n       :rtype: HttpResponse\n       \"\"\"\n\n        return reverse('course-detail', kwargs={\n            'project_slug': self.project_slug,\n            'organisation_slug': self.organisation_slug,\n            'slug': self.course_slug\n        })\n\n    def get_context_data(self, **kwargs):\n        \"\"\"Get the context data which is passed to a template.\n\n        :param kwargs: Any arguments to pass to the superclass.\n        :type kwargs: dict\n\n        :returns: Context data which will be passed to the template.\n        :rtype: dict\n        \"\"\"\n\n        context = super(\n            CertificateCreateView, self).get_context_data(**kwargs)\n        context['course'] = Course.objects.get(slug=self.course_slug)\n        context['attendee'] = Attendee.objects.get(pk=self.pk)\n        return context\n\n    def get_form_kwargs(self):\n        \"\"\"Get keyword arguments from form.\n\n        :returns keyword argument from the form\n        :rtype: dict\n        \"\"\"\n\n        kwargs = super(CertificateCreateView, self).get_form_kwargs()\n        self.project_slug = self.kwargs.get('project_slug', None)\n        self.organisation_slug = self.kwargs.get('organisation_slug', None)\n        self.course_slug = self.kwargs.get('course_slug', None)\n        self.pk = self.kwargs.get('pk', None)\n        self.course = Course.objects.get(slug=self.course_slug)\n        self.attendee = Attendee.objects.get(pk=self.pk)\n        kwargs.update({\n            'user': self.request.user,\n            'course': self.course,\n            'attendee': self.attendee,\n        })\n        return kwargs\n\n    def form_valid(self, form):\n        \"\"\"Save new created certificate\n\n        :param form\n        :type form\n\n        :returns HttpResponseRedirect object to success_url\n        :rtype: HttpResponseRedirect\n\n        We check that there is no referential integrity error when saving.\"\"\"\n\n        try:\n            super(CertificateCreateView, self).form_valid(form)\n            certificate_id = form.instance.certificateID\n\n            # Send email to the attendee when the certificate is issued.\n            if Site._meta.installed:\n                site = Site.objects.get_current().domain\n\n            send_mail(\n                'Certificate from %s Course' % self.course.course_type,\n                'Dear %s %s,\\n\\n' % (\n                    self.attendee.firstname, self.attendee.surname) +\n                'Congratulations!\\n'\n                'Your certificate from the following course '\n                'has been issued.\\n\\n' +\n                'Course type: %s\\n' % self.course.course_type +\n                'Course date: %s to %s\\n' % (\n                    self.course.start_date.strftime('%d %B %Y'),\n                    self.course.end_date.strftime('%d %B %Y')) +\n                'Training center: %s\\n' % self.course.training_center +\n                'Certifying organisation: %s\\n\\n'\n                % self.course.certifying_organisation +\n                'You may check the full details of the certificate '\n                'by visiting:\\n'\n                'http://%s/en/%s/certificate/%s/\\n\\n' % (\n                    site,\n                    self.course.certifying_organisation.project.slug,\n                    certificate_id\n                ) +\n                'Sincerely,\\n%s %s' % (\n                    self.course.course_convener.user.first_name,\n                    self.course.course_convener.user.last_name\n                ),\n                self.course.course_convener.user.email,\n                [self.attendee.email],\n                fail_silently=False,\n            )\n\n            return HttpResponseRedirect(self.get_success_url())\n        except IntegrityError:\n            return ValidationError(\n                'ERROR: Certificate already exists!')\n\n\nclass CertificateDetailView(DetailView):\n    \"\"\"Detail view for Certificate.\"\"\"\n\n    model = Certificate\n    context_object_name = 'certificate'\n    template_name = 'certificate/detail.html'\n\n    def get_context_data(self, **kwargs):\n        \"\"\"Get the context data which is passed to a template.\n\n        :param kwargs: Any arguments to pass to the superclass.\n        :type kwargs: dict\n\n        :returns: Context data which will be passed to the template.\n        :rtype: dict\n        \"\"\"\n\n        self.certificateID = self.kwargs.get('id', None)\n        self.project_slug = self.kwargs.get('project_slug', None)\n        context = super(\n            CertificateDetailView, self).get_context_data(**kwargs)\n        issued_id = \\\n            Certificate.objects.all().values_list('certificateID', flat=True)\n        if self.certificateID in issued_id:\n            context['certificate'] = \\\n                Certificate.objects.get(certificateID=self.certificateID)\n        context['project_slug'] = self.project_slug\n        return context\n\n    def get_queryset(self):\n        \"\"\"Get the queryset for this view.\n\n        :returns: Queryset which is all certificate in the\n            corresponding organisation.\n        :rtype: QuerySet\n        \"\"\"\n\n        qs = Certificate.objects.all()\n        return qs\n\n    def get_object(self, queryset=None):\n        \"\"\"Get the object for this view.\n\n        :param queryset: A query set\n        :type queryset: QuerySet\n\n        :returns: Queryset which is filtered to only show a certificate\n            depends on the input certificate ID.\n        :rtype: QuerySet\n        :raises: Http404\n        \"\"\"\n\n        if queryset is None:\n            queryset = self.get_queryset()\n            certificateID = self.kwargs.get('id', None)\n            if certificateID:\n                try:\n                    obj = queryset.get(certificateID=certificateID)\n                    return obj\n                except Certificate.DoesNotExist:\n                    return None\n            else:\n                raise Http404('Sorry! Certificate by this ID is not exist.')\n\n\ndef certificate_pdf_view(request, **kwargs):\n\n    project_slug = kwargs.pop('project_slug')\n    course_slug = kwargs.pop('course_slug')\n    pk = kwargs.pop('pk')\n    project = Project.objects.get(slug=project_slug)\n    course = Course.objects.get(slug=course_slug)\n    attendee = Attendee.objects.get(pk=pk)\n    certificate = Certificate.objects.get(course=course, attendee=attendee)\n    current_site = request.META['HTTP_HOST']\n\n    # Create the HttpResponse object with the appropriate PDF headers.\n    response = HttpResponse(content_type='application/pdf')\n    response['Content-Disposition'] = 'filename=\"certificate.pdf\"'\n\n    # Create the PDF object, using the response object as its \"file.\"\n    page = canvas.Canvas(response, pagesize=landscape(A4))\n    width, height = A4\n    center = height * 0.5\n\n    if project.image_file:\n        project_logo = ImageReader(project.image_file)\n    else:\n        project_logo = None\n\n    if course.certifying_organisation.logo:\n        organisation_logo = ImageReader(course.certifying_organisation.logo)\n    else:\n        organisation_logo = None\n\n    if project.signature:\n        project_owner_signature = ImageReader(project.signature)\n    else:\n        project_owner_signature = None\n\n    if course.course_convener.signature:\n        convener_signature = ImageReader(course.course_convener.signature)\n    else:\n        convener_signature = None\n\n    if course.template_certificate:\n        background = ImageReader(course.template_certificate)\n    else:\n        background = None\n\n    # Certificate margin.\n    margin_right = height - 50\n    margin_left = 50\n    margin_bottom = 50\n    max_left = margin_right - 100\n\n    # Draw things on the PDF. Here's where the PDF generation happens.\n    # See the ReportLab documentation for the full list of functionality.\n    if background is not None:\n        page.drawImage(\n            background, 0, 0, height=width, width=height,\n            preserveAspectRatio=True, mask='auto')\n    page.setFillColorRGB(0.1, 0.1, 0.1)\n    page.setFont('Times-Roman', 18)\n    # page.drawString(margin_left, 480, project.name)\n    # page.drawRightString(\n    #     (margin_right), 480, course.certifying_organisation.name)\n\n    if project_logo is not None:\n        page.drawImage(\n            project_logo, 50, 450, width=100, height=100,\n            preserveAspectRatio=True, mask='auto')\n\n    if organisation_logo is not None:\n        page.drawImage(\n            organisation_logo, max_left, 450, height=100, width=100,\n            preserveAspectRatio=True, anchor='c', mask='auto')\n\n    page.setFont('Times-Bold', 26)\n    page.drawCentredString(center, 480, 'Certificate of Completion')\n    page.drawCentredString(\n        center, 400, '%s %s' % (attendee.firstname, attendee.surname))\n    page.setFont('Times-Roman', 16)\n    page.drawCentredString(\n        center, 360, 'Has attended and completed the course:')\n    page.setFont('Times-Bold', 20)\n    page.drawCentredString(center, 300, course.course_type.name)\n    page.setFont('Times-Roman', 16)\n    page.drawCentredString(\n        center, 270,\n        'From %s %s %s to %s %s %s'\n        % (course.start_date.day, course.start_date.strftime('%B'),\n           course.start_date.year, course.end_date.day,\n           course.end_date.strftime('%B'), course.end_date.year))\n    page.setFillColorRGB(0.1, 0.1, 0.1)\n    page.drawCentredString(\n        center, 220, 'Convened by %s %s at %s' % (\n            course.course_convener.user.first_name,\n            course.course_convener.user.last_name, course.training_center))\n\n    if project_owner_signature is not None:\n        page.drawImage(\n            project_owner_signature,\n            (margin_left + 100), (margin_bottom + 70), width=100, height=70,\n            preserveAspectRatio=True, anchor='s', mask='auto')\n\n    if convener_signature is not None:\n        page.drawImage(\n            convener_signature, (margin_right - 200), (margin_bottom + 70),\n            width=100, height=70, preserveAspectRatio=True, anchor='s',\n            mask='auto')\n\n    page.setFont('Times-Italic', 12)\n    page.drawCentredString(\n        (margin_left + 150), (margin_bottom + 60),\n        '%s %s' % (project.owner.first_name, project.owner.last_name))\n    page.drawCentredString(\n        (margin_right - 150), (margin_bottom + 60),\n        '%s %s' % (\n            course.course_convener.user.first_name,\n            course.course_convener.user.last_name))\n    page.line(\n        (margin_left + 70), (margin_bottom + 55),\n        (margin_left + 230), (margin_bottom + 55))\n    page.line(\n        (margin_right - 70), (margin_bottom + 55),\n        (margin_right - 230), (margin_bottom + 55))\n    page.setFont('Times-Roman', 13)\n    page.drawCentredString(\n        (margin_left + 150), (margin_bottom + 40), 'Project Owner')\n    page.drawCentredString(\n        (margin_right - 150), (margin_bottom + 40), 'Convener')\n\n    # Footnotes.\n    page.setFont('Times-Roman', 14)\n    page.drawString(\n        margin_left, margin_bottom - 10, 'ID: %s' % certificate.certificateID)\n    page.setFont('Times-Roman', 8)\n    page.drawString(\n        margin_left, (margin_bottom - 20),\n        'You can verify this certificate by visiting '\n        'http://%s/en/%s/certificate/%s/.'\n        % (current_site, project.slug, certificate.certificateID))\n\n    # Close the PDF object cleanly.\n    page.showPage()\n    page.save()\n    return response\n", "path": "django_project/certification/views/certificate.py"}]}