1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-12-25 00:58:50 -05:00

Improve our display of inline images in HTML mail to not also offer

themselves up for download.

To do so, we need to start storing the original content-id and
content-disposition for attachments - this includes a database upgrade.

Based on a patch from @achen.code
This commit is contained in:
Jesse Vincent 2010-08-15 02:37:06 +00:00
parent 95fd605b0e
commit 73c3872dd0
2 changed files with 67 additions and 23 deletions

View File

@ -11,6 +11,8 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.IOUtils;
@ -1887,18 +1889,14 @@ public class MessageView extends K9Activity implements OnClickListener
// Inline parts with a content-id are almost certainly components of an HTML message
// not attachments. Don't show attachment download buttons for them.
//
// TODO: This code won't work until we correct attachment storage
if ("inline".equalsIgnoreCase(MimeUtility.getHeaderParameter(contentDisposition, null))
&& part.getHeader("Content-Id") != null)
if ( contentDisposition != null &&
MimeUtility.getHeaderParameter(contentDisposition, null).matches("^(?i:inline)")
&& part.getHeader("Content-ID") != null)
{
return;
}
if (name == null)
{
name = MimeUtility.getHeaderParameter(contentDisposition, "filename");
@ -2140,22 +2138,15 @@ public class MessageView extends K9Activity implements OnClickListener
}
});
// TODO: Only check for external (non inline) images
final boolean hasPictures = text.contains("<img");
// If the message contains pictures and the "Show pictures"
// button wasn't already pressed...
if (hasPictures && (mShowPictures == false))
// If the message contains external pictures and the "Show pictures"
// button wasn't already pressed, see if the user's preferences has us
// showing them anyway.
if ( hasExternalImages(MimeUtility.unfoldAndDecode(text))
&& (mShowPictures == false))
{
boolean forceShowPictures = false;
if ((account.getShowPictures() == Account.ShowPictures.ALWAYS) ||
((account.getShowPictures() == Account.ShowPictures.ONLY_FROM_CONTACTS) &&
mContacts.isInContacts(message.getFrom()[0].getAddress())))
{
forceShowPictures = true;
}
if (forceShowPictures)
{
onShowPictures();
}
@ -2188,6 +2179,21 @@ public class MessageView extends K9Activity implements OnClickListener
}
}//loadMessageForViewBodyAvailable
private static final String IMG_SRC_REGEX = "(?is:<img[^>]+src\\s*=\\s*['\"]?([a-z]+)\\:)";
private boolean hasExternalImages(final String message) {
Pattern mImgPattern = Pattern.compile(IMG_SRC_REGEX);
Matcher mImgMatches = mImgPattern.matcher(message);
while(mImgMatches.find()) {
if(!mImgMatches.group(1).equals("content")) {
if (K9.DEBUG)
Log.d(K9.LOG_TAG, "External images found.");
return true;
}
}
if (K9.DEBUG)
Log.d(K9.LOG_TAG, "No external images.");
return false;
}
@Override
public void loadMessageForViewFailed(Account account, String folder, String uid,

View File

@ -44,7 +44,7 @@ public class LocalStore extends Store implements Serializable
*/
private static final String[] EMPTY_STRING_ARRAY = new String[0];
private static final int DB_VERSION = 35;
private static final int DB_VERSION = 37;
private static final Flag[] PERMANENT_FLAGS = { Flag.DELETED, Flag.X_DESTROYED, Flag.SEEN, Flag.FLAGGED };
private String mPath;
@ -62,6 +62,8 @@ public class LocalStore extends Store implements Serializable
HEADERS_TO_SAVE.add("From");
HEADERS_TO_SAVE.add("In-Reply-To");
HEADERS_TO_SAVE.add("References");
HEADERS_TO_SAVE.add("Content-ID");
HEADERS_TO_SAVE.add("Content-Disposition");
HEADERS_TO_SAVE.add("X-User-Agent");
}
/*
@ -164,7 +166,7 @@ public class LocalStore extends Store implements Serializable
mDb.execSQL("DROP TABLE IF EXISTS attachments");
mDb.execSQL("CREATE TABLE attachments (id INTEGER PRIMARY KEY, message_id INTEGER,"
+ "store_data TEXT, content_uri TEXT, size INTEGER, name TEXT,"
+ "mime_type TEXT)");
+ "mime_type TEXT, content_id TEXT, content_disposition TEXT)");
mDb.execSQL("DROP TABLE IF EXISTS pending_commands");
mDb.execSQL("CREATE TABLE pending_commands " +
@ -244,6 +246,28 @@ public class LocalStore extends Store implements Serializable
Log.e(K9.LOG_TAG, "Unable to get rid of obsolete flag X_NO_SEEN_INFO", e);
}
}
if (mDb.getVersion() < 36)
{
try
{
mDb.execSQL("ALTER TABLE attachments ADD content_id TEXT");
}
catch (SQLiteException e)
{
Log.e(K9.LOG_TAG, "Unable to add content_id column to attachments");
}
}
if (mDb.getVersion() < 37)
{
try
{
mDb.execSQL("ALTER TABLE attachments ADD content_disposition TEXT");
}
catch (SQLiteException e)
{
Log.e(K9.LOG_TAG, "Unable to add content_disposition column to attachments");
}
}
}
@ -1391,7 +1415,9 @@ public class LocalStore extends Store implements Serializable
"name",
"mime_type",
"store_data",
"content_uri"
"content_uri",
"content_id",
"content_disposition"
},
"message_id = ?",
new String[] { Long.toString(localMessage.mId) },
@ -1407,7 +1433,15 @@ public class LocalStore extends Store implements Serializable
String type = cursor.getString(3);
String storeData = cursor.getString(4);
String contentUri = cursor.getString(5);
String contentId = cursor.getString(6);
String contentDisposition = cursor.getString(7);
Body body = null;
if (contentDisposition == null )
{
contentDisposition = "attachment";
}
if (contentUri != null)
{
body = new LocalAttachmentBody(Uri.parse(contentUri), mApplication);
@ -1419,10 +1453,12 @@ public class LocalStore extends Store implements Serializable
name));
bp.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
bp.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION,
String.format("attachment;\n filename=\"%s\";\n size=%d",
String.format("%s;\n filename=\"%s\";\n size=%d",
contentDisposition,
name,
size));
bp.setHeader(MimeHeader.HEADER_CONTENT_ID, contentId);
/*
* HEADER_ANDROID_ATTACHMENT_STORE_DATA is a custom header we add to that
* we can later pull the attachment from the remote store if neccesary.
@ -2040,6 +2076,8 @@ public class LocalStore extends Store implements Serializable
cv.put("size", size);
cv.put("name", name);
cv.put("mime_type", attachment.getMimeType());
cv.put("content_id", contentId);
cv.put("content_disposition", contentDisposition);
attachmentId = mDb.insert("attachments", "message_id", cv);
}