Skip to content

Commit

Permalink
Implement user page and working digest email and reminder email.
Browse files Browse the repository at this point in the history
  • Loading branch information
kushal committed Jan 9, 2011
1 parent b669d90 commit c470f2b
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 80 deletions.
45 changes: 45 additions & 0 deletions dateutil.py
@@ -0,0 +1,45 @@
import datetime

class Eastern_tzinfo(datetime.tzinfo):
"""Implementation of the Eastern timezone.
Adapted from http://code.google.com/appengine/docs/python/datastore/typesandpropertyclasses.html
"""
def utcoffset(self, dt):
return datetime.timedelta(hours=-5) + self.dst(dt)

def _FirstSunday(self, dt):
"""First Sunday on or after dt."""
return dt + datetime.timedelta(days=(6-dt.weekday()))

def dst(self, dt):
# 2 am on the second Sunday in March
dst_start = self._FirstSunday(datetime.datetime(dt.year, 3, 8, 2))
# 1 am on the first Sunday in November
dst_end = self._FirstSunday(datetime.datetime(dt.year, 11, 1, 1))

if dst_start <= dt.replace(tzinfo=None) < dst_end:
return datetime.timedelta(hours=1)
else:
return datetime.timedelta(hours=0)

def tzname(self, dt):
if self.dst(dt) == datetime.timedelta(hours=0):
return "EST"
else:
return "EDT"


def date_for_new_snippet():
"""Return next Monday, unless it is Monday (0) or Tuesday (1)"""
today = datetime.datetime.now(Eastern_tzinfo()).date()
if (today.weekday() < 2):
aligned = today - datetime.timedelta(days=today.weekday())
else:
aligned = today + datetime.timedelta(days=(7 - today.weekday()))
return aligned

def date_for_retrieval():
"""Always return the most recent Monday."""
today = datetime.datetime.now(Eastern_tzinfo()).date()
return today - datetime.timedelta(days=today.weekday())
65 changes: 38 additions & 27 deletions emails.py
@@ -1,37 +1,48 @@
import logging

from google.appengine.api import mail from google.appengine.api import mail
from google.appengine.api import taskqueue from google.appengine.api import taskqueue
from google.appengine.ext import webapp from google.appengine.ext import webapp
from google.appengine.ext.webapp import util from google.appengine.ext.webapp import util


class ReminderEmail(webapp.RequestHandler): from dateutil import *
def get(self): from model import *
pass
taskqueue.add(url='/onereminder', params={'user': key})

class DigestEmail(webapp.RequestHandler):
def get(self):
# Find all users and add to queue
taskqueue.add(url='/onedigest', params={'user': key})


class OneReminder(webapp.RequestHandler): REMINDER = """
def post(self): Hey nerd,
key = self.request.get('user')
mail.send_mail(sender="Example.com Support <support@example.com>",
to="Albert Johnson <Albert.Johnson@example.com>",
subject="Your account has been approved",
body="""
Dear Albert:
Your example.com account has been approved. You can now visit The kids want to know what you're up to. Don't leave 'em hanging.
http://www.example.com/ and sign in using your Google Account to """
access new features.


Please let us know if you have any questions. class ReminderEmail(webapp.RequestHandler):
def __send_mail(self, recipient):
The example.com Team mail.send_mail(sender="snippets <snippets@fssnippets.appspotmail.com>",
""") to=recipient,
subject="Snippet time!",
body=REMINDER)


class OneDigest(webapp.RequestHandler): def get(self):
def post(self): all_users = User.all().filter("enabled =", True).fetch(500)
key = self.request.get('user') for user in all_users:
# TODO: Check if one has already been submitted for this period.
self.__send_mail(user.user.email())


class DigestEmail(webapp.RequestHandler):
def __send_mail(self, recipient, body):
mail.send_mail(sender="snippets <snippets@fssnippets.appspotmail.com>",
to=recipient,
subject="Snippet delivery!",
body=body)

def __snippet_to_text(self, snippet):
divider = '-' * 30
return '%s\n%s\n%s' % (snippet.user.user.email(), divider, snippet.text)

def get(self):
all_users = User.all().filter("enabled =", True).fetch(500)
d = date_for_retrieval()
all_snippets = Snippet.all().filter("date =", d).fetch(500)
# TODO: Build custom emails
body = '\n\n\n'.join([self.__snippet_to_text(s) for s in all_snippets])
for user in all_users:
self.__send_mail(user.user.email(), body)
18 changes: 15 additions & 3 deletions main.py
Expand Up @@ -57,13 +57,15 @@ class UserHandler(BaseHandler):
"""Show a given user's snippets.""" """Show a given user's snippets."""


def authed_get(self, user): def authed_get(self, user):
desired_user = user_from_email(self.request.get('user')) desired_user = user_from_email(self.request.get('email'))
snippets = user.snippets_set snippets = user.snippet_set
snippets = sorted(snippets, key=lambda s: s.date, reverse=True)


self.response.headers['Content-Type'] = 'text/html' self.response.headers['Content-Type'] = 'text/html'
template_values = { template_values = {
'current_user' : user, 'current_user' : user,
'user': desired_user 'user': desired_user,
'snippets': snippets
} }


path = os.path.join(os.path.dirname(__file__), 'templates/user.html') path = os.path.join(os.path.dirname(__file__), 'templates/user.html')
Expand All @@ -81,6 +83,16 @@ class MainHandler(BaseHandler):
"""Show list of all users and acting user's settings.""" """Show list of all users and acting user's settings."""


def authed_get(self, user): def authed_get(self, user):
# Update enabled state if requested
set_enabled = self.request.get('setenabled')
if set_enabled == '1':
user.enabled = True
user.put()
elif set_enabled == '0':
user.enabled = False
user.put()

# Fetch user list and display
all_users = User.all().fetch(500) all_users = User.all().fetch(500)
self.response.headers['Content-Type'] = 'text/html' self.response.headers['Content-Type'] = 'text/html'
template_values = { template_values = {
Expand Down
3 changes: 1 addition & 2 deletions model.py
Expand Up @@ -6,15 +6,14 @@
class User(db.Model): class User(db.Model):
user = db.UserProperty() user = db.UserProperty()
following = db.ListProperty(db.Key) following = db.ListProperty(db.Key)
enabled = db.BooleanProperty() enabled = db.BooleanProperty(default=True)


class Snippet(db.Model): class Snippet(db.Model):
user = db.ReferenceProperty(User) user = db.ReferenceProperty(User)
text = db.TextProperty() text = db.TextProperty()
date = db.DateProperty() date = db.DateProperty()


def user_from_email(email): def user_from_email(email):
logging.info(email)
return User.all().filter("user =", users.User(email)).fetch(1)[0] return User.all().filter("user =", users.User(email)).fetch(1)[0]


def create_or_replace_snippet(user, text, date): def create_or_replace_snippet(user, text, date):
Expand Down
42 changes: 2 additions & 40 deletions receive_email.py
Expand Up @@ -6,54 +6,16 @@
from google.appengine.ext.webapp.mail_handlers import InboundMailHandler from google.appengine.ext.webapp.mail_handlers import InboundMailHandler
from google.appengine.ext.webapp import util from google.appengine.ext.webapp import util


from dateutil import date_for_new_snippet
from model import user_from_email, create_or_replace_snippet from model import user_from_email, create_or_replace_snippet



class Eastern_tzinfo(datetime.tzinfo):
"""Implementation of the Eastern timezone.
Adapted from http://code.google.com/appengine/docs/python/datastore/typesandpropertyclasses.html
"""
def utcoffset(self, dt):
return datetime.timedelta(hours=-5) + self.dst(dt)

def _FirstSunday(self, dt):
"""First Sunday on or after dt."""
return dt + datetime.timedelta(days=(6-dt.weekday()))

def dst(self, dt):
# 2 am on the second Sunday in March
dst_start = self._FirstSunday(datetime.datetime(dt.year, 3, 8, 2))
# 1 am on the first Sunday in November
dst_end = self._FirstSunday(datetime.datetime(dt.year, 11, 1, 1))

if dst_start <= dt.replace(tzinfo=None) < dst_end:
return datetime.timedelta(hours=1)
else:
return datetime.timedelta(hours=0)

def tzname(self, dt):
if self.dst(dt) == datetime.timedelta(hours=0):
return "EST"
else:
return "EDT"


class ReceiveEmail(InboundMailHandler): class ReceiveEmail(InboundMailHandler):
"""Receive a snippet email and create or replace snippet for this week.""" """Receive a snippet email and create or replace snippet for this week."""


def receive(self, message): def receive(self, message):
user = user_from_email(message.sender) user = user_from_email(message.sender)
for content_type, body in message.bodies('text/plain'): for content_type, body in message.bodies('text/plain'):
today = datetime.datetime.now(Eastern_tzinfo()).date() create_or_replace_snippet(user, body.decode(), date_for_new_snippet())

# For now, just align to next Monday, unless it is Monday (0), Tuesday (1)
if (today.weekday() < 2):
aligned = today - datetime.timedelta(days=today.weekday())
else:
aligned = today + datetime.timedelta(days=(7 - today.weekday()))

create_or_replace_snippet(user, body.decode(), aligned)




def main(): def main():
Expand Down
8 changes: 5 additions & 3 deletions templates/base.html
Expand Up @@ -2,13 +2,15 @@
<html> <html>
<head> <head>
<style> <style>
body { font-family: Helvetica, sans-serif; font-size: 83% } body { font-family: Courier New, monospaced; font-size: 83% }
a.title { color: #CCC; text-decoration: none }
a.title:hover { text-decoration: underline }
</style> </style>
<title>{% block title %}Snippets{% endblock %}</title> <title>{% block title %}snippets{% endblock %}</title>
</head> </head>


<body> <body>
<h2>Snippets</h2> <h1><a class="title" href="/">snippets</a></h2>
{% block body %} {% block body %}
{% endblock %} {% endblock %}
</body> </body>
Expand Down
14 changes: 9 additions & 5 deletions templates/index.html
@@ -1,13 +1,17 @@
{% extends "base.html" %} {% extends "base.html" %}


{% block body %} {% block body %}
<b><a href="/user?email={{ current_user.user.email }}">{{ current_user.user.email }}</a></b> <h2><a href="/user?email={{ current_user.user.email }}">{{ current_user.user.email }}</a></h2>
<br/> currently
Currently {{ current_user.enabled }} {% if current_user.enabled %}

<b>enabled</b> <a href="?setenabled=0">disable</a>
{% else %}
<b>disabled</b> <a href="?setenabled=1">enable</a>
{% endif %}

<h3>Users</h3> <h3>Users</h3>
{% for user in all_users %} {% for user in all_users %}
<a href="/user?email={{ user.email }}">{{ user.email }}</a> <a href="/user?email={{ user.user.email }}">{{ user.user.email }}</a>
<br/> <br/>
{% endfor %} {% endfor %}


Expand Down
12 changes: 12 additions & 0 deletions templates/user.html
@@ -0,0 +1,12 @@
{% extends "base.html" %}

{% block body %}
<h2>{{ user.user.email }}</h2>

{% for snippet in snippets %}
<b>{{ snippet.date }}</b><br/>
{{ snippet.text }}
<br/></br>
{% endfor %}

{% endblock %}

0 comments on commit c470f2b

Please sign in to comment.