Parent: [3cd6e9] (diff)

Child: [22f354] (diff)

Download this file

common_react.py    126 lines (112 with data), 4.8 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
import logging
import tg
from pylons import c, g
from pymongo.bson import ObjectId
from pyforge.lib.decorators import audit
from pyforge.lib.helpers import push_config
from pyforge 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('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
<plugin name>.<topic>
'''
msg = util.parse_message(data['data'])
user = util.identify_sender(data['peer'], data['mailfrom'], 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)
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']),
filename=part['filename'],
content_type=part['content_type'],
payload=part['payload'],
user_id=str(user._id))
g.publish('audit', topic, msg,
serializer='yaml')
continue
log.info('eq, is = (%s,%s)',
part['headers'] == msg_hdrs,
part['headers'] is msg_hdrs)
log.info('Headers: %s', part['headers'])
continue
g.publish('audit', topic,
dict(part, user_id=str(user._id)),
serializer='pickle')
else:
g.publish('audit', topic,
dict(msg, user_id=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 = []
# 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.url_decode(addr))
if not user:
log.warning('Cannot find user with ID %s', addr)
continue
addr = user.preferences.email_address
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 has not set any email address, can't deliver",
user._id)
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.markdown.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,
data['from'],
data['subject'],
data['message_id'],
data.get('in_reply_to', None),
multi_msg)
smtp_client.sendmail(
addrs_plain,
data['from'],
data['subject'],
data['message_id'],
data.get('in_reply_to', None),
plain_msg)
smtp_client.sendmail(
addrs_html,
data['from'],
data['subject'],
data['message_id'],
data.get('in_reply_to', None),
html_msg)