SecretSnowflakeOrganizer.py


SUBMITTED BY: Guest

DATE: Jan. 19, 2014, 5:27 p.m.

FORMAT: Python

SIZE: 9.6 kB

HITS: 1220

  1. #!/usr/bin/env python
  2. # SecretSnowflakeOrganizer.py
  3. # Web app that automatically coordinates a Secret Snowflake Gift Exchange
  4. COORDINATOR_PASSWORD = 'COORDINATOR_PASSWORD'
  5. DB_HOST = 'DB_HOST'
  6. DB_USER = 'DB_USER'
  7. DB_PASSWORD = 'DB_PASSWORD'
  8. DB_NAME = 'DB_NAME'
  9. GMAIL_USER = 'EMAIL'
  10. GMAIL_PASSWORD = 'EMAIL_PASSWORD'
  11. ORGANIZATION = 'ORGANIZATION'
  12. import MySQLdb
  13. class DB:
  14. def connect(self):
  15. self.db = MySQLdb.connect(host=DB_HOST,
  16. user=DB_USER,
  17. passwd=DB_PASSWORD,
  18. db=DB_NAME)
  19. return self.db.cursor()
  20. def commit(self):
  21. self.db.commit()
  22. def close(self):
  23. self.db.close()
  24. db = DB()
  25. def is_open():
  26. sql = db.connect()
  27. sql.execute("""SELECT open FROM status WHERE 1 LIMIT 1""")
  28. for status in sql.fetchall():
  29. db.close()
  30. return bool(int(status[0]))
  31. # email stuff
  32. import smtplib
  33. from email.MIMEMultipart import MIMEMultipart
  34. from email.MIMEText import MIMEText
  35. def mail(to, subject, text):
  36. msg = MIMEMultipart()
  37. msg['From'] = GMAIL_USER
  38. msg['To'] = to
  39. msg['Subject'] = subject
  40. msg.attach(MIMEText(text))
  41. mailServer = smtplib.SMTP("smtp.gmail.com", 587)
  42. mailServer.ehlo()
  43. mailServer.starttls()
  44. mailServer.ehlo()
  45. mailServer.login(GMAIL_USER, GMAIL_PASSWORD)
  46. mailServer.sendmail(GMAIL_USER, to, msg.as_string())
  47. mailServer.close()
  48. import web
  49. urls = (
  50. '/', 'index',
  51. '/signup', 'signup',
  52. '/assign', 'assign',
  53. '/open', 'open'
  54. )
  55. class index:
  56. def signup(self,open):
  57. if open:
  58. return """<div style="color:white;line-height:200%">
  59. <form action="signup" method="post">
  60. Name: <input type="text" name="name"><br/>
  61. Email: <input type="text" name="email"><br/>
  62. Additional Info (interests/favorites/allergies/etc.):<br/>
  63. <textarea name="info" columns=64 rows=4></textarea><br/>
  64. <label><input type="checkbox" name="promise"> I promise to make my Secret Snowflake's day!</label><br/>
  65. <input type="submit" value="Sign Up"/>
  66. </form>
  67. </div>
  68. <div style="color:white;line-height:200%">
  69. <form action="assign" method="post">
  70. <b>Coordinator Only</b><br/>
  71. Password: <input type="password" name="password"><br/>
  72. <input type="submit" value="Assign Snowflakes"/>
  73. </form>
  74. </div>
  75. """
  76. else:
  77. return """<h3 style="color:white">Sign-up is currently closed.</h3>
  78. <div style="color:white;line-height:200%">
  79. <form action="open" method="post">
  80. <b>Coordinator Only</b><br/>
  81. Password: <input type="password" name="password"><br/>
  82. <input type="submit" value="Open Sign-Up"/>
  83. </form>
  84. </div>
  85. """
  86. def GET(self):
  87. web.header('Content-Type','text/html; charset=utf-8', unique=True)
  88. try:
  89. message = self.signup(is_open())
  90. except:
  91. message = '<div style="color:white;line-height:200%">Currently experiencing problems, but hoping to be back up shortly. Sorry!</div>'
  92. return """<html>
  93. <head>
  94. <title>{0} | Secret Snowflake | Sign-Up</title>
  95. <script type="text/javascript">
  96. </script>
  97. </head>
  98. <body style="background-image:url(static/snowflake.png);font-family:Georgia;padding:5% 20%">
  99. <center>
  100. <h1 style="color:white">{0}'s Secret Snowflake Sign-Up</h1>
  101. </center>""".format(ORGANIZATION) \
  102. + message + \
  103. """</html>"""
  104. class signup:
  105. def POST(self):
  106. import re
  107. data = web.input()
  108. message = ''
  109. if data.name == '': message += 'Please enter your name.<br/>'
  110. 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/>'
  111. if not hasattr(data, 'promise'): message += 'Please make the promise.<br/>'
  112. if message == '':
  113. message += '<b>You have signed up! Please look for a email confirming your participation in the gift exchange.</b>'
  114. sql = db.connect()
  115. sql.execute("""INSERT INTO snowflakes VALUES (%s, %s, %s)""", (data.name, data.email, data.info))
  116. db.commit()
  117. db.close()
  118. 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))
  119. else:
  120. message += '<b><a href="javascript:history.back()">Back to sign-up.</a></b>'
  121. web.header('Content-Type','text/html; charset=utf-8', unique=True)
  122. return """<html>
  123. <head>
  124. <title>{0} | Secret Snowflake | Sign-Up</title>
  125. <style type="text/css">
  126. a:link {color:#FFFFFF;}
  127. a:visited {color:#FFFFFF;}
  128. a:hover {color:#FFFFFF;text-decoration:none;}
  129. a:active {color:#FFFFFF;}
  130. </style>
  131. </head>
  132. <body style="background-image:url(static/snowflake.png);font-family:Georgia;padding:5% 20%">
  133. <center>
  134. <h1 style="color:white">{0}'s Secret Snowflake Sign-Up</h1>
  135. </center>
  136. <div style="color:white;line-height:200%">""".format(ORGANIZATION) \
  137. + message + \
  138. """</div>
  139. </html>"""
  140. class Snowflake:
  141. def __init__(self,name,email,info):
  142. self.name = name
  143. self.email = email
  144. self.info = info
  145. class assign:
  146. def POST(self):
  147. data = web.input()
  148. if not is_open():
  149. message = 'You can only assign Secret Snowflakes once!'
  150. elif data.password == PASSWORD:
  151. message = 'Secret Snowflake assignments have been emailed successfully!'
  152. sql = db.connect()
  153. sql.execute("""UPDATE status SET open=0 WHERE 1 LIMIT 1""")
  154. sql.execute("""SELECT name, email, info FROM snowflakes WHERE 1""")
  155. db.commit()
  156. from collections import deque
  157. from random import shuffle
  158. snowflakes = deque([])
  159. for sf in sql.fetchall():
  160. snowflakes.append(Snowflake(sf[0], sf[1], sf[2]))
  161. db.close()
  162. shuffle(snowflakes)
  163. shuffle(snowflakes)
  164. shuffle(snowflakes)
  165. snowflakes2 = deque(snowflakes)
  166. snowflakes2.rotate(1)
  167. for i in xrange(len(snowflakes)):
  168. a = snowflakes[i]
  169. b = snowflakes2[i]
  170. 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]'))
  171. else:
  172. message = 'Incorrect password.<br/><b><a href="javascript:history.back()">Back.</a></b>'
  173. web.header('Content-Type','text/html; charset=utf-8', unique=True)
  174. return """<html>
  175. <head>
  176. <title>{0} | Secret Snowflake | Sign-Up</title>
  177. <style type="text/css">
  178. a:link {color:#FFFFFF;}
  179. a:visited {color:#FFFFFF;}
  180. a:hover {color:#FFFFFF;text-decoration:none;}
  181. a:active {color:#FFFFFF;}
  182. </style>
  183. </head>
  184. <body style="background-image:url(static/snowflake.png);font-family:Georgia;padding:5% 20%">
  185. <center>
  186. <h1 style="color:white">{0}'s Secret Snowflake Sign-Up</h1>
  187. </center>
  188. <div style="color:white;line-height:200%">""".format(ORGANIZATION) + message + """</div>
  189. </html>"""
  190. class open:
  191. def POST(self):
  192. data = web.input()
  193. if data.password == PASSWORD:
  194. message = 'Sign-up is now open!<br/><b><a href="/">Go to sign-up.</a></b>'
  195. sql = db.connect()
  196. sql.execute("""UPDATE status SET open=1 WHERE 1 LIMIT 1""")
  197. sql.execute("""DELETE FROM snowflakes WHERE 1""")
  198. db.commit()
  199. db.close()
  200. else:
  201. message = 'Incorrect password.<br/><b><a href="javascript:history.back()">Back.</a></b>'
  202. web.header('Content-Type','text/html; charset=utf-8', unique=True)
  203. return """<html>
  204. <head>
  205. <title>{0} | Secret Snowflake | Sign-Up</title>
  206. <style type="text/css">
  207. a:link {color:#FFFFFF;}
  208. a:visited {color:#FFFFFF;}
  209. a:hover {color:#FFFFFF;text-decoration:none;}
  210. a:active {color:#FFFFFF;}
  211. </style>
  212. </head>
  213. <body style="background-image:url(static/snowflake.png);font-family:Georgia;padding:5% 20%">
  214. <center>
  215. <h1 style="color:white">{0}'s Secret Snowflake Sign-Up</h1>
  216. </center>
  217. <div style="color:white;line-height:200%">""".format(ORGANIZATION) + message + """</div>
  218. </html>"""
  219. app = web.application(urls, globals())
  220. application = app.wsgifunc()

comments powered by Disqus