summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/camel/camel-file-utils.c26
-rw-r--r--src/camel/camel-file-utils.h2
-rw-r--r--src/camel/camel-object.c19
-rw-r--r--src/camel/providers/imapx/camel-imapx-folder.c53
-rw-r--r--src/camel/providers/imapx/camel-imapx-folder.h5
-rw-r--r--src/camel/providers/imapx/camel-imapx-provider.c2
-rw-r--r--src/camel/providers/imapx/camel-imapx-server.c59
-rw-r--r--src/camel/providers/imapx/camel-imapx-settings.c73
-rw-r--r--src/camel/providers/imapx/camel-imapx-settings.h5
9 files changed, 227 insertions, 17 deletions
diff --git a/src/camel/camel-file-utils.c b/src/camel/camel-file-utils.c
index e4b052eb9..368a3b77a 100644
--- a/src/camel/camel-file-utils.c
+++ b/src/camel/camel-file-utils.c
@@ -249,6 +249,32 @@ CFU_ENCODE_T (gsize)
CFU_DECODE_T (gsize)
/**
+ * camel_file_util_encode_gint64:
+ * @out: file to output to
+ * @value: value to output
+ *
+ * Encode a gint64 type.
+ *
+ * Returns: 0 on success, -1 on error.
+ *
+ * Since: 3.50
+ **/
+CFU_ENCODE_T (gint64)
+
+/**
+ * camel_file_util_decode_gint64:
+ * @in: file to read from
+ * @dest: pointer to a variable to put the value in
+ *
+ * Decode a gint64 type.
+ *
+ * Returns: 0 on success, -1 on failure.
+ *
+ * Since: 3.50
+ **/
+CFU_DECODE_T (gint64)
+
+/**
* camel_file_util_encode_string:
* @out: file to output to
* @str: value to output
diff --git a/src/camel/camel-file-utils.h b/src/camel/camel-file-utils.h
index 6bc4513ac..76c66d04a 100644
--- a/src/camel/camel-file-utils.h
+++ b/src/camel/camel-file-utils.h
@@ -48,6 +48,8 @@ gint camel_file_util_encode_off_t (FILE *out, off_t value);
gint camel_file_util_decode_off_t (FILE *in, off_t *dest);
gint camel_file_util_encode_gsize (FILE *out, gsize value);
gint camel_file_util_decode_gsize (FILE *in, gsize *dest);
+gint camel_file_util_encode_gint64 (FILE *out, gint64 value);
+gint camel_file_util_decode_gint64 (FILE *in, gint64 *dest);
gint camel_file_util_encode_string (FILE *out, const gchar *str);
gint camel_file_util_decode_string (FILE *in, gchar **str);
gint camel_file_util_encode_fixed_string (FILE *out, const gchar *str, gsize len);
diff --git a/src/camel/camel-object.c b/src/camel/camel-object.c
index 2c7ebd3f1..2572acf0c 100644
--- a/src/camel/camel-object.c
+++ b/src/camel/camel-object.c
@@ -81,7 +81,8 @@ enum camel_arg_t {
CAMEL_ARG_STR = 0x30000000, /* c string */
CAMEL_ARG_PTR = 0x40000000, /* ptr */
CAMEL_ARG_BOO = 0x50000000, /* bool */
- CAMEL_ARG_3ST = 0x60000000 /* three-state */
+ CAMEL_ARG_3ST = 0x60000000, /* three-state */
+ CAMEL_ARG_I64 = 0x70000000 /* gint64 */
};
#define CAMEL_ARGV_MAX (20)
@@ -197,6 +198,7 @@ object_state_read (CamelObject *object,
gboolean property_set = FALSE;
guint32 tag, v_uint32;
gint32 v_int32;
+ gint64 v_int64;
if (camel_file_util_decode_uint32 (fp, &tag) == -1)
goto exit;
@@ -222,6 +224,12 @@ object_state_read (CamelObject *object,
g_value_init (&value, CAMEL_TYPE_THREE_STATE);
g_value_set_enum (&value, (CamelThreeState) v_uint32);
break;
+ case CAMEL_ARG_I64:
+ if (camel_file_util_decode_gint64 (fp, &v_int64) == -1)
+ goto exit;
+ g_value_init (&value, G_TYPE_INT64);
+ g_value_set_int64 (&value, v_int64);
+ break;
default:
g_warn_if_reached ();
goto exit;
@@ -324,6 +332,7 @@ object_state_write (CamelObject *object,
GParamSpec *pspec = properties[ii];
guint32 tag, v_uint32;
gint32 v_int32;
+ gint64 v_int64;
if ((pspec->flags & CAMEL_PARAM_PERSISTENT) == 0)
continue;
@@ -354,6 +363,14 @@ object_state_write (CamelObject *object,
if (camel_file_util_encode_fixed_int32 (fp, v_int32) == -1)
goto exit;
break;
+ case G_TYPE_INT64:
+ tag |= CAMEL_ARG_I64;
+ v_int64 = g_value_get_int64 (&value);
+ if (camel_file_util_encode_uint32 (fp, tag) == -1)
+ goto exit;
+ if (camel_file_util_encode_gint64 (fp, v_int64) == -1)
+ goto exit;
+ break;
default:
if (pspec->value_type == CAMEL_TYPE_THREE_STATE) {
tag |= CAMEL_ARG_3ST;
diff --git a/src/camel/providers/imapx/camel-imapx-folder.c b/src/camel/providers/imapx/camel-imapx-folder.c
index 91ce26097..4a0769fee 100644
--- a/src/camel/providers/imapx/camel-imapx-folder.c
+++ b/src/camel/providers/imapx/camel-imapx-folder.c
@@ -46,6 +46,7 @@ struct _CamelIMAPXFolderPrivate {
GHashTable *move_to_inbox_uids;
gboolean check_folder;
+ gint64 last_full_update;
};
/* The custom property ID is a CamelArg artifact.
@@ -54,7 +55,8 @@ enum {
PROP_0,
PROP_MAILBOX,
PROP_APPLY_FILTERS = 0x2501,
- PROP_CHECK_FOLDER = 0x2502
+ PROP_CHECK_FOLDER = 0x2502,
+ PROP_LAST_FULL_UPDATE = 0x2503
};
G_DEFINE_TYPE_WITH_PRIVATE (CamelIMAPXFolder, camel_imapx_folder, CAMEL_TYPE_OFFLINE_FOLDER)
@@ -161,6 +163,12 @@ imapx_folder_set_property (GObject *object,
g_value_get_boolean (value));
return;
+ case PROP_LAST_FULL_UPDATE:
+ camel_imapx_folder_set_last_full_update (
+ CAMEL_IMAPX_FOLDER (object),
+ g_value_get_int64 (value));
+ return;
+
case PROP_MAILBOX:
camel_imapx_folder_set_mailbox (
CAMEL_IMAPX_FOLDER (object),
@@ -192,6 +200,13 @@ imapx_folder_get_property (GObject *object,
CAMEL_IMAPX_FOLDER (object)));
return;
+ case PROP_LAST_FULL_UPDATE:
+ g_value_set_int64 (
+ value,
+ camel_imapx_folder_get_last_full_update (
+ CAMEL_IMAPX_FOLDER (object)));
+ return;
+
case PROP_MAILBOX:
g_value_take_object (
value,
@@ -1141,6 +1156,18 @@ camel_imapx_folder_class_init (CamelIMAPXFolderClass *class)
g_object_class_install_property (
object_class,
+ PROP_LAST_FULL_UPDATE,
+ g_param_spec_int64 (
+ "last-full-update",
+ "Last Full Update",
+ NULL,
+ G_MININT64, G_MAXINT64, 0,
+ G_PARAM_READWRITE |
+ G_PARAM_EXPLICIT_NOTIFY |
+ CAMEL_PARAM_PERSISTENT));
+
+ g_object_class_install_property (
+ object_class,
PROP_MAILBOX,
g_param_spec_object (
"mailbox",
@@ -1707,6 +1734,30 @@ camel_imapx_folder_set_check_folder (CamelIMAPXFolder *folder,
g_object_notify (G_OBJECT (folder), "check-folder");
}
+gint64
+camel_imapx_folder_get_last_full_update (CamelIMAPXFolder *folder)
+{
+ g_return_val_if_fail (folder != NULL, 0);
+ g_return_val_if_fail (CAMEL_IS_IMAPX_FOLDER (folder), 0);
+
+ return folder->priv->last_full_update;
+}
+
+void
+camel_imapx_folder_set_last_full_update (CamelIMAPXFolder *folder,
+ gint64 last_full_update)
+{
+ g_return_if_fail (folder != NULL);
+ g_return_if_fail (CAMEL_IS_IMAPX_FOLDER (folder));
+
+ if (folder->priv->last_full_update == last_full_update)
+ return;
+
+ folder->priv->last_full_update = last_full_update;
+
+ g_object_notify (G_OBJECT (folder), "last-full-update");
+}
+
void
camel_imapx_folder_update_cache_expire (CamelFolder *folder,
time_t expire_when)
diff --git a/src/camel/providers/imapx/camel-imapx-folder.h b/src/camel/providers/imapx/camel-imapx-folder.h
index 1d42f7f7a..0229f3f78 100644
--- a/src/camel/providers/imapx/camel-imapx-folder.h
+++ b/src/camel/providers/imapx/camel-imapx-folder.h
@@ -102,6 +102,11 @@ gboolean camel_imapx_folder_get_check_folder
void camel_imapx_folder_set_check_folder
(CamelIMAPXFolder *folder,
gboolean check_folder);
+gint64 camel_imapx_folder_get_last_full_update
+ (CamelIMAPXFolder *folder);
+void camel_imapx_folder_set_last_full_update
+ (CamelIMAPXFolder *folder,
+ gint64 last_full_update);
void camel_imapx_folder_claim_move_to_real_junk_uids
(CamelIMAPXFolder *folder,
GPtrArray *out_uids_to_copy);
diff --git a/src/camel/providers/imapx/camel-imapx-provider.c b/src/camel/providers/imapx/camel-imapx-provider.c
index f6180bdb2..2b8f7d14b 100644
--- a/src/camel/providers/imapx/camel-imapx-provider.c
+++ b/src/camel/providers/imapx/camel-imapx-provider.c
@@ -93,6 +93,8 @@ CamelProviderConfEntry imapx_conf_entries[] = {
{ CAMEL_PROVIDER_CONF_CHECKSPIN, "store-changes-interval", NULL,
/* Translators: The '%s' is replaced with a spin button with the actual value */
N_("Store folder changes after %s second(s)"), "" },
+ { CAMEL_PROVIDER_CONF_CHECKBOX, "single-client-mode", NULL,
+ N_("Single client mode"), "1" },
{ CAMEL_PROVIDER_CONF_SECTION_END },
{ CAMEL_PROVIDER_CONF_END }
};
diff --git a/src/camel/providers/imapx/camel-imapx-server.c b/src/camel/providers/imapx/camel-imapx-server.c
index e43d3ed38..1c4160288 100644
--- a/src/camel/providers/imapx/camel-imapx-server.c
+++ b/src/camel/providers/imapx/camel-imapx-server.c
@@ -5556,13 +5556,36 @@ imapx_server_fetch_changes (CamelIMAPXServer *is,
return success;
}
+/* It does not verify single-client-mode, it only checks whether it's time
+ to do a full update according to folder's last-full-update property and
+ return TRUE, when the full update should be done. It also stores the current
+ time when returning TRUE. */
static gboolean
-camel_imapx_server_skip_old_flags_update (CamelStore *store)
+camel_imapx_server_check_folder_last_full_update (CamelFolder *folder)
{
+ gint64 now = g_get_real_time () / G_USEC_PER_SEC;
+ gint64 diff = now - camel_imapx_folder_get_last_full_update (CAMEL_IMAPX_FOLDER (folder));
+
+ if (diff > 0 && diff < 24 * 60 * 60)
+ return FALSE;
+
+ camel_imapx_folder_set_last_full_update (CAMEL_IMAPX_FOLDER (folder), now);
+ camel_object_state_write (CAMEL_OBJECT (folder));
+
+ return TRUE;
+}
+
+static gboolean
+camel_imapx_server_do_old_flags_update (CamelFolder *folder)
+{
+ CamelStore *store;
CamelSession *session;
CamelSettings *settings;
GNetworkMonitor *network_monitor;
- gboolean skip_old_flags_update = FALSE;
+ gboolean do_old_flags_update = TRUE;
+ gboolean single_client_mode = FALSE;
+
+ store = camel_folder_get_parent_store (folder);
if (!CAMEL_IS_STORE (store))
return FALSE;
@@ -5572,23 +5595,28 @@ camel_imapx_server_skip_old_flags_update (CamelStore *store)
gboolean allow_update;
allow_update = camel_imapx_settings_get_full_update_on_metered_network (CAMEL_IMAPX_SETTINGS (settings));
+ single_client_mode = camel_imapx_settings_get_single_client_mode (CAMEL_IMAPX_SETTINGS (settings));
g_object_unref (settings);
- if (allow_update)
- return FALSE;
+ if (allow_update) {
+ if (single_client_mode)
+ do_old_flags_update = camel_imapx_server_check_folder_last_full_update (folder);
+
+ return do_old_flags_update;
+ }
}
session = camel_service_ref_session (CAMEL_SERVICE (store));
if (!session)
- return skip_old_flags_update;
+ return do_old_flags_update;
network_monitor = camel_session_ref_network_monitor (session);
- skip_old_flags_update = network_monitor && g_network_monitor_get_network_metered (network_monitor);
+ do_old_flags_update = !network_monitor || !g_network_monitor_get_network_metered (network_monitor);
#ifdef HAVE_GPOWERPROFILEMONITOR
- if (!skip_old_flags_update) {
+ if (do_old_flags_update) {
GSettings *eds_settings;
eds_settings = g_settings_new ("org.gnome.evolution-data-server");
@@ -5597,7 +5625,7 @@ camel_imapx_server_skip_old_flags_update (CamelStore *store)
GPowerProfileMonitor *power_monitor;
power_monitor = g_power_profile_monitor_dup_default ();
- skip_old_flags_update = power_monitor && g_power_profile_monitor_get_power_saver_enabled (power_monitor);
+ do_old_flags_update = !power_monitor || !g_power_profile_monitor_get_power_saver_enabled (power_monitor);
g_clear_object (&power_monitor);
}
@@ -5607,7 +5635,10 @@ camel_imapx_server_skip_old_flags_update (CamelStore *store)
g_clear_object (&network_monitor);
g_clear_object (&session);
- return skip_old_flags_update;
+ if (single_client_mode && do_old_flags_update)
+ do_old_flags_update = camel_imapx_server_check_folder_last_full_update (folder);
+
+ return do_old_flags_update;
}
gboolean
@@ -5630,7 +5661,7 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is,
guint64 highestmodseq;
guint32 total;
guint64 uidl;
- gboolean need_rescan, skip_old_flags_update;
+ gboolean need_rescan, do_old_flags_update;
gboolean success;
g_return_val_if_fail (CAMEL_IS_IMAPX_SERVER (is), FALSE);
@@ -5738,9 +5769,9 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is,
known_uids = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free, NULL);
- skip_old_flags_update = camel_imapx_server_skip_old_flags_update (camel_folder_get_parent_store (folder));
+ do_old_flags_update = camel_imapx_server_do_old_flags_update (folder);
- if (!skip_old_flags_update) {
+ if (do_old_flags_update) {
/* Remember summary state before running the update, in case there are
added new messages into the folder meanwhile, like with a COPY/MOVE filter;
such new messages would be considered removed, because not being part
@@ -5749,7 +5780,7 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is,
}
success = imapx_server_fetch_changes (is, mailbox, folder, known_uids, uidl, 0, cancellable, error);
- if (success && uidl != 1 && !skip_old_flags_update)
+ if (success && uidl != 1 && do_old_flags_update)
success = imapx_server_fetch_changes (is, mailbox, folder, known_uids, 0, uidl, cancellable, error);
if (success) {
@@ -5766,7 +5797,7 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is,
g_mutex_unlock (&is->priv->changes_lock);
- if (success && !skip_old_flags_update) {
+ if (success && do_old_flags_update) {
GList *removed = NULL;
gint ii;
diff --git a/src/camel/providers/imapx/camel-imapx-settings.c b/src/camel/providers/imapx/camel-imapx-settings.c
index af1fc93fb..ff386fb89 100644
--- a/src/camel/providers/imapx/camel-imapx-settings.c
+++ b/src/camel/providers/imapx/camel-imapx-settings.c
@@ -48,6 +48,7 @@ struct _CamelIMAPXSettingsPrivate {
gboolean ignore_shared_folders_namespace;
gboolean full_update_on_metered_network;
gboolean send_client_id;
+ gboolean single_client_mode;
CamelSortType fetch_order;
};
@@ -81,7 +82,8 @@ enum {
PROP_IGNORE_OTHER_USERS_NAMESPACE,
PROP_IGNORE_SHARED_FOLDERS_NAMESPACE,
PROP_FULL_UPDATE_ON_METERED_NETWORK,
- PROP_SEND_CLIENT_ID
+ PROP_SEND_CLIENT_ID,
+ PROP_SINGLE_CLIENT_MODE
};
G_DEFINE_TYPE_WITH_CODE (
@@ -266,6 +268,12 @@ imapx_settings_set_property (GObject *object,
CAMEL_IMAPX_SETTINGS (object),
g_value_get_boolean (value));
return;
+
+ case PROP_SINGLE_CLIENT_MODE:
+ camel_imapx_settings_set_single_client_mode (
+ CAMEL_IMAPX_SETTINGS (object),
+ g_value_get_boolean (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -473,6 +481,13 @@ imapx_settings_get_property (GObject *object,
camel_imapx_settings_get_send_client_id (
CAMEL_IMAPX_SETTINGS (object)));
return;
+
+ case PROP_SINGLE_CLIENT_MODE:
+ g_value_set_boolean (
+ value,
+ camel_imapx_settings_get_single_client_mode (
+ CAMEL_IMAPX_SETTINGS (object)));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -838,6 +853,19 @@ camel_imapx_settings_class_init (CamelIMAPXSettingsClass *class)
G_PARAM_CONSTRUCT |
G_PARAM_EXPLICIT_NOTIFY |
G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SINGLE_CLIENT_MODE,
+ g_param_spec_boolean (
+ "single-client-mode",
+ "Single Client Mode",
+ "When set to true, does full folder flags refresh only once per day",
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_EXPLICIT_NOTIFY |
+ G_PARAM_STATIC_STRINGS));
}
static void
@@ -2022,3 +2050,46 @@ camel_imapx_settings_set_send_client_id (CamelIMAPXSettings *settings,
g_object_notify (G_OBJECT (settings), "send-client-id");
}
+
+/**
+ * camel_imapx_settings_get_single_client_mode:
+ * @settings: a #CamelIMAPXSettings
+ *
+ * Returns whether using single client mode. That is, the full folder refresh
+ * flags are done only once per day, not on each folder refresh.
+ *
+ * Returns: whether the single client mode is enabled
+ *
+ * Since: 3.50
+ **/
+gboolean
+camel_imapx_settings_get_single_client_mode (CamelIMAPXSettings *settings)
+{
+ g_return_val_if_fail (CAMEL_IS_IMAPX_SETTINGS (settings), FALSE);
+
+ return settings->priv->single_client_mode;
+}
+
+/**
+ * camel_imapx_settings_set_single_client_mode:
+ * @settings: a #CamelIMAPXSettings
+ * @single_client_mode: value to set
+ *
+ * Sets whether to use a single client mode. See camel_imapx_settings_get_single_client_mode()
+ * for an explanation what it means.
+ *
+ * Since: 3.50
+ **/
+void
+camel_imapx_settings_set_single_client_mode (CamelIMAPXSettings *settings,
+ gboolean single_client_mode)
+{
+ g_return_if_fail (CAMEL_IS_IMAPX_SETTINGS (settings));
+
+ if ((settings->priv->single_client_mode ? 1 : 0) == (single_client_mode ? 1 : 0))
+ return;
+
+ settings->priv->single_client_mode = single_client_mode;
+
+ g_object_notify (G_OBJECT (settings), "single-client-mode");
+}
diff --git a/src/camel/providers/imapx/camel-imapx-settings.h b/src/camel/providers/imapx/camel-imapx-settings.h
index a23a75a02..37e618b52 100644
--- a/src/camel/providers/imapx/camel-imapx-settings.h
+++ b/src/camel/providers/imapx/camel-imapx-settings.h
@@ -181,6 +181,11 @@ gboolean camel_imapx_settings_get_send_client_id
void camel_imapx_settings_set_send_client_id
(CamelIMAPXSettings *settings,
gboolean send_client_id);
+gboolean camel_imapx_settings_get_single_client_mode
+ (CamelIMAPXSettings *settings);
+void camel_imapx_settings_set_single_client_mode
+ (CamelIMAPXSettings *settings,
+ gboolean single_client_mode);
G_END_DECLS