Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions app/api/helpers/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from app.models.user import User


def send_email(to, action, subject, html):
def send_email(to, action, subject, html, attachments=None):
"""
Sends email and records it in DB
"""
Expand All @@ -30,7 +30,8 @@ def send_email(to, action, subject, html):
'to': to,
'from': email_from,
'subject': subject,
'html': html
'html': html,
'attachments': attachments
}

if not current_app.config['TESTING']:
Expand Down Expand Up @@ -278,7 +279,8 @@ def send_email_change_user_email(user, email):
send_email_with_action(email, USER_CHANGE_EMAIL, email=email, new_email=user.email)


def send_email_to_attendees(order, purchaser_id):
def send_email_to_attendees(order, purchaser_id, attachments=None):

for holder in order.ticket_holders:
if holder.user and holder.user.id == purchaser_id:
# Ticket holder is the purchaser
Expand All @@ -292,7 +294,8 @@ def send_email_to_attendees(order, purchaser_id):
html=MAILS[TICKET_PURCHASED]['message'].format(
pdf_url=holder.pdf_url,
event_name=order.event.name
)
),
attachments=attachments
)
else:
# The Ticket holder is not the purchaser
Expand All @@ -306,7 +309,8 @@ def send_email_to_attendees(order, purchaser_id):
html=MAILS[TICKET_PURCHASED_ATTENDEE]['message'].format(
pdf_url=holder.pdf_url,
event_name=order.event.name
)
),
attachments=attachments
)


Expand Down
2 changes: 1 addition & 1 deletion app/api/helpers/system_mails.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
'message': (
u"Hi, this is a confirmation mail of your tickets for the event {event_name}"
u"<br/>Your order has been processed successfully." +
u"<br/> <a href='{pdf_url}'>Click here</a> to view/download your invoice."
u"<br/> You can find your Tickets and Order Invoice attached to this mail."
u"<br><br><em>Looking forward to seeing you at the event."
u"<br/>Login to manage your orders at https://eventyay.com </em>"
)
Expand Down
38 changes: 26 additions & 12 deletions app/api/helpers/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

from flask import current_app, render_template
from marrow.mailer import Mailer, Message
from app import get_settings
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import (
Mail, Attachment, FileContent, FileName,
FileType, Disposition)

from app import make_celery
from app.api.helpers.utilities import strip_tags
Expand Down Expand Up @@ -41,25 +46,33 @@
from app.api.helpers.db import save_to_db
from app.api.helpers.files import create_save_pdf
import urllib.error
import base64

celery = make_celery()


@celery.task(name='send.email.post')
def send_email_task(payload, headers):
data = {"personalizations": [{"to": []}]}
data["personalizations"][0]["to"].append({"email": payload["to"]})
data["from"] = {"email": payload["from"]}
data["subject"] = payload["subject"]
data["content"] = [{"type": "text/html", "value": payload["html"]}]
logging.info('Sending an email regarding {} on behalf of {}'.format(data["subject"], data["from"]))
message = Mail(from_email=payload['from'],
to_emails=payload['to'],
subject=payload['subject'],
html_content=payload["html"])
if payload['attachments'] is not None:
for attachment in payload['attachments']:
with open(attachment, 'rb') as f:
file_data = f.read()
f.close()
encoded = base64.b64encode(file_data).decode()
attachment = Attachment()
attachment.file_content = FileContent(encoded)
attachment.file_type = FileType('application/pdf')
attachment.file_name = FileName(payload['to'])
attachment.disposition = Disposition('attachment')
message.add_attachment(attachment)
sendgrid_client = SendGridAPIClient(get_settings()['sendgrid_key'])
logging.info('Sending an email regarding {} on behalf of {}'.format(payload["subject"], payload["from"]))
try:
requests.post(
"https://api.sendgrid.com/v3/mail/send",
data=json.dumps(data),
headers=headers,
verify=False # doesn't work with verification in celery context
)
sendgrid_client.send(message)
logging.info('Email sent successfully')
except Exception:
logging.exception('Error occured while sending the email')
Expand All @@ -84,6 +97,7 @@ def send_mail_via_smtp_task(config, payload):
message.subject = payload['subject']
message.plain = strip_tags(payload['html'])
message.rich = payload['html']
message.attach(name=payload['attachments'])
mailer.send(message)
logging.info('Message sent via SMTP')
mailer.stop()
Expand Down
34 changes: 30 additions & 4 deletions app/api/orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from app.api.bootstrap import api
from app.api.data_layers.ChargesLayer import ChargesLayer
from app.api.helpers.db import save_to_db, safe_query, safe_query_without_soft_deleted_entries
from app.api.helpers.storage import generate_hash, UPLOAD_PATHS
from app.api.helpers.errors import BadRequestError
from app.api.helpers.exceptions import ForbiddenException, UnprocessableEntity, ConflictException
from app.api.helpers.files import make_frontend_url
Expand Down Expand Up @@ -139,10 +140,22 @@ def after_create_object(self, order, data, view_kwargs):

# send e-mail and notifications if the order status is completed
if order.status == 'completed':
# fetch tickets attachment
order_identifier = order.identifier

key = UPLOAD_PATHS['pdf']['ticket_attendee'].format(identifier=order_identifier)
ticket_path = 'generated/tickets/{}/{}/'.format(key, generate_hash(key)) + order_identifier + '.pdf'

key = UPLOAD_PATHS['pdf']['order'].format(identifier=order_identifier)
invoice_path = 'generated/invoices/{}/{}/'.format(key, generate_hash(key)) + order_identifier + '.pdf'

# send email and notifications.
send_email_to_attendees(order=order, purchaser_id=current_user.id, attachments=[ticket_path, invoice_path])

send_notif_to_attendees(order, current_user.id)

if order.payment_mode in ['free', 'bank', 'cheque', 'onsite']:
order.completed_at = datetime.utcnow()
send_email_to_attendees(order, current_user.id)
send_notif_to_attendees(order, current_user.id)

order_url = make_frontend_url(path='/orders/{identifier}'.format(identifier=order.identifier))
for organizer in order.event.organizers:
Expand Down Expand Up @@ -310,10 +323,23 @@ def after_update_object(self, order, data, view_kwargs):
delete_related_attendees_for_order(order)

elif order.status == 'completed':

# Send email to attendees with invoices and tickets attached
order_identifier = order.identifier

key = UPLOAD_PATHS['pdf']['ticket_attendee'].format(identifier=order_identifier)
ticket_path = 'generated/tickets/{}/{}/'.format(key, generate_hash(key)) + order_identifier + '.pdf'

key = UPLOAD_PATHS['pdf']['order'].format(identifier=order_identifier)
invoice_path = 'generated/invoices/{}/{}/'.format(key, generate_hash(key)) + order_identifier + '.pdf'

# send email and notifications.
send_email_to_attendees(order=order, purchaser_id=current_user.id, attachments=[ticket_path, invoice_path])

send_notif_to_attendees(order, current_user.id)

if order.payment_mode in ['free', 'bank', 'cheque', 'onsite']:
order.completed_at = datetime.utcnow()
send_email_to_attendees(order, current_user.id)
send_notif_to_attendees(order, current_user.id)

order_url = make_frontend_url(path='/orders/{identifier}'.format(identifier=order.identifier))
for organizer in order.event.organizers:
Expand Down
1 change: 1 addition & 0 deletions requirements/common.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ celery>=3.1.23,<4
redis>=2.10.5,<3
apscheduler>=3.3.0,<4
pillow
sendgrid>=6.0.5
amqp<2.0,>=1.4.9
gunicorn>=19.6.0,<20
boto>=2.45.0,<3
Expand Down