summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorPatrick Maia <pmaia@thoughtworks.com>2014-09-15 11:39:25 -0300
committerPatrick Maia <pmaia@thoughtworks.com>2014-09-15 11:48:47 -0300
commit4eeca4b0e3ba10ad08a937d08546384f1c67351c (patch)
treecb6fee2a42121ab658dc35c9fbee19b01954d4e8 /service
parentfa6806de54873dca3823a9a95b3c40c1c97934cc (diff)
#74 - Moving message to trash mailbox
Diffstat (limited to 'service')
-rw-r--r--service/pixelated/adapter/mail_service.py5
-rw-r--r--service/pixelated/adapter/pixelated_mail.py36
-rw-r--r--service/pixelated/adapter/pixelated_mailbox.py8
-rw-r--r--service/pixelated/adapter/pixelated_mailboxes.py8
-rw-r--r--service/pixelated/adapter/status.py1
-rw-r--r--service/pixelated/user_agent.py10
-rw-r--r--service/test/adapter/pixelated_mail_test.py5
-rw-r--r--service/test/adapter/test_tag_service.py4
8 files changed, 63 insertions, 14 deletions
diff --git a/service/pixelated/adapter/mail_service.py b/service/pixelated/adapter/mail_service.py
index 52c1abc7..debdc9b7 100644
--- a/service/pixelated/adapter/mail_service.py
+++ b/service/pixelated/adapter/mail_service.py
@@ -66,7 +66,10 @@ class MailService:
raise NotImplementedError()
def delete_mail(self, mail_id):
- raise NotImplementedError()
+ mail = self.mailboxes.mail(mail_id)
+ new_mailbox_tag, old_mailbox_tag = mail.move_to(self.mailboxes.trash())
+ self.tag_service.notify_tags_updated([], [old_mailbox_tag], mail_id)
+ self.tag_service.notify_tags_updated([new_mailbox_tag], [], None)
def save_draft(self, draft):
raise NotImplementedError()
diff --git a/service/pixelated/adapter/pixelated_mail.py b/service/pixelated/adapter/pixelated_mail.py
index fd03ea48..2aead409 100644
--- a/service/pixelated/adapter/pixelated_mail.py
+++ b/service/pixelated/adapter/pixelated_mail.py
@@ -15,6 +15,7 @@
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
from pixelated.adapter.status import Status
from pixelated.support.id_gen import gen_pixelated_uid
+import json
import pixelated.support.date
import dateutil.parser as dateparser
from email.MIMEMultipart import MIMEMultipart
@@ -27,19 +28,22 @@ class PixelatedMail:
pass
@staticmethod
- def from_leap_mail(leap_mail, leap_mail_collection=None):
+ def from_leap_mail(leap_mail, leap_mailbox=None):
mail = PixelatedMail()
mail.leap_mail = leap_mail
- mail.leap_mail._collection = leap_mail_collection # Work around until they fix the issue of mails not having the collection set on a LeapMailbox
+ mail.leap_mailbox = leap_mailbox
mail.body = leap_mail.bdoc.content['raw']
mail.headers = mail._extract_headers()
mail.date = PixelatedMail._get_date(mail.headers)
- mail.ident = gen_pixelated_uid(leap_mail._mbox, leap_mail.getUID())
mail.status = set(mail._extract_status())
mail.security_casing = {}
mail.tags = mail._extract_tags()
return mail
+ @property
+ def ident(self):
+ return gen_pixelated_uid(self.leap_mailbox.mbox, self.leap_mail.getUID())
+
def set_from(self, _from):
self.headers['from'] = [_from]
@@ -70,7 +74,7 @@ class PixelatedMail:
return temporary_headers
def _extract_tags(self):
- return set(self.headers.get('x-tags', []))
+ return set(json.loads(self.headers.get('x-tags', '[]')))
def update_tags(self, tags):
old_tags = self.tags
@@ -87,12 +91,34 @@ class PixelatedMail:
def _persist_mail_tags(self, current_tags):
hdoc = self.leap_mail.hdoc
- hdoc.content['headers']['X-Tags'] = list(current_tags)
+ hdoc.content['headers']['X-Tags'] = json.dumps(list(current_tags))
self.leap_mail._soledad.put_doc(hdoc)
def has_tag(self, tag):
return tag in self.tags
+ def move_to(self, destiny_mailbox):
+ new_leap_mail = destiny_mailbox.add_mail(self)
+ self._delete_from_leap_mailbox()
+ old_mailbox_tag = self.leap_mailbox.mbox.lower()
+ self._update_leap_references(destiny_mailbox.leap_mailbox, new_leap_mail)
+
+ return destiny_mailbox.mailbox_tag, old_mailbox_tag
+
+ def _delete_from_leap_mailbox(self):
+ self.leap_mail.setFlags((Status.PixelatedStatus.DELETED,), 1)
+ self.leap_mailbox.expunge()
+
+ def _update_leap_references(self, new_leap_mailbox, new_leap_mail):
+ self.leap_mailbox = new_leap_mailbox
+ self.leap_mail = new_leap_mail
+
+ def raw_message(self):
+ raw_message = ''.join("%s: %s\n" % (key, value) for key, value in self.leap_mail.hdoc.content['headers'].items())
+ raw_message += '\n\n'
+ raw_message += self.leap_mail.bdoc.content['raw']
+ return raw_message
+
def as_dict(self):
statuses = [status.name for status in self.status]
_headers = self.headers.copy()
diff --git a/service/pixelated/adapter/pixelated_mailbox.py b/service/pixelated/adapter/pixelated_mailbox.py
index 4d4d8faa..cc44ede7 100644
--- a/service/pixelated/adapter/pixelated_mailbox.py
+++ b/service/pixelated/adapter/pixelated_mailbox.py
@@ -16,7 +16,6 @@
from pixelated.adapter.pixelated_mail import PixelatedMail
from pixelated.adapter.tag_service import TagService
-from pixelated.support.id_gen import gen_pixelated_uid
class PixelatedMailbox:
@@ -39,7 +38,8 @@ class PixelatedMailbox:
mails = self.leap_mailbox.messages or []
result = []
for mail in mails:
- pixelated_mail = PixelatedMail.from_leap_mail(mail, mails)
+ mail._collection = mails
+ pixelated_mail = PixelatedMail.from_leap_mail(mail, self.leap_mailbox)
self.add_mailbox_tag_if_not_there(pixelated_mail)
result.append(pixelated_mail)
return result
@@ -54,6 +54,10 @@ class PixelatedMailbox:
if message.ident == mail_id:
return message
+ def add_mail(self, mail):
+ original_flags = mail.leap_mail.getFlags()
+ self.leap_mailbox.addMessage(mail.raw_message(), original_flags)
+
@classmethod
def create(cls, account, mailbox_name='INBOX'):
return PixelatedMailbox(account.getMailbox(mailbox_name))
diff --git a/service/pixelated/adapter/pixelated_mailboxes.py b/service/pixelated/adapter/pixelated_mailboxes.py
index 411e8ac0..c003f3fd 100644
--- a/service/pixelated/adapter/pixelated_mailboxes.py
+++ b/service/pixelated/adapter/pixelated_mailboxes.py
@@ -22,3 +22,11 @@ class PixelatedMailBoxes():
mail = mailbox.mail(mail_id)
if mail:
return mail
+
+ def mailbox_exists(self, name):
+ return name.upper() in map(lambda x: x.upper(), self.account.mailboxes)
+
+ def trash(self):
+ if not self.mailbox_exists('TRASH'):
+ self.account.addMailbox('TRASH')
+ return PixelatedMailbox.create(self.account, 'TRASH')
diff --git a/service/pixelated/adapter/status.py b/service/pixelated/adapter/status.py
index 96257414..0917b748 100644
--- a/service/pixelated/adapter/status.py
+++ b/service/pixelated/adapter/status.py
@@ -20,6 +20,7 @@ class Status:
class PixelatedStatus:
SEEN = u'\\Seen'
ANSWERED = u'\\Answered'
+ DELETED = u'\\Deleted'
LEAP_FLAGS_STATUSES = {
PixelatedStatus.SEEN: 'read',
diff --git a/service/pixelated/user_agent.py b/service/pixelated/user_agent.py
index aba06f05..c018b1bb 100644
--- a/service/pixelated/user_agent.py
+++ b/service/pixelated/user_agent.py
@@ -96,11 +96,19 @@ def mails():
@app.route('/mail/<mail_id>', methods=['DELETE'])
-def delete_mails(mail_id):
+def delete_mail(mail_id):
mail_service.delete_mail(mail_id)
return respond_json(None)
+@app.route('/mails', methods=['DELETE'])
+def delete_mails():
+ idents = json.loads(request.form['idents'])
+ for ident in idents:
+ mail_service.delete_mail(ident)
+ return respond_json(None)
+
+
@app.route('/tags')
def tags():
tags = mail_service.all_tags()
diff --git a/service/test/adapter/pixelated_mail_test.py b/service/test/adapter/pixelated_mail_test.py
index e364f7a9..9d7176a4 100644
--- a/service/test/adapter/pixelated_mail_test.py
+++ b/service/test/adapter/pixelated_mail_test.py
@@ -17,7 +17,6 @@ import unittest
import pixelated.support.date
from pixelated.adapter.pixelated_mail import PixelatedMail
-from pixelated.adapter.pixelated_mail import Status
import test_helper
@@ -74,7 +73,7 @@ class TestPixelatedMail(unittest.TestCase):
self.assertEqual('date now', mail.headers['date'])
def test_update_tags_return_a_set_for_added_tags_and_a_set_for_removed_ones(self):
- pixelated_mail = PixelatedMail.from_leap_mail(test_helper.leap_mail(extra_headers={'X-tags': ['custom_1', 'custom_2']}))
+ pixelated_mail = PixelatedMail.from_leap_mail(test_helper.leap_mail(extra_headers={'X-tags': '["custom_1", "custom_2"]'}))
added, removed = pixelated_mail.update_tags(set(['custom_1', 'custom_3']))
self.assertEquals(set(['custom_3']), added)
self.assertEquals(set(['custom_2']), removed)
@@ -116,6 +115,6 @@ class TestPixelatedMail(unittest.TestCase):
def test_mark_as_read(self):
mail = PixelatedMail.from_leap_mail(test_helper.leap_mail(flags=[]))
- read_mail = mail.mark_as_read()
+ mail.mark_as_read()
self.assertEquals(mail.leap_mail.setFlags.call_args[0], (('\\Seen',), 1))
diff --git a/service/test/adapter/test_tag_service.py b/service/test/adapter/test_tag_service.py
index 20888092..b3a68c2b 100644
--- a/service/test/adapter/test_tag_service.py
+++ b/service/test/adapter/test_tag_service.py
@@ -30,8 +30,8 @@ class TagServiceTest(unittest.TestCase):
self.tag_service = TagService(tag_index=self.tag_index)
def test_index_is_initialized_with_mail_tags_if_empty(self):
- mail_one = PixelatedMail.from_leap_mail(test_helper.leap_mail(uid=0, extra_headers={'X-Tags': ['tag_1']}))
- mail_two = PixelatedMail.from_leap_mail(test_helper.leap_mail(uid=1, extra_headers={'X-Tags': ['tag_2']}))
+ mail_one = PixelatedMail.from_leap_mail(test_helper.leap_mail(uid=0, extra_headers={'X-Tags': '["tag_1"]'}), test_helper.leap_mailbox())
+ mail_two = PixelatedMail.from_leap_mail(test_helper.leap_mail(uid=1, extra_headers={'X-Tags': '["tag_2"]'}), test_helper.leap_mailbox())
mails = [mail_one, mail_two]
self.tag_service.load_index(mails)