mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-23 09:52:16 -05:00
Fix downloading/saving single message parts
This commit is contained in:
parent
743e640d8c
commit
bd97004ebd
@ -2,14 +2,25 @@ package com.fsck.k9.mail;
|
||||
|
||||
|
||||
public abstract class BodyPart implements Part {
|
||||
private Multipart mParent;
|
||||
private String serverExtra;
|
||||
private Multipart parent;
|
||||
|
||||
@Override
|
||||
public String getServerExtra() {
|
||||
return serverExtra;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServerExtra(String serverExtra) {
|
||||
this.serverExtra = serverExtra;
|
||||
}
|
||||
|
||||
public Multipart getParent() {
|
||||
return mParent;
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(Multipart parent) {
|
||||
mParent = parent;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public abstract void setEncoding(String encoding) throws MessagingException;
|
||||
|
@ -46,4 +46,8 @@ public interface Part {
|
||||
*/
|
||||
//TODO perhaps it would be clearer to use a flag "force7bit" in writeTo
|
||||
void setUsing7bitTransport() throws MessagingException;
|
||||
|
||||
String getServerExtra();
|
||||
|
||||
void setServerExtra(String serverExtra);
|
||||
}
|
||||
|
@ -11,28 +11,11 @@ import java.util.*;
|
||||
public class MimeHeader {
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
|
||||
/**
|
||||
* Application specific header that contains Store specific information about an attachment.
|
||||
* In IMAP this contains the IMAP BODYSTRUCTURE part id so that the ImapStore can later
|
||||
* retrieve the attachment at will from the server.
|
||||
* The info is recorded from this header on LocalStore.appendMessages and is put back
|
||||
* into the MIME data by LocalStore.fetch.
|
||||
*/
|
||||
public static final String HEADER_ANDROID_ATTACHMENT_STORE_DATA = "X-Android-Attachment-StoreData";
|
||||
|
||||
public static final String HEADER_CONTENT_TYPE = "Content-Type";
|
||||
public static final String HEADER_CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
|
||||
public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
|
||||
public static final String HEADER_CONTENT_ID = "Content-ID";
|
||||
|
||||
/**
|
||||
* Fields that should be omitted when writing the header using writeTo()
|
||||
*/
|
||||
private static final String[] writeOmitFields = {
|
||||
// HEADER_ANDROID_ATTACHMENT_DOWNLOADED,
|
||||
// HEADER_ANDROID_ATTACHMENT_ID,
|
||||
HEADER_ANDROID_ATTACHMENT_STORE_DATA
|
||||
};
|
||||
|
||||
private List<Field> mFields = new ArrayList<Field>();
|
||||
private String mCharset = null;
|
||||
@ -101,7 +84,6 @@ public class MimeHeader {
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
|
||||
for (Field field : mFields) {
|
||||
if (!Arrays.asList(writeOmitFields).contains(field.name)) {
|
||||
if (field.hasRawData()) {
|
||||
writer.write(field.getRaw());
|
||||
} else {
|
||||
@ -109,7 +91,6 @@ public class MimeHeader {
|
||||
}
|
||||
writer.write("\r\n");
|
||||
}
|
||||
}
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@ public class MimeMessage extends Message {
|
||||
|
||||
private Body mBody;
|
||||
protected int mSize;
|
||||
private String serverExtra;
|
||||
|
||||
public MimeMessage() {
|
||||
}
|
||||
@ -693,4 +694,16 @@ public class MimeMessage extends Message {
|
||||
setEncoding(MimeUtil.ENC_QUOTED_PRINTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerExtra() {
|
||||
return serverExtra;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServerExtra(String serverExtra) {
|
||||
this.serverExtra = serverExtra;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1455,13 +1455,9 @@ public class ImapStore extends RemoteStore {
|
||||
throws MessagingException {
|
||||
checkOpen(); //only need READ access
|
||||
|
||||
String[] parts = part.getHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA);
|
||||
if (parts == null) {
|
||||
return;
|
||||
}
|
||||
String partId = part.getServerExtra();
|
||||
|
||||
String fetch;
|
||||
String partId = parts[0];
|
||||
if ("TEXT".equalsIgnoreCase(partId)) {
|
||||
fetch = String.format(Locale.US, "BODY.PEEK[TEXT]<0.%d>",
|
||||
mStoreConfig.getMaximumAutoDownloadMessageSize());
|
||||
@ -1834,7 +1830,7 @@ public class ImapStore extends RemoteStore {
|
||||
if (part instanceof ImapMessage) {
|
||||
((ImapMessage) part).setSize(size);
|
||||
}
|
||||
part.setHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA, id);
|
||||
part.setServerExtra(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -672,6 +672,7 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable {
|
||||
long parentId = cursor.getLong(2);
|
||||
String mimeType = cursor.getString(3);
|
||||
byte[] header = cursor.getBlob(6);
|
||||
String serverExtra = cursor.getString(15);
|
||||
|
||||
final Part part;
|
||||
if (id == message.getMessagePartId()) {
|
||||
@ -698,6 +699,7 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable {
|
||||
parseHeaderBytes(part, header);
|
||||
}
|
||||
partById.put(id, part);
|
||||
part.setServerExtra(serverExtra);
|
||||
|
||||
boolean isMultipart = mimeType.startsWith("multipart/");
|
||||
if (isMultipart) {
|
||||
@ -1322,14 +1324,22 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable {
|
||||
|
||||
Part part = partContainer.part;
|
||||
|
||||
byte[] headerBytes = getHeaderBytes(part);
|
||||
|
||||
ContentValues cv = new ContentValues();
|
||||
if (rootMessagePartId != -1) {
|
||||
cv.put("root", rootMessagePartId);
|
||||
}
|
||||
cv.put("parent", partContainer.parent);
|
||||
cv.put("seq", order);
|
||||
cv.put("server_extra", part.getServerExtra());
|
||||
|
||||
partToContentValues(cv, part);
|
||||
|
||||
return db.insertOrThrow("message_parts", null, cv);
|
||||
}
|
||||
|
||||
private void partToContentValues(ContentValues cv, Part part) throws IOException, MessagingException {
|
||||
byte[] headerBytes = getHeaderBytes(part);
|
||||
|
||||
cv.put("mime_type", part.getMimeType());
|
||||
cv.put("header", headerBytes);
|
||||
cv.put("type", MessagePartType.UNKNOWN);
|
||||
@ -1355,8 +1365,6 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable {
|
||||
cv.put("data", bodyData);
|
||||
cv.put("content_id", part.getContentId());
|
||||
}
|
||||
|
||||
return db.insertOrThrow("message_parts", null, cv);
|
||||
}
|
||||
|
||||
private byte[] getHeaderBytes(Part part) throws IOException, MessagingException {
|
||||
@ -1403,9 +1411,39 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable {
|
||||
|
||||
public void addPartToMessage(final LocalMessage message, final Part part) throws MessagingException {
|
||||
open(OPEN_MODE_RW);
|
||||
throw new RuntimeException("Not implemented yet");
|
||||
|
||||
// localStore.notifyChange();
|
||||
localStore.database.execute(false, new DbCallback<Void>() {
|
||||
@Override
|
||||
public Void doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
|
||||
String messagePartId;
|
||||
|
||||
Cursor cursor = db.query("message_parts", new String[] { "id" }, "root = ? AND server_extra = ?",
|
||||
new String[] { Long.toString(message.getMessagePartId()), part.getServerExtra() },
|
||||
null, null, null);
|
||||
try {
|
||||
if (!cursor.moveToFirst()) {
|
||||
throw new IllegalStateException("Message part not found");
|
||||
}
|
||||
|
||||
messagePartId = cursor.getString(0);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
try {
|
||||
ContentValues cv = new ContentValues();
|
||||
partToContentValues(cv, part);
|
||||
|
||||
db.update("message_parts", cv, "id = ?", new String[] { messagePartId });
|
||||
} catch (Exception e) {
|
||||
Log.e(K9.LOG_TAG, "Error writing message part", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
localStore.notifyChange();
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user