summaryrefslogtreecommitdiff
path: root/service/pixelated/adapter/services
diff options
context:
space:
mode:
authorDuda Dornelles <ddornell@thoughtworks.com>2014-12-22 09:35:01 -0200
committerDuda Dornelles <ddornell@thoughtworks.com>2014-12-22 09:38:08 -0200
commit66839f191708a0725c8d9841d5266ad13af8ee81 (patch)
tree337fb19e99625cc3243f998a2351cea123c037a2 /service/pixelated/adapter/services
parenta0cbaf84fd86fc91cba892a7a19b0ade7c017a3c (diff)
refactoring package structure
Diffstat (limited to 'service/pixelated/adapter/services')
-rw-r--r--service/pixelated/adapter/services/__init__.py15
-rw-r--r--service/pixelated/adapter/services/draft_service.py34
-rw-r--r--service/pixelated/adapter/services/mail_sender.py38
-rw-r--r--service/pixelated/adapter/services/mail_service.py89
-rw-r--r--service/pixelated/adapter/services/mailbox.py51
-rw-r--r--service/pixelated/adapter/services/mailboxes.py68
-rw-r--r--service/pixelated/adapter/services/tag_service.py26
7 files changed, 321 insertions, 0 deletions
diff --git a/service/pixelated/adapter/services/__init__.py b/service/pixelated/adapter/services/__init__.py
new file mode 100644
index 00000000..2756a319
--- /dev/null
+++ b/service/pixelated/adapter/services/__init__.py
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2014 ThoughtWorks, Inc.
+#
+# Pixelated is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pixelated is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
diff --git a/service/pixelated/adapter/services/draft_service.py b/service/pixelated/adapter/services/draft_service.py
new file mode 100644
index 00000000..ddb86c5c
--- /dev/null
+++ b/service/pixelated/adapter/services/draft_service.py
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2014 ThoughtWorks, Inc.
+#
+# Pixelated is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pixelated is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
+
+
+class DraftService(object):
+ __slots__ = '_mailboxes'
+
+ def __init__(self, mailboxes):
+ self._mailboxes = mailboxes
+
+ def create_draft(self, input_mail):
+ self._drafts().add(input_mail)
+ return input_mail
+
+ def update_draft(self, ident, input_mail):
+ new_mail = self.create_draft(input_mail)
+ self._drafts().remove(ident)
+ return new_mail
+
+ def _drafts(self):
+ return self._mailboxes.drafts()
diff --git a/service/pixelated/adapter/services/mail_sender.py b/service/pixelated/adapter/services/mail_sender.py
new file mode 100644
index 00000000..50c17ba5
--- /dev/null
+++ b/service/pixelated/adapter/services/mail_sender.py
@@ -0,0 +1,38 @@
+#
+# Copyright (c) 2014 ThoughtWorks, Inc.
+#
+# Pixelated is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pixelated is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
+from StringIO import StringIO
+
+from twisted.internet.defer import Deferred
+from twisted.mail.smtp import SMTPSenderFactory
+from twisted.internet import reactor
+from pixelated.support.functional import flatten
+
+
+class MailSender():
+ def __init__(self, account_email_address, smtp_client=None):
+ self.account_email_address = account_email_address
+
+ def sendmail(self, mail):
+ recipients = flatten([mail.to, mail.cc, mail.bcc])
+
+ resultDeferred = Deferred()
+ senderFactory = SMTPSenderFactory(
+ fromEmail=self.account_email_address,
+ toEmail=recipients,
+ file=StringIO(mail.to_smtp_format()),
+ deferred=resultDeferred)
+
+ return reactor.connectTCP('localhost', 4650, senderFactory)
diff --git a/service/pixelated/adapter/services/mail_service.py b/service/pixelated/adapter/services/mail_service.py
new file mode 100644
index 00000000..722b9a29
--- /dev/null
+++ b/service/pixelated/adapter/services/mail_service.py
@@ -0,0 +1,89 @@
+#
+# Copyright (c) 2014 ThoughtWorks, Inc.
+#
+# Pixelated is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pixelated is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
+
+
+class MailService:
+ __slots__ = ['leap_session', 'account', 'mailbox_name']
+
+ def __init__(self, mailboxes, mail_sender, tag_service, soledad_querier):
+ self.tag_service = tag_service
+ self.mailboxes = mailboxes
+ self.querier = soledad_querier
+ self.mail_sender = mail_sender
+
+ def all_mails(self):
+ return self.querier.all_mails()
+
+ def mails(self, ids):
+ return self.querier.mails(ids)
+
+ def update_tags(self, mail_id, new_tags):
+ reserved_words = self.tag_service.extract_reserved(new_tags)
+ if len(reserved_words):
+ raise ValueError('None of the following words can be used as tags: ' + ' '.join(reserved_words))
+ mail = self.mail(mail_id)
+ mail.update_tags(set(new_tags))
+ return mail
+
+ def mail(self, mail_id):
+ return self.mailboxes.mail(mail_id)
+
+ def send(self, last_draft_ident, mail):
+ self.mail_sender.sendmail(mail)
+ if last_draft_ident:
+ self.mailboxes.drafts().remove(last_draft_ident)
+ return self.mailboxes.sent().add(mail)
+
+ def thread(self, thread_id):
+ raise NotImplementedError()
+
+ def mark_as_read(self, mail_id):
+ return self.mail(mail_id).mark_as_read()
+
+ def mark_as_unread(self, mail_id):
+ return self.mail(mail_id).mark_as_unread()
+
+ def tags_for_thread(self, thread):
+ raise NotImplementedError()
+
+ def add_tag_to_thread(self, thread_id, tag):
+ raise NotImplementedError()
+
+ def remove_tag_from_thread(self, thread_id, tag):
+ raise NotImplementedError()
+
+ def delete_mail(self, mail_id):
+ return self.mailboxes.move_to_trash(mail_id)
+
+ def delete_permanent(self, mail_id):
+ mail = self.mail(mail_id)
+ self.querier.remove_mail(mail)
+
+ def save_draft(self, draft):
+ raise NotImplementedError()
+
+ def draft_reply_for(self, mail_id):
+ raise NotImplementedError()
+
+ def all_contacts(self, query):
+ raise NotImplementedError()
+
+ def drafts(self):
+ raise NotImplementedError()
+
+ def reply_all_template(self, mail_id):
+ mail = self.mail(mail_id)
+ return mail.to_reply_template()
diff --git a/service/pixelated/adapter/services/mailbox.py b/service/pixelated/adapter/services/mailbox.py
new file mode 100644
index 00000000..fbdbfc30
--- /dev/null
+++ b/service/pixelated/adapter/services/mailbox.py
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2014 ThoughtWorks, Inc.
+#
+# Pixelated is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pixelated is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
+
+
+class Mailbox:
+
+ def __init__(self, mailbox_name, querier):
+ self.mailbox_name = mailbox_name
+ self.mailbox_tag = mailbox_name.lower()
+ self.querier = querier
+
+ def mails(self):
+ _mails = self.querier.all_mails_by_mailbox(self.mailbox_name)
+
+ result = []
+ for mail in _mails:
+ result.append(mail)
+ return result
+
+ def mails_by_tags(self, tags):
+ if 'all' in tags or self.mailbox_tag in tags:
+ return self.mails()
+ return [mail for mail in self.mails() if len(mail.tags.intersection(tags)) > 0]
+
+ def mail(self, mail_id):
+ return self.querier.mail(mail_id)
+
+ def add(self, mail):
+ return self.querier.create_mail(mail, self.mailbox_name)
+
+ def remove(self, ident):
+ mail = self.querier.mail(ident)
+ mail.remove_all_tags()
+ self.querier.remove_mail(mail)
+
+ @classmethod
+ def create(cls, mailbox_name, soledad_querier):
+ return Mailbox(mailbox_name, soledad_querier)
diff --git a/service/pixelated/adapter/services/mailboxes.py b/service/pixelated/adapter/services/mailboxes.py
new file mode 100644
index 00000000..56304dd6
--- /dev/null
+++ b/service/pixelated/adapter/services/mailboxes.py
@@ -0,0 +1,68 @@
+#
+# Copyright (c) 2014 ThoughtWorks, Inc.
+#
+# Pixelated is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pixelated is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
+from pixelated.adapter.services.mailbox import Mailbox
+from pixelated.adapter.listeners.mailbox_indexer_listener import MailboxIndexerListener
+
+
+class Mailboxes():
+
+ def __init__(self, account, soledad_querier):
+ self.account = account
+ self.querier = soledad_querier
+ for mailbox_name in account.mailboxes:
+ MailboxIndexerListener.listen(self.account, mailbox_name, soledad_querier)
+
+ def _create_or_get(self, mailbox_name):
+ mailbox_name = mailbox_name.upper()
+ if mailbox_name not in self.account.mailboxes:
+ self.account.addMailbox(mailbox_name)
+ MailboxIndexerListener.listen(self.account, mailbox_name, self.querier)
+ return Mailbox.create(mailbox_name, self.querier)
+
+ def inbox(self):
+ return self._create_or_get('INBOX')
+
+ def drafts(self):
+ return self._create_or_get('DRAFTS')
+
+ def trash(self):
+ return self._create_or_get('TRASH')
+
+ def sent(self):
+ return self._create_or_get('SENT')
+
+ def mailboxes(self):
+ return [self._create_or_get(leap_mailbox_name) for leap_mailbox_name in self.account.mailboxes]
+
+ def mails_by_tag(self, query_tags):
+ mails = []
+ for mailbox in self.mailboxes():
+ mails.extend(mailbox.mails_by_tags(query_tags))
+
+ return mails
+
+ def move_to_trash(self, mail_id):
+ mail = self.querier.mail(mail_id)
+ mail.remove_all_tags()
+ mail.set_mailbox(self.trash().mailbox_name)
+ mail.save()
+ return mail
+
+ def mail(self, mail_id):
+ for mailbox in self.mailboxes():
+ mail = mailbox.mail(mail_id)
+ if mail:
+ return mail
diff --git a/service/pixelated/adapter/services/tag_service.py b/service/pixelated/adapter/services/tag_service.py
new file mode 100644
index 00000000..c723b04c
--- /dev/null
+++ b/service/pixelated/adapter/services/tag_service.py
@@ -0,0 +1,26 @@
+#
+# Copyright (c) 2014 ThoughtWorks, Inc.
+#
+# Pixelated is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Pixelated is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
+from pixelated.adapter.model.tag import Tag
+
+
+class TagService:
+
+ instance = None
+ SPECIAL_TAGS = {Tag('inbox', True), Tag('sent', True), Tag('drafts', True), Tag('trash', True)}
+
+ @classmethod
+ def extract_reserved(cls, tags):
+ return {tag.name for tag in cls.SPECIAL_TAGS if tag.name in tags}