mirror of
https://github.com/moparisthebest/k-9
synced 2024-12-25 00:58:50 -05:00
Merge branch 'mime_type_rewriting'
This commit is contained in:
commit
c9510f8f16
@ -876,7 +876,14 @@ public class MimeUtility {
|
||||
{ "zmm", "application/vnd.handheld-entertainment+xml"}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Table for MIME type replacements.
|
||||
*
|
||||
* Table format: wrong type, correct type
|
||||
*/
|
||||
private static final String[][] MIME_TYPE_REPLACEMENT_MAP = new String[][] {
|
||||
{"image/jpg", "image/jpeg"}
|
||||
};
|
||||
|
||||
public static String unfold(String s) {
|
||||
if (s == null) {
|
||||
@ -1193,6 +1200,46 @@ public class MimeUtility {
|
||||
return DEFAULT_ATTACHMENT_MIME_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert some wrong MIME types encountered in the wild to canonical MIME
|
||||
* types.
|
||||
*
|
||||
* @param mimeType The original MIME type
|
||||
* @return If {@code mimeType} is known to be wrong the correct MIME type
|
||||
* is returned. Otherwise the value of {@code mimeType} is returned
|
||||
* unmodified.
|
||||
*
|
||||
* @see #MIME_TYPE_REPLACEMENT_MAP
|
||||
*/
|
||||
public static String canonicalizeMimeType(String mimeType) {
|
||||
for (String[] mimeTypeMapEntry : MIME_TYPE_REPLACEMENT_MAP) {
|
||||
if (mimeTypeMapEntry[0].equals(mimeType)) {
|
||||
return mimeTypeMapEntry[1];
|
||||
}
|
||||
}
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* When viewing the attachment we want the MIME type to be as sensible as
|
||||
* possible. So we fix it up if necessary.
|
||||
*
|
||||
* @param mimeType The original MIME type of the attachment.
|
||||
* @param name The (file)name of the attachment.
|
||||
*
|
||||
* @return The best MIME type we can come up with.
|
||||
*/
|
||||
public static String getMimeTypeForViewing(String mimeType, String name) {
|
||||
if (DEFAULT_ATTACHMENT_MIME_TYPE.equalsIgnoreCase(mimeType)) {
|
||||
// If the MIME type is the generic "application/octet-stream"
|
||||
// we try to find a better one by looking at the file extension.
|
||||
return getMimeTypeByExtension(name);
|
||||
} else {
|
||||
// Some messages contain wrong MIME types. See if we know better.
|
||||
return canonicalizeMimeType(mimeType);
|
||||
}
|
||||
}
|
||||
|
||||
private static Message getMessageFromPart(Part part) {
|
||||
while (part != null) {
|
||||
if (part instanceof Message)
|
||||
|
@ -988,49 +988,18 @@ public class LocalStore extends Store implements Serializable {
|
||||
|
||||
}
|
||||
|
||||
public String getAttachmentType(final String attachmentId) throws UnavailableStorageException {
|
||||
return database.execute(false, new DbCallback<String>() {
|
||||
@Override
|
||||
public String doDbWork(final SQLiteDatabase db) throws WrappedException {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = db.query(
|
||||
"attachments",
|
||||
new String[] { "mime_type", "name" },
|
||||
"id = ?",
|
||||
new String[] { attachmentId },
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
cursor.moveToFirst();
|
||||
String type = cursor.getString(0);
|
||||
String name = cursor.getString(1);
|
||||
cursor.close();
|
||||
|
||||
if (MimeUtility.DEFAULT_ATTACHMENT_MIME_TYPE.equalsIgnoreCase(type)) {
|
||||
type = MimeUtility.getMimeTypeByExtension(name);
|
||||
}
|
||||
return type;
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public AttachmentInfo getAttachmentInfo(final String attachmentId) throws UnavailableStorageException {
|
||||
return database.execute(false, new DbCallback<AttachmentInfo>() {
|
||||
@Override
|
||||
public AttachmentInfo doDbWork(final SQLiteDatabase db) throws WrappedException {
|
||||
String name;
|
||||
String type;
|
||||
int size;
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = db.query(
|
||||
"attachments",
|
||||
new String[] { "name", "size" },
|
||||
new String[] { "name", "size", "mime_type" },
|
||||
"id = ?",
|
||||
new String[] { attachmentId },
|
||||
null,
|
||||
@ -1041,9 +1010,11 @@ public class LocalStore extends Store implements Serializable {
|
||||
}
|
||||
name = cursor.getString(0);
|
||||
size = cursor.getInt(1);
|
||||
type = cursor.getString(2);
|
||||
final AttachmentInfo attachmentInfo = new AttachmentInfo();
|
||||
attachmentInfo.name = name;
|
||||
attachmentInfo.size = size;
|
||||
attachmentInfo.type = type;
|
||||
return attachmentInfo;
|
||||
} finally {
|
||||
if (cursor != null) {
|
||||
@ -1057,6 +1028,7 @@ public class LocalStore extends Store implements Serializable {
|
||||
public static class AttachmentInfo {
|
||||
public String name;
|
||||
public int size;
|
||||
public String type;
|
||||
}
|
||||
|
||||
public void createFolders(final List<LocalFolder> foldersToCreate, final int visibleLimit) throws UnavailableStorageException {
|
||||
|
@ -30,6 +30,7 @@ public class AttachmentProvider extends ContentProvider {
|
||||
public static final Uri CONTENT_URI = Uri.parse("content://com.fsck.k9.attachmentprovider");
|
||||
|
||||
private static final String FORMAT_RAW = "RAW";
|
||||
private static final String FORMAT_VIEW = "VIEW";
|
||||
private static final String FORMAT_THUMBNAIL = "THUMBNAIL";
|
||||
|
||||
public static class AttachmentProviderColumns {
|
||||
@ -40,7 +41,11 @@ public class AttachmentProvider extends ContentProvider {
|
||||
}
|
||||
|
||||
public static Uri getAttachmentUri(Account account, long id) {
|
||||
return getAttachmentUri(account.getUuid(), id);
|
||||
return getAttachmentUri(account.getUuid(), id, true);
|
||||
}
|
||||
|
||||
public static Uri getAttachmentUriForViewing(Account account, long id) {
|
||||
return getAttachmentUri(account.getUuid(), id, false);
|
||||
}
|
||||
|
||||
public static Uri getAttachmentThumbnailUri(Account account, long id, int width, int height) {
|
||||
@ -53,11 +58,11 @@ public class AttachmentProvider extends ContentProvider {
|
||||
.build();
|
||||
}
|
||||
|
||||
private static Uri getAttachmentUri(String db, long id) {
|
||||
private static Uri getAttachmentUri(String db, long id, boolean raw) {
|
||||
return CONTENT_URI.buildUpon()
|
||||
.appendPath(db)
|
||||
.appendPath(Long.toString(id))
|
||||
.appendPath(FORMAT_RAW)
|
||||
.appendPath(raw ? FORMAT_RAW : FORMAT_VIEW)
|
||||
.build();
|
||||
}
|
||||
|
||||
@ -98,6 +103,11 @@ public class AttachmentProvider extends ContentProvider {
|
||||
String dbName = segments.get(0);
|
||||
String id = segments.get(1);
|
||||
String format = segments.get(2);
|
||||
|
||||
return getType(dbName, id, format);
|
||||
}
|
||||
|
||||
private String getType(String dbName, String id, String format) {
|
||||
if (FORMAT_THUMBNAIL.equals(format)) {
|
||||
return "image/png";
|
||||
} else {
|
||||
@ -105,7 +115,14 @@ public class AttachmentProvider extends ContentProvider {
|
||||
|
||||
try {
|
||||
final LocalStore localStore = LocalStore.getLocalInstance(account, K9.app);
|
||||
return localStore.getAttachmentType(id);
|
||||
|
||||
AttachmentInfo attachmentInfo = localStore.getAttachmentInfo(id);
|
||||
if (FORMAT_VIEW.equals(format)) {
|
||||
return MimeUtility.getMimeTypeForViewing(attachmentInfo.type, attachmentInfo.name);
|
||||
} else {
|
||||
// When accessing the "raw" message we deliver the original MIME type.
|
||||
return attachmentInfo.type;
|
||||
}
|
||||
} catch (MessagingException e) {
|
||||
Log.e(K9.LOG_TAG, "Unable to retrieve LocalStore for " + account, e);
|
||||
return null;
|
||||
@ -148,8 +165,7 @@ public class AttachmentProvider extends ContentProvider {
|
||||
File dir = getContext().getCacheDir();
|
||||
File file = new File(dir, filename);
|
||||
if (!file.exists()) {
|
||||
Uri attachmentUri = getAttachmentUri(dbName, Long.parseLong(id));
|
||||
String type = getType(attachmentUri);
|
||||
String type = getType(dbName, id, FORMAT_VIEW);
|
||||
try {
|
||||
FileInputStream in = new FileInputStream(getFile(dbName, id));
|
||||
try {
|
||||
|
@ -78,10 +78,7 @@ public class AttachmentView extends FrameLayout {
|
||||
mListener = listener;
|
||||
|
||||
size = Integer.parseInt(MimeUtility.getHeaderParameter(contentDisposition, "size"));
|
||||
contentType = part.getMimeType();
|
||||
if (MimeUtility.DEFAULT_ATTACHMENT_MIME_TYPE.equalsIgnoreCase(contentType)) {
|
||||
contentType = MimeUtility.getMimeTypeByExtension(name);
|
||||
}
|
||||
contentType = MimeUtility.getMimeTypeForViewing(part.getMimeType(), name);
|
||||
TextView attachmentName = (TextView) findViewById(R.id.attachment_name);
|
||||
TextView attachmentInfo = (TextView) findViewById(R.id.attachment_info);
|
||||
ImageView attachmentIcon = (ImageView) findViewById(R.id.attachment_icon);
|
||||
@ -196,7 +193,7 @@ public class AttachmentView extends FrameLayout {
|
||||
|
||||
|
||||
public void showFile() {
|
||||
Uri uri = AttachmentProvider.getAttachmentUri(mAccount, part.getAttachmentId());
|
||||
Uri uri = AttachmentProvider.getAttachmentUriForViewing(mAccount, part.getAttachmentId());
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(uri);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
@ -227,7 +224,7 @@ public class AttachmentView extends FrameLayout {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Uri uri = AttachmentProvider.getAttachmentUri(mAccount, part.getAttachmentId());
|
||||
Uri uri = AttachmentProvider.getAttachmentUriForViewing(mAccount, part.getAttachmentId());
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(uri);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
|
Loading…
Reference in New Issue
Block a user