Parent: [7536f4] (diff)

Child: [d41b6a] (diff)

Download this file

common_react.py    147 lines (131 with data), 5.4 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import logging
import tg
from pylons import c, g
from bson import ObjectId
from allura.lib.decorators import audit, react
from allura.lib.helpers import push_config
from allura import model as M
from forgemail.lib import util, exc
log = logging.getLogger(__name__)
common_suffix = tg.config.get('forgemail.domain', '.sourceforge.net')
smtp_client = util.SMTPClient()
@audit('search.check_commit')
@react('forgemail.fire')
def fire_ready_emails(routing_key, data):
M.Mailbox.fire_ready()
@react('forgemail.notify')
def received_notification(routing_key, data):
g.set_app(data['mount_point'])
M.Mailbox.deliver(
data['notification_id'],
data['artifact_index_id'],
data['topic'])
g.publish('react', 'forgemail.fire')
@audit('forgemail.received_email')
def received_email(routing_key, data):
'''Route messages according to their destination:
<topic>@<mount_point>.<subproj2>.<subproj1>.<project>.projects.sourceforge.net
goes to the audit with routing ID
<tool name>.mail.<topic>
'''
msg = util.parse_message(data['data'])
user = util.identify_sender(data['peer'], data['mailfrom'], msg['headers'], msg)
log.info('Received email from %s', user)
# For each of the addrs, determine the project/app and route appropriately
for addr in data['rcpttos']:
try:
topic, project, app = util.parse_address(addr)
routing_key = topic
with push_config(c, project=project, app=app):
if not app.has_access(user, topic):
log.info('Access denied for %s to mailbox %s',
user, topic)
else:
log.info('Sending message to audit queue %s', topic)
if msg['multipart']:
msg_hdrs = msg['headers']
for part in msg['parts'][1:]:
msg = dict(
headers=dict(msg_hdrs, **part['headers']),
message_id=part['message_id'][0],
in_reply_to=part['in_reply_to'],
references=part['references'],
filename=part['filename'],
content_type=part['content_type'],
payload=part['payload'],
user_id=user._id and str(user._id))
g.publish('audit', routing_key, msg,
serializer='yaml')
else:
g.publish('audit', routing_key,
dict(msg, user_id=user._id and str(user._id)),
serializer='pickle')
except exc.ForgeMailException, e:
log.error('Error routing email to %s: %s', addr, e)
except:
log.exception('Error routing mail to %s', addr)
@audit('forgemail.send_email')
def send_email(routing_key, data):
addrs_plain = []
addrs_html = []
addrs_multi = []
fromaddr = data['from']
if '@' not in fromaddr:
user = M.User.query.get(_id=ObjectId(fromaddr))
if not user:
log.warning('Cannot find user with ID %s', fromaddr)
fromaddr = 'noreply@in.sf.net'
else:
fromaddr = user.email_address_header()
# Divide addresses based on preferred email formats
for addr in data['destinations']:
if '@' in addr:
addrs_plain.append(addr)
else:
user = M.User.query.get(_id=ObjectId(addr))
if not user:
log.warning('Cannot find user with ID %s', addr)
continue
addr = user.email_address_header()
if not addr and user.email_addresses:
addr = user.email_addresses[0]
log.warning('User %s has not set primary email address, using %s',
user._id, addr)
if not addr:
log.error("User %s (%s) has not set any email address, can't deliver",
user._id, user.username)
continue
if user.preferences.email_format == 'plain':
addrs_plain.append(addr)
elif user.preferences.email_format == 'html':
addrs_html.append(addr)
else:
addrs_multi.append(addr)
plain_msg = util.encode_email_part(data['text'], 'plain')
html_text = g.forge_markdown(email=True).convert(data['text'])
html_msg = util.encode_email_part(html_text, 'html')
multi_msg = util.make_multipart_message(plain_msg, html_msg)
smtp_client.sendmail(
addrs_multi,
fromaddr,
data['reply_to'],
data['subject'],
data['message_id'],
data.get('in_reply_to', None),
multi_msg)
smtp_client.sendmail(
addrs_plain,
fromaddr,
data['reply_to'],
data['subject'],
data['message_id'],
data.get('in_reply_to', None),
plain_msg)
smtp_client.sendmail(
addrs_html,
fromaddr,
data['reply_to'],
data['subject'],
data['message_id'],
data.get('in_reply_to', None),
html_msg)