def parse_attachment(message_part): content_disposition = message_part.get("Content-Disposition", None) if not content_disposition: return None dispo_type, dispo_dict = parse_dispositions(content_disposition) if not (dispo_type == "attachment" or (dispo_type == 'inline' and 'filename' in dispo_dict)): return None content_type = message_part.get("Content-Type", None) file_data = message_part.get_payload(decode=True) if file_data is None: payloads = message_part.get_payload() file_data = '\n\n'.join([p.as_string() for p in payloads]).encode('utf-8') attachment = BytesIO(file_data) attachment.content_type = message_part.get_content_type() attachment.size = len(file_data) attachment.name = None attachment.create_date = None attachment.mod_date = None attachment.read_date = None attachment.name = get_attachment_name(attachment, dispo_dict, content_type=content_type) if "create-date" in dispo_dict: attachment.create_date = dispo_dict['create-date'] # TODO: datetime if "modification-date" in dispo_dict: attachment.mod_date = dispo_dict['modification-date'] # TODO: datetime if "read-date" in dispo_dict: attachment.read_date = dispo_dict['read-date'] # TODO: datetime return attachment
def parse_attachment(message_part): content_disposition = message_part.get("Content-Disposition", None) if not content_disposition: return None dispo_type, dispo_dict = parse_dispositions(content_disposition) if not (dispo_type == "attachment" or (dispo_type == 'inline' and 'filename' in dispo_dict)): return None content_type = message_part.get("Content-Type", None) file_data = message_part.get_payload(decode=True) if file_data is None: payloads = message_part.get_payload() file_data = '\n\n'.join([p.as_string() for p in payloads]).encode('utf-8') attachment = BytesIO(file_data) attachment.content_type = message_part.get_content_type() attachment.size = len(file_data) attachment.name = None attachment.create_date = None attachment.mod_date = None attachment.read_date = None attachment.name = get_attachment_name( attachment, dispo_dict, content_type=content_type ) if "create-date" in dispo_dict: attachment.create_date = dispo_dict['create-date'] # TODO: datetime if "modification-date" in dispo_dict: attachment.mod_date = dispo_dict['modification-date'] # TODO: datetime if "read-date" in dispo_dict: attachment.read_date = dispo_dict['read-date'] # TODO: datetime return attachment
def parse_postmark(self, obj): from_field = (obj['FromFull']['Name'], obj['FromFull']['Email']) tos = [(o['Name'], o['Email']) for o in obj['ToFull']] ccs = [(o['Name'], o['Email']) for o in obj['CcFull']] attachments = [] for a in obj['Attachments']: attachment = BytesIO(base64.b64decode(a['Content'])) attachment.content_type = a['ContentType'] attachment.size = a['ContentLength'] attachment.name = a['Name'] attachment.create_date = None attachment.mod_date = None attachment.read_date = None attachments.append(attachment) return ParsedEmail(None, **{ 'postmark_msgobj': obj, 'date': parse_date(obj['Date']), 'subject': obj['Subject'], 'body': obj['TextBody'], 'html': obj['HtmlBody'], 'from_': from_field, 'to': tos, 'cc': ccs, 'resent_to': [], 'resent_cc': [], 'attachments': attachments })
def _parse_attachment(message_part): content_disposition = message_part.get("Content-Disposition", None) if content_disposition: dispositions = content_disposition.strip().split(";") if content_disposition and dispositions[0].lower() == "attachment": file_data = message_part.get_payload(decode=True) attachment = BytesIO(file_data) attachment.content_type = message_part.get_content_type() attachment.size = len(file_data) attachment.name = None attachment.create_date = None attachment.mod_date = None attachment.read_date = None for param in dispositions[1:]: name, value = param.strip().split("=") name = name.lower() if name == "filename": attachment.name = value elif name == "create-date": attachment.create_date = value # FIXME: datetime elif name == "modification-date": attachment.mod_date = value # FIXME: datetime elif name == "read-date": attachment.read_date = value # FIXME: datetime attachment.checksum = _md5(attachment) return attachment return None
def test_binary_gpg_data(self): url = reverse('account:register') client = Client() self.assertEqual(User.objects.count(), 0) get = client.get(url) self.assertEqual(get.status_code, 200) self.assertTrue(get.context['user'].is_anonymous) self.assertTrue('form' in get.context) with open(os.path.join(testdata_path, 'non_armored.gpg'), 'rb') as stream: data = stream.read() data = BytesIO(data) data.name = 'non_armored.gpg' data.content_type = 'application/pgp-encrypted' with self.mock_celery() as mock: response = client.post(url, { 'username_0': NODE, 'username_1': DOMAIN, 'email': EMAIL, 'gpg_key': data, }, follow=True) self.assertEqual(User.objects.count(), 0) self.assertNoTasks(mock) self.assertFormError(response, 'form', 'gpg_key', ['Please upload an ASCII armored GPG key.'])
def parse_postmark(self, obj): from_field = (obj['FromFull']['Name'], obj['FromFull']['Email']) tos = [(o['Name'], o['Email']) for o in obj['ToFull']] ccs = [(o['Name'], o['Email']) for o in obj['CcFull']] attachments = [] for a in obj['Attachments']: attachment = BytesIO(base64.b64decode(a['Content'])) attachment.content_type = a['ContentType'] attachment.size = a['ContentLength'] attachment.name = a['Name'] attachment.create_date = None attachment.mod_date = None attachment.read_date = None attachments.append(attachment) return ParsedEmail( None, **{ 'postmark_msgobj': obj, 'date': parse_date(obj['Date']), 'subject': obj['Subject'], 'body': obj['TextBody'], 'html': obj['HtmlBody'], 'from_': from_field, 'to': tos, 'cc': ccs, 'resent_to': [], 'resent_cc': [], 'attachments': attachments })
def _build_file_upload(self, file_path): with open(file_path, "rb") as fp: upload = BytesIO(fp.read()) upload.name = os.path.basename(file_path) # get file name from path upload.content_type = ( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) return upload
def _run_upload(self, name): with factory.load_test_file(name) as fp: upload = BytesIO(fp.read()) upload.name = name upload.content_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' response = self.client.post( reverse('main:describe', kwargs=self.target_kwargs), data={"file": upload}, ) return response
def test_invalid_filetype(self): upload = BytesIO(b"") upload.name = "testfile.docx" upload.content_type = "application/octet-stream" response = self.client.post( reverse("main:describe", kwargs=self.target_kwargs), data={"file": upload}, # front-end returns one of: xlsx, csv, xml, txt; view requires xlsx HTTP_X_EDD_FILE_TYPE="txt", HTTP_X_FILE_NAME="testfile.docx", ) self.assertEqual(response.status_code, codes.bad_request)
def test_validate_image_type(self): faker = Faker._get_faker() data = BytesIO(faker.binary(length=10)) data.name = faker.file_name(category='image') class DummyField: pass # noqa: E701 test_content = DummyField() # Mocking the Django's ImageField. with self.assertNotRaises(ValidationError): # A field with no underlying file is expected to pass the validation. validate_image(test_content) type(test_content).file = PropertyMock( side_effect=FileNotFoundError) validate_image(test_content) del type(test_content ).file # Clear the property mock for further testing. # A field with file of unknown content type is expected to pass the validation. test_content.file = data validate_image(test_content) # A field with file of content type 'image' is expected to pass the validation. data.content_type = faker.mime_type(category='image') validate_image(test_content) # A field with file of unsupported content type is expected to fail validation. for category in [ 'application', 'audio', 'message', 'model', 'multipart', 'text', 'video' ]: data.content_type = faker.mime_type(category=category) with self.subTest(content_type=data.content_type): with self.assertRaises(ValidationError) as cm: validate_image(test_content) with override_settings(LANGUAGE_CODE='en'): self.assertEqual(next(iter(cm.exception)), "File type is not supported.") with override_settings(LANGUAGE_CODE='eo'): self.assertEqual(next(iter(cm.exception)), "Dosiertipo ne akceptebla.")
def _attachment_upload(self, filename): with factory.load_test_file(filename) as fp: upload = BytesIO(fp.read()) upload.name = filename upload.content_type = ( "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) response = self.client.post( reverse("main:overview", kwargs=self.target_kwargs), data={"action": "attach", "file": upload, "description": "foobar"}, follow=True, ) return response
def resize_image(image_object, max_dimension=2048): try: image = Image.open(image_object) if image.height > max_dimension or image.width > max_dimension: im = Image.open(image_object) im.thumbnail((max_dimension, max_dimension), Image.ANTIALIAS) outfile = BytesIO() im.save(outfile, image_object.content_type.split('/')[1]) outfile.content_type = image_object.content_type return outfile except: pass return image_object
def test_comment_image_upload_invalid(self): """ comment image upload, invalid image """ utils.login(self) image = BytesIO('BAD\x02D\x01\x00;'.encode('utf-8')) image.name = 'image.gif' image.content_type = 'image/gif' files = {'image': SimpleUploadedFile(image.name, image.read()), } response = self.client.post(reverse('spirit:comment-image-upload-ajax'), HTTP_X_REQUESTED_WITH='XMLHttpRequest', data=files) res = json.loads(response.content.decode('utf-8')) self.assertIn('error', res.keys()) self.assertIn('image', res['error'].keys())
def _create_workbook(self, parts): upload = BytesIO() wb = Workbook() ws = wb.active for i, title in enumerate(['Line Name', 'Part ID', 'Media'], 1): ws.cell(row=1, column=i).value = title for i, part in enumerate(parts, 2): ws.cell(row=i, column=1).value = part ws.cell(row=i, column=2).value = part ws.cell(row=i, column=3).value = 'M9' wb.save(upload) upload.name = 'description.xlsx' upload.content_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' upload.seek(0) return upload
def test_conversion_tool(self): response = self.client.get(reverse("edd_utils:proteomics_home")) self.assertEqual(response.status_code, codes.ok) fixture = (environ.Path(__file__) - 2)("fixtures", "misc_data", "skyline.csv") with open(fixture, "rb") as fp: upload = BytesIO(fp.read()) upload.name = "skyline.csv" upload.content_type = "text/csv" response = self.client.post(reverse("edd_utils:parse_skyline"), data={"file": upload}) self.assertEqual(response.status_code, codes.ok) message = response.json() self.assertEqual(message["n_proteins"], 4) self.assertEqual(message["n_samples"], 4) self.assertEqual(message["n_records"], 32)
def test_conversion_tool(self): response = self.client.get(reverse('edd_utils:proteomics_home')) self.assertEqual(response.status_code, codes.ok) fixture = (environ.Path(__file__) - 2)('fixtures', 'misc_data', 'skyline.csv') with open(fixture, 'rb') as fp: upload = BytesIO(fp.read()) upload.name = 'skyline.csv' upload.content_type = 'text/csv' response = self.client.post( reverse('edd_utils:parse_skyline'), data={'file': upload}, ) self.assertEqual(response.status_code, codes.ok) message = response.json() self.assertEqual(message['n_proteins'], 4) self.assertEqual(message['n_samples'], 4) self.assertEqual(message['n_records'], 32)
def attempt_upload_file_and_verify_result(self, test_case, event_name, content=None): """ Running on a test case, creating a temp file, uploading it by calling the corresponding ajax event, and verifying that upload happens or is rejected as expected. """ if 'magic_number' in test_case: f_handler = BytesIO(codecs.decode(test_case['magic_number'], 'hex_codec')) elif content is not None: f_handler = BytesIO( json.dumps(content, sort_keys=True) if six.PY2 else json.dumps(content, sort_keys=True).encode('utf-8')) else: f_handler = BytesIO(b'') f_handler.content_type = test_case['mimetypes'] f_handler.name = 'file' + test_case['suffixes'] url = self.get_handler_url(event_name) resp = self.client.post(url, {'file': f_handler}) self.assertEqual(resp.status_code, test_case['status'])
def test_attachments(self): att1 = BytesIO('test attachment'.encode('utf-8')) att1.name = 'test.txt' image_content = sample_image_content() att2 = BytesIO(image_content) att2.name = 'image.png' email_content = sample_email_content() att3 = BytesIO(email_content) att3.content_type = 'message/rfc822; charset="us-ascii"' raw_event = mailgun_sign_legacy_payload({ 'message-headers': '[]', 'attachment-count': '3', 'content-id-map': """{"<abc123>": "attachment-2"}""", 'attachment-1': att1, 'attachment-2': att2, # inline 'attachment-3': att3, }) response = self.client.post('/anymail/mailgun/inbound/', data=raw_event) self.assertEqual(response.status_code, 200) kwargs = self.assert_handler_called_once_with( self.inbound_handler, sender=MailgunInboundWebhookView, event=ANY, esp_name='Mailgun') event = kwargs['event'] message = event.message attachments = message.attachments # AnymailInboundMessage convenience accessor self.assertEqual(len(attachments), 2) self.assertEqual(attachments[0].get_filename(), 'test.txt') self.assertEqual(attachments[0].get_content_type(), 'text/plain') self.assertEqual(attachments[0].get_content_text(), 'test attachment') self.assertEqual(attachments[1].get_content_type(), 'message/rfc822') self.assertEqualIgnoringHeaderFolding( attachments[1].get_content_bytes(), email_content) inlines = message.inline_attachments self.assertEqual(len(inlines), 1) inline = inlines['abc123'] self.assertEqual(inline.get_filename(), 'image.png') self.assertEqual(inline.get_content_type(), 'image/png') self.assertEqual(inline.get_content_bytes(), image_content)
def create_file(self): attachment = BytesIO(self.data) attachment.content_type = self.content_type attachment.size = self.size attachment.name = "archivo.pdf" return attachment
def test_attachments(self): att1 = BytesIO('test attachment'.encode('utf-8')) att1.name = 'test.txt' image_content = sample_image_content() att2 = BytesIO(image_content) att2.name = 'image.png' email_content = sample_email_content() att3 = BytesIO(email_content) att3.content_type = 'message/rfc822; charset="us-ascii"' raw_event = { 'headers': '', 'attachments': '3', 'attachment-info': json.dumps({ "attachment3": { "filename": "", "name": "", "charset": "US-ASCII", "type": "message/rfc822" }, "attachment2": { "filename": "image.png", "name": "image.png", "type": "image/png", "content-id": "abc123" }, "attachment1": { "filename": "test.txt", "name": "test.txt", "type": "text/plain" }, }), 'content-ids': '{"abc123": "attachment2"}', 'attachment1': att1, 'attachment2': att2, # inline 'attachment3': att3, } response = self.client.post('/anymail/sendgrid/inbound/', data=raw_event) self.assertEqual(response.status_code, 200) kwargs = self.assert_handler_called_once_with( self.inbound_handler, sender=SendGridInboundWebhookView, event=ANY, esp_name='SendGrid') event = kwargs['event'] message = event.message attachments = message.attachments # AnymailInboundMessage convenience accessor self.assertEqual(len(attachments), 2) self.assertEqual(attachments[0].get_filename(), 'test.txt') self.assertEqual(attachments[0].get_content_type(), 'text/plain') self.assertEqual(attachments[0].get_content_text(), 'test attachment') self.assertEqual(attachments[1].get_content_type(), 'message/rfc822') self.assertEqualIgnoringHeaderFolding( attachments[1].get_content_bytes(), email_content) inlines = message.inline_attachments self.assertEqual(len(inlines), 1) inline = inlines['abc123'] self.assertEqual(inline.get_filename(), 'image.png') self.assertEqual(inline.get_content_type(), 'image/png') self.assertEqual(inline.get_content_bytes(), image_content)
def prep_data(length): data = BytesIO(faker.binary(length=length)) data.name = faker.file_name(category='image') data.content_type = faker.mime_type(category='image') data.size = length return data