use of com.fsck.k9.mailstore.migrations.MigrationTo51.MimeStructureState in project k-9 by k9mail.
the class MigrationMimeStructureStateTest method init_apply_nextmulti_nextchild_shouldCrash.
@Test(expected = IllegalStateException.class)
public void init_apply_nextmulti_nextchild_shouldCrash() throws Exception {
MimeStructureState state = MimeStructureState.getNewRootState();
ContentValues cv = new ContentValues();
state.applyValues(cv);
state.nextMultipartChild(1);
state.nextChild(1);
}
use of com.fsck.k9.mailstore.migrations.MigrationTo51.MimeStructureState 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);
}
use of com.fsck.k9.mailstore.migrations.MigrationTo51.MimeStructureState in project k-9 by k9mail.
the class MigrationTo51 method insertTextualPartIntoDatabase.
private static MimeStructureState insertTextualPartIntoDatabase(SQLiteDatabase db, MimeStructureState structureState, MimeHeader mimeHeader, String content, boolean isHtml) throws IOException {
if (mimeHeader == null) {
mimeHeader = new MimeHeader();
}
mimeHeader.setHeader(MimeHeader.HEADER_CONTENT_TYPE, isHtml ? "text/html; charset=\"utf-8\"" : "text/plain; charset=\"utf-8\"");
mimeHeader.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, MimeUtil.ENC_QUOTED_PRINTABLE);
byte[] contentBytes;
int decodedBodySize;
int dataLocation;
if (content != null) {
ByteArrayOutputStream contentOutputStream = new ByteArrayOutputStream();
QuotedPrintableOutputStream quotedPrintableOutputStream = new QuotedPrintableOutputStream(contentOutputStream, false);
quotedPrintableOutputStream.write(content.getBytes());
quotedPrintableOutputStream.flush();
dataLocation = DATA_LOCATION__IN_DATABASE;
contentBytes = contentOutputStream.toByteArray();
decodedBodySize = content.length();
} else {
dataLocation = DATA_LOCATION__MISSING;
contentBytes = null;
decodedBodySize = 0;
}
ContentValues cv = new ContentValues();
cv.put("type", MESSAGE_PART_TYPE__UNKNOWN);
cv.put("data_location", dataLocation);
cv.put("mime_type", isHtml ? "text/html" : "text/plain");
cv.put("header", mimeHeader.toString());
cv.put("data", contentBytes);
cv.put("decoded_body_size", decodedBodySize);
cv.put("encoding", MimeUtil.ENC_QUOTED_PRINTABLE);
cv.put("charset", "utf-8");
structureState.applyValues(cv);
long partId = db.insertOrThrow("message_parts", null, cv);
return structureState.nextChild(partId);
}
use of com.fsck.k9.mailstore.migrations.MigrationTo51.MimeStructureState in project k-9 by k9mail.
the class MigrationMimeStructureStateTest method init_apply_nextchild_apply_shouldCrash.
@Test(expected = IllegalStateException.class)
public void init_apply_nextchild_apply_shouldCrash() throws Exception {
MimeStructureState state = MimeStructureState.getNewRootState();
ContentValues cv = new ContentValues();
state.applyValues(cv);
state = state.nextChild(123);
cv.clear();
state.applyValues(cv);
}
use of com.fsck.k9.mailstore.migrations.MigrationTo51.MimeStructureState in project k-9 by k9mail.
the class MigrationMimeStructureStateTest method init_apply_nextchild_nextmulti_shouldCrash.
@Test(expected = IllegalStateException.class)
public void init_apply_nextchild_nextmulti_shouldCrash() throws Exception {
MimeStructureState state = MimeStructureState.getNewRootState();
ContentValues cv = new ContentValues();
state.applyValues(cv);
state.nextChild(1);
state.nextMultipartChild(1);
}
Aggregations