diff options
| author | Milan Crha <mcrha@redhat.com> | 2017-05-16 10:02:16 +0200 |
|---|---|---|
| committer | Milan Crha <mcrha@redhat.com> | 2017-05-16 10:02:16 +0200 |
| commit | 2e0d6e9bdb3c60697332114653d4ae75b6fad90f (patch) | |
| tree | a26397b57be0fc754ec56d3c094408f4c867f8c0 | |
| parent | 6495b365363b19a78a07ab9584bb6f3ca7ec01dc (diff) | |
| download | evolution-data-server-2e0d6e9bdb3c60697332114653d4ae75b6fad90f.tar.gz | |
[ECalMetaBackend] Locally stored attachments (beside cache file) never removed
| -rw-r--r-- | src/calendar/libedata-cal/e-cal-cache.c | 115 | ||||
| -rw-r--r-- | src/calendar/libedata-cal/e-cal-cache.h | 4 | ||||
| -rw-r--r-- | src/calendar/libedata-cal/e-cal-meta-backend.c | 20 |
3 files changed, 135 insertions, 4 deletions
diff --git a/src/calendar/libedata-cal/e-cal-cache.c b/src/calendar/libedata-cal/e-cal-cache.c index bf845eeab..8a186ed8e 100644 --- a/src/calendar/libedata-cal/e-cal-cache.c +++ b/src/calendar/libedata-cal/e-cal-cache.c @@ -32,6 +32,7 @@ #include "evolution-data-server-config.h" #include <glib/gi18n-lib.h> +#include <glib/gstdio.h> #include <sqlite3.h> #include <libebackend/libebackend.h> @@ -2803,6 +2804,78 @@ e_cal_cache_get_offline_changes (ECalCache *cal_cache, } /** + * e_cal_cache_delete_attachments: + * @cal_cache: an #ECalCache + * @component: an icalcomponent + * @cancellable: optional #GCancellable object, or %NULL + * @error: return location for a #GError, or %NULL + * + * Deletes all locally stored attachments beside the cache file from the disk. + * This doesn't modify the @component. It's usually called before the @component + * is being removed from the @cal_cache. + * + * Returns: Whether succeeded. + * + * Since: 3.26 + **/ +gboolean +e_cal_cache_delete_attachments (ECalCache *cal_cache, + icalcomponent *component, + GCancellable *cancellable, + GError **error) +{ + icalproperty *prop; + gchar *cache_dirname = NULL; + + g_return_val_if_fail (E_IS_CAL_CACHE (cal_cache), FALSE); + g_return_val_if_fail (component != NULL, FALSE); + + for (prop = icalcomponent_get_first_property (component, ICAL_ATTACH_PROPERTY); + prop; + prop = icalcomponent_get_next_property (component, ICAL_ATTACH_PROPERTY)) { + icalattach *attach = icalproperty_get_attach (prop); + + if (attach && icalattach_get_is_url (attach)) { + const gchar *url; + + url = icalattach_get_url (attach); + if (url) { + gsize buf_size; + gchar *buf; + + buf_size = strlen (url); + buf = g_malloc0 (buf_size + 1); + + icalvalue_decode_ical_string (url, buf, buf_size); + + if (g_str_has_prefix (buf, "file://")) { + gchar *filename; + + filename = g_filename_from_uri (buf, NULL, NULL); + if (filename) { + if (!cache_dirname) + cache_dirname = g_path_get_dirname (e_cache_get_filename (E_CACHE (cal_cache))); + + if (g_str_has_prefix (filename, cache_dirname) && + g_unlink (filename) == -1) { + /* Ignore these errors */ + } + + g_free (filename); + } + } + + g_free (buf); + } + } + } + + g_free (cache_dirname); + + return TRUE; +} + +/** * e_cal_cache_put_timezone: * @cal_cache: an #ECalCache * @zone: an icaltimezone to put @@ -3213,6 +3286,41 @@ e_cal_cache_resolve_timezone_simple_cb (const gchar *tzid, } static gboolean +ecc_search_delete_attachment_cb (ECalCache *cal_cache, + const gchar *uid, + const gchar *rid, + const gchar *revision, + const gchar *object, + const gchar *extra, + EOfflineState offline_state, + gpointer user_data) +{ + icalcomponent *icalcomp; + GCancellable *cancellable = user_data; + GError *local_error = NULL; + + g_return_val_if_fail (E_IS_CAL_CACHE (cal_cache), FALSE); + g_return_val_if_fail (object != NULL, FALSE); + + icalcomp = icalcomponent_new_from_string (object); + if (!icalcomp) + return TRUE; + + if (!e_cal_cache_delete_attachments (cal_cache, icalcomp, cancellable, &local_error)) { + if (rid && !*rid) + rid = NULL; + + g_debug ("%s: Failed to remove attachments for '%s%s%s': %s", G_STRFUNC, + uid, rid ? "|" : "", rid ? rid : "", local_error ? local_error->message : "Unknown error"); + g_clear_error (&local_error); + } + + icalcomponent_free (icalcomp); + + return !g_cancellable_is_cancelled (cancellable); +} + +static gboolean ecc_empty_aux_tables (ECache *cache, GCancellable *cancellable, GError **error) @@ -3323,8 +3431,11 @@ e_cal_cache_remove_all_locked (ECache *cache, g_return_val_if_fail (E_IS_CAL_CACHE (cache), FALSE); g_return_val_if_fail (E_CACHE_CLASS (e_cal_cache_parent_class)->remove_all_locked != NULL, FALSE); - /* Cannot free content of priv->loaded_timezones and priv->modified_timezones, because those can be used anywhere */ - success = ecc_empty_aux_tables (cache, cancellable, error); + /* Cannot free content of priv->loaded_timezones and priv->modified_timezones, + because those can be used anywhere */ + success = ecc_empty_aux_tables (cache, cancellable, error) && + e_cal_cache_search_with_callback (E_CAL_CACHE (cache), NULL, + ecc_search_delete_attachment_cb, cancellable, cancellable, error); success = success && E_CACHE_CLASS (e_cal_cache_parent_class)->remove_all_locked (cache, uids, cancellable, error); diff --git a/src/calendar/libedata-cal/e-cal-cache.h b/src/calendar/libedata-cal/e-cal-cache.h index 305fbb3cb..ede88a72e 100644 --- a/src/calendar/libedata-cal/e-cal-cache.h +++ b/src/calendar/libedata-cal/e-cal-cache.h @@ -295,6 +295,10 @@ gboolean e_cal_cache_search_with_callback GSList * e_cal_cache_get_offline_changes (ECalCache *cal_cache, GCancellable *cancellable, GError **error); +gboolean e_cal_cache_delete_attachments (ECalCache *cal_cache, + icalcomponent *component, + GCancellable *cancellable, + GError **error); gboolean e_cal_cache_put_timezone (ECalCache *cal_cache, const icaltimezone *zone, diff --git a/src/calendar/libedata-cal/e-cal-meta-backend.c b/src/calendar/libedata-cal/e-cal-meta-backend.c index 9f37bbb4a..47e58de95 100644 --- a/src/calendar/libedata-cal/e-cal-meta-backend.c +++ b/src/calendar/libedata-cal/e-cal-meta-backend.c @@ -759,7 +759,8 @@ ecmb_maybe_remove_from_cache (ECalMetaBackend *meta_backend, id = e_cal_component_get_id (comp); if (id) { - if (!e_cal_cache_remove_component (cal_cache, id->uid, id->rid, offline_flag, cancellable, error)) { + if (!e_cal_cache_delete_attachments (cal_cache, e_cal_component_get_icalcomponent (comp), cancellable, error) || + !e_cal_cache_remove_component (cal_cache, id->uid, id->rid, offline_flag, cancellable, error)) { e_cal_component_free_id (id); g_slist_free_full (comps, g_object_unref); @@ -1158,6 +1159,10 @@ ecmb_put_instances (ECalMetaBackend *meta_backend, if (!id) continue; + success = e_cal_cache_delete_attachments (cal_cache, e_cal_component_get_icalcomponent (comp), cancellable, error); + if (!success) + break; + success = e_cal_cache_remove_component (cal_cache, id->uid, id->rid, offline_flag, cancellable, error); e_cal_backend_notify_component_removed (cal_backend, id, comp, NULL); @@ -3739,11 +3744,14 @@ e_cal_meta_backend_inline_local_attachments_sync (ECalMetaBackend *meta_backend, GError **error) { icalproperty *prop; + const gchar *uid; gboolean success = TRUE; g_return_val_if_fail (E_IS_CAL_META_BACKEND (meta_backend), FALSE); g_return_val_if_fail (component != NULL, FALSE); + uid = icalcomponent_get_uid (component); + for (prop = icalcomponent_get_first_property (component, ICAL_ATTACH_PROPERTY); prop && success; prop = icalcomponent_get_next_property (component, ICAL_ATTACH_PROPERTY)) { @@ -3785,7 +3793,15 @@ e_cal_meta_backend_inline_local_attachments_sync (ECalMetaBackend *meta_backend, /* Preserve existing FILENAME parameter */ if (!icalproperty_get_first_parameter (prop, ICAL_FILENAME_PARAMETER)) { - param = icalparameter_new_filename (basename); + const gchar *use_filename = basename; + + /* generated filename by Evolution */ + if (uid && g_str_has_prefix (use_filename, uid) && + use_filename[strlen (uid)] == '-') { + use_filename += strlen (uid) + 1; + } + + param = icalparameter_new_filename (use_filename); icalproperty_add_parameter (prop, param); } } else { |
