diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/camel/camel-file-utils.c | 26 | ||||
-rw-r--r-- | src/camel/camel-file-utils.h | 2 | ||||
-rw-r--r-- | src/camel/camel-object.c | 19 | ||||
-rw-r--r-- | src/camel/providers/imapx/camel-imapx-folder.c | 53 | ||||
-rw-r--r-- | src/camel/providers/imapx/camel-imapx-folder.h | 5 | ||||
-rw-r--r-- | src/camel/providers/imapx/camel-imapx-provider.c | 2 | ||||
-rw-r--r-- | src/camel/providers/imapx/camel-imapx-server.c | 59 | ||||
-rw-r--r-- | src/camel/providers/imapx/camel-imapx-settings.c | 73 | ||||
-rw-r--r-- | src/camel/providers/imapx/camel-imapx-settings.h | 5 |
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 |