Search in sources :

Example 1 with Attachment

use of com.fsck.k9.activity.misc.Attachment in project k-9 by k9mail.

the class MigrationTo51 method insertMimeAttachmentPart.

private static MimeStructureState insertMimeAttachmentPart(SQLiteDatabase db, File attachmentDirOld, File attachmentDirNew, MimeStructureState structureState, long id, int size, String name, String mimeType, String storeData, String contentUriString, String contentId, String contentDisposition) {
    Timber.d("processing attachment %d, %s, %s, %s, %s", id, name, mimeType, storeData, contentUriString);
    if (contentDisposition == null) {
        contentDisposition = "attachment";
    }
    MimeHeader mimeHeader = new MimeHeader();
    mimeHeader.setHeader(MimeHeader.HEADER_CONTENT_TYPE, String.format("%s;\r\n name=\"%s\"", mimeType, name));
    mimeHeader.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION, String.format(Locale.US, "%s;\r\n filename=\"%s\";\r\n size=%d", contentDisposition, name, // TODO: Should use encoded word defined in RFC 2231.
    size));
    if (contentId != null) {
        mimeHeader.setHeader(MimeHeader.HEADER_CONTENT_ID, contentId);
    }
    boolean hasData = contentUriString != null;
    File attachmentFileToMove;
    if (hasData) {
        try {
            Uri contentUri = Uri.parse(contentUriString);
            List<String> pathSegments = contentUri.getPathSegments();
            String attachmentId = pathSegments.get(1);
            boolean isMatchingAttachmentId = Long.parseLong(attachmentId) == id;
            File attachmentFile = new File(attachmentDirOld, attachmentId);
            boolean isExistingAttachmentFile = attachmentFile.exists();
            if (!isMatchingAttachmentId) {
                Timber.e("mismatched attachment id. mark as missing");
                attachmentFileToMove = null;
            } else if (!isExistingAttachmentFile) {
                Timber.e("attached file doesn't exist. mark as missing");
                attachmentFileToMove = null;
            } else {
                attachmentFileToMove = attachmentFile;
            }
        } catch (Exception e) {
            // anything here fails, conservatively assume the data doesn't exist
            attachmentFileToMove = null;
        }
    } else {
        attachmentFileToMove = null;
    }
    if (attachmentFileToMove == null) {
        Timber.d("matching attachment is in local cache");
    }
    boolean hasContentTypeAndIsInline = !TextUtils.isEmpty(contentId) && "inline".equalsIgnoreCase(contentDisposition);
    int messageType = hasContentTypeAndIsInline ? MESSAGE_PART_TYPE__HIDDEN_ATTACHMENT : MESSAGE_PART_TYPE__UNKNOWN;
    ContentValues cv = new ContentValues();
    cv.put("type", messageType);
    cv.put("mime_type", mimeType);
    cv.put("decoded_body_size", size);
    cv.put("display_name", name);
    cv.put("header", mimeHeader.toString());
    cv.put("encoding", MimeUtil.ENC_BINARY);
    cv.put("data_location", attachmentFileToMove != null ? DATA_LOCATION__ON_DISK : DATA_LOCATION__MISSING);
    cv.put("content_id", contentId);
    cv.put("server_extra", storeData);
    structureState.applyValues(cv);
    long partId = db.insertOrThrow("message_parts", null, cv);
    structureState = structureState.nextChild(partId);
    if (attachmentFileToMove != null) {
        boolean moveOk = attachmentFileToMove.renameTo(new File(attachmentDirNew, Long.toString(partId)));
        if (!moveOk) {
            Timber.e("Moving attachment to new dir failed!");
        }
    }
    return structureState;
}
Also used : ContentValues(android.content.ContentValues) MimeHeader(com.fsck.k9.mail.internet.MimeHeader) File(java.io.File) Uri(android.net.Uri) IOException(java.io.IOException)

Example 2 with Attachment

use of com.fsck.k9.activity.misc.Attachment in project k-9 by k9mail.

the class AttachmentPresenter method addAttachment.

public void addAttachment(Uri uri, String contentType) {
    if (attachments.containsKey(uri)) {
        return;
    }
    int loaderId = getNextFreeLoaderId();
    Attachment attachment = Attachment.createAttachment(uri, loaderId, contentType);
    addAttachmentAndStartLoader(attachment);
}
Also used : Attachment(com.fsck.k9.activity.misc.Attachment)

Example 3 with Attachment

use of com.fsck.k9.activity.misc.Attachment in project k-9 by k9mail.

the class PgpMessageBuilderTest method createDefaultPgpMessageBuilder.

private static PgpMessageBuilder createDefaultPgpMessageBuilder(OpenPgpApi openPgpApi) {
    PgpMessageBuilder builder = new PgpMessageBuilder(RuntimeEnvironment.application, MessageIdGenerator.getInstance(), BoundaryGenerator.getInstance());
    builder.setOpenPgpApi(openPgpApi);
    Identity identity = new Identity();
    identity.setName("tester");
    identity.setEmail("test@example.org");
    identity.setDescription("test identity");
    identity.setSignatureUse(false);
    builder.setSubject("subject").setSentDate(new Date()).setHideTimeZone(false).setTo(new ArrayList<Address>()).setCc(new ArrayList<Address>()).setBcc(new ArrayList<Address>()).setInReplyTo("inreplyto").setReferences("references").setRequestReadReceipt(false).setIdentity(identity).setMessageFormat(SimpleMessageFormat.TEXT).setText(TEST_MESSAGE_TEXT).setAttachments(new ArrayList<Attachment>()).setSignature("signature").setQuoteStyle(QuoteStyle.PREFIX).setQuotedTextMode(QuotedTextMode.NONE).setQuotedText("quoted text").setQuotedHtmlContent(new InsertableHtmlContent()).setReplyAfterQuote(false).setSignatureBeforeQuotedText(false).setIdentityChanged(false).setSignatureChanged(false).setCursorPosition(0).setMessageReference(null).setDraft(false);
    return builder;
}
Also used : Address(com.fsck.k9.mail.Address) ArrayList(java.util.ArrayList) Attachment(com.fsck.k9.activity.misc.Attachment) InsertableHtmlContent(com.fsck.k9.message.quote.InsertableHtmlContent) Identity(com.fsck.k9.Identity) Date(java.util.Date)

Example 4 with Attachment

use of com.fsck.k9.activity.misc.Attachment in project k-9 by k9mail.

the class MessageBuilderTest method build_withMessageAttachment_shouldAttachAsApplicationOctetStream.

@Test
public void build_withMessageAttachment_shouldAttachAsApplicationOctetStream() throws Exception {
    MessageBuilder messageBuilder = createSimpleMessageBuilder();
    Attachment attachment = createAttachmentWithContent("message/rfc822", "attach.txt", TEST_ATTACHMENT_TEXT);
    messageBuilder.setAttachments(Collections.singletonList(attachment));
    messageBuilder.buildAsync(callback);
    MimeMessage message = getMessageFromCallback();
    assertEquals(MESSAGE_HEADERS + MESSAGE_CONTENT_WITH_MESSAGE_ATTACH, getMessageContents(message));
}
Also used : MimeMessage(com.fsck.k9.mail.internet.MimeMessage) Attachment(com.fsck.k9.activity.misc.Attachment) Test(org.junit.Test)

Example 5 with Attachment

use of com.fsck.k9.activity.misc.Attachment in project k-9 by k9mail.

the class ImapFolder method parseBodyStructure.

private void parseBodyStructure(ImapList bs, Part part, String id) throws MessagingException {
    if (bs.get(0) instanceof ImapList) {
        /*
             * This is a multipart/*
             */
        MimeMultipart mp = MimeMultipart.newInstance();
        for (int i = 0, count = bs.size(); i < count; i++) {
            if (bs.get(i) instanceof ImapList) {
                /*
                     * For each part in the message we're going to add a new BodyPart and parse
                     * into it.
                     */
                MimeBodyPart bp = new MimeBodyPart();
                if (id.equalsIgnoreCase("TEXT")) {
                    parseBodyStructure(bs.getList(i), bp, Integer.toString(i + 1));
                } else {
                    parseBodyStructure(bs.getList(i), bp, id + "." + (i + 1));
                }
                mp.addBodyPart(bp);
            } else {
                /*
                     * We've got to the end of the children of the part, so now we can find out
                     * what type it is and bail out.
                     */
                String subType = bs.getString(i);
                mp.setSubType(subType.toLowerCase(Locale.US));
                break;
            }
        }
        MimeMessageHelper.setBody(part, mp);
    } else {
        /*
             * This is a body. We need to add as much information as we can find out about
             * it to the Part.
             */
        /*
             *  0| 0  body type
             *  1| 1  body subtype
             *  2| 2  body parameter parenthesized list
             *  3| 3  body id (unused)
             *  4| 4  body description (unused)
             *  5| 5  body encoding
             *  6| 6  body size
             *  -| 7  text lines (only for type TEXT, unused)
             * Extensions (optional):
             *  7| 8  body MD5 (unused)
             *  8| 9  body disposition
             *  9|10  body language (unused)
             * 10|11  body location (unused)
             */
        String type = bs.getString(0);
        String subType = bs.getString(1);
        String mimeType = (type + "/" + subType).toLowerCase(Locale.US);
        ImapList bodyParams = null;
        if (bs.get(2) instanceof ImapList) {
            bodyParams = bs.getList(2);
        }
        String encoding = bs.getString(5);
        int size = bs.getNumber(6);
        if (MimeUtility.isMessage(mimeType)) {
            /*
                 * This will be caught by fetch and handled appropriately.
                 */
            throw new MessagingException("BODYSTRUCTURE message/rfc822 not yet supported.");
        }
        /*
             * Set the content type with as much information as we know right now.
             */
        StringBuilder contentType = new StringBuilder();
        contentType.append(mimeType);
        if (bodyParams != null) {
            /*
                 * If there are body params we might be able to get some more information out
                 * of them.
                 */
            for (int i = 0, count = bodyParams.size(); i < count; i += 2) {
                String paramName = bodyParams.getString(i);
                String paramValue = bodyParams.getString(i + 1);
                contentType.append(String.format(";\r\n %s=\"%s\"", paramName, paramValue));
            }
        }
        part.setHeader(MimeHeader.HEADER_CONTENT_TYPE, contentType.toString());
        // Extension items
        ImapList bodyDisposition = null;
        if ("text".equalsIgnoreCase(type) && bs.size() > 9 && bs.get(9) instanceof ImapList) {
            bodyDisposition = bs.getList(9);
        } else if (!("text".equalsIgnoreCase(type)) && bs.size() > 8 && bs.get(8) instanceof ImapList) {
            bodyDisposition = bs.getList(8);
        }
        StringBuilder contentDisposition = new StringBuilder();
        if (bodyDisposition != null && !bodyDisposition.isEmpty()) {
            if (!"NIL".equalsIgnoreCase(bodyDisposition.getString(0))) {
                contentDisposition.append(bodyDisposition.getString(0).toLowerCase(Locale.US));
            }
            if (bodyDisposition.size() > 1 && bodyDisposition.get(1) instanceof ImapList) {
                ImapList bodyDispositionParams = bodyDisposition.getList(1);
                /*
                     * If there is body disposition information we can pull some more information
                     * about the attachment out.
                     */
                for (int i = 0, count = bodyDispositionParams.size(); i < count; i += 2) {
                    String paramName = bodyDispositionParams.getString(i).toLowerCase(Locale.US);
                    String paramValue = bodyDispositionParams.getString(i + 1);
                    contentDisposition.append(String.format(";\r\n %s=\"%s\"", paramName, paramValue));
                }
            }
        }
        if (MimeUtility.getHeaderParameter(contentDisposition.toString(), "size") == null) {
            contentDisposition.append(String.format(Locale.US, ";\r\n size=%d", size));
        }
        /*
             * Set the content disposition containing at least the size. Attachment
             * handling code will use this down the road.
             */
        part.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION, contentDisposition.toString());
        /*
             * Set the Content-Transfer-Encoding header. Attachment code will use this
             * to parse the body.
             */
        part.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, encoding);
        if (part instanceof ImapMessage) {
            ((ImapMessage) part).setSize(size);
        }
        part.setServerExtra(id);
    }
}
Also used : MimeMultipart(com.fsck.k9.mail.internet.MimeMultipart) MessagingException(com.fsck.k9.mail.MessagingException) MimeBodyPart(com.fsck.k9.mail.internet.MimeBodyPart)

Aggregations

Test (org.junit.Test)12 Attachment (com.fsck.k9.activity.misc.Attachment)9 MimeBodyPart (com.fsck.k9.mail.internet.MimeBodyPart)9 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)9 RobolectricTest (com.fsck.k9.RobolectricTest)8 MessagingException (com.fsck.k9.mail.MessagingException)7 Body (com.fsck.k9.mail.Body)6 BodyPart (com.fsck.k9.mail.BodyPart)6 Part (com.fsck.k9.mail.Part)6 InlineAttachment (com.fsck.k9.activity.misc.InlineAttachment)5 Multipart (com.fsck.k9.mail.Multipart)4 MimeMultipart (com.fsck.k9.mail.internet.MimeMultipart)4 AttachmentViewInfo (com.fsck.k9.mailstore.AttachmentViewInfo)4 File (java.io.File)4 ArrayList (java.util.ArrayList)4 TextBody (com.fsck.k9.mail.internet.TextBody)3 SQLiteException (android.database.sqlite.SQLiteException)2 Uri (android.net.Uri)2 Address (com.fsck.k9.mail.Address)2 Html (com.fsck.k9.mail.internet.Viewable.Html)2