From 91e4481c450eb7eb928debc1cb7fa59bdb63dd7b Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 25 Jul 2017 11:40:11 -0400 Subject: [pkg] packaging and path changes - move all the pixelated python package under src/ - move the pixelated_www package under the leap namespace - allow to set globally the static folder - add hours and minutes to the timestamp in package version, to allow for several releases a day. --- service/src/pixelated/resources/mails_resource.py | 244 ++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 service/src/pixelated/resources/mails_resource.py (limited to 'service/src/pixelated/resources/mails_resource.py') diff --git a/service/src/pixelated/resources/mails_resource.py b/service/src/pixelated/resources/mails_resource.py new file mode 100644 index 00000000..d911e0d2 --- /dev/null +++ b/service/src/pixelated/resources/mails_resource.py @@ -0,0 +1,244 @@ +# +# Copyright (c) 2015 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 . + +import time +import json + +from twisted.internet import defer +from twisted.logger import Logger +from twisted.web.server import NOT_DONE_YET +from twisted.web.resource import Resource +from twisted.web import server + +from leap.common import events + +from pixelated.adapter.model.mail import InputMail +from pixelated.resources import respond_json_deferred, BaseResource +from pixelated.adapter.services.mail_sender import SMTPDownException +from pixelated.support.functional import to_unicode + + +log = Logger() + + +class MailsUnreadResource(Resource): + isLeaf = True + + def __init__(self, mail_service): + Resource.__init__(self) + self._mail_service = mail_service + + def render_POST(self, request): + idents = json.load(request.content).get('idents') + deferreds = [] + for ident in idents: + deferreds.append(self._mail_service.mark_as_unread(ident)) + + d = defer.gatherResults(deferreds, consumeErrors=True) + d.addCallback(lambda _: respond_json_deferred(None, request)) + d.addErrback(lambda _: respond_json_deferred(None, request, status_code=500)) + + return NOT_DONE_YET + + +class MailsReadResource(Resource): + isLeaf = True + + def __init__(self, mail_service): + Resource.__init__(self) + self._mail_service = mail_service + + def render_POST(self, request): + idents = json.load(request.content).get('idents') + deferreds = [] + for ident in idents: + deferreds.append(self._mail_service.mark_as_read(ident)) + + d = defer.gatherResults(deferreds, consumeErrors=True) + d.addCallback(lambda _: respond_json_deferred(None, request)) + d.addErrback(lambda _: respond_json_deferred(None, request, status_code=500)) + + return NOT_DONE_YET + + +class MailsDeleteResource(Resource): + isLeaf = True + + def __init__(self, mail_service): + Resource.__init__(self) + self._mail_service = mail_service + + def render_POST(self, request): + def response_failed(failure): + log.error('something failed: %s' % failure.getErrorMessage()) + request.finish() + + idents = json.loads(request.content.read())['idents'] + deferreds = [] + for ident in idents: + deferreds.append(self._mail_service.delete_mail(ident)) + + d = defer.gatherResults(deferreds, consumeErrors=True) + d.addCallback(lambda _: respond_json_deferred(None, request)) + d.addErrback(response_failed) + return NOT_DONE_YET + + +class MailsRecoverResource(Resource): + isLeaf = True + + def __init__(self, mail_service): + Resource.__init__(self) + self._mail_service = mail_service + + def render_POST(self, request): + idents = json.loads(request.content.read())['idents'] + deferreds = [] + for ident in idents: + deferreds.append(self._mail_service.recover_mail(ident)) + d = defer.gatherResults(deferreds, consumeErrors=True) + d.addCallback(lambda _: respond_json_deferred(None, request)) + d.addErrback(lambda _: respond_json_deferred(None, request, status_code=500)) + return NOT_DONE_YET + + +class MailsArchiveResource(Resource): + isLeaf = True + + def __init__(self, mail_service): + Resource.__init__(self) + self._mail_service = mail_service + + def render_POST(self, request): + idents = json.loads(request.content.read())['idents'] + deferreds = [] + for ident in idents: + deferreds.append(self._mail_service.archive_mail(ident)) + d = defer.gatherResults(deferreds, consumeErrors=True) + d.addCallback(lambda _: respond_json_deferred({'successMessage': 'your-message-was-archived'}, request)) + d.addErrback(lambda _: respond_json_deferred(None, request, status_code=500)) + return NOT_DONE_YET + + +class MailsResource(BaseResource): + + def _register_smtp_error_handler(self): + + def on_error(event, content): + delivery_error_mail = InputMail.delivery_error_template(delivery_address=event.content) + self._mail_service.mailboxes.inbox.add(delivery_error_mail) + + events.register(events.catalog.SMTP_SEND_MESSAGE_ERROR, callback=on_error) + + def __init__(self, services_factory): + BaseResource.__init__(self, services_factory) + self._register_smtp_error_handler() + + def getChild(self, action, request): + _mail_service = self.mail_service(request) + + if action == 'delete': + return MailsDeleteResource(_mail_service) + if action == 'recover': + return MailsRecoverResource(_mail_service) + if action == 'archive': + return MailsArchiveResource(_mail_service) + if action == 'read': + return MailsReadResource(_mail_service) + if action == 'unread': + return MailsUnreadResource(_mail_service) + + def _build_mails_response(self, (mails, total)): + return { + "stats": { + "total": total, + }, + "mails": [mail.as_dict() for mail in mails] + } + + def render_GET(self, request): + + _mail_service = self.mail_service(request) + query, window_size, page = request.args.get('q')[0], request.args.get('w')[0], request.args.get('p')[0] + unicode_query = to_unicode(query) + d = _mail_service.mails(unicode_query, window_size, page) + + d.addCallback(self._build_mails_response) + d.addCallback(lambda res: respond_json_deferred(res, request)) + + def error_handler(error): + print error + + d.addErrback(error_handler) + + return NOT_DONE_YET + + def render_POST(self, request): + def onError(error): + if isinstance(error.value, SMTPDownException): + respond_json_deferred({'message': str(error.value)}, request, status_code=503) + else: + log.error('error occurred while sending: %s' % error.getErrorMessage()) + respond_json_deferred({'message': 'an error occurred while sending'}, request, status_code=422) + + deferred = self._handle_post(request) + deferred.addErrback(onError) + + return server.NOT_DONE_YET + + def render_PUT(self, request): + def onError(error): + log.error('error saving draft: %s' % error.getErrorMessage()) + respond_json_deferred("", request, status_code=422) + + deferred = self._handle_put(request) + deferred.addErrback(onError) + + return server.NOT_DONE_YET + + @defer.inlineCallbacks + def _fetch_attachment_contents(self, content_dict, _mail_service): + attachments = content_dict.get('attachments', []) if content_dict else [] + for attachment in attachments: + retrieved_attachment = yield _mail_service.attachment(attachment['ident']) + attachment['raw'] = retrieved_attachment['content'] + content_dict['attachments'] = attachments + defer.returnValue(content_dict) + + @defer.inlineCallbacks + def _handle_post(self, request): + _mail_service = self.mail_service(request) + content_dict = json.loads(request.content.read()) + with_attachment_content = yield self._fetch_attachment_contents(content_dict, _mail_service) + + sent_mail = yield _mail_service.send_mail(with_attachment_content) + respond_json_deferred(sent_mail.as_dict(), request, status_code=201) + + @defer.inlineCallbacks + def _handle_put(self, request): + _draft_service = self.draft_service(request) + _mail_service = self.mail_service(request) + content_dict = json.loads(request.content.read()) + with_attachment_content = yield self._fetch_attachment_contents(content_dict, _mail_service) + + _mail = InputMail.from_dict(with_attachment_content, from_address=_mail_service.account_email) + draft_id = content_dict.get('ident') + pixelated_mail = yield _draft_service.process_draft(draft_id, _mail) + + if not pixelated_mail: + respond_json_deferred("", request, status_code=422) + else: + respond_json_deferred({'ident': pixelated_mail.ident}, request) -- cgit v1.2.3