aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
Diffstat (limited to 'mail')
-rw-r--r--mail/mail-send-recv.c211
1 files changed, 210 insertions, 1 deletions
diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c
index a04c3a5c38..d6b0edd4c9 100644
--- a/mail/mail-send-recv.c
+++ b/mail/mail-send-recv.c
@@ -953,6 +953,126 @@ receive_get_folder (CamelFilterDriver *d,
/* ********************************************************************** */
+static gboolean
+delete_junk_sync (CamelStore *store,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CamelFolder *folder;
+ GPtrArray *uids;
+ guint32 flags;
+ guint32 mask;
+ guint ii;
+
+ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE);
+
+ folder = camel_store_get_junk_folder_sync (store, cancellable, error);
+ if (folder == NULL)
+ return FALSE;
+
+ uids = camel_folder_get_uids (folder);
+ flags = mask = CAMEL_MESSAGE_DELETED | CAMEL_MESSAGE_SEEN;
+
+ camel_folder_freeze (folder);
+
+ for (ii = 0; ii < uids->len; ii++) {
+ const gchar *uid = uids->pdata[ii];
+ camel_folder_set_message_flags (folder, uid, flags, mask);
+ }
+
+ camel_folder_thaw (folder);
+
+ camel_folder_free_uids (folder, uids);
+ g_object_unref (folder);
+
+ return TRUE;
+}
+
+struct TestShouldData
+{
+ gint64 last_delete_junk;
+ gint64 last_expunge;
+};
+
+static void
+test_should_delete_junk_or_expunge (CamelStore *store,
+ gboolean *should_delete_junk,
+ gboolean *should_expunge)
+{
+ static GMutex mutex;
+ static GHashTable *last_expunge = NULL;
+
+ GSettings *settings;
+ const gchar *uid;
+ gint64 trash_empty_date = 0, junk_empty_date = 0;
+ gint trash_empty_days = 0, junk_empty_days = 0;
+ gint64 now;
+
+ g_return_if_fail (CAMEL_IS_STORE (store));
+ g_return_if_fail (should_delete_junk != NULL);
+ g_return_if_fail (should_expunge != NULL);
+
+ *should_delete_junk = FALSE;
+ *should_expunge = FALSE;
+
+ uid = camel_service_get_uid (CAMEL_SERVICE (store));
+ g_return_if_fail (uid != NULL);
+
+ settings = g_settings_new ("org.gnome.evolution.mail");
+
+ now = time (NULL) / 60 / 60 / 24;
+
+ *should_delete_junk = g_settings_get_boolean (settings, "junk-empty-on-exit");
+ *should_expunge = g_settings_get_boolean (settings, "trash-empty-on-exit");
+
+ if (*should_delete_junk || *should_expunge) {
+ junk_empty_days = g_settings_get_int (settings, "junk-empty-on-exit-days");
+ junk_empty_date = g_settings_get_int (settings, "junk-empty-date");
+
+ trash_empty_days = g_settings_get_int (settings, "trash-empty-on-exit-days");
+ trash_empty_date = g_settings_get_int (settings, "trash-empty-date");
+
+ g_mutex_lock (&mutex);
+ if (!last_expunge) {
+ last_expunge = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ } else {
+ struct TestShouldData *tsd;
+
+ tsd = g_hash_table_lookup (last_expunge, uid);
+ if (tsd) {
+ junk_empty_date = tsd->last_delete_junk;
+ trash_empty_date = tsd->last_expunge;
+ }
+ }
+ g_mutex_unlock (&mutex);
+ }
+
+ *should_delete_junk = *should_delete_junk && junk_empty_days > 0 && junk_empty_date + junk_empty_days <= now;
+ *should_expunge = *should_expunge && trash_empty_days > 0 && trash_empty_date + trash_empty_days <= now;
+
+ if (*should_delete_junk || *should_expunge) {
+ struct TestShouldData *tsd;
+
+ if (*should_delete_junk)
+ junk_empty_date = now;
+ if (*should_expunge)
+ trash_empty_date = now;
+
+ g_mutex_lock (&mutex);
+ tsd = g_hash_table_lookup (last_expunge, uid);
+ if (!tsd) {
+ tsd = g_new0 (struct TestShouldData, 1);
+ g_hash_table_insert (last_expunge, g_strdup (uid), tsd);
+ }
+
+ tsd->last_delete_junk = junk_empty_date;
+ tsd->last_expunge = trash_empty_date;
+ g_mutex_unlock (&mutex);
+ }
+
+ g_object_unref (settings);
+}
+
static void
get_folders (CamelStore *store,
GPtrArray *folders,
@@ -1006,6 +1126,7 @@ refresh_folders_exec (struct _refresh_folders_msg *m,
CamelFolder *folder;
gint i;
gboolean success;
+ gboolean delete_junk = FALSE, expunge = FALSE;
GError *local_error = NULL;
gulong handler_id = 0;
@@ -1023,12 +1144,19 @@ refresh_folders_exec (struct _refresh_folders_msg *m,
camel_operation_push_message (m->info->cancellable, _("Updating..."));
+ test_should_delete_junk_or_expunge (m->store, &delete_junk, &expunge);
+
+ if (delete_junk && !delete_junk_sync (m->store, cancellable, error)) {
+ camel_operation_pop_message (m->info->cancellable);
+ goto exit;
+ }
+
for (i = 0; i < m->folders->len; i++) {
folder = e_mail_session_uri_to_folder_sync (
E_MAIL_SESSION (m->info->session),
m->folders->pdata[i], 0,
cancellable, &local_error);
- if (folder && camel_folder_synchronize_sync (folder, FALSE, cancellable, &local_error))
+ if (folder && camel_folder_synchronize_sync (folder, expunge, cancellable, &local_error))
camel_folder_refresh_info_sync (folder, cancellable, &local_error);
if (local_error != NULL) {
@@ -1169,6 +1297,85 @@ receive_update_got_store (CamelStore *store,
}
}
+
+struct _refresh_local_store_msg {
+ MailMsg base;
+
+ CamelStore *store;
+ gboolean delete_junk;
+ gboolean expunge_trash;
+};
+
+static gchar *
+refresh_local_store_desc (struct _refresh_local_store_msg *m)
+{
+ const gchar *display_name;
+
+ display_name = camel_service_get_display_name (CAMEL_SERVICE (m->store));
+
+ if (m->delete_junk && m->expunge_trash)
+ return g_strdup_printf (_("Deleting junk and expunging trash at '%s'"), display_name);
+ else if (m->delete_junk)
+ return g_strdup_printf (_("Deleting junk at '%s'"), display_name);
+ else
+ return g_strdup_printf (_("Expunging trash at '%s'"), display_name);
+}
+
+static void
+refresh_local_store_exec (struct _refresh_local_store_msg *m,
+ GCancellable *cancellable,
+ GError **error)
+{
+ if (m->delete_junk && !delete_junk_sync (m->store, cancellable, error))
+ return;
+
+ if (m->expunge_trash) {
+ CamelFolder *trash;
+
+ trash = camel_store_get_trash_folder_sync (m->store, cancellable, error);
+
+ if (trash != NULL) {
+ e_mail_folder_expunge_sync (trash, cancellable, error);
+ g_object_unref (trash);
+ }
+ }
+}
+
+static void
+refresh_local_store_free (struct _refresh_local_store_msg *m)
+{
+ g_object_unref (m->store);
+}
+
+static MailMsgInfo refresh_local_store_info = {
+ sizeof (struct _refresh_local_store_msg),
+ (MailMsgDescFunc) refresh_local_store_desc,
+ (MailMsgExecFunc) refresh_local_store_exec,
+ (MailMsgDoneFunc) NULL,
+ (MailMsgFreeFunc) refresh_local_store_free
+};
+
+static void
+maybe_delete_junk_or_expunge_local_store (EMailSession *session)
+{
+ CamelStore *store;
+ gboolean delete_junk = FALSE, expunge_trash = FALSE;
+ struct _refresh_local_store_msg *m;
+
+ store = e_mail_session_get_local_store (session);
+ test_should_delete_junk_or_expunge (store, &delete_junk, &expunge_trash);
+
+ if (!delete_junk && !expunge_trash)
+ return;
+
+ m = mail_msg_new (&refresh_local_store_info);
+ m->store = g_object_ref (store);
+ m->delete_junk = delete_junk;
+ m->expunge_trash = expunge_trash;
+
+ mail_msg_unordered_push (m);
+}
+
static CamelService *
ref_default_transport (EMailSession *session)
{
@@ -1241,6 +1448,8 @@ send_receive (GtkWindow *parent,
if (transport != NULL)
g_object_unref (transport);
+ maybe_delete_junk_or_expunge_local_store (session);
+
scan = g_list_copy (data->infos);
for (siter = scan; siter != NULL; siter = siter->next) {