#!/usr/bin/env python
# SecretSnowflakeOrganizer.py
# Web app that automatically coordinates a Secret Snowflake Gift Exchange
COORDINATOR_PASSWORD = 'COORDINATOR_PASSWORD'
DB_HOST = 'DB_HOST'
DB_USER = 'DB_USER'
DB_PASSWORD = 'DB_PASSWORD'
DB_NAME = 'DB_NAME'
GMAIL_USER = 'EMAIL'
GMAIL_PASSWORD = 'EMAIL_PASSWORD'
ORGANIZATION = 'ORGANIZATION'
import MySQLdb
class DB:
def connect(self):
self.db = MySQLdb.connect(host=DB_HOST,
user=DB_USER,
passwd=DB_PASSWORD,
db=DB_NAME)
return self.db.cursor()
def commit(self):
self.db.commit()
def close(self):
self.db.close()
db = DB()
def is_open():
sql = db.connect()
sql.execute("""SELECT open FROM status WHERE 1 LIMIT 1""")
for status in sql.fetchall():
db.close()
return bool(int(status[0]))
# email stuff
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
def mail(to, subject, text):
msg = MIMEMultipart()
msg['From'] = GMAIL_USER
msg['To'] = to
msg['Subject'] = subject
msg.attach(MIMEText(text))
mailServer = smtplib.SMTP("smtp.gmail.com", 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(GMAIL_USER, GMAIL_PASSWORD)
mailServer.sendmail(GMAIL_USER, to, msg.as_string())
mailServer.close()
import web
urls = (
'/', 'index',
'/signup', 'signup',
'/assign', 'assign',
'/open', 'open'
)
class index:
def signup(self,open):
if open:
return """<div style="color:white;line-height:200%">
<form action="signup" method="post">
Name: <input type="text" name="name"><br/>
Email: <input type="text" name="email"><br/>
Additional Info (interests/favorites/allergies/etc.):<br/>
<textarea name="info" columns=64 rows=4></textarea><br/>
<label><input type="checkbox" name="promise"> I promise to make my Secret Snowflake's day!</label><br/>
<input type="submit" value="Sign Up"/>
</form>
</div>
<div style="color:white;line-height:200%">
<form action="assign" method="post">
<b>Coordinator Only</b><br/>
Password: <input type="password" name="password"><br/>
<input type="submit" value="Assign Snowflakes"/>
</form>
</div>
"""
else:
return """<h3 style="color:white">Sign-up is currently closed.</h3>
<div style="color:white;line-height:200%">
<form action="open" method="post">
<b>Coordinator Only</b><br/>
Password: <input type="password" name="password"><br/>
<input type="submit" value="Open Sign-Up"/>
</form>
</div>
"""
def GET(self):
web.header('Content-Type','text/html; charset=utf-8', unique=True)
try:
message = self.signup(is_open())
except:
message = '<div style="color:white;line-height:200%">Currently experiencing problems, but hoping to be back up shortly. Sorry!</div>'
return """<html>
<head>
<title>{0} | Secret Snowflake | Sign-Up</title>
<script type="text/javascript">
</script>
</head>
<body style="background-image:url(static/snowflake.png);font-family:Georgia;padding:5% 20%">
<center>
<h1 style="color:white">{0}'s Secret Snowflake Sign-Up</h1>
</center>""".format(ORGANIZATION) \
+ message + \
"""</html>"""
class signup:
def POST(self):
import re
data = web.input()
message = ''
if data.name == '': message += 'Please enter your name.<br/>'
if not re.match(r"[a-z0-9!#$%&'*+/=?^_{|}~-]+(?:.[a-z0-9!#$%&'*+/=?^_{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Za-z]{2}|com|org|net|edu|info)\b", data['email']): message += 'Please enter your email.<br/>'
if not hasattr(data, 'promise'): message += 'Please make the promise.<br/>'
if message == '':
message += '<b>You have signed up! Please look for a email confirming your participation in the gift exchange.</b>'
sql = db.connect()
sql.execute("""INSERT INTO snowflakes VALUES (%s, %s, %s)""", (data.name, data.email, data.info))
db.commit()
db.close()
mail(data.email, '{} Secret Snowflake'.format(ORGANIZATION), 'Hi {},\n\nJust an email confirmation that you have succesfully signed up for {}\'s Secret Snowflake gift exchange! Expect\n\nHappy Holidays!\nYour Secret Snowflake Coordinator'.format(data.name.split()[0], ORGANIZATION))
else:
message += '<b><a href="javascript:history.back()">Back to sign-up.</a></b>'
web.header('Content-Type','text/html; charset=utf-8', unique=True)
return """<html>
<head>
<title>{0} | Secret Snowflake | Sign-Up</title>
<style type="text/css">
a:link {color:#FFFFFF;}
a:visited {color:#FFFFFF;}
a:hover {color:#FFFFFF;text-decoration:none;}
a:active {color:#FFFFFF;}
</style>
</head>
<body style="background-image:url(static/snowflake.png);font-family:Georgia;padding:5% 20%">
<center>
<h1 style="color:white">{0}'s Secret Snowflake Sign-Up</h1>
</center>
<div style="color:white;line-height:200%">""".format(ORGANIZATION) \
+ message + \
"""</div>
</html>"""
class Snowflake:
def __init__(self,name,email,info):
self.name = name
self.email = email
self.info = info
class assign:
def POST(self):
data = web.input()
if not is_open():
message = 'You can only assign Secret Snowflakes once!'
elif data.password == PASSWORD:
message = 'Secret Snowflake assignments have been emailed successfully!'
sql = db.connect()
sql.execute("""UPDATE status SET open=0 WHERE 1 LIMIT 1""")
sql.execute("""SELECT name, email, info FROM snowflakes WHERE 1""")
db.commit()
from collections import deque
from random import shuffle
snowflakes = deque([])
for sf in sql.fetchall():
snowflakes.append(Snowflake(sf[0], sf[1], sf[2]))
db.close()
shuffle(snowflakes)
shuffle(snowflakes)
shuffle(snowflakes)
snowflakes2 = deque(snowflakes)
snowflakes2.rotate(1)
for i in xrange(len(snowflakes)):
a = snowflakes[i]
b = snowflakes2[i]
mail(a.email, 'Your {} Snowflake'.format(ORGANIZATION), 'Hi {},\n\nThanks for participating in {}\'s Secret Snowflake gift exchange! Your Secret Snowflake is {}. They would like you to know the following about themselves:\n{}\n\nHappy Holidays!\nYour Secret Snowflake Coordinator'.format(a.name.split()[0], ORGANIZATION, b.name, b.info if b.info else '[Nothing]'))
else:
message = 'Incorrect password.<br/><b><a href="javascript:history.back()">Back.</a></b>'
web.header('Content-Type','text/html; charset=utf-8', unique=True)
return """<html>
<head>
<title>{0} | Secret Snowflake | Sign-Up</title>
<style type="text/css">
a:link {color:#FFFFFF;}
a:visited {color:#FFFFFF;}
a:hover {color:#FFFFFF;text-decoration:none;}
a:active {color:#FFFFFF;}
</style>
</head>
<body style="background-image:url(static/snowflake.png);font-family:Georgia;padding:5% 20%">
<center>
<h1 style="color:white">{0}'s Secret Snowflake Sign-Up</h1>
</center>
<div style="color:white;line-height:200%">""".format(ORGANIZATION) + message + """</div>
</html>"""
class open:
def POST(self):
data = web.input()
if data.password == PASSWORD:
message = 'Sign-up is now open!<br/><b><a href="/">Go to sign-up.</a></b>'
sql = db.connect()
sql.execute("""UPDATE status SET open=1 WHERE 1 LIMIT 1""")
sql.execute("""DELETE FROM snowflakes WHERE 1""")
db.commit()
db.close()
else:
message = 'Incorrect password.<br/><b><a href="javascript:history.back()">Back.</a></b>'
web.header('Content-Type','text/html; charset=utf-8', unique=True)
return """<html>
<head>
<title>{0} | Secret Snowflake | Sign-Up</title>
<style type="text/css">
a:link {color:#FFFFFF;}
a:visited {color:#FFFFFF;}
a:hover {color:#FFFFFF;text-decoration:none;}
a:active {color:#FFFFFF;}
</style>
</head>
<body style="background-image:url(static/snowflake.png);font-family:Georgia;padding:5% 20%">
<center>
<h1 style="color:white">{0}'s Secret Snowflake Sign-Up</h1>
</center>
<div style="color:white;line-height:200%">""".format(ORGANIZATION) + message + """</div>
</html>"""
app = web.application(urls, globals())
application = app.wsgifunc()