summaryrefslogtreecommitdiff
path: root/service/pixelated/adapter
diff options
context:
space:
mode:
authorDuda Dornelles <ddornell@thoughtworks.com>2014-09-11 14:25:19 -0300
committerDuda Dornelles <ddornell@thoughtworks.com>2014-09-11 14:25:19 -0300
commit332e7d54e0e4c3d71e20a9dc8d9957298e6dcb90 (patch)
tree3be446548f7149e32def8eadf595cb1ce4f4a8ac /service/pixelated/adapter
parente0cd19256171b18eee571808f7fc12cd042faf19 (diff)
Refactoring tags functionality into TagService
Diffstat (limited to 'service/pixelated/adapter')
-rw-r--r--service/pixelated/adapter/mail_service.py20
-rw-r--r--service/pixelated/adapter/pixelated_mailbox.py48
-rw-r--r--service/pixelated/adapter/pixelated_mailboxes.py11
-rw-r--r--service/pixelated/adapter/tag.py4
-rw-r--r--service/pixelated/adapter/tag_index.py7
-rw-r--r--service/pixelated/adapter/tag_service.py55
6 files changed, 87 insertions, 58 deletions
diff --git a/service/pixelated/adapter/mail_service.py b/service/pixelated/adapter/mail_service.py
index 7f0d111b..52c1abc7 100644
--- a/service/pixelated/adapter/mail_service.py
+++ b/service/pixelated/adapter/mail_service.py
@@ -13,25 +13,23 @@
#
# 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.tag_service import TagService
class MailService:
__slots__ = ['leap_session', 'account', 'mailbox_name']
- def __init__(self, mailboxes, mail_sender):
+ ALL_MAILS_QUERY = {'tags': ['all']}
+
+ def __init__(self, mailboxes, mail_sender, tag_service=TagService.get_instance()):
+ self.tag_service = tag_service
self.mailboxes = mailboxes
self.mail_sender = mail_sender
-
- @property
- def mailbox(self):
- return self.mailboxes.inbox()
+ self.tag_service.load_index(self.mails(MailService.ALL_MAILS_QUERY))
def mails(self, query):
_mails = None
- if not query['tags']:
- return self.mailbox.mails()
-
if query['tags']:
_mails = self.mailboxes.mails_by_tag(query['tags'])
@@ -40,17 +38,17 @@ class MailService:
def update_tags(self, mail_id, new_tags):
mail = self.mail(mail_id)
added, removed = mail.update_tags(set(new_tags))
- self.mailbox.notify_tags_updated(added, removed, mail_id)
+ self.tag_service.notify_tags_updated(added, removed, mail_id)
return new_tags
def mail(self, mail_id):
- return self.mailbox.mail(mail_id)
+ return self.mailboxes.mail(mail_id)
def send(self, mail):
self.mail_sender.sendmail(mail)
def all_tags(self):
- return self.mailbox.all_tags()
+ return self.tag_service.all_tags()
def thread(self, thread_id):
raise NotImplementedError()
diff --git a/service/pixelated/adapter/pixelated_mailbox.py b/service/pixelated/adapter/pixelated_mailbox.py
index 6323d3c3..06f30896 100644
--- a/service/pixelated/adapter/pixelated_mailbox.py
+++ b/service/pixelated/adapter/pixelated_mailbox.py
@@ -14,48 +14,39 @@
# You should have received a copy of the GNU Affero General Public License
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
-import os
-
from pixelated.adapter.pixelated_mail import PixelatedMail
-from pixelated.adapter.tag import Tag
-from pixelated.adapter.tag_index import TagIndex
+from pixelated.adapter.tag_service import TagService
from pixelated.support.id_gen import gen_pixelated_uid
class PixelatedMailbox:
- SPECIAL_TAGS = set([Tag('inbox', True), Tag('sent', True), Tag('drafts', True), Tag('trash', True)])
-
- def __init__(self, leap_mailbox, index_file_path):
+ def __init__(self, leap_mailbox, tag_service=TagService.get_instance()):
+ self.tag_service = tag_service
self.leap_mailbox = leap_mailbox
- self.tag_index = TagIndex(index_file_path)
- if self.tag_index.empty():
- for mail in self.mails():
- self.notify_tags_updated(mail.tags, [], mail.ident)
- for tag in self.SPECIAL_TAGS:
- self.tag_index.add(tag)
+ self.mailbox_tag = self.leap_mailbox.mbox.lower()
@property
def messages(self):
return self.leap_mailbox.messages
+ def add_mailbox_tag_if_not_there(self, pixelated_mail):
+ if not pixelated_mail.has_tag(self.mailbox_tag):
+ pixelated_mail.update_tags({self.mailbox_tag}.union(pixelated_mail.tags))
+ self.tag_service.notify_tags_updated({self.mailbox_tag}, [], pixelated_mail.ident)
+
def mails(self):
mails = self.leap_mailbox.messages or []
result = []
- mailbox_name = self.leap_mailbox.mbox
for mail in mails:
pixelated_mail = PixelatedMail.from_leap_mail(mail)
- if not pixelated_mail.has_tag(mailbox_name):
- new_tags = set([mailbox_name.lower()])
- pixelated_mail.update_tags(new_tags.union(pixelated_mail.tags))
- self.notify_tags_updated(new_tags, [], pixelated_mail.ident)
+ self.add_mailbox_tag_if_not_there(pixelated_mail)
result.append(pixelated_mail)
return result
def mails_by_tags(self, tags):
if 'all' in tags:
return self.mails()
-
return [mail for mail in self.mails() if len(mail.tags.intersection(tags)) > 0]
def mail(self, mail_id):
@@ -63,23 +54,6 @@ class PixelatedMailbox:
if gen_pixelated_uid(self.leap_mailbox.mbox, message.getUID()) == mail_id:
return PixelatedMail.from_leap_mail(message)
- def all_tags(self):
- return self.tag_index.values().union(self.SPECIAL_TAGS)
-
- def notify_tags_updated(self, added_tags, removed_tags, mail_ident):
- for removed_tag in removed_tags:
- tag = self.tag_index.get(removed_tag)
- tag.decrement(mail_ident)
- if tag.total == 0:
- self.tag_index.remove(tag.name)
- else:
- self.tag_index.set(tag)
- for added_tag in added_tags:
- tag = self.tag_index.get(added_tag) or Tag(added_tag)
- tag.increment(mail_ident)
- self.tag_index.set(tag)
-
@classmethod
def create(cls, account, mailbox_name='INBOX'):
- db_path = os.path.join(os.environ['HOME'], '.pixelated_index')
- return PixelatedMailbox(account.getMailbox(mailbox_name), db_path)
+ return PixelatedMailbox(account.getMailbox(mailbox_name))
diff --git a/service/pixelated/adapter/pixelated_mailboxes.py b/service/pixelated/adapter/pixelated_mailboxes.py
index 652080ca..411e8ac0 100644
--- a/service/pixelated/adapter/pixelated_mailboxes.py
+++ b/service/pixelated/adapter/pixelated_mailboxes.py
@@ -4,10 +4,6 @@ from pixelated.adapter.pixelated_mailbox import PixelatedMailbox
class PixelatedMailBoxes():
def __init__(self, account):
self.account = account
- self.mailbox_name = 'INBOX'
-
- def inbox(self):
- return PixelatedMailbox.create(self.account)
@property
def mailboxes(self):
@@ -21,5 +17,8 @@ class PixelatedMailBoxes():
return mails
- def leap_inbox_mailbox(self):
- return self.account.getMailbox(self.mailbox_name)
+ 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/tag.py b/service/pixelated/adapter/tag.py
index ba545043..2e965fdf 100644
--- a/service/pixelated/adapter/tag.py
+++ b/service/pixelated/adapter/tag.py
@@ -36,8 +36,8 @@ class Tag:
return len(self.mails)
def __init__(self, name, default=False):
- self.name = name
- self.ident = name.__hash__()
+ self.name = name.lower()
+ self.ident = self.name.__hash__()
self.default = default
self.mails = set()
diff --git a/service/pixelated/adapter/tag_index.py b/service/pixelated/adapter/tag_index.py
index 357f7513..2a0955ef 100644
--- a/service/pixelated/adapter/tag_index.py
+++ b/service/pixelated/adapter/tag_index.py
@@ -13,9 +13,10 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
-
+#
import dbm
import atexit
+import os
from pixelated.adapter.tag import Tag
@@ -23,10 +24,11 @@ class TagIndex:
"""
Manages an index for mail's tags using a file storage.
"""
+ DB_PATH = os.path.join(os.environ['HOME'], '.pixelated_index')
__db_instances = dict()
- def __init__(self, db_path):
+ def __init__(self, db_path=DB_PATH):
self.db_path = db_path
if db_path not in TagIndex.__db_instances:
TagIndex.__db_instances[db_path] = dbm.open(db_path, 'c')
@@ -39,6 +41,7 @@ class TagIndex:
def add(self, tag):
if tag.name not in self.db:
self.set(tag)
+ return tag
def get(self, tag_name):
if tag_name in self.db:
diff --git a/service/pixelated/adapter/tag_service.py b/service/pixelated/adapter/tag_service.py
new file mode 100644
index 00000000..00f28b40
--- /dev/null
+++ b/service/pixelated/adapter/tag_service.py
@@ -0,0 +1,55 @@
+#
+# 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.tag import Tag
+from pixelated.adapter.tag_index import TagIndex
+
+
+class TagService:
+
+ instance = None
+ SPECIAL_TAGS = {Tag('inbox', True), Tag('sent', True), Tag('drafts', True), Tag('trash', True)}
+
+ @classmethod
+ def get_instance(cls):
+ if not cls.instance:
+ cls.instance = TagService()
+ return cls.instance
+
+ def __init__(self, tag_index=TagIndex()):
+ self.tag_index = tag_index
+
+ def load_index(self, mails):
+ if self.tag_index.empty():
+ for mail in mails:
+ self.notify_tags_updated(mail.tags, [], mail.ident)
+ for tag in self.SPECIAL_TAGS:
+ self.tag_index.add(tag)
+
+ def notify_tags_updated(self, added_tags, removed_tags, mail_ident):
+ for removed_tag in removed_tags:
+ tag = self.tag_index.get(removed_tag)
+ tag.decrement(mail_ident)
+ if tag.total == 0:
+ self.tag_index.remove(tag.name)
+ else:
+ self.tag_index.set(tag)
+ for added_tag in added_tags:
+ tag = self.tag_index.get(added_tag) or self.tag_index.add(Tag(added_tag))
+ tag.increment(mail_ident)
+ self.tag_index.set(tag)
+
+ def all_tags(self):
+ return self.tag_index.values().union(self.SPECIAL_TAGS)