Search in sources :

Example 11 with MimeType

use of com.fsck.k9.mail.MimeType in project k-9 by k9mail.

the class MimeMessage method getMimeType.

@Override
public String getMimeType() {
    String mimeTypeFromHeader = MimeUtility.getHeaderParameter(getContentType(), null);
    MimeType mimeType = MimeType.parseOrNull(mimeTypeFromHeader);
    return mimeType != null ? mimeType.toString() : DEFAULT_MIME_TYPE;
}
Also used : MimeType(com.fsck.k9.mail.MimeType)

Example 12 with MimeType

use of com.fsck.k9.mail.MimeType in project k-9 by k9mail.

the class MigrationTo51 method db51MigrateMessageFormat.

/**
     * This method converts from the old message table structure to the new one.
     *
     * This is a complex migration, and ultimately we do not have enough
     * information to recreate the mime structure of the original mails.
     * What we have:
     *  - general mail info
     *  - html_content and text_content data, which is the squashed readable content of the mail
     *  - a table with message headers
     *  - attachments
     *
     * What we need to do:
     *  - migrate general mail info as-is
     *  - flag mails as migrated for re-download
     *  - for each message, recreate a mime structure from its message content and attachments:
     *    + insert one or both of textContent and htmlContent, depending on mimeType
     *    + if mimeType is text/plain, text/html or multipart/alternative and no
     *      attachments are present, just insert that.
     *    + otherwise, use multipart/mixed, adding attachments after textual content
     *    + revert content:// URIs in htmlContent to original cid: URIs.
     */
public static void db51MigrateMessageFormat(SQLiteDatabase db, MigrationsHelper migrationsHelper) {
    renameOldMessagesTableAndCreateNew(db);
    copyMessageMetadataToNewTable(db);
    File attachmentDirNew, attachmentDirOld;
    Account account = migrationsHelper.getAccount();
    attachmentDirNew = StorageManager.getInstance(K9.app).getAttachmentDirectory(account.getUuid(), account.getLocalStorageProviderId());
    attachmentDirOld = renameOldAttachmentDirAndCreateNew(account, attachmentDirNew);
    Cursor msgCursor = db.query("messages_old", new String[] { "id", "flags", "html_content", "text_content", "mime_type", "attachment_count" }, null, null, null, null, null);
    try {
        Timber.d("migrating %d messages", msgCursor.getCount());
        ContentValues cv = new ContentValues();
        while (msgCursor.moveToNext()) {
            long messageId = msgCursor.getLong(0);
            String messageFlags = msgCursor.getString(1);
            String htmlContent = msgCursor.getString(2);
            String textContent = msgCursor.getString(3);
            String mimeType = msgCursor.getString(4);
            int attachmentCount = msgCursor.getInt(5);
            try {
                updateFlagsForMessage(db, messageId, messageFlags, migrationsHelper);
                MimeHeader mimeHeader = loadHeaderFromHeadersTable(db, messageId);
                MimeStructureState structureState = MimeStructureState.getNewRootState();
                boolean messageHadSpecialFormat = false;
                // we do not rely on the protocol parameter here but guess by the multipart structure
                boolean isMaybePgpMimeEncrypted = attachmentCount == 2 && MimeUtil.isSameMimeType(mimeType, "multipart/encrypted");
                if (isMaybePgpMimeEncrypted) {
                    MimeStructureState maybeStructureState = migratePgpMimeEncryptedContent(db, messageId, attachmentDirOld, attachmentDirNew, mimeHeader, structureState);
                    if (maybeStructureState != null) {
                        structureState = maybeStructureState;
                        messageHadSpecialFormat = true;
                    }
                }
                if (!messageHadSpecialFormat) {
                    boolean isSimpleStructured = attachmentCount == 0 && Utility.isAnyMimeType(mimeType, "text/plain", "text/html", "multipart/alternative");
                    if (isSimpleStructured) {
                        structureState = migrateSimpleMailContent(db, htmlContent, textContent, mimeType, mimeHeader, structureState);
                    } else {
                        mimeType = "multipart/mixed";
                        structureState = migrateComplexMailContent(db, attachmentDirOld, attachmentDirNew, messageId, htmlContent, textContent, mimeHeader, structureState);
                    }
                }
                cv.clear();
                cv.put("mime_type", mimeType);
                cv.put("message_part_id", structureState.rootPartId);
                cv.put("attachment_count", attachmentCount);
                db.update("messages", cv, "id = ?", new String[] { Long.toString(messageId) });
            } catch (IOException e) {
                Timber.e(e, "error inserting into database");
            }
        }
    } finally {
        msgCursor.close();
    }
    cleanUpOldAttachmentDirectory(attachmentDirOld);
    dropOldMessagesTable(db);
}
Also used : ContentValues(android.content.ContentValues) Account(com.fsck.k9.Account) MimeHeader(com.fsck.k9.mail.internet.MimeHeader) IOException(java.io.IOException) Cursor(android.database.Cursor) File(java.io.File)

Example 13 with MimeType

use of com.fsck.k9.mail.MimeType in project k-9 by k9mail.

the class EncryptionDetector method containsPartWithMimeType.

private boolean containsPartWithMimeType(Part part, String... wantedMimeTypes) {
    String mimeType = part.getMimeType();
    if (isMimeTypeAnyOf(mimeType, wantedMimeTypes)) {
        return true;
    }
    Body body = part.getBody();
    if (body instanceof Multipart) {
        Multipart multipart = (Multipart) body;
        for (BodyPart bodyPart : multipart.getBodyParts()) {
            if (containsPartWithMimeType(bodyPart, wantedMimeTypes)) {
                return true;
            }
        }
    }
    return false;
}
Also used : BodyPart(com.fsck.k9.mail.BodyPart) Multipart(com.fsck.k9.mail.Multipart) Body(com.fsck.k9.mail.Body)

Example 14 with MimeType

use of com.fsck.k9.mail.MimeType in project k-9 by k9mail.

the class AttachmentProvider method getType.

private String getType(String accountUuid, String id, String mimeType) {
    String type;
    final Account account = Preferences.getPreferences(getContext()).getAccount(accountUuid);
    try {
        final LocalStore localStore = DI.get(LocalStoreProvider.class).getInstance(account);
        AttachmentInfo attachmentInfo = localStore.getAttachmentInfo(id);
        if (mimeType != null) {
            type = mimeType;
        } else {
            type = attachmentInfo.type;
        }
    } catch (MessagingException e) {
        Timber.e(e, "Unable to retrieve LocalStore for %s", account);
        type = MimeUtility.DEFAULT_ATTACHMENT_MIME_TYPE;
    }
    return type;
}
Also used : Account(com.fsck.k9.Account) MessagingException(com.fsck.k9.mail.MessagingException) AttachmentInfo(com.fsck.k9.mailstore.LocalStore.AttachmentInfo) LocalStore(com.fsck.k9.mailstore.LocalStore) LocalStoreProvider(com.fsck.k9.mailstore.LocalStoreProvider)

Example 15 with MimeType

use of com.fsck.k9.mail.MimeType in project k-9 by k9mail.

the class LocalFolder method loadMessagePart.

private void loadMessagePart(LocalMessage message, Map<Long, Part> partById, Cursor cursor) throws MessagingException {
    long id = cursor.getLong(0);
    long parentId = cursor.getLong(2);
    String mimeType = cursor.getString(3);
    long size = cursor.getLong(4);
    byte[] header = cursor.getBlob(6);
    int dataLocation = cursor.getInt(9);
    String serverExtra = cursor.getString(15);
    // TODO we don't currently cache much of the part data which is computed with AttachmentInfoExtractor,
    // TODO might want to do that at a later point?
    // String displayName = cursor.getString(5);
    // int type = cursor.getInt(1);
    // boolean inlineAttachment = (type == MessagePartType.HIDDEN_ATTACHMENT);
    final Part part;
    if (id == message.getMessagePartId()) {
        part = message;
    } else {
        Part parentPart = partById.get(parentId);
        if (parentPart == null) {
            throw new IllegalStateException("Parent part not found");
        }
        String parentMimeType = parentPart.getMimeType();
        if (MimeUtility.isMultipart(parentMimeType)) {
            BodyPart bodyPart = new LocalBodyPart(getAccountUuid(), message, id, size);
            ((Multipart) parentPart.getBody()).addBodyPart(bodyPart);
            part = bodyPart;
        } else if (MimeUtility.isMessage(parentMimeType)) {
            Message innerMessage = new LocalMimeMessage(getAccountUuid(), message, id);
            parentPart.setBody(innerMessage);
            part = innerMessage;
        } else {
            throw new IllegalStateException("Parent is neither a multipart nor a message");
        }
        parseHeaderBytes(part, header);
    }
    partById.put(id, part);
    part.setServerExtra(serverExtra);
    if (MimeUtility.isMultipart(mimeType)) {
        byte[] preamble = cursor.getBlob(11);
        byte[] epilogue = cursor.getBlob(12);
        String boundary = cursor.getString(13);
        MimeMultipart multipart = new MimeMultipart(mimeType, boundary);
        part.setBody(multipart);
        multipart.setPreamble(preamble);
        multipart.setEpilogue(epilogue);
    } else if (dataLocation == DataLocation.IN_DATABASE) {
        String encoding = cursor.getString(7);
        byte[] data = cursor.getBlob(10);
        Body body = new BinaryMemoryBody(data, encoding);
        part.setBody(body);
    } else if (dataLocation == DataLocation.ON_DISK) {
        String encoding = cursor.getString(7);
        File file = localStore.getAttachmentFile(Long.toString(id));
        if (file.exists()) {
            Body body = new FileBackedBody(file, encoding);
            part.setBody(body);
        }
    }
}
Also used : BodyPart(com.fsck.k9.mail.BodyPart) Multipart(com.fsck.k9.mail.Multipart) MimeMultipart(com.fsck.k9.mail.internet.MimeMultipart) Message(com.fsck.k9.mail.Message) MimeMultipart(com.fsck.k9.mail.internet.MimeMultipart) BodyPart(com.fsck.k9.mail.BodyPart) Part(com.fsck.k9.mail.Part) Body(com.fsck.k9.mail.Body) BinaryTempFileBody(com.fsck.k9.mail.internet.BinaryTempFileBody) File(java.io.File)

Aggregations

Body (com.fsck.k9.mail.Body)8 Multipart (com.fsck.k9.mail.Multipart)8 BodyPart (com.fsck.k9.mail.BodyPart)6 Part (com.fsck.k9.mail.Part)6 MessagingException (com.fsck.k9.mail.MessagingException)4 IOException (java.io.IOException)4 Message (com.fsck.k9.mail.Message)3 MimeType (com.fsck.k9.mail.MimeType)3 File (java.io.File)3 ContentValues (android.content.ContentValues)2 Uri (android.net.Uri)2 Nullable (androidx.annotation.Nullable)2 Account (com.fsck.k9.Account)2 MimeBodyPart (com.fsck.k9.mail.internet.MimeBodyPart)2 MimeHeader (com.fsck.k9.mail.internet.MimeHeader)2 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)2 MimeMultipart (com.fsck.k9.mail.internet.MimeMultipart)2 Cursor (android.database.Cursor)1 RobolectricTest (com.fsck.k9.RobolectricTest)1 Address (com.fsck.k9.mail.Address)1