summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authormnandri <mnandri@eunglick.corporate.thoughtworks.com>2015-12-16 16:35:33 +0100
committermnandri <mnandri@eunglick.corporate.thoughtworks.com>2015-12-18 11:22:34 +0100
commit338498cef1cd4f2b9ae49bc54bd496de0e5472a0 (patch)
treec64272dc1f7bb8502974f6993cda33b157f31cf2 /service
parentf8ac23150f5f840eaa4ef920b003966f911de8fa (diff)
WIP: rename me later
Diffstat (limited to 'service')
-rw-r--r--service/pixelated/adapter/services/mail_service.py36
-rw-r--r--service/pixelated/resources/attachments_resource.py15
-rw-r--r--service/test/integration/test_retrieve_attachment.py17
-rw-r--r--service/test/support/integration/app_test_client.py11
-rw-r--r--service/test/support/test_helper.py4
5 files changed, 69 insertions, 14 deletions
diff --git a/service/pixelated/adapter/services/mail_service.py b/service/pixelated/adapter/services/mail_service.py
index 964e4354..2f63a2bc 100644
--- a/service/pixelated/adapter/services/mail_service.py
+++ b/service/pixelated/adapter/services/mail_service.py
@@ -13,13 +13,17 @@
#
# 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 email import encoders
+from email.mime.nonmultipart import MIMENonMultipart
+from email.mime.multipart import MIMEMultipart
+from leap.mail.mail import Message
+
from twisted.internet import defer
+
from pixelated.adapter.model.mail import InputMail
from pixelated.adapter.model.status import Status
from pixelated.adapter.services.tag_service import extract_reserved_tags
-from email import message_from_file
-import os
-
+from leap.mail.adaptors.soledad import SoledadMailAdaptor
class MailService(object):
@@ -34,10 +38,28 @@ class MailService(object):
mails = yield self.mail_store.all_mails()
defer.returnValue(mails)
- @defer.inlineCallbacks
- def attachment_id(self, _file):
- _attachment_id = yield 'mocked_for_now'
- defer.returnValue(_attachment_id)
+ def _attachment_to_cdoc(self, content, content_type, encoder=encoders.encode_base64):
+ major, sub = content_type.split('/')
+ attachment = MIMENonMultipart(major, sub)
+ attachment.set_payload(content)
+ encoder(attachment)
+ attachment.add_header('Content-Disposition', 'attachment', filename='does_not_matter.txt')
+
+ pseudo_mail = MIMEMultipart()
+ pseudo_mail.attach(attachment)
+
+ tmp_mail = SoledadMailAdaptor().get_msg_from_string(MessageClass=Message, raw_msg=pseudo_mail.as_string())
+
+ cdoc = tmp_mail.get_wrapper().cdocs[1]
+ return cdoc
+
+ def _calc_attachment_id_(self, content, content_type, encoder=encoders.encode_base64):
+ cdoc = self._attachment_to_cdoc(content, content_type, encoder)
+
+ return cdoc.phash
+
+ def attachment_id(self, content, content_type):
+ return self._calc_attachment_id_(content, content_type)
@defer.inlineCallbacks
def mails(self, query, window_size, page):
diff --git a/service/pixelated/resources/attachments_resource.py b/service/pixelated/resources/attachments_resource.py
index 667d030e..2b5a6912 100644
--- a/service/pixelated/resources/attachments_resource.py
+++ b/service/pixelated/resources/attachments_resource.py
@@ -13,6 +13,7 @@
#
# 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 cgi
import io
import re
@@ -78,16 +79,24 @@ class AttachmentsResource(Resource):
def getChild(self, attachment_id, request):
return AttachmentResource(self.mail_service, attachment_id)
- def render_POST(self, request):
- _file = request.args['attachment'][0]
+ def render_GET(self, request):
+ return '<html><body><p></p>' \
+ '<form method="POST" enctype="multipart/form-data">' \
+ '<input name="attachment" type="file" /> <p></p>' \
+ '<input type="submit" /></form><p></p>' \
+ '</body></html>'
- deferred = self.mail_service.attachment_id(_file)
+ def render_POST(self, request):
+ fields = cgi.FieldStorage(fp=request.content, headers=request.headers, environ={'REQUEST_METHOD':'POST'})
+ _file = fields['attachment']
+ deferred = defer.maybeDeferred(self.mail_service.attachment_id, _file.value, _file.type)
def send_location(attachment_id):
request.headers['Location'] = '/%s/%s'% (self.BASE_URL, attachment_id)
respond_json_deferred({"attachment_id": attachment_id}, request, status_code=201)
def error_handler(error):
+ print error
respond_json_deferred({"message": "Something went wrong. Attachement not saved."}, request, status_code=500)
deferred.addCallback(send_location)
diff --git a/service/test/integration/test_retrieve_attachment.py b/service/test/integration/test_retrieve_attachment.py
index bc7f8a0d..ca11a14d 100644
--- a/service/test/integration/test_retrieve_attachment.py
+++ b/service/test/integration/test_retrieve_attachment.py
@@ -13,10 +13,13 @@
#
# 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 base64
+from email import encoders
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
+from poster.encode import multipart_encode, MultipartParam
from twisted.internet import defer
from test.support.integration.soledad_test_base import SoledadTestBase
@@ -49,3 +52,17 @@ class RetrieveAttachmentTest(SoledadTestBase):
self.assertEqual(404, req.code)
self.assertIsNone(attachment)
+
+ @defer.inlineCallbacks
+ def test_post_new_attachment(self):
+ content_type = 'text/plain'
+ filename = 'filename.txt'
+ data = 'pretend to be binary attachment data'
+ file = MultipartParam('attachment', value=data, filename=filename, filetype=content_type)
+ datagen, headers = multipart_encode([file])
+ post_data = "".join(datagen)
+
+ _, req = yield self.post_attachment(post_data, headers)
+
+ self.assertEqual(201, req.code)
+ self.assertEqual('/attachment/B5B4ED80AC3B894523D72E375DACAA2FC6606C18EDF680FE95903086C8B5E14A', req.headers['Location'])
diff --git a/service/test/support/integration/app_test_client.py b/service/test/support/integration/app_test_client.py
index 484bea6e..5f7eb90a 100644
--- a/service/test/support/integration/app_test_client.py
+++ b/service/test/support/integration/app_test_client.py
@@ -123,8 +123,9 @@ class AppTestClient(object):
request.args = get_args
return self._render(request, as_json)
- def post(self, path, body=''):
- request = request_mock(path=path, method="POST", body=body, headers={'Content-Type': ['application/json']})
+ def post(self, path, body='', headers=None):
+ headers = headers or {'Content-Type': 'application/json'}
+ request = request_mock(path=path, method="POST", body=body, headers=headers)
return self._render(request)
def put(self, path, body):
@@ -198,6 +199,12 @@ class AppTestClient(object):
res = yield deferred_result
defer.returnValue((res, req))
+ @defer.inlineCallbacks
+ def post_attachment(self, data, headers):
+ deferred_result, req = self.post('/attachment', body=data, headers=headers)
+ res = yield deferred_result
+ defer.returnValue((res, req))
+
def put_mail(self, data):
res, req = self.put('/mails', data)
return res, req
diff --git a/service/test/support/test_helper.py b/service/test/support/test_helper.py
index 21f59d8f..703b62fa 100644
--- a/service/test/support/test_helper.py
+++ b/service/test/support/test_helper.py
@@ -96,8 +96,8 @@ class PixRequestMock(DummyRequest):
def request_mock(path='', method='GET', body='', headers={}):
dummy = PixRequestMock(path.split('/'))
- for name, value in headers.iteritems():
- dummy.setHeader(name, value)
+ for name, val in headers.iteritems():
+ dummy.headers[name.lower()] = val
dummy.method = method
dummy.content = io.BytesIO(body)
return dummy