From a3596720f1a753f4aa02e566b3d9965b3389f0e0 Mon Sep 17 00:00:00 2001 From: M66B Date: Thu, 3 Nov 2022 17:40:45 +0100 Subject: [PATCH] Update invitation on accept/decline --- .../java/eu/faircode/email/MessageHelper.java | 4 +- .../java/eu/faircode/email/ServiceSend.java | 81 ++++++++++++++++++- 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java index dfe41d839c..f32d5490fe 100644 --- a/app/src/main/java/eu/faircode/email/MessageHelper.java +++ b/app/src/main/java/eu/faircode/email/MessageHelper.java @@ -3941,7 +3941,8 @@ public class MessageHelper { // 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); + EntityLog.log(context, EntityLog.Type.General, message, + "Deleted event id=" + eventId + " rows=" + rows); } } @@ -3993,7 +3994,6 @@ public class MessageHelper { if (!TextUtils.isEmpty(location)) values.put(CalendarContract.Events.EVENT_LOCATION, location); values.put(CalendarContract.Events.STATUS, CalendarContract.Events.STATUS_TENTATIVE); - values.put(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_TENTATIVE); Uri uri = resolver.insert(CalendarContract.Events.CONTENT_URI, values); long eventId = Long.parseLong(uri.getLastPathSegment()); diff --git a/app/src/main/java/eu/faircode/email/ServiceSend.java b/app/src/main/java/eu/faircode/email/ServiceSend.java index 85408d00a8..a7b5234449 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSend.java +++ b/app/src/main/java/eu/faircode/email/ServiceSend.java @@ -19,21 +19,28 @@ package eu.faircode.email; Copyright 2018-2022 by Marcel Bokhorst (M66B) */ +import android.Manifest; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; +import android.database.Cursor; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; +import android.net.Uri; import android.os.PowerManager; import android.os.SystemClock; +import android.provider.CalendarContract; import android.text.TextUtils; import androidx.annotation.NonNull; @@ -68,6 +75,14 @@ import javax.mail.Session; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; +import biweekly.Biweekly; +import biweekly.ICalendar; +import biweekly.component.VEvent; +import biweekly.parameter.ParticipationStatus; +import biweekly.property.Attendee; +import biweekly.property.Method; +import biweekly.property.Uid; + public class ServiceSend extends ServiceBase implements SharedPreferences.OnSharedPreferenceChangeListener { private TupleUnsent lastUnsent = null; private Network lastActive = null; @@ -850,18 +865,82 @@ public class ServiceSend extends ServiceBase implements SharedPreferences.OnShar // Message could have been deleted EntityMessage orphan = db.message().getMessage(sid); - if (orphan != null) + if (orphan != null) { EntityOperation.queue(this, orphan, EntityOperation.EXISTS); + } db.setTransactionSuccessful(); } finally { db.endTransaction(); } + + checkICalendar(sid); } ServiceSynchronize.eval(this, "sent"); } + private void checkICalendar(long sid) { + boolean permission = Helper.hasPermission(this, Manifest.permission.WRITE_CALENDAR); + if (!permission) + return; + + DB db = DB.getInstance(this); + List attachments = db.attachment().getAttachments(sid); + if (attachments == null || attachments.size() == 0) + return; + + for (EntityAttachment attachment : attachments) + if ("text/calendar".equals(attachment.type)) + try { + File ics = attachment.getFile(this); + ICalendar icalendar = Biweekly.parse(ics).first(); + + Method method = icalendar.getMethod(); + if (method == null || !method.isReply()) + return; + + VEvent event = icalendar.getEvents().get(0); + Uid uid = event.getUid(); + List attendees = event.getAttendees(); + 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; + } catch (Throwable ex) { + Log.e(ex); + } + } + static void boot(final Context context) { executor.submit(new Runnable() { @Override