Refactoring

pull/209/head
M66B 3 years ago
parent 010d95f187
commit ee3f1dcc03

@ -0,0 +1,176 @@
package eu.faircode.email;
/*
This file is part of FairEmail.
FairEmail is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FairEmail is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FairEmail. If not, see <http://www.gnu.org/licenses/>.
Copyright 2018-2022 by Marcel Bokhorst (M66B)
*/
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CalendarContract;
import android.text.TextUtils;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import biweekly.ICalVersion;
import biweekly.component.VEvent;
import biweekly.io.TimezoneInfo;
import biweekly.io.WriteContext;
import biweekly.io.scribe.property.RecurrenceRuleScribe;
import biweekly.parameter.ParticipationStatus;
import biweekly.property.Attendee;
import biweekly.property.RecurrenceRule;
import biweekly.util.ICalDate;
public class CalendarHelper {
static void insert(Context context, TimezoneInfo tz, VEvent event,
String selectedAccount, String selectedName, EntityMessage message) {
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 rrule = null;
RecurrenceRule recurrence = event.getRecurrenceRule();
if (recurrence != null) {
RecurrenceRuleScribe scribe = new RecurrenceRuleScribe();
WriteContext wcontext = new WriteContext(ICalVersion.V2_0, tz, null);
rrule = scribe.writeText(recurrence, wcontext);
}
String uid = (event.getUid() == null ? null : event.getUid().getValue());
if (TextUtils.isEmpty(uid) || start == null || end == null)
return;
ContentResolver resolver = context.getContentResolver();
try (Cursor cursor = resolver.query(CalendarContract.Calendars.CONTENT_URI,
new String[]{CalendarContract.Calendars._ID},
CalendarContract.Calendars.VISIBLE + " <> 0 AND " +
CalendarContract.Calendars.ACCOUNT_NAME + " = ?" +
(selectedName == null
? ""
: " AND " + CalendarContract.Calendars.CALENDAR_DISPLAY_NAME + " = ?"),
selectedName == null
? new String[]{selectedAccount}
: new String[]{selectedAccount, selectedName},
null)) {
if (cursor.getCount() == 0)
EntityLog.log(context, EntityLog.Type.General, message,
"Account not found account=" + selectedAccount + ":" + selectedName);
if (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 (rrule != null)
values.put(CalendarContract.Events.RRULE, rrule);
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 +
" uid=" + uid +
" start=" + new Date(start.getTime()) +
" end=" + new Date(end.getTime()) +
" summary=" + summary);
}
}
}
static void update(Context context, VEvent event, EntityMessage message) {
String uid = (event.getUid() == null ? null : event.getUid().getValue());
if (TextUtils.isEmpty(uid))
return;
List<Attendee> attendees = event.getAttendees();
if (attendees == null || attendees.size() == 0)
return;
ParticipationStatus status = attendees.get(0).getParticipationStatus();
if (!ParticipationStatus.ACCEPTED.equals(status) &&
!ParticipationStatus.DECLINED.equals(status))
return;
ContentResolver resolver = context.getContentResolver();
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#modify-calendar
Uri updateUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
ContentValues values = new ContentValues();
if (ParticipationStatus.ACCEPTED.equals(status))
values.put(CalendarContract.Events.STATUS, CalendarContract.Events.STATUS_CONFIRMED);
else
values.put(CalendarContract.Events.STATUS, CalendarContract.Events.STATUS_CANCELED);
int rows = resolver.update(updateUri, values, null, null);
EntityLog.log(context, EntityLog.Type.General, message,
"Updated event id=" + eventId + " uid=" + uid + " rows=" + rows);
}
}
}
static void delete(Context context, VEvent event, EntityMessage message) {
String uid = (event.getUid() == null ? null : event.getUid().getValue());
if (TextUtils.isEmpty(uid))
return;
ContentResolver resolver = context.getContentResolver();
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 + " uid=" + uid + " rows=" + rows);
}
}
}
}

@ -22,15 +22,10 @@ package eu.faircode.email;
import static android.system.OsConstants.ENOSPC; import static android.system.OsConstants.ENOSPC;
import android.Manifest; import android.Manifest;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.provider.CalendarContract;
import android.system.ErrnoException; import android.system.ErrnoException;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.TextUtils; import android.text.TextUtils;
@ -145,14 +140,9 @@ import javax.mail.internet.ParameterList;
import javax.mail.internet.ParseException; import javax.mail.internet.ParseException;
import biweekly.Biweekly; import biweekly.Biweekly;
import biweekly.ICalVersion;
import biweekly.ICalendar; import biweekly.ICalendar;
import biweekly.component.VEvent; import biweekly.component.VEvent;
import biweekly.io.WriteContext;
import biweekly.io.scribe.property.RecurrenceRuleScribe;
import biweekly.property.Method; import biweekly.property.Method;
import biweekly.property.RecurrenceRule;
import biweekly.util.ICalDate;
public class MessageHelper { public class MessageHelper {
private boolean ensuredEnvelope = false; private boolean ensuredEnvelope = false;
@ -3885,126 +3875,43 @@ public class MessageHelper {
EntityFolder.SYSTEM.equals(folder.type) || EntityFolder.SYSTEM.equals(folder.type) ||
EntityFolder.USER.equals(folder.type))); EntityFolder.USER.equals(folder.type)));
if (!permission || !received || account == null || account.calendar == null) if (!permission || !received || account == null || account.calendar == null) {
EntityLog.log(context, "Event not processed" + EntityLog.log(context, "Event not processed" +
" permission=" + permission + " permission=" + permission +
" account=" + (account != null) + " account=" + (account != null) +
" calendar=" + (account == null ? null : account.calendar) + " calendar=" + (account == null ? null : account.calendar) +
" folder=" + (folder != null) + ":" + (folder == null ? null : folder.type) + " folder=" + (folder != null) + ":" + (folder == null ? null : folder.type) +
" received=" + received); " received=" + received);
else { return;
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()); File file = local.getFile(context);
ICalDate end = (event.getDateEnd() == null ? null : event.getDateEnd().getValue()); ICalendar icalendar = Biweekly.parse(file).first();
String rrule = null; Method method = icalendar.getMethod();
RecurrenceRule recurrence = event.getRecurrenceRule(); if (method == null)
if (recurrence != null) { return;
RecurrenceRuleScribe scribe = new RecurrenceRuleScribe();
WriteContext wcontext = new WriteContext(ICalVersion.V2_0, icalendar.getTimezoneInfo(), null);
rrule = scribe.writeText(recurrence, wcontext);
}
String uid = (event.getUid() == null ? null : event.getUid().getValue()); VEvent event = icalendar.getEvents().get(0);
EntityLog.log(context, EntityLog.Type.General, message, "Processing event" +
" uid=" + uid +
" method=" + method +
" start=" + (start != null) +
" end=" + (end != null) +
" rrule=" + rrule +
" calendar=" + account.calendar);
if (!TextUtils.isEmpty(uid) &&
icalendar.getMethod() != null &&
start != null && end != null) {
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()) { if (method.isRequest() || method.isCancel())
String selectedAccount; CalendarHelper.delete(context, event, message);
String selectedName;
try {
JSONObject jselected = new JSONObject(account.calendar);
selectedAccount = jselected.getString("account");
selectedName = jselected.getString("name");
} catch (Throwable ex) {
Log.i(ex);
selectedAccount = account.calendar;
selectedName = null;
}
try (Cursor cursor = resolver.query(CalendarContract.Calendars.CONTENT_URI, if (method.isRequest()) {
new String[]{CalendarContract.Calendars._ID}, String selectedAccount;
CalendarContract.Calendars.VISIBLE + " <> 0 AND " + String selectedName;
CalendarContract.Calendars.ACCOUNT_NAME + " = ?" + try {
(selectedName == null JSONObject jselected = new JSONObject(account.calendar);
? "" selectedAccount = jselected.getString("account");
: " AND " + CalendarContract.Calendars.CALENDAR_DISPLAY_NAME + " = ?"), selectedName = jselected.getString("name");
selectedName == null } catch (Throwable ex) {
? new String[]{selectedAccount} Log.i(ex);
: new String[]{selectedAccount, selectedName}, selectedAccount = account.calendar;
null)) { selectedName = null;
if (cursor.getCount() == 0)
EntityLog.log(context, EntityLog.Type.General, message,
"Account not found username=" + account.user);
if (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 (rrule != null)
values.put(CalendarContract.Events.RRULE, rrule);
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);
}
}
}
} }
CalendarHelper.insert(context, icalendar.getTimezoneInfo(), event,
selectedAccount, selectedName, message);
} }
} catch (Throwable ex) { } catch (Throwable ex) {
Log.w(ex); Log.w(ex);

@ -25,22 +25,16 @@ import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.Network; import android.net.Network;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
import android.net.NetworkRequest; import android.net.NetworkRequest;
import android.net.Uri;
import android.os.PowerManager; import android.os.PowerManager;
import android.os.SystemClock; import android.os.SystemClock;
import android.provider.CalendarContract;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -78,10 +72,7 @@ import javax.mail.internet.MimeMessage;
import biweekly.Biweekly; import biweekly.Biweekly;
import biweekly.ICalendar; import biweekly.ICalendar;
import biweekly.component.VEvent; import biweekly.component.VEvent;
import biweekly.parameter.ParticipationStatus;
import biweekly.property.Attendee;
import biweekly.property.Method; import biweekly.property.Method;
import biweekly.property.Uid;
public class ServiceSend extends ServiceBase implements SharedPreferences.OnSharedPreferenceChangeListener { public class ServiceSend extends ServiceBase implements SharedPreferences.OnSharedPreferenceChangeListener {
private TupleUnsent lastUnsent = null; private TupleUnsent lastUnsent = null;
@ -900,40 +891,8 @@ public class ServiceSend extends ServiceBase implements SharedPreferences.OnShar
return; return;
VEvent event = icalendar.getEvents().get(0); VEvent event = icalendar.getEvents().get(0);
Uid uid = event.getUid(); EntityMessage message = db.message().getMessage(sid);
List<Attendee> attendees = event.getAttendees(); CalendarHelper.update(this, event, message);
if (uid == null || attendees == null || attendees.size() == 0)
return;
ParticipationStatus status = attendees.get(0).getParticipationStatus();
if (!ParticipationStatus.ACCEPTED.equals(status) &&
!ParticipationStatus.DECLINED.equals(status))
return;
ContentResolver resolver = getContentResolver();
try (Cursor cursor = resolver.query(CalendarContract.Events.CONTENT_URI,
new String[]{CalendarContract.Events._ID},
CalendarContract.Events.UID_2445 + " = ? ",
new String[]{uid.getValue()},
null)) {
while (cursor.moveToNext()) {
long eventId = cursor.getLong(0);
// https://developer.android.com/guide/topics/providers/calendar-provider#modify-calendar
Uri updateUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
ContentValues values = new ContentValues();
if (ParticipationStatus.ACCEPTED.equals(status))
values.put(CalendarContract.Events.STATUS, CalendarContract.Events.STATUS_CONFIRMED);
else
values.put(CalendarContract.Events.STATUS, CalendarContract.Events.STATUS_CANCELED);
int rows = resolver.update(updateUri, values, null, null);
EntityMessage message = db.message().getMessage(sid);
EntityLog.log(this, EntityLog.Type.General, message,
"Updated event id=" + eventId + " rows=" + rows);
}
}
break; break;
} catch (Throwable ex) { } catch (Throwable ex) {
Log.e(ex); Log.e(ex);

Loading…
Cancel
Save