Refactoring

pull/209/head
M66B 2 years ago
parent dae313849d
commit 20834556b7

@ -3564,41 +3564,18 @@ public class MessageHelper {
void downloadAttachment(Context context, int index, EntityAttachment local) throws MessagingException, IOException {
Log.i("downloading attachment id=" + local.id + " index=" + index + " " + local);
DB db = DB.getInstance(context);
// Get data
AttachmentPart apart = attachments.get(index);
// Download attachment
File file = EntityAttachment.getFile(context, local.id, local.name);
File file = local.getFile(context);
DB db = DB.getInstance(context);
db.attachment().setProgress(local.id, 0);
if (EntityAttachment.PGP_CONTENT.equals(apart.encrypt) ||
EntityAttachment.SMIME_CONTENT.equals(apart.encrypt)) {
ContentType ct = new ContentType(apart.part.getContentType());
String boundary = ct.getParameter("boundary");
if (TextUtils.isEmpty(boundary))
throw new ParseException("Signed boundary missing");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
apart.part.writeTo(bos);
String raw = new String(bos.toByteArray(), StandardCharsets.ISO_8859_1);
String[] parts = raw.split("\\r?\\n" + Pattern.quote("--" + boundary) + "\\r?\\n");
if (parts.length < 2)
throw new ParseException("Signed part missing");
// PGP: https://datatracker.ietf.org/doc/html/rfc3156#section-5
// S/MIME: https://datatracker.ietf.org/doc/html/rfc8551#section-3.1.1
String c = parts[1]
.replaceAll("\\r?\\n", "\r\n"); // normalize new lines
if (EntityAttachment.PGP_CONTENT.equals(apart.encrypt))
c = c.replaceAll(" +$", ""); // trim trailing spaces
try (OutputStream os = new FileOutputStream(file)) {
os.write(c.getBytes(StandardCharsets.ISO_8859_1));
}
db.attachment().setDownloaded(local.id, file.length());
decodeEncrypted(context, local, apart);
} else {
try (InputStream is = apart.part.getInputStream()) {
long size = 0;
@ -3643,12 +3620,59 @@ public class MessageHelper {
}
if ("message/rfc822".equals(local.type))
decodeRfc822(context, local);
else if ("text/calendar".equals(local.type))
decodeICalendar(context, local);
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && local.isCompressed()) {
decodeCompressed(context, local);
} else if (Helper.isTnef(local.type, local.name))
decodeTNEF(context, local);
else if ("msg".equalsIgnoreCase(Helper.getExtension(local.name)))
decodeOutlook(context, local);
}
}
private void decodeEncrypted(Context context, EntityAttachment local, AttachmentPart apart) throws MessagingException, IOException {
ContentType ct = new ContentType(apart.part.getContentType());
String boundary = ct.getParameter("boundary");
if (TextUtils.isEmpty(boundary))
throw new ParseException("Signed boundary missing");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
apart.part.writeTo(bos);
String raw = new String(bos.toByteArray(), StandardCharsets.ISO_8859_1);
String[] parts = raw.split("\\r?\\n" + Pattern.quote("--" + boundary) + "\\r?\\n");
if (parts.length < 2)
throw new ParseException("Signed part missing");
// PGP: https://datatracker.ietf.org/doc/html/rfc3156#section-5
// S/MIME: https://datatracker.ietf.org/doc/html/rfc8551#section-3.1.1
String c = parts[1]
.replaceAll("\\r?\\n", "\r\n"); // normalize new lines
if (EntityAttachment.PGP_CONTENT.equals(apart.encrypt))
c = c.replaceAll(" +$", ""); // trim trailing spaces
File file = local.getFile(context);
try (OutputStream os = new FileOutputStream(file)) {
os.write(c.getBytes(StandardCharsets.ISO_8859_1));
}
DB db = DB.getInstance(context);
db.attachment().setDownloaded(local.id, file.length());
}
private void decodeRfc822(Context context, EntityAttachment local) {
DB db = DB.getInstance(context);
try (FileInputStream fis = new FileInputStream(local.getFile(context))) {
Properties props = MessageHelper.getSessionProperties(true);
Session isession = Session.getInstance(props, null);
MimeMessage imessage = new MimeMessage(isession, fis);
MessageHelper helper = new MessageHelper(imessage, context);
MessageHelper.MessageParts parts = helper.getMessageParts();
MessageParts parts = helper.getMessageParts();
int subsequence = 1;
for (AttachmentPart epart : parts.getAttachmentParts())
@ -3682,117 +3706,17 @@ public class MessageHelper {
else
db.attachment().setWarning(local.id, Log.formatThrowable(ex));
}
else if ("text/calendar".equals(local.type))
try {
boolean permission = Helper.hasPermission(context, Manifest.permission.WRITE_CALENDAR);
EntityMessage message = db.message().getMessage(local.message);
EntityFolder folder = (message == null ? null : db.folder().getFolder(message.folder));
EntityAccount account = (folder == null ? null : db.account().getAccount(folder.account));
boolean received = (folder != null &&
(EntityFolder.INBOX.equals(folder.type) ||
EntityFolder.SYSTEM.equals(folder.type) ||
EntityFolder.USER.equals(folder.type)));
if (!permission || !received || account == null || account.calendar == null)
EntityLog.log(context, "Event not processed" +
" permission=" + permission +
" account=" + (account != null) +
" calendar=" + (account == null ? null : account.calendar) +
" folder=" + (folder != null) + ":" + (folder == null ? null : folder.type) +
" received=" + received);
else {
ICalendar icalendar = Biweekly.parse(file).first();
String method = (icalendar.getMethod() == null ? null : icalendar.getMethod().getValue());
VEvent event = icalendar.getEvents().get(0);
String summary = (event.getSummary() == null ? null : event.getSummary().getValue());
String description = (event.getDescription() == null ? null : event.getDescription().getValue());
String location = (event.getLocation() == null ? null : event.getLocation().getValue());
ICalDate start = (event.getDateStart() == null ? null : event.getDateStart().getValue());
ICalDate end = (event.getDateEnd() == null ? null : event.getDateEnd().getValue());
String uid = (event.getUid() == null ? null : event.getUid().getValue());
EntityLog.log(context, EntityLog.Type.General, message, "Processing event" +
" uid=" + uid + " method=" + method + " calendar=" + account.calendar);
if (icalendar.getMethod() != null &&
start != null && end != null &&
!TextUtils.isEmpty(uid)) {
ContentResolver resolver = context.getContentResolver();
if (icalendar.getMethod().isRequest() || icalendar.getMethod().isCancel())
try (Cursor cursor = resolver.query(CalendarContract.Events.CONTENT_URI,
new String[]{CalendarContract.Events._ID},
CalendarContract.Events.UID_2445 + " = ? ",
new String[]{uid},
null)) {
while (cursor.moveToNext()) {
long eventId = cursor.getLong(0);
// https://developer.android.com/guide/topics/providers/calendar-provider#delete-event
Uri deleteUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
int rows = resolver.delete(deleteUri, null, null);
EntityLog.log(context, EntityLog.Type.General, message, "Deleted event id=" + eventId + " rows=" + rows);
}
}
if (icalendar.getMethod().isRequest())
try (Cursor cursor = resolver.query(CalendarContract.Calendars.CONTENT_URI,
new String[]{CalendarContract.Calendars._ID},
CalendarContract.Calendars.VISIBLE + " = 1 AND " +
CalendarContract.Calendars.IS_PRIMARY + " = 1 AND " +
CalendarContract.Calendars.ACCOUNT_NAME + " = ?",
new String[]{account.calendar},
null)) {
if (cursor.getCount() == 0)
EntityLog.log(context, EntityLog.Type.General, message,
"Account not found username=" + account.user);
while (cursor.moveToNext()) {
// https://developer.android.com/guide/topics/providers/calendar-provider#add-event
// https://developer.android.com/reference/android/provider/CalendarContract.EventsColumns
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.CALENDAR_ID, cursor.getLong(0));
if (!TextUtils.isEmpty(uid))
values.put(CalendarContract.Events.UID_2445, uid);
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
values.put(CalendarContract.Events.DTSTART, start.getTime());
values.put(CalendarContract.Events.DTEND, end.getTime());
if (!TextUtils.isEmpty(summary))
values.put(CalendarContract.Events.TITLE, summary);
if (!TextUtils.isEmpty(description))
values.put(CalendarContract.Events.DESCRIPTION, description);
if (!TextUtils.isEmpty(location))
values.put(CalendarContract.Events.EVENT_LOCATION, location);
values.put(CalendarContract.Events.STATUS, CalendarContract.Events.STATUS_TENTATIVE);
Uri uri = resolver.insert(CalendarContract.Events.CONTENT_URI, values);
long eventId = Long.parseLong(uri.getLastPathSegment());
EntityLog.log(context, EntityLog.Type.General, message, "Inserted event" +
" id=" + eventId +
" start=" + new Date(start.getTime()) +
" end=" + new Date(end.getTime()) +
" summary=" + summary);
}
}
}
}
} catch (Throwable ex) {
Log.w(ex);
db.attachment().setWarning(local.id, Log.formatThrowable(ex));
}
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && local.isCompressed()) {
private void decodeCompressed(Context context, EntityAttachment local) {
// https://commons.apache.org/proper/commons-compress/examples.html
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean unzip = prefs.getBoolean("unzip", !BuildConfig.PLAY_STORE_RELEASE);
if (!unzip)
return;
DB db = DB.getInstance(context);
if (unzip)
if (local.isGzip() && !local.isTarGzip())
try (GzipCompressorInputStream gzip = new GzipCompressorInputStream(
new BufferedInputStream(new FileInputStream(local.getFile(context))))) {
@ -3940,12 +3864,112 @@ public class MessageHelper {
else
db.attachment().setWarning(local.id, Log.formatThrowable(ex));
}
}
} else if (Helper.isTnef(local.type, local.name))
decodeTNEF(context, local);
private void decodeICalendar(Context context, EntityAttachment local) {
DB db = DB.getInstance(context);
try {
boolean permission = Helper.hasPermission(context, Manifest.permission.WRITE_CALENDAR);
else if ("msg".equalsIgnoreCase(Helper.getExtension(local.name)))
decodeOutlook(context, local);
EntityMessage message = db.message().getMessage(local.message);
EntityFolder folder = (message == null ? null : db.folder().getFolder(message.folder));
EntityAccount account = (folder == null ? null : db.account().getAccount(folder.account));
boolean received = (folder != null &&
(EntityFolder.INBOX.equals(folder.type) ||
EntityFolder.SYSTEM.equals(folder.type) ||
EntityFolder.USER.equals(folder.type)));
if (!permission || !received || account == null || account.calendar == null)
EntityLog.log(context, "Event not processed" +
" permission=" + permission +
" account=" + (account != null) +
" calendar=" + (account == null ? null : account.calendar) +
" folder=" + (folder != null) + ":" + (folder == null ? null : folder.type) +
" received=" + received);
else {
File file = local.getFile(context);
ICalendar icalendar = Biweekly.parse(file).first();
String method = (icalendar.getMethod() == null ? null : icalendar.getMethod().getValue());
VEvent event = icalendar.getEvents().get(0);
String summary = (event.getSummary() == null ? null : event.getSummary().getValue());
String description = (event.getDescription() == null ? null : event.getDescription().getValue());
String location = (event.getLocation() == null ? null : event.getLocation().getValue());
ICalDate start = (event.getDateStart() == null ? null : event.getDateStart().getValue());
ICalDate end = (event.getDateEnd() == null ? null : event.getDateEnd().getValue());
String uid = (event.getUid() == null ? null : event.getUid().getValue());
EntityLog.log(context, EntityLog.Type.General, message, "Processing event" +
" uid=" + uid + " method=" + method + " calendar=" + account.calendar);
if (icalendar.getMethod() != null &&
start != null && end != null &&
!TextUtils.isEmpty(uid)) {
ContentResolver resolver = context.getContentResolver();
if (icalendar.getMethod().isRequest() || icalendar.getMethod().isCancel())
try (Cursor cursor = resolver.query(CalendarContract.Events.CONTENT_URI,
new String[]{CalendarContract.Events._ID},
CalendarContract.Events.UID_2445 + " = ? ",
new String[]{uid},
null)) {
while (cursor.moveToNext()) {
long eventId = cursor.getLong(0);
// https://developer.android.com/guide/topics/providers/calendar-provider#delete-event
Uri deleteUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
int rows = resolver.delete(deleteUri, null, null);
EntityLog.log(context, EntityLog.Type.General, message, "Deleted event id=" + eventId + " rows=" + rows);
}
}
if (icalendar.getMethod().isRequest())
try (Cursor cursor = resolver.query(CalendarContract.Calendars.CONTENT_URI,
new String[]{CalendarContract.Calendars._ID},
CalendarContract.Calendars.VISIBLE + " = 1 AND " +
CalendarContract.Calendars.IS_PRIMARY + " = 1 AND " +
CalendarContract.Calendars.ACCOUNT_NAME + " = ?",
new String[]{account.calendar},
null)) {
if (cursor.getCount() == 0)
EntityLog.log(context, EntityLog.Type.General, message,
"Account not found username=" + account.user);
while (cursor.moveToNext()) {
// https://developer.android.com/guide/topics/providers/calendar-provider#add-event
// https://developer.android.com/reference/android/provider/CalendarContract.EventsColumns
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.CALENDAR_ID, cursor.getLong(0));
if (!TextUtils.isEmpty(uid))
values.put(CalendarContract.Events.UID_2445, uid);
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
values.put(CalendarContract.Events.DTSTART, start.getTime());
values.put(CalendarContract.Events.DTEND, end.getTime());
if (!TextUtils.isEmpty(summary))
values.put(CalendarContract.Events.TITLE, summary);
if (!TextUtils.isEmpty(description))
values.put(CalendarContract.Events.DESCRIPTION, description);
if (!TextUtils.isEmpty(location))
values.put(CalendarContract.Events.EVENT_LOCATION, location);
values.put(CalendarContract.Events.STATUS, CalendarContract.Events.STATUS_TENTATIVE);
Uri uri = resolver.insert(CalendarContract.Events.CONTENT_URI, values);
long eventId = Long.parseLong(uri.getLastPathSegment());
EntityLog.log(context, EntityLog.Type.General, message, "Inserted event" +
" id=" + eventId +
" start=" + new Date(start.getTime()) +
" end=" + new Date(end.getTime()) +
" summary=" + summary);
}
}
}
}
} catch (Throwable ex) {
Log.w(ex);
db.attachment().setWarning(local.id, Log.formatThrowable(ex));
}
}

Loading…
Cancel
Save