mail util

This commit is contained in:
matticoli 2022-01-11 23:09:26 -05:00
parent ffe4075157
commit 4a0c307f13
5 changed files with 237 additions and 4 deletions

View file

@ -16,7 +16,8 @@ from flask_sqlalchemy import SQLAlchemy
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
from config_hackWPI import (api_keys, SERVER_LISTEN_ADDR, SERVER_PORT, WAITLIST_LIMIT, HACKATHON_TIME, from config_hackWPI import (api_keys, SERVER_LISTEN_ADDR, SERVER_PORT, WAITLIST_LIMIT, HACKATHON_TIME,
ALLOWED_EXTENSIONS, REGISTRATION_OPEN) ALLOWED_EXTENSIONS, REGISTRATION_OPEN, MCE_API_KEY)
from mail import send_message
app = Flask(__name__) app = Flask(__name__)
app.config.from_pyfile('config.py') app.config.from_pyfile('config.py')
@ -241,9 +242,46 @@ def register():
# Finally, send them to their dashboard # Finally, send them to their dashboard
return redirect(url_for('dashboard')) return redirect(url_for('dashboard'))
@app.route('/mail')
def mail():
if not is_admin():
return redirect(url_for('register'))
return render_template('mail.html', MCE_API_KEY=MCE_API_KEY, NUM_HACKERS=len(admin(True)))
@app.route('/send', methods=['POST'])
def send():
if not is_admin():
return "Not Authorized", 401
args = request.json
print(args)
recipients = args.get("recipients") or ""
subject = args.get("subject") or ""
html = args.get("html") or ""
text = args.get("text") or ""
to = []
if(recipients == "org"):
to = ["hack@wpi.edu"]
elif(recipients == "admin"):
to = ["acm-sysadmin@wpi.edu"]
elif(recipients == "all"):
to = [x["email"] for x in admin(True)]
elif(recipients == "wpi"):
to = [ x["email"] for x in admin(True) if "wpi.edu" in x["email"] or \
(x["school"] and ("WPI" in x["school"]["name"] or "Worcester Polytechnic" in x["school"]["name"])) ]
# return str(to)
send_message(to, subject, html, text)
return "Message sent successfully to {0} recipients".format(len(to))
@app.route('/hackers', methods=['GET'])
def hackers():
if not is_admin():
return redirect(url_for('register'))
return jsonify(admin(True))
@app.route('/admin', methods=['GET']) @app.route('/admin', methods=['GET'])
def admin(): def admin(return_hackers=False):
# Displays total registration information... # Displays total registration information...
# As Firebase could not be used with MyMLH, use PubNub to simulate the realtime database... # As Firebase could not be used with MyMLH, use PubNub to simulate the realtime database...
@ -314,6 +352,8 @@ def admin():
'special_needs': obj.special_needs, 'special_needs': obj.special_needs,
'school': hacker['school'] if 'school' in hacker else 'NULL' 'school': hacker['school'] if 'school' in hacker else 'NULL'
}) })
if(return_hackers):
return hackers
return render_template('admin.html', hackers=hackers, total_count=total_count, waitlist_count=waitlist_count, return render_template('admin.html', hackers=hackers, total_count=total_count, waitlist_count=waitlist_count,
check_in_count=check_in_count, shirt_count=shirt_count, female_count=female_count, check_in_count=check_in_count, shirt_count=shirt_count, female_count=female_count,
@ -538,7 +578,7 @@ def is_self(mlh_id):
return False return False
return True return True
# TODO: Migrate to new mail module
def send_email(to, subject, body): def send_email(to, subject, body):
print("Email sent to: " + to) print("Email sent to: " + to)
body += '\nPlease let your friends know about the event as well!\n' body += '\nPlease let your friends know about the event as well!\n'

45
mail/__init__.py Normal file
View file

@ -0,0 +1,45 @@
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from config_hackWPI import (api_keys)
user = api_keys['smtp_email']['user']
bcc = api_keys['smtp_email']['bcc']
reply = api_keys['smtp_email']['reply']
sender = api_keys['smtp_email']['sender']
smtp_server = api_keys['smtp_email']['smtp_server']
smtp_port = api_keys['smtp_email']['smtp_port']
def send_message(recipients, subject="", html="", text=""):
print("Sending email to {0} with subject {1}".format(recipients, subject))
# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = sender
msg.add_header('reply-to', reply)
# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(text, 'plain')
part2 = MIMEText(html, 'html')
# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)
server = smtplib.SMTP(smtp_server, smtp_port)
# Enable TLS if we're using secure SMTP
if(smtp_port > 25):
server.starttls()
# Login if we're using server with auth
if ('pass' in api_keys['smtp_email']):
server.login(user, api_keys['smtp_email']['pass'])
server.sendmail(sender, recipients, msg.as_string())
server.quit()
if __name__ == "__main__":
send_message(["acm-sysadmin@wpi.edu"], "Test Subject", "<b>Test HTML</b>", "Test text")

47
static/css/mail.css Normal file
View file

@ -0,0 +1,47 @@
/* For best practice, move CSS below to an external CSS file. */
@keyframes fadeinall {
0% {
opacity: 1; }
97% {
opacity: 0; }
98% {
opacity: 0;
-webkit-transform: translateY(0);
transform: translateY(0); }
99% {
opacity: 0;
-webkit-transform: translateY(-100%);
transform: translateY(-100%); }
100% {
opacity: 0;
z-index: -1; } }
#loader {
opacity: 1;
position: fixed;
width: 100%;
height: 100%;
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
background-color: #fff;
z-index: 999;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
-webkit-animation: fadeinall 1s normal both;
animation: fadeinall 1s normal both;
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s;
}
#loader {
background-color: #222;
}
body {
background-color: #222222;
color: whitesmoke;
}
input, button, select, textarea {
border-radius: 5px;
}

@ -1 +1 @@
Subproject commit bfb9d7799fbb8630f4351f043a05aa617964becf Subproject commit b2a60294b8f9d37d8c486cd817f8260cc860caad

101
templates/mail.html Normal file
View file

@ -0,0 +1,101 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>🍪CookieMailer</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="description" content="" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<meta name="theme-color" content="">
<link rel="stylesheet" type="text/css" href="/static/css/mail.css" />
<script src="https://cdn.tiny.cloud/1/{{MCE_API_KEY}}/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script></head>
<body>
<div id="loader"></div>
<div class="container">
<div class="row">
<div id="root" class="col">
<h2>🍪CookieMailer</h2>
<label for="recipients">To: </label>
<br/>
<select id="recipients" name="recipients">
<option value="admin">Test Email (SysAdmin)</option>
<option value="org">Test Email (Organizers)</option>
<!-- <option value="wpi">WPI Only</option> -->
<option value="all">All Participants ({{NUM_HACKERS}})</option>
</select>
<br/>
<label for="subject">Subject: </label>
<br/>
<input id="subject" name="subject" width="100%" type="text" value="Hack@WPI" />
<br/>
<br/>
<textarea id="content" name="content">
Message
<br/>
<br/>
Best,<br/>
<b>Hack@WPI Team</b><br/>
<i><a href="mailto:hack@wpi.edu">hack@wpi.edu</a></i><br/>
<img height="75px" width="75px" src="https://media.discordapp.net/attachments/829437603291856938/930311998057635880/hack317-min.png">
</textarea>
<br/>
<br/>
<input type="button" onClick="send()" value="Send"/>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" crossorigin="anonymous"></script>
<script type="text/javascript">
window.onload = function(){
tinymce.init({
selector: '#content',
plugins: 'advlist,link'
});
setTimeout(function(){
document.getElementById("loader").remove();
},1000);
};
function send() {
let rec = document.getElementById("recipients").value;
let subject = document.getElementById("subject").value;
let text = tinyMCE.activeEditor.getContent({ format: 'text' });
let html = tinyMCE.activeEditor.getContent({ format: 'html' });
let body = {
"recipients": rec,
"subject": subject,
"text": text,
"html": html
}
console.log("Sending Email:"+JSON.stringify(body))
const headers = [
["Content-Type", "application/json"],
];
if((rec != "all" && window.confirm("Send test email?")) || (rec == "all" && window.confirm("Send email to {{NUM_HACKERS}} recipients?"))) {
fetch('/send', {method: 'POST', body: JSON.stringify(body), headers: headers}).then(async (res) => {
window.alert(await res.text());
}).catch((err) => {
window.alert("Error sending message - see console for details");
console.log(err);
});
} else {
window.alert("Nothing was sent");
}
// fetch('/send', {method: 'POST', body: JSON.stringify(body), headers: headers}).then(async (res) => {
// alert("Message sent");
// document.body.innerHTML = await res.text()
// }).catch((err) => {
// alert("Error sending message");
// document.body.innerHTML = err;
// })
}
</script>
</body>
</html>