diff options
-rw-r--r-- | service/pixelated/adapter/mail_service.py | 5 | ||||
-rw-r--r-- | service/pixelated/adapter/pixelated_mail.py | 36 | ||||
-rw-r--r-- | service/pixelated/adapter/pixelated_mailbox.py | 8 | ||||
-rw-r--r-- | service/pixelated/adapter/pixelated_mailboxes.py | 8 | ||||
-rw-r--r-- | service/pixelated/adapter/status.py | 1 | ||||
-rw-r--r-- | service/pixelated/user_agent.py | 10 | ||||
-rw-r--r-- | service/test/adapter/pixelated_mail_test.py | 5 | ||||
-rw-r--r-- | service/test/adapter/test_tag_service.py | 4 |
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) |