def POSTING(message, post_name=None, host=None, action=None): name, address = parseaddr(message['from']) if not action: post.post(post_name, address, host, message) msg = view.respond(locals(), 'mail/page_ready.msg', From="noreply@%(host)s", To=message['from'], Subject="Your page '%(post_name)s' is ready.") relay.deliver(msg) # first real message, now we can index it index_q = queue.Queue("run/posts") index_q.push(message) elif action == "delete": post.delete(post_name, address) msg = view.respond(locals(), 'mail/deleted.msg', From="noreply@%(host)s", To=message['from'], Subject="Your page '%(post_name)s' was deleted.") relay.deliver(msg) else: logging.debug("Invalid action: %r", action) return POSTING
def ENROLL(message, nonce, host=None): server_name = server_name_config service_address = 'pm-enroll-%s' % (nonce,) # check if the email address is know, if it is, croak sender = c.place_sender(message) if sender == INTERNAL: logging.debug(u"INTERNAL ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return # ignore if sender != UNKNOWN: msg = "Already playing" if type(sender) is tuple: msg = msg + " " + c.campaign_name(sender[0]) if silent: logging.debug(u"ALREADY ignoring %s@%s from %s - already playing" % (service_address, server_name, message['from'])) return raise SMTPError(550, msg) enrollment = c.find_enrollment(nonce) if enrollment is None: if silent: logging.debug(u"INVALID code, ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return raise SMTPError(550, "Enrollment code invalid") (cid, short_form) = enrollment c.do_enrollment(cid, nonce, message['from'], short_form) lang = c.campaign_language(cid) campaign_name = c.campaign_name(cid) attribution = c.get_attribution(message['from']) msg = view.respond(locals(), "%s/enrolled_pc.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/enrolled_pc.subj" % (lang,))) logging.debug(u"ENROLLED short form %s, enrolled at %s, campaign %s" % (short_form, service_address, str(cid))) send_or_queue(msg, cid) (gm_address, gm_full, attribution) = c.campaign_gm(cid) msg = view.respond(locals(), "%s/enrolled_gm.msg" % (lang,), From="pm-enroll@%s" % (server_name,), To=gm_full, Subject=view.render(locals(), "%s/enrolled_gm.subj" % (lang,))) send_or_queue(msg, cid) return
def PC_END(message, nonce, host=None): # drop to NPC and inform the GM service_address = 'pm-unenroll-%s' % (nonce,) server_name = server_name_config sender = c.place_sender(message) if sender == INTERNAL: logging.debug(u"INTERNAL ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return # ignore if sender == UNKNOWN: if silent: return raise SMTPError(550, "Unknown sender") unenrollment = c.find_unenrollment(nonce) if unenrollment is None: if silent: logging.debug(u"INVALID code, ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return raise SMTPError(550, "Unenrollment code invalid") (cid, short_form) = unenrollment lang = c.campaign_language(cid) campaign_name = c.campaign_name(cid) attribution = c.get_attribution(message['from']) c.do_unenrollment(cid, nonce) logging.debug(u"UNENROLLED short form %s, unenrolled at %s, campaign %s" % (short_form, service_address, str(cid))) msg = view.respond(locals(), "%s/unenrolled_pc.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/unenrolled_pc.subj" % (lang,))) send_or_queue(msg, cid) # inform the GM (gm_address, gm_full, attribution) = c.campaign_gm(cid) msg = view.respond(locals(), "%s/unenrolled_gm.msg" % (lang,), From="pm-unenrolled@%s" % (server_name,), To=gm_full, Subject=view.render(locals(), "%s/unenrolled_gm.subj" % (lang,))) send_or_queue(msg, cid) return
def GAME_END(message, host=None): service_address = 'pm-end' server_name = server_name_config sender = c.place_sender(message) if sender == INTERNAL: return # ignore if sender == UNKNOWN: if silent: return raise SMTPError(550, "Unknown sender") cid = sender[0] lang = c.campaign_language(cid) campaign_name = c.campaign_name(cid) if sender[1]: # GM, pack and go logging.debug(u"END_GAME request from gm, campaign %s" % (str(cid),)) all_characters = c.all_characters(cid) emails = set() # save emails before the purge for character in all_characters: emails.add(character['controller']) report_id = end_campaign(cid) report_url = '%s/%s.zip' % (campaign_reports_url_config, report_id) for email in emails: msg = view.respond(locals(), "%s/end_game.msg" % (lang,), From="%s@%s" % (service_address, server_name,), To=email, Subject=view.render(locals(), "%s/end_game.subj" % (lang,))) send_or_queue(msg, cid) else: # PC, generate unenrollment address short_form = sender[2] unenrollment_address = t.start_unenrollment(cid, short_form) msg = view.respond(locals(), "%s/drop_pc.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/drop_pc.subj" % (lang,))) msg['Reply-To'] = "pm-unenroll-%s@%s" % (unenrollment_address, server_name) logging.debug(u"END_PC short form %s, unenroll at %s, campaign %s" % (short_form, unenrollment_address, str(cid))) send_or_queue(msg, cid) return
def test_respond_attach(self): person = "hello" mail = view.respond(locals(), Body="template.txt", From="test@localhost", To="receiver@localhost", Subject='Test body from someone.') view.attach(mail, locals(), 'template.html', content_type="text/html", filename="template.html", disposition='attachment') self.assertEqual(len(mail.attachments), 1) msg = mail.to_message() self.assertEqual(len(msg.get_payload()), 2) assert str(msg) mail.clear() view.attach(mail, locals(), 'template.html', content_type="text/html") self.assertEqual(len(mail.attachments), 1) msg = mail.to_message() self.assertEqual(len(msg.get_payload()), 2) assert str(msg)
def START(message, list_name=None, host=None, bad_list=None): if bad_list: if '-' in bad_list: # probably put a '.' in it, try to find a similar list similar_lists = mailinglist.similar_named_lists( bad_list.replace('-', '.')) else: similar_lists = mailinglist.similar_named_lists(bad_list) help = view.respond(locals(), "mail/bad_list_name.msg", From="noreply@%(host)s", To=message['from'], Subject="That's not a valid list name.") relay.deliver(help) return START elif list_name in INVALID_LISTS or message['from'].endswith(host): logging.debug("LOOP MESSAGE to %r from %r.", message['to'], message['from']) return START elif mailinglist.find_list(list_name): action = "subscribe to" CONFIRM.send(relay, list_name, message, 'mail/confirmation.msg', locals()) return CONFIRMING_SUBSCRIBE else: similar_lists = mailinglist.similar_named_lists(list_name) CONFIRM.send(relay, list_name, message, 'mail/create_confirmation.msg', locals()) return CONFIRMING_SUBSCRIBE
def START(message, list_name=None, host=None, bad_list=None): if bad_list: if '-' in bad_list: # probably put a '.' in it, try to find a similar list similar_lists = mailinglist.similar_named_lists(bad_list.replace('-','.')) else: similar_lists = mailinglist.similar_named_lists(bad_list) help = view.respond(locals(), "mail/bad_list_name.msg", From="noreply@%(host)s", To=message['from'], Subject="That's not a valid list name.") relay.deliver(help) return START elif list_name in INVALID_LISTS or message['from'].endswith(host): logging.debug("LOOP MESSAGE to %r from %r.", message['to'], message['from']) return START elif mailinglist.find_list(list_name): action = "subscribe to" CONFIRM.send(relay, list_name, message, 'mail/confirmation.msg', locals()) return CONFIRMING_SUBSCRIBE else: similar_lists = mailinglist.similar_named_lists(list_name) CONFIRM.send(relay, list_name, message, 'mail/create_confirmation.msg', locals()) return CONFIRMING_SUBSCRIBE
def NEW_ATTRIBUTION(message, host=None): service_address = 'pm-new-attribution' server_name = server_name_config # check the sender is known sender = c.place_sender(message) if sender == INTERNAL: logging.debug(u"INTERNAL ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return # ignore if sender == UNKNOWN: if silent: logging.debug(u"UNKNOWN ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return raise SMTPError(550, "Unknown sender") cid = sender[0] lang = c.campaign_language(cid) campaign_name = c.campaign_name(cid) attribution = message['subject'] c.set_attribution(message['from'], attribution) msg = view.respond(locals(), "%s/new_attribution.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/new_attribution.subj" % (lang,))) logging.debug(u"New attribution: %s attribute to %s" % (message['from'],attribution)) send_or_queue(msg, cid) return
def you_are_now_unbounced(message): msg = view.respond(locals(), 'mail/you_are_unbounced.msg', From='*****@*****.**', To=message['from'], Subject="You are now unbounced.") return msg
def BOUNCING(message, address=None, host=None): msg = view.respond(locals(), 'mail/we_have_disabled_you.msg', From='*****@*****.**', To=message['from'], Subject='You have bounced and are disabled.') relay.deliver(msg) return BOUNCING
def test_unicode(): person = u'H\xe9avy M\xe9t\xe5l Un\xeec\xf8d\xe9' mail = view.respond(locals(), Html="unicode.html", From="test@localhost", To="receiver@localhost", Subject='Test body from someone.') assert str(mail) view.attach(mail, locals(), "unicode.html", filename="attached.html") assert str(mail)
def test_respond_html_only(): person = 'Tester' msg = view.respond(locals(), Html='template.html', From='test@localhost', To='receiver@localhost', Subject='Test body from "%(person)s".') assert not msg.Body assert msg.Html for k in ['From', 'To', 'Subject']: assert k in msg
def COMMENTING(message, user_id=None, post_name=None, host=None, domain=None): comment.attach_headers(message, user_id, post_name, domain) comment.defer_to_queue(message) original = message # keeps the template happy msg = view.respond(locals(), "mail/comment_submitted.msg", From="noreply@%(host)s", To=original['from'], Subject="Your comment has been posted.") relay.deliver(msg) return COMMENTING
def PROTECTING(message, marketroid_id=None, host=None, user_id=None): if user_id: logging.warning("Attempted user->user email from %r", message['from']) forbid = view.respond(locals(), "mail/forbid.msg", From="noreply@%(host)s", To=message['from'], Subject="You cannot email another user or yourself.") relay.deliver(forbid) else: reply = filter.route_reply(message, marketroid_id, host) relay.deliver(reply) return PROTECTING
def test_respond_plain_text(): dude = 'Tester' msg = view.respond(locals(), Body='template.txt', From='test@localhost', To='receiver@localhost', Subject='Test body from "%(dude)s".') assert msg.Body assert not msg.Html for k in ['From', 'To', 'Subject']: assert k in msg
def test_respond_cadillac_version(self): person = 'Tester' msg = view.respond(locals(), Body='template.txt', Html='template.html', From='test@localhost', To='receiver@localhost', Subject='Test body from "%(person)s".') assert msg.Body assert msg.Html for k in ['From', 'To', 'Subject']: assert k in msg
def PROTECTING(message, marketroid_id=None, host=None, user_id=None): if user_id: logging.warning("Attempted user->user email from %r", message['from']) forbid = view.respond( locals(), "mail/forbid.msg", From="noreply@%(host)s", To=message['from'], Subject="You cannot email another user or yourself.") relay.deliver(forbid) else: reply = filter.route_reply(message, marketroid_id, host) relay.deliver(reply) return PROTECTING
def CONFIRMING(message, id_number=None, host=None): original = CONFIRM.verify('start', message['from'], id_number) if original: user_anon = addressing.mapping(message['from'], 'user', host) welcome = view.respond(locals(), "mail/welcome.msg", From=user_anon, To=message['from'], Subject="Welcome to MyInboxIsNotA.TV") relay.deliver(welcome) return PROTECTING else: logging.warning("Invalid confirm from %s", message['from']) return CONFIRMING
def CONFIRMING(message, id_number=None, host=None): original = CONFIRM.verify('comment', message['from'], id_number) if original: # headers are already attached from START comment.defer_to_queue(original) msg = view.respond(locals(), "mail/comment_submitted.msg", From="noreply@%(host)s", To=original['from'], Subject="Your comment has been posted.") relay.deliver(msg) return COMMENTING else: logging.debug("Invalid confirm from %s", message['from']) return CONFIRMING
def CONFIRMING_SUBSCRIBE(message, list_name=None, id_number=None, host=None): original = CONFIRM.verify(list_name, message['from'], id_number) if original: mailinglist.add_subscriber(message['from'], list_name) msg = view.respond(locals(), "mail/subscribed.msg", From="noreply@%(host)s", To=message['from'], Subject="Welcome to %(list_name)s list.") relay.deliver(msg) CONFIRM.cancel(list_name, message['from'], id_number) return POSTING else: logging.warning("Invalid confirm from %s", message['from']) return CONFIRMING_SUBSCRIBE
def CONFIRMING(message, id_number=None, host=None): original = CONFIRM.verify('post', message['from'], id_number) if original: name, address = parseaddr(original['from']) post_name = original['x-post-name'] post_id = post.post(post_name, address, host, original) msg = view.respond(locals(), "mail/welcome.msg", From="noreply@%(host)s", To=message['from'], Subject="Welcome, your blog is ready.") relay.deliver(msg) return POSTING else: logging.warning("Invalid confirm from %s", message['from']) return CONFIRMING
def CONFIRMING_UNSUBSCRIBE(message, list_name=None, id_number=None, host=None): original = CONFIRM.verify(list_name, message['from'], id_number) if original: mailinglist.remove_subscriber(message['from'], list_name) msg = view.respond(locals(), 'mail/unsubscribed.msg', From="noreply@%(host)s", To=message['from'], Subject="You are now unsubscribed from %(list_name)s.") relay.deliver(msg) CONFIRM.cancel(list_name, message['from'], id_number) return START else: logging.warning("Invalid unsubscribe confirm from %s", message['from']) return CONFIRMING_UNSUBSCRIBE
def mail_to_you_is_bouncing(message): reason = message.bounce.error_for_humans() msg = view.respond(locals(), 'mail/you_bounced.msg', From='*****@*****.**', To=message.bounce.original['to'], Subject="Email to you is bouncing.") if message.bounce.report: for report in message.bounce.report: msg.attach('bounce_report.msg', content_type='text/plain', data=encoding.to_string(report), disposition='attachment') if message.bounce.notification: msg.attach('notification_report.msg', content_type='text/plain', data=encoding.to_string(message.bounce.notification), disposition='attachment') return msg
def CONFIRMING_UNSUBSCRIBE(message, list_name=None, id_number=None, host=None): original = CONFIRM.verify(list_name, message['from'], id_number) if original: mailinglist.remove_subscriber(message['from'], list_name) msg = view.respond( locals(), 'mail/unsubscribed.msg', From="noreply@%(host)s", To=message['from'], Subject="You are now unsubscribed from %(list_name)s.") relay.deliver(msg) CONFIRM.cancel(list_name, message['from'], id_number) return START else: logging.warning("Invalid unsubscribe confirm from %s", message['from']) return CONFIRMING_UNSUBSCRIBE
def test_respond_attach(): person = "hello" mail = view.respond(locals(), Body="template.txt", From="test@localhost", To="receiver@localhost", Subject='Test body from someone.') view.attach(mail, locals(), 'template.html', content_type="text/html", filename="template.html", disposition='attachment') assert_equal(len(mail.attachments), 1) msg = mail.to_message() assert_equal(len(msg.get_payload()), 2) assert str(msg) mail.clear() view.attach(mail, locals(), 'template.html', content_type="text/html") assert_equal(len(mail.attachments), 1) msg = mail.to_message() assert_equal(len(msg.get_payload()), 2) assert str(msg)
def send(self, relay, target, message, template, vars): """ This is the method you should use to send out confirmation messages. You give it the relay, a target (i.e. "subscribe"), the message they sent requesting the confirm, your confirmation template, and any vars that template needs. The result of calling this is that the template message gets sent through the relay, the original message is stored in the pending queue, and data is put into the storage for later calls to verify. """ confirm_address = self.register(target, message) vars.update(locals()) msg = view.respond(vars, template, To=message['from'], From="%(confirm_address)s@%(host)s", Subject="Confirmation required") msg['Reply-To'] = "%(confirm_address)s@%(host)s" % vars relay.deliver(msg)
def GAME_SUMMARY(message, host=None): service_address = 'pm-summary' server_name = server_name_config sender = c.place_sender(message) if sender == INTERNAL: return # ignore if sender == UNKNOWN: if silent: return raise SMTPError(550, "Unknown sender") cid = sender[0] lang = c.campaign_language(cid) campaign_name = c.campaign_name(cid) if not sender[1]: if silent: logging.debug(u"NOT_GM ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return raise SMTPError(550, "Not a GM") logging.debug(u"GAME_SUMMARY request from gm, campaign %s" % (str(cid),)) all_characters = c.all_characters(cid) emails = set() # save emails before the purge for character in all_characters: emails.add(character['controller']) report_id = end_campaign(cid, purge=False) report_url = '%s/%s.zip' % (campaign_reports_url_config, report_id) msg = view.respond(locals(), "%s/game_summary.msg" % (lang,), From="%s@%s" % (service_address, server_name,), To=message['from'], Subject=view.render(locals(), "%s/game_summary.subj" % (lang,))) send_or_queue(msg, cid) return
def _new_campaign(message, lang, service_address): # check if the email address is know, if it is, croak sender = c.place_sender(message) if sender == INTERNAL: return # ignore server_name = server_name_config if sender != UNKNOWN: msg = "Already playing" if type(sender) is tuple: msg = msg + " " + c.campaign_name(sender[0]) if silent: logging.debug(u"MESSAGE to %s@%s from %s - already playing" % (service_address, server_name, message['from'])) return raise SMTPError(550, msg) # use subject for name of campaign campaign_name = message['subject'] # create campaign, set language to lang cid = c.new_campaign(campaign_name, message['from'], lang) # generate reply attribution = c.get_attribution(message['from']) msg = view.respond(locals(), "%s/new_campaign.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/new_campaign.subj" % (lang,))) logging.debug(u"MESSAGE to %s@%s from %s, new campaign %s - %s" % (service_address, server_name, safe_unicode(message['from']), str(cid), campaign_name)) send_or_queue(msg, cid) return
def test_most_basic_form(): msg = view.respond(locals(), 'template.txt') assert msg.Body
def NEW_CHARACTER(message, host=None, pc_or_npc="n"): service_address = 'pm-new-' + ("n" if pc_or_npc else "") + "pc" server_name = server_name_config # check the sender is an active GM, otherwise raise 550 sender = c.place_sender(message) if sender == INTERNAL: logging.debug(u"INTERNAL ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return # ignore if sender == UNKNOWN: if silent: logging.debug(u"UNKNOWN ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return raise SMTPError(550, "Unknown sender") if not sender[1]: if silent: logging.debug(u"NOT_GM ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return raise SMTPError(550, "Not a GM") cid = sender[0] lang = c.campaign_language(cid) campaign_name = c.campaign_name(cid) attribution = c.get_attribution(message['from']) # get name of the character from subject, produce short form, # ensure short form doesn't collide with existing characters full_name = message['subject'] if '(' in full_name: ( full_name, short_form ) = full_name.split('(') full_name = full_name.strip() if ')' in short_form: short_form = short_form.split(')')[0].strip() else: short_form = full_name.split(' ')[0] full_name = full_name.strip() short_form = short_form.lower() if c.character_exists(cid, short_form): all_characters = c.all_characters(cid) msg = view.respond(locals(), "%s/repeated_short_form.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/repeated_short_form.subj" % (lang,))) logging.debug(u"DUPLICATE short form %s, campaign %s" % (short_form, str(cid))) send_or_queue(msg, cid) return if pc_or_npc: # create NPC, associate it with current campaign c.new_npc(cid, short_form, full_name) all_characters = c.all_characters(cid) # return template on the campaign language confirming its creation msg = view.respond(locals(), "%s/new_npc.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/new_npc.subj" % (lang,))) logging.debug(u"NEW_NPC short form %s, campaign %s" % (short_form, str(cid))) send_or_queue(msg, cid) return else: # create PC, associate it with current campaign and generate # enrollment email enrollment_address = c.new_pc(cid, short_form, full_name) all_characters = c.all_characters(cid) # return template on the campaign language with the enrollment email msg = view.respond(locals(), "%s/new_pc.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/new_pc.subj" % (lang,))) logging.debug(u"NEW_PC short form %s, enroll at %s, campaign %s" % (short_form, enrollment_address, str(cid))) send_or_queue(msg, cid) return
def START(message, address=None, host=None): server_name = server_name_config if(address.startswith("pm-")): return # ignore sender = c.place_sender(message) if sender == INTERNAL: return # ignore if sender == UNKNOWN: if silent: logging.debug(u"MESSAGE to %s@%s from %s - unknown" % (address, server_name, message['from'])) return raise SMTPError(550, "Unknown sender") cid = sender[0] # check the message haven't been processed already if tst_email_processed(message, cid): logging.debug(u"IGNORING processed email %s" % (message['message-id'],)) return # ignore # the message as been set as processed lang = c.campaign_language(cid) campaign_name = c.campaign_name(cid) server_name = server_name_config recipients = c.get_recipients(message) if sender[1]: # GM EMAIL # determine if the email is sent as somebody else (gm_address, gm_full, attribution) = c.campaign_gm(cid) send_as = None for recipient in recipients: if recipient.startswith('as-'): if send_as: other = send_as = recipient[3:].lower() msg = view.respond(locals(), "%s/repeated_as.msg" % (lang,), From="gm@%s" % (server_name,), To=gm_full, Subject=view.render(locals(), "%s/repeated_as.subj" % (lang,))) send_or_queue(msg, cid) return send_as = recipient[3:].lower() # validate the as-XYZ is valid or note, otherwise if send_as: original_send_as = send_as send_as = c.get_character(cid, send_as) if not send_as: # reply with error to the GM with list of valid send-as all_characters = c.all_characters(cid) send_as = original_send_as msg = view.respond(locals(), "%s/unknown_as.msg" % (lang,), From="gm@%s" % (server_name,), To=gm_full, Subject=view.render(locals(), "%s/unknown_as.subj" % (lang,))) send_or_queue(msg, cid) return if send_as: sender = formataddr( (send_as['name'], '%s@%s' % (send_as['address'], server_name)) ) else: sender = 'gm@%s' % (server_name,) # for each recipient that is not an NPC, generate an email # either from the gm or from whomever is send_as to them with # cc: to the other characters and send them # extract the text full_content = message.body() #TODO check message.base.parts for recipient in recipients: if recipient.startswith('as-'): continue if recipient.startswith('pm-'): continue character = c.get_character(cid, recipient) if int(character['is_npc']) : continue if character is None: #TODO localize full_content = "UNKNOWN: " + recipient msg = view.respond(locals(), "%s/base.msg" % (lang,), From="gm@%s" % (server_name,), To=gm_full, Subject=full_content) logging.debug(u"INVALID character %s" % (recipient,)) send_or_queue(msg, cid) return # ignore cc_list = [] for other in recipients: if other.startswith('as-'): cc_list.append('gm@%s' % (server_name,)) elif other.startswith('pm-') and not send_as: # this will be ignored by the server, but notifies # the users unless is a send-as which will # highlight the send-as to the players cc_list.append('%s@%s' % (other, server_name)) elif other != recipient: other_character = c.get_character(cid, other) if other_character is None: full_content = "UNKNOWN: " + other msg = view.respond(locals(), "%s/base.msg" % (lang,), From="gm@%s" % (server_name,), To=gm_full, Subject=full_content) logging.debug(u"INVALID character %s" % (othert,)) send_or_queue(msg, cid) return # ignore cc_list.append(formataddr( (other_character['name'], '%s@%s' % (other,server_name,)) )) # sort them cc_list = sorted(cc_list) attribution = c.get_attribution(character['controller']) msg = view.respond(locals(), "%s/base.msg" % (lang,), From=sender, To=formataddr( (attribution, character['controller']) ), Subject=campaign_name) if cc_list: msg['cc'] = ", ".join(cc_list) send_or_queue(msg, cid) else: short_form = sender[2] full_character = c.get_character(cid, short_form) # change the sender to their character email and send to GM (gm_address, gm_full, attribution) = c.campaign_gm(cid) # cc: for show cc_list = [] for recipient in recipients: if recipient == 'gm': continue character = c.get_character(cid, recipient) cc_list.append(formataddr( (character['name'], '%s@%s' % (recipient,server_name,)) )) # sort them cc_list = sorted(cc_list) # extract the text full_content = sanitize(message.body()) #TODO check message.base.parts msg = view.respond(locals(), "%s/base.msg" % (lang,), From=formataddr( (full_character['name'], "%s@%s" % (short_form, server_name)) ), To=gm_full, Subject="%s: %s" % (campaign_name, full_character['name'])) if cc_list: msg['cc'] = ", ".join(cc_list) send_or_queue(msg, cid) return
def test_no_templates(self): with self.assertRaises(TypeError): view.respond(locals(), From="me@localhost", To="you@localhost", Subject="Hello")
def ROLL(message, host=None): service_address = 'pm-roll' server_name = server_name_config sender = c.place_sender(message) if sender == INTERNAL: return # ignore if sender == UNKNOWN: if silent: return raise SMTPError(550, "Unknown sender") cid = sender[0] lang = c.campaign_language(cid) if not sender[1]: # croak only GMs can ask for rolls msg = view.respond(locals(), "%s/roll/not_gm.msg" % (lang,), From="%s@%s" % (service_address, server_name,), To=message['from'], Subject=view.render(locals(), "%s/roll/not_gm.subj" % (lang,))) send_or_queue(msg, cid) return (gm_address, gm_full, attribution) = c.campaign_gm(cid) # find the recipient that is a PC (if none, internal roll from the GM) recipients = c.get_recipients(message) character = None for recipient in recipients: if recipient == 'gm': continue if recipient == service_address: continue this_character = c.get_character(cid, recipient) if not int(this_character['is_npc']): if character is not None: # croak only one character per roll msg = view.respond(locals(), "%s/roll/too_many_characters.msg" % (lang,), From="%s@%s" % (service_address, server_name,), To=gm_full, Subject=view.render(locals(), "%s/roll/too_many_characters.subj" % (lang,))) send_or_queue(msg, cid) return character = recipient # find the roll commands rolls = [] full_content = message.body() text = safe_unicode(full_content) lines = text.split('\n') for line in lines: if line.startswith('ROLL:'): rolls.append(line[len('ROLL:'):]) if len(rolls) == 0: # croak no rolls msg = view.respond(locals(), "%s/roll/no_rolls.msg" % (lang,), From="%s@%s" % (service_address, server_name,), To=gm_full, Subject=view.render(locals(), "%s/roll/no_rolls.subj" % (lang,))) send_or_queue(msg, cid) return # for each roll command, register a roll-id and send a pm-dice-(rollid) email if character is not None: full_character = c.get_character(cid, character) character = full_character attribution = c.get_attribution(character['controller']) for roll in rolls: try: hashid = add_roll( cid, 'gm' if character is None else character['address'], roll ) return_service_address = 'pm-dice-' + hashid roll_address = "%s@%s" % (return_service_address, server_name,) msg = view.respond(locals(), "%s/roll/to_roll.msg" % (lang,), From="%s@%s" % (service_address, server_name,), To=gm_full if character is None else character['controller'], Subject=view.render(locals(), "%s/roll/to_roll.subj" % (lang,))) msg['Reply-To'] = roll_address except RollStrParseException as e: msg = view.respond(locals(), "%s/roll/syntax_error.msg" % (lang,), From="%s@%s" % (service_address, server_name,), To=gm_full, Subject=view.render(locals(), "%s/roll/syntax_error.subj" % (lang,))) send_or_queue(msg, cid) return
def DICE(message, rollid, host=None): service_address = 'pm-dice-' + rollid server_name = server_name_config # check the sender is known sender = c.place_sender(message) if sender == INTERNAL: logging.debug(u"INTERNAL ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return # ignore if sender == UNKNOWN: if silent: logging.debug(u"UNKNOWN ignoring %s@%s from %s" % (service_address, server_name, message['from'])) return raise SMTPError(550, "Unknown sender") cid = sender[0] lang = c.campaign_language(cid) # verify the rollid exists and belongs to the sender roll_obj = find_roll(rollid) if roll_obj is None: # croak no roll msg = view.respond(locals(), "%s/roll/no_roll.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/roll/no_roll.subj" % (lang,))) send_or_queue(msg, cid) return if roll_obj is True: # croak already rolled, return result ( roll, check, roll_str ) = execute_roll(rollid) msg = view.respond(locals(), "%s/roll/already_rolled.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/roll/already_rolled.subj" % (lang,))) send_or_queue(msg, cid) return ( roll_cid, roll_character, roll_str ) = roll_obj if str(roll_cid) != str(cid): # croak spurious ID msg = view.respond(locals(), "%s/roll/no_roll.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/roll/no_roll.subj" % (lang,))) send_or_queue(msg, cid) return if not sender[1] and safe_unicode(roll_character).lower() != safe_unicode(sender[2]): # croak not the right person for this roll you_are = sender[2] intended_for = roll_character msg = view.respond(locals(), "%s/roll/wrong_person.msg" % (lang,), From="%s@%s" % (service_address, server_name), To=message['from'], Subject=view.render(locals(), "%s/roll/wrong_person.subj" % (lang,))) send_or_queue(msg, cid) return # perform the roll ( roll, check, roll_str ) = execute_roll(rollid) # report back to the sender and GM (if they are different) (gm_address, gm_full, attribution) = c.campaign_gm(cid) # GM email msg = view.respond(locals(), "%s/roll/rolled.msg" % (lang,), From="%s@%s" % (service_address, server_name,), To=gm_full, Subject=view.render(locals(), "%s/roll/rolled.subj" % (lang,))) if not sender[1]: msg['cc'] = '%s@%s' % (roll_character, server_name,) send_or_queue(msg, cid) if not sender[1]: character = c.get_character(cid, sender[2]) attribution = c.get_attribution(character['controller']) msg = view.respond(locals(), "%s/roll/rolled.msg" % (lang,), From="%s@%s" % (service_address, server_name,), To= formataddr( (attribution, character['controller']) ), Subject=view.render(locals(), "%s/roll/rolled.subj" % (lang,))) msg['cc'] = 'gm@%s' % (server_name,) send_or_queue(msg, cid) return