summaryrefslogtreecommitdiffstats
path: root/askbot/lamson_handlers.py
diff options
context:
space:
mode:
Diffstat (limited to 'askbot/lamson_handlers.py')
-rw-r--r--askbot/lamson_handlers.py167
1 files changed, 167 insertions, 0 deletions
diff --git a/askbot/lamson_handlers.py b/askbot/lamson_handlers.py
new file mode 100644
index 00000000..488d8b12
--- /dev/null
+++ b/askbot/lamson_handlers.py
@@ -0,0 +1,167 @@
+import re
+from lamson.routing import route, stateless
+from lamson.server import Relay
+from django.utils.translation import ugettext as _
+from django.core.files.uploadedfile import SimpleUploadedFile
+from django.conf import settings
+from askbot.models import ReplyAddress
+from askbot.utils import mail
+
+
+#we might end up needing to use something like this
+#to distinguish the reply text from the quoted original message
+"""
+def _strip_message_qoute(message_text):
+ import re
+ result = message_text
+ pattern = "(?P<qoute>" + \
+ "On ([a-zA-Z0-9, :/<>@\.\"\[\]]* wrote:.*)|" + \
+ "From: [\w@ \.]* \[mailto:[\w\.]*@[\w\.]*\].*|" + \
+ "From: [\w@ \.]*(\n|\r\n)+Sent: [\*\w@ \.,:/]*(\n|\r\n)+To:.*(\n|\r\n)+.*|" + \
+ "[- ]*Forwarded by [\w@ \.,:/]*.*|" + \
+ "From: [\w@ \.<>\-]*(\n|\r\n)To: [\w@ \.<>\-]*(\n|\r\n)Date: [\w@ \.<>\-:,]*\n.*|" + \
+ "From: [\w@ \.<>\-]*(\n|\r\n)To: [\w@ \.<>\-]*(\n|\r\n)Sent: [\*\w@ \.,:/]*(\n|\r\n).*|" + \
+ "From: [\w@ \.<>\-]*(\n|\r\n)To: [\w@ \.<>\-]*(\n|\r\n)Subject:.*|" + \
+ "(-| )*Original Message(-| )*.*)"
+ groups = re.search(pattern, email_text, re.IGNORECASE + re.DOTALL)
+ qoute = None
+ if not groups is None:
+ if groups.groupdict().has_key("qoute"):
+ qoute = groups.groupdict()["qoute"]
+ if qoute:
+ result = reslut.split(qoute)[0]
+ #if the last line contains an email message remove that one too
+ lines = result.splitlines(True)
+ if re.search(r'[\w\.]*@[\w\.]*\].*', lines[-1]):
+ result = '\n'.join(lines[:-1])
+ return result
+"""
+
+def get_disposition(part):
+ """return list of part's content dispositions
+ or an empty list
+ """
+ dispositions = part.content_encoding.get('Content-Disposition', None)
+ if dispositions:
+ return dispositions[0]
+ else:
+ return list()
+
+def get_attachment_info(part):
+ return part.content_encoding['Content-Disposition'][1]
+
+def is_attachment(part):
+ """True if part content disposition is
+ attachment"""
+ return get_disposition(part) == 'attachment'
+
+def process_attachment(part):
+ """takes message part and turns it into SimpleUploadedFile object"""
+ att_info = get_attachment_info(part)
+ name = att_info.get('filename', None)
+ content_type = get_content_type(part)
+ return SimpleUploadedFile(name, part.body, content_type)
+
+def get_content_type(part):
+ """return content type of the message part"""
+ return part.content_encoding.get('Content-Type', (None,))[0]
+
+def is_body(part):
+ """True, if part is plain text and is not attachment"""
+ if get_content_type(part) == 'text/plain':
+ if not is_attachment(part):
+ return True
+ return False
+
+def get_body(message):
+ """returns plain text body of the message"""
+ body = message.body()
+ if body:
+ return body
+ for part in message.walk():
+ if is_body(part):
+ return part.body
+
+def get_attachments(message):
+ """returns a list of file attachments
+ represented by StringIO objects"""
+ attachments = list()
+ for part in message.walk():
+ if is_attachment(part):
+ attachments.append(process_attachment(part))
+ return attachments
+
+@route('ask@(host)')
+@stateless
+def ASK(message, host = None):
+ body = get_body(message)
+ attachments = get_attachments(message)
+ from_address = message.From
+ subject = message['Subject']#why lamson does not give it normally?
+ mail.process_emailed_question(from_address, subject, body, attachments)
+
+
+@route('reply-(address)@(host)', address='.+')
+@stateless
+def PROCESS(message, address = None, host = None):
+ """handler to process the emailed message
+ and make a post to askbot based on the contents of
+ the email, including the text body and the file attachments"""
+ try:
+ for rule in settings.LAMSON_FORWARD:
+ if re.match(rule['pattern'], message.base['to']):
+ relay = Relay(host=rule['host'],
+ port=rule['port'], debug=1)
+ relay.deliver(message)
+ return
+ except AttributeError:
+ pass
+
+ error = None
+ try:
+ reply_address = ReplyAddress.objects.get(
+ address = address,
+ allowed_from_email = message.From
+ )
+ separator = _("======= Reply above this line. ====-=-=")
+ parts = get_body(message).split(separator)
+ attachments = get_attachments(message)
+ if len(parts) != 2 :
+ error = _("Your message was malformed. Please make sure to qoute \
+ the original notification you received at the end of your reply.")
+ else:
+ reply_part = parts[0]
+ reply_part = '\n'.join(reply_part.splitlines(True)[:-3])
+ #the function below actually posts to the forum
+ if reply_address.was_used:
+ reply_address.edit_post(
+ reply_part.strip(),
+ attachments = attachments
+ )
+ else:
+ reply_address.create_reply(
+ reply_part.strip(),
+ attachments = attachments
+ )
+ except ReplyAddress.DoesNotExist:
+ error = _("You were replying to an email address\
+ unknown to the system or you were replying from a different address from the one where you\
+ received the notification.")
+ except Exception, e:
+ import sys
+ sys.stderr.write(str(e))
+ import traceback
+ sys.stderr.write(traceback.format_exc())
+
+ if error is not None:
+ from askbot.utils import mail
+ from django.template import Context
+ from askbot.skins.loaders import get_template
+
+ template = get_template('reply_by_email_error.html')
+ body_text = template.render(Context({'error':error}))
+ mail.send_mail(
+ subject_line = "Error posting your reply",
+ body_text = body_text,
+ recipient_list = [message.From],
+ )