summaryrefslogtreecommitdiff
path: root/service/pixelated
diff options
context:
space:
mode:
Diffstat (limited to 'service/pixelated')
-rw-r--r--service/pixelated/adapter/mailstore/leap_mailstore.py40
-rw-r--r--service/pixelated/adapter/model/mail.py6
-rw-r--r--service/pixelated/adapter/services/mail_service.py2
-rw-r--r--service/pixelated/config/services.py2
-rw-r--r--service/pixelated/resources/mail_resource.py13
-rw-r--r--service/pixelated/resources/mails_resource.py2
-rw-r--r--service/pixelated/support/replier.py32
7 files changed, 52 insertions, 45 deletions
diff --git a/service/pixelated/adapter/mailstore/leap_mailstore.py b/service/pixelated/adapter/mailstore/leap_mailstore.py
index c2912bbe..cf8c8ed1 100644
--- a/service/pixelated/adapter/mailstore/leap_mailstore.py
+++ b/service/pixelated/adapter/mailstore/leap_mailstore.py
@@ -121,6 +121,9 @@ class LeapMail(Mail):
return result
+ def remove_duplicates(self, values):
+ return list(set(values))
+
def _decoded_header_utf_8(self, header_value):
if isinstance(header_value, list):
return self.remove_duplicates([self._decoded_header_utf_8(v) for v in header_value])
@@ -143,47 +146,12 @@ class LeapMail(Mail):
'body': self._body,
'security_casing': self.security_casing,
'textPlainBody': self._body,
- 'replying': self._replying_dict(),
'mailbox': self._mailbox_name.lower(),
'attachments': [attachment.as_dict() for attachment in self._attachments]
}
- def _replying_dict(self):
- result = {'single': None, 'all': {'to-field': [], 'cc-field': []}}
-
- sender_mail = self._decoded_header_utf_8(self.headers.get('Reply-To', self.headers.get('From')))
- # Issue #215: Fix for existing mails without any from address.
- if sender_mail is None:
- sender_mail = InputMail.FROM_EMAIL_ADDRESS
-
- recipients = self._reply_recipient('To')
- recipients = self._decoded_header_utf_8(recipients)
- recipients.append(sender_mail)
- recipients = self.remove_duplicates(recipients)
- ccs = self._decoded_header_utf_8(self._reply_recipient('Cc'))
-
- result['single'] = sender_mail
- result['all']['to-field'] = self._remove_me(recipients) if len(recipients) > 1 else recipients
- result['all']['cc-field'] = self._remove_me(ccs) if len(ccs) > 1 else ccs
- return result
-
- def _remove_me(self, recipients):
- return [recipient for recipient in recipients if not self._parsed_mail_matches(recipient, InputMail.FROM_EMAIL_ADDRESS)]
-
- def remove_duplicates(self, recipients):
- return list(set(recipients))
-
def _reply_recipient(self, kind):
- recipients = self.headers.get(kind, [])
- if not recipients:
- recipients = []
-
- return recipients
-
- def _parsed_mail_matches(self, to_parse, expected):
- if InputMail.FROM_EMAIL_ADDRESS is None:
- return False
- return parseaddr(to_parse)[1] == expected
+ return self.headers.get(kind, [])
@staticmethod
def from_dict(mail_dict):
diff --git a/service/pixelated/adapter/model/mail.py b/service/pixelated/adapter/model/mail.py
index dd2f4c0d..76df076e 100644
--- a/service/pixelated/adapter/model/mail.py
+++ b/service/pixelated/adapter/model/mail.py
@@ -141,8 +141,6 @@ class Mail(object):
class InputMail(Mail):
- FROM_EMAIL_ADDRESS = None
-
def __init__(self):
self._raw_message = None
self._fd = None
@@ -193,12 +191,12 @@ class InputMail(Mail):
})
@staticmethod
- def from_dict(mail_dict):
+ def from_dict(mail_dict, from_address):
input_mail = InputMail()
input_mail.headers = {key.capitalize(): value for key, value in mail_dict.get('header', {}).items()}
input_mail.headers['Date'] = date.mail_date_now()
- input_mail.headers['From'] = InputMail.FROM_EMAIL_ADDRESS
+ input_mail.headers['From'] = from_address
input_mail.body = mail_dict.get('body', '')
input_mail.tags = set(mail_dict.get('tags', []))
diff --git a/service/pixelated/adapter/services/mail_service.py b/service/pixelated/adapter/services/mail_service.py
index 75c0808e..cf47bfa6 100644
--- a/service/pixelated/adapter/services/mail_service.py
+++ b/service/pixelated/adapter/services/mail_service.py
@@ -96,7 +96,7 @@ class MailService(object):
@defer.inlineCallbacks
def send_mail(self, content_dict):
- mail = InputMail.from_dict(content_dict)
+ mail = InputMail.from_dict(content_dict, self.account_email)
draft_id = content_dict.get('ident')
yield self.mail_sender.sendmail(mail)
diff --git a/service/pixelated/config/services.py b/service/pixelated/config/services.py
index 114609e0..048d04a4 100644
--- a/service/pixelated/config/services.py
+++ b/service/pixelated/config/services.py
@@ -22,8 +22,6 @@ class Services(object):
@defer.inlineCallbacks
def setup(self, leap_home, leap_session):
- InputMail.FROM_EMAIL_ADDRESS = leap_session.account_email()
-
search_index_storage_key = self.setup_search_index_storage_key(leap_session.soledad)
yield self.setup_search_engine(
leap_home,
diff --git a/service/pixelated/resources/mail_resource.py b/service/pixelated/resources/mail_resource.py
index 14cb047a..3d151777 100644
--- a/service/pixelated/resources/mail_resource.py
+++ b/service/pixelated/resources/mail_resource.py
@@ -1,5 +1,6 @@
import json
from pixelated.resources import respond_json, respond_json_deferred
+from pixelated.support import replier
from twisted.web.resource import Resource
from twisted.web.server import NOT_DONE_YET
from twisted.python.log import err
@@ -36,8 +37,18 @@ class Mail(Resource):
self._mail_service = mail_service
def render_GET(self, request):
+ def populate_reply(mail):
+ mail_dict = mail.as_dict()
+ current_user = self._mail_service.account_email
+ sender = mail.headers.get('Reply-to', mail.headers.get('From'))
+ to = mail.headers.get('To', [])
+ ccs = mail.headers.get('Cc', [])
+ mail_dict['replying'] = replier.generate_recipients(sender, to, ccs, current_user)
+ return mail_dict
+
d = self._mail_service.mail(self._mail_id)
- d.addCallback(lambda mail: respond_json_deferred(mail.as_dict(), request))
+ d.addCallback(lambda mail: populate_reply(mail))
+ d.addCallback(lambda mail_dict: respond_json_deferred(mail_dict, request))
return NOT_DONE_YET
def render_DELETE(self, request):
diff --git a/service/pixelated/resources/mails_resource.py b/service/pixelated/resources/mails_resource.py
index 3a5b6286..a2f07093 100644
--- a/service/pixelated/resources/mails_resource.py
+++ b/service/pixelated/resources/mails_resource.py
@@ -198,7 +198,7 @@ class MailsResource(Resource):
content_dict = json.loads(request.content.read())
with_attachment_content = yield self._fetch_attachment_contents(content_dict)
- _mail = InputMail.from_dict(with_attachment_content)
+ _mail = InputMail.from_dict(with_attachment_content, from_address=self._mail_service.account_email)
draft_id = content_dict.get('ident')
pixelated_mail = yield self._draft_service.process_draft(draft_id, _mail)
diff --git a/service/pixelated/support/replier.py b/service/pixelated/support/replier.py
new file mode 100644
index 00000000..0bcb1a27
--- /dev/null
+++ b/service/pixelated/support/replier.py
@@ -0,0 +1,32 @@
+from email.utils import parseaddr
+
+
+def generate_recipients(sender, to, ccs, current_user):
+ result = {'single': None, 'all': {'to-field': [], 'cc-field': []}}
+
+ to.append(sender)
+ to = remove_duplicates(to)
+ ccs = remove_duplicates(ccs)
+
+ result['single'] = swap_recipient_if_needed(sender, remove_address(to, current_user), current_user)
+ result['all']['to-field'] = remove_address(to, current_user) if len(to) > 1 else to
+ result['all']['cc-field'] = remove_address(ccs, current_user) if len(ccs) > 1 else ccs
+ return result
+
+
+def remove_duplicates(recipients):
+ return list(set(recipients))
+
+
+def remove_address(recipients, current_user):
+ return [recipient for recipient in recipients if not parsed_mail_matches(recipient, current_user)]
+
+
+def parsed_mail_matches(to_parse, expected):
+ return parseaddr(to_parse)[1] == expected
+
+
+def swap_recipient_if_needed(sender, recipients, current_user):
+ if len(recipients) == 1 and parsed_mail_matches(sender, current_user):
+ return recipients[0]
+ return sender