def get(self): settings = Settings.get() #Force email address update... posts = Post.query().order(-Post.date).fetch(1) is_newest = True if posts: post = posts[0] is_oldest = post.date == Post.min_date() else: post = None is_oldest = True #See if this is the very first time we've been here. In that case #send an email immediately to get people started... first_time = False if not Slug.query().get() and not Post.query().get(): first_time = True DailyMail().send(True) self.response.write( get_template('frontpage.html').render({ "page": "frontpage", "post": post, "is_oldest": is_oldest, "is_newest": is_newest, "first_time": first_time, "email": settings.email_address }))
def get(self): settings = Settings.get() #Force email address update... posts = Post.query().order(-Post.date).fetch(1) is_newest = True if posts: post = posts[0] is_oldest = post.date == Post.min_date() else: post = None is_oldest = True #See if this is the very first time we've been here. In that case #send an email immediately to get people started... first_time = False if not Slug.query().get() and not Post.query().get(): first_time = True DailyMail().send(True) self.response.write(get_template('frontpage.html').render( { "page":"frontpage", "post":post, "is_oldest" : is_oldest, "is_newest" : is_newest, "first_time" : first_time, "email" : settings.email_address }))
def check_if_mail_already_sent(self, date): #Check if we've already sent an email existing_slug = Slug.query(Slug.date == date).get() if existing_slug: msg = 'Tried to send another email on %s, already sent %s' % (date, existing_slug.slug) log_error('Tried to send email again', msg) raise Exception(msg)
def get_slug(self): slug = str(uuid.uuid4())[0:13].replace('-', '') # OK, this should never happen, but I'm not using the full uuid here # so lets just make sure... while Slug.query(Slug.slug == slug).get(): slug = str(uuid.uuid4())[0:13].replace('-', '') return slug
def receive(self, mail_message): try: id = self.get_id(mail_message) if not id: return slug = Slug.query(Slug.slug == id).get() if not slug: log_error('Invalid slug', 'Found no slug for id %s', id) return body_text, body_html = self.get_bodies(mail_message) raw_mail = RawMail( subject=mail_message.subject, sender=mail_message.sender, slug=id, date=slug.date, text=body_text, html=body_html ) raw_mail.put() post = Post.query(Post.date == slug.date).get() is_new_post = post is None if is_new_post: post = Post( date=slug.date, source='email', has_images=False ) #Now let's try parsing it into a good post... if body_html: post_text = strip_html(body_html) #Prefer html because then we don't get linebreak issues logging.info('Parsing post from html') else: post_text = body_text logging.info('Parsing post from plain text') if not post_text: raise Exception('No plain text body in email, html body can\'t be parsed yet!') try: email_index = post_text.index('post+%s@' % id) post_text = post_text[:email_index] newline_index = post_text.rstrip().rindex('\n') post_text = post_text[:newline_index].strip() except: logging.info('Failed to remove all crap from post') #Strip 'Sent from my iPhone' if it's there. There are probably endless other Sent from #we could handle, but hey, I have an iPhone so that's the one I care about... post_text = re.sub('\s*Sent from my iPhone\s*$', '', post_text) post_text = post_text.rstrip() if post.text: post.text = post.text + '\r\n\r\n' + Post.seperator + '\r\n\r\n' + post_text else: post.text = post_text self.process_attachments(mail_message, post) post.put() if is_new_post: counter = PostCounter.get() counter.increment(post.date.year, post.date.month) except: log_error('Failed to parse incoming email', traceback.format_exc(6))
def check_if_intro_email_sent_today(self, date): two_slugs = [s for s in Slug.query().fetch(2)] return len(two_slugs) == 1 and two_slugs[0].date == date
def receive(self, mail_message): try: id = self.get_id(mail_message) if not id: return slug = Slug.query(Slug.slug == id).get() if not slug: log_error('Invalid slug', 'Found no slug for id %s', id) return body_text, body_html = self.get_bodies(mail_message) raw_mail = RawMail(subject=mail_message.subject, sender=mail_message.sender, slug=id, date=slug.date, text=body_text, html=body_html) raw_mail.put() post = Post.query(Post.date == slug.date).get() is_new_post = post is None if is_new_post: post = Post(date=slug.date, source='email', has_images=False) #Now let's try parsing it into a good post... if body_html: post_text = strip_html( body_html ) #Prefer html because then we don't get linebreak issues logging.info('Parsing post from html') else: post_text = body_text logging.info('Parsing post from plain text') if not post_text: raise Exception( 'No plain text body in email, html body can\'t be parsed yet!' ) try: email_index = post_text.index('post+%s@' % id) post_text = post_text[:email_index] newline_index = post_text.rstrip().rindex('\n') post_text = post_text[:newline_index].strip() except: logging.info('Failed to remove all crap from post') #Strip 'Sent from my iPhone' if it's there. There are probably endless other Sent from #we could handle, but hey, I have an iPhone so that's the one I care about... post_text = re.sub('\s*Sent from my iPhone\s*$', '', post_text) post_text = post_text.rstrip() if post.text: post.text = post.text + '\r\n\r\n' + Post.seperator + '\r\n\r\n' + post_text else: post.text = post_text self.process_attachments(mail_message, post) post.put() if is_new_post: counter = PostCounter.get() counter.increment(post.date.year, post.date.month) except: log_error('Failed to parse incoming email', traceback.format_exc(6))
def send(self, is_intro_email=False, force_send=False, date=None): try: now = datetime.datetime.now() settings = Settings.get() if is_intro_email: current_time = now logging.info('Sending intro email to %s' % settings.email_address) else: current_time, id, name, offset = self.get_time_in_timezone(settings) if current_time.hour != settings.email_hour and not force_send: logging.info('Current time for %s is %s, not sending email now, will send at %02d:00' % (name, current_time, settings.email_hour)) return if date and force_send: today = date #Allow overriding this stuff else: today = current_time.date() if self.check_if_intro_email_sent_today(today) and not force_send: logging.info('Already sent the intro email today, skipping this email for now') return #Check if we've already sent an email slug = Slug.query(Slug.date == today).get() if slug and not force_send: msg = 'Tried to send another email on %s, already sent %s' % (date, slug.slug) log_error('Tried to send email again', msg) raise Exception(msg) if not slug: slug_id = self.get_slug() slug = Slug(slug=slug_id, date=today) slug.put() subject = "It's %s, %s %s - How did your day go?" % (today.strftime('%A'), today.strftime("%b"), today.day) app_id = app_identity.get_application_id() sender = "MyLife <post+%s@%s.appspotmail.com>" % (slug.slug, app_id) message = mail.EmailMessage(sender=sender, subject=subject) message.to = settings.email_address if not settings.email_address: log_error('Missing To in daily email', 'There is no configured email address in your settings. Please visit your settings page to configure it so we can send you your daily email.') return message.body = """ Just reply to this email with your entry. OLD_POST """.replace('APP_ID', app_id) message.html = """ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.= w3.org/TR/html4/loose.dtd"> <html> <head> <title></title> </head> <body> Just reply to this email with your entry. <br> <br> OLD_POST </body> </html> """.replace('APP_ID', app_id) if is_intro_email: intro_msg = "Welcome to MyLife. We've sent you this email immediately so you can try the system out. In the future we will email you once a day and include an old post in each email. You can configure when you get your email and which email address we should use on the settings page." message.html = message.html.replace('OLD_POST', intro_msg + '<br><br>') message.body = message.body.replace('OLD_POST', intro_msg + '\r\n\r\n') else: #Lets try to put in an old post... old_post, old_type = self.get_old_post(today) if old_post and settings.include_old_post_in_entry: old_post_text = 'Remember this? One %s ago you wrote:\r\n\r\n' % old_type old_post_text += old_post.text.rstrip() + '\r\n\r\n' message.body = re.sub(r'OLD_POST\r?\n', old_post_text, message.body) old_post_text = re.sub(r'\r?\n', '<br>', old_post_text) message.html = re.sub(r'OLD_POST\r?\n', old_post_text, message.html) else: message.body = re.sub('OLD_POST\r?\n', '', message.body) message.html = re.sub('OLD_POST\r?\n', '', message.html) message.send() if is_intro_email: logging.info('Sent intro email') else: if old_post: logging.info('Sent daily email to %s, using old post from %s' % (message.to, old_post.date)) else: logging.info('Sent daily email to %s, could not find old post' % message.to) return 'Email sent' except: log_error('Failed to send daily email', traceback.format_exc(6)) return 'Failed sending email: %s' % traceback.format_exc(6)
def send(self, is_intro_email=False, force_send=False, date=None): try: now = datetime.datetime.now() settings = Settings.get() if is_intro_email: current_time = now logging.info('Sending intro email to %s' % settings.email_address) else: current_time, id, name, offset = self.get_time_in_timezone(settings) if current_time.hour != settings.email_hour and not force_send: logging.info('Current time for %s is %s, not sending email now, will send at %02d:00' % (name, current_time, settings.email_hour)) return if date and force_send: today = date #Allow overriding this stuff else: today = current_time.date() if self.check_if_intro_email_sent_today(today) and not force_send: logging.info('Already sent the intro email today, skipping this email for now') return #Check if we've already sent an email slug = Slug.query(Slug.date == today).get() if slug and not force_send: msg = 'Tried to send another email on %s, already sent %s' % (date, slug.slug) log_error('Tried to send email again', msg) raise Exception(msg) if not slug: slug_id = self.get_slug() slug = Slug(slug=slug_id, date=today) slug.put() subject = "It's %s, %s %s - How did your day go?" % (today.strftime('%A'), today.strftime("%b"), today.day) app_id = app_identity.get_application_id() sender = "MyLife <post+%s@%s.appspotmail.com>" % (slug.slug, app_id) message = mail.EmailMessage(sender=sender, subject=subject) message.to = settings.email_address if not settings.email_address: log_error('Missing To in daily email', 'There is no configured email address in your settings. Please visit your settings page to configure it so we can send you your daily email.') return message.body = """ Just reply to this email with your entry. OLD_POST """.replace('APP_ID', app_id) message.html = """ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.= w3.org/TR/html4/loose.dtd"> <html> <head> <title></title> </head> <body> Just reply to this email with your entry. <br> <br> OLD_POST </body> </html> """.replace('APP_ID', app_id) if is_intro_email: intro_msg = "Welcome to MyLife. We've sent you this email immediately so you can try the system out. In the future we will email you once a day and include an old post in each email. You can configure when you get your email and which email address we should use on the settings page." message.html = message.html.replace('OLD_POST', intro_msg + '<br><br>') message.body = message.body.replace('OLD_POST', intro_msg + '\r\n\r\n') else: #Lets try to put in an old post... old_post, old_type = self.get_old_post(today) if old_post and settings.include_old_post_in_entry: logging.info('Going to use old post %s because %s' % (old_post, settings.include_old_post_in_entry)) if (old_type == 'random'): old_post_text = 'Remember this? On <b>%s, %s %s, %s</b> you wrote:\r\n\r\n' % (old_post.date.strftime('%A'), old_post.date.strftime("%b"), old_post.date.day, old_post.date.strftime("%Y")) else: old_post_text = 'Remember this? One %s ago you wrote:\r\n\r\n' % old_type old_post_text += old_post.text.rstrip() + '\r\n\r\n' message.body = re.sub(r'OLD_POST\r?\n', old_post_text, message.body) old_post_text = re.sub(r'\r?\n', '<br>', old_post_text) message.html = re.sub(r'OLD_POST\r?\n', old_post_text, message.html) else: logging.info('Not using Old post %s because %s' % (old_post, settings.include_old_post_in_entry)) message.body = re.sub('OLD_POST\r?\n', '', message.body) message.html = re.sub('OLD_POST\r?\n', '', message.html) message.send() if is_intro_email: logging.info('Sent intro email') else: if old_post: logging.info('Sent daily email to %s, using old post from %s' % (message.to, old_post.date)) else: logging.info('Sent daily email to %s, could not find old post' % message.to) return 'Email sent' except: log_error('Failed to send daily email', traceback.format_exc(6)) return 'Failed sending email: %s' % traceback.format_exc(6)