I#2326 - RSS: Limit re-download on content change, if possible
Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/2326
This commit is contained in:
@@ -34,6 +34,8 @@ typedef struct _RssFeed {
|
||||
gchar *href;
|
||||
gchar *display_name;
|
||||
gchar *icon_filename;
|
||||
gchar *last_etag;
|
||||
gchar *last_modified;
|
||||
CamelRssContentType content_type;
|
||||
guint32 total_count;
|
||||
guint32 unread_count;
|
||||
@@ -216,6 +218,8 @@ camel_rss_store_summary_load (CamelRssStoreSummary *self,
|
||||
feed->href = g_key_file_get_string (key_file, group, "href", NULL);
|
||||
feed->display_name = g_key_file_get_string (key_file, group, "display-name", NULL);
|
||||
feed->icon_filename = g_key_file_get_string (key_file, group, "icon-filename", NULL);
|
||||
feed->last_etag = g_key_file_get_string (key_file, group, "last-etag", NULL);
|
||||
feed->last_modified = g_key_file_get_string (key_file, group, "last-modified", NULL);
|
||||
feed->content_type = g_key_file_get_integer (key_file, group, "content-type", NULL);
|
||||
feed->total_count = (guint32) g_key_file_get_uint64 (key_file, group, "total-count", NULL);
|
||||
feed->unread_count = (guint32) g_key_file_get_uint64 (key_file, group, "unread-count", NULL);
|
||||
@@ -291,6 +295,8 @@ camel_rss_store_summary_save (CamelRssStoreSummary *self,
|
||||
g_key_file_set_string (key_file, group, "href", feed->href);
|
||||
g_key_file_set_string (key_file, group, "display-name", feed->display_name);
|
||||
g_key_file_set_string (key_file, group, "icon-filename", feed->icon_filename ? feed->icon_filename : "");
|
||||
g_key_file_set_string (key_file, group, "last-etag", feed->last_etag ? feed->last_etag : "");
|
||||
g_key_file_set_string (key_file, group, "last-modified", feed->last_modified ? feed->last_modified : "");
|
||||
g_key_file_set_integer (key_file, group, "content-type", feed->content_type);
|
||||
g_key_file_set_uint64 (key_file, group, "total-count", feed->total_count);
|
||||
g_key_file_set_uint64 (key_file, group, "unread-count", feed->unread_count);
|
||||
@@ -850,3 +856,103 @@ camel_rss_store_summary_set_last_updated (CamelRssStoreSummary *self,
|
||||
|
||||
camel_rss_store_summary_unlock (self);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
camel_rss_store_summary_get_last_etag (CamelRssStoreSummary *self,
|
||||
const gchar *id)
|
||||
{
|
||||
RssFeed *feed;
|
||||
const gchar *result = NULL;
|
||||
|
||||
g_return_val_if_fail (CAMEL_IS_RSS_STORE_SUMMARY (self), NULL);
|
||||
g_return_val_if_fail (id != NULL, NULL);
|
||||
|
||||
camel_rss_store_summary_lock (self);
|
||||
|
||||
feed = g_hash_table_lookup (self->priv->feeds, id);
|
||||
if (feed)
|
||||
result = feed->last_etag;
|
||||
|
||||
camel_rss_store_summary_unlock (self);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
camel_rss_store_summary_set_last_etag (CamelRssStoreSummary *self,
|
||||
const gchar *id,
|
||||
const gchar *last_etag)
|
||||
{
|
||||
RssFeed *feed;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_if_fail (CAMEL_IS_RSS_STORE_SUMMARY (self));
|
||||
g_return_if_fail (id != NULL);
|
||||
|
||||
camel_rss_store_summary_lock (self);
|
||||
|
||||
feed = g_hash_table_lookup (self->priv->feeds, id);
|
||||
if (feed) {
|
||||
if (g_strcmp0 (feed->last_etag, last_etag) != 0) {
|
||||
g_free (feed->last_etag);
|
||||
feed->last_etag = g_strdup (last_etag);
|
||||
self->priv->dirty = TRUE;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
camel_rss_store_summary_unlock (self);
|
||||
|
||||
if (changed)
|
||||
camel_rss_store_summary_schedule_feed_changed (self, id);
|
||||
}
|
||||
|
||||
const gchar *
|
||||
camel_rss_store_summary_get_last_modified (CamelRssStoreSummary *self,
|
||||
const gchar *id)
|
||||
{
|
||||
RssFeed *feed;
|
||||
const gchar *result = NULL;
|
||||
|
||||
g_return_val_if_fail (CAMEL_IS_RSS_STORE_SUMMARY (self), NULL);
|
||||
g_return_val_if_fail (id != NULL, NULL);
|
||||
|
||||
camel_rss_store_summary_lock (self);
|
||||
|
||||
feed = g_hash_table_lookup (self->priv->feeds, id);
|
||||
if (feed)
|
||||
result = feed->last_modified;
|
||||
|
||||
camel_rss_store_summary_unlock (self);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
camel_rss_store_summary_set_last_modified (CamelRssStoreSummary *self,
|
||||
const gchar *id,
|
||||
const gchar *last_modified)
|
||||
{
|
||||
RssFeed *feed;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
g_return_if_fail (CAMEL_IS_RSS_STORE_SUMMARY (self));
|
||||
g_return_if_fail (id != NULL);
|
||||
|
||||
camel_rss_store_summary_lock (self);
|
||||
|
||||
feed = g_hash_table_lookup (self->priv->feeds, id);
|
||||
if (feed) {
|
||||
if (g_strcmp0 (feed->last_modified, last_modified) != 0) {
|
||||
g_free (feed->last_modified);
|
||||
feed->last_modified = g_strdup (last_modified);
|
||||
self->priv->dirty = TRUE;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
camel_rss_store_summary_unlock (self);
|
||||
|
||||
if (changed)
|
||||
camel_rss_store_summary_schedule_feed_changed (self, id);
|
||||
}
|
||||
|
||||
@@ -110,6 +110,18 @@ gint64 camel_rss_store_summary_get_last_updated(CamelRssStoreSummary *self,
|
||||
void camel_rss_store_summary_set_last_updated(CamelRssStoreSummary *self,
|
||||
const gchar *id,
|
||||
gint64 last_updated);
|
||||
const gchar * camel_rss_store_summary_get_last_etag (CamelRssStoreSummary *self,
|
||||
const gchar *id);
|
||||
void camel_rss_store_summary_set_last_etag (CamelRssStoreSummary *self,
|
||||
const gchar *id,
|
||||
const gchar *last_etag);
|
||||
const gchar * camel_rss_store_summary_get_last_modified
|
||||
(CamelRssStoreSummary *self,
|
||||
const gchar *id);
|
||||
void camel_rss_store_summary_set_last_modified
|
||||
(CamelRssStoreSummary *self,
|
||||
const gchar *id,
|
||||
const gchar *last_modified);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -240,6 +240,8 @@ rss_folder_refresh_info_sync (CamelFolder *folder,
|
||||
CamelFolderChangeInfo *changes = NULL;
|
||||
CamelSession *session;
|
||||
gchar *href;
|
||||
gchar *last_etag;
|
||||
gchar *last_modified;
|
||||
gint64 last_updated;
|
||||
gboolean success = TRUE;
|
||||
|
||||
@@ -260,14 +262,18 @@ rss_folder_refresh_info_sync (CamelFolder *folder,
|
||||
camel_rss_store_summary_lock (rss_store_summary);
|
||||
|
||||
href = g_strdup (camel_rss_store_summary_get_href (rss_store_summary, self->priv->id));
|
||||
last_etag = g_strdup (camel_rss_store_summary_get_last_etag (rss_store_summary, self->priv->id));
|
||||
last_modified = g_strdup (camel_rss_store_summary_get_last_modified (rss_store_summary, self->priv->id));
|
||||
last_updated = camel_rss_store_summary_get_last_updated (rss_store_summary, self->priv->id);
|
||||
|
||||
camel_rss_store_summary_unlock (rss_store_summary);
|
||||
|
||||
if (href && *href) {
|
||||
SoupSession *soup_session;
|
||||
SoupMessageHeaders *request_headers;
|
||||
SoupMessage *message;
|
||||
GBytes *bytes;
|
||||
GError *local_error = NULL;
|
||||
|
||||
message = soup_message_new (SOUP_METHOD_GET, href);
|
||||
if (!message) {
|
||||
@@ -290,10 +296,22 @@ rss_folder_refresh_info_sync (CamelFolder *folder,
|
||||
g_object_unref (logger);
|
||||
}
|
||||
|
||||
bytes = soup_session_send_and_read (soup_session, message, cancellable, error);
|
||||
request_headers = soup_message_get_request_headers (message);
|
||||
|
||||
if (bytes) {
|
||||
soup_message_headers_append (request_headers, "Connection", "close");
|
||||
|
||||
if (last_etag && *last_etag)
|
||||
soup_message_headers_append (request_headers, "If-None-Match", last_etag);
|
||||
else if (last_modified && *last_modified)
|
||||
soup_message_headers_append (request_headers, "If-Modified-Since", last_modified);
|
||||
|
||||
bytes = soup_session_send_and_read (soup_session, message, cancellable, &local_error);
|
||||
|
||||
if (soup_message_get_status (message) == SOUP_STATUS_NOT_MODIFIED) {
|
||||
g_clear_error (&local_error);
|
||||
} else if (bytes) {
|
||||
GSList *feeds = NULL;
|
||||
gboolean save_summary = FALSE;
|
||||
|
||||
success = SOUP_STATUS_IS_SUCCESSFUL (soup_message_get_status (message));
|
||||
|
||||
@@ -392,13 +410,49 @@ rss_folder_refresh_info_sync (CamelFolder *folder,
|
||||
camel_rss_store_summary_set_last_updated (rss_store_summary, self->priv->id, max_last_modified);
|
||||
camel_rss_store_summary_unlock (rss_store_summary);
|
||||
|
||||
success = camel_rss_store_summary_save (rss_store_summary, error);
|
||||
save_summary = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_free_full (feeds, e_rss_feed_free);
|
||||
|
||||
if (success) {
|
||||
SoupMessageHeaders *response_headers;
|
||||
|
||||
response_headers = soup_message_get_response_headers (message);
|
||||
|
||||
if (response_headers) {
|
||||
const gchar *tmp;
|
||||
|
||||
camel_rss_store_summary_lock (rss_store_summary);
|
||||
|
||||
tmp = soup_message_headers_get_one (response_headers, "ETag");
|
||||
/* ignore weak ETag-s */
|
||||
if (tmp && (g_ascii_strncasecmp (tmp, "W/", 2) == 0 || g_ascii_strncasecmp (tmp, "\"W/", 3) == 0))
|
||||
tmp = NULL;
|
||||
if (tmp && !*tmp)
|
||||
tmp = NULL;
|
||||
|
||||
camel_rss_store_summary_set_last_etag (rss_store_summary, self->priv->id, tmp);
|
||||
|
||||
tmp = soup_message_headers_get_one (response_headers, "Last-Modified");
|
||||
if (tmp && !*tmp)
|
||||
tmp = NULL;
|
||||
|
||||
camel_rss_store_summary_set_last_modified (rss_store_summary, self->priv->id, tmp);
|
||||
|
||||
camel_rss_store_summary_unlock (rss_store_summary);
|
||||
|
||||
save_summary = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (success && save_summary)
|
||||
success = camel_rss_store_summary_save (rss_store_summary, error);
|
||||
} else {
|
||||
success = FALSE;
|
||||
if (local_error)
|
||||
g_propagate_error (error, local_error);
|
||||
}
|
||||
|
||||
g_clear_pointer (&bytes, g_bytes_unref);
|
||||
@@ -409,6 +463,8 @@ rss_folder_refresh_info_sync (CamelFolder *folder,
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
g_free (last_modified);
|
||||
g_free (last_etag);
|
||||
g_free (href);
|
||||
|
||||
if (changes) {
|
||||
|
||||
@@ -592,11 +592,12 @@ e_rss_parser_parse (const gchar *xml,
|
||||
xmlDoc *doc;
|
||||
xmlNodePtr root;
|
||||
|
||||
g_return_val_if_fail (xml != NULL, FALSE);
|
||||
|
||||
if (out_feeds)
|
||||
*out_feeds = NULL;
|
||||
|
||||
if (!xml || !xml_len)
|
||||
return FALSE;
|
||||
|
||||
doc = e_xml_parse_data (xml, xml_len);
|
||||
|
||||
if (!doc)
|
||||
|
||||
@@ -124,6 +124,8 @@ action_rss_mail_folder_reload_cb (GtkAction *action,
|
||||
g_object_get (store, "summary", &store_summary, NULL);
|
||||
|
||||
camel_rss_store_summary_set_last_updated (store_summary, folder_path, 0);
|
||||
camel_rss_store_summary_set_last_etag (store_summary, folder_path, NULL);
|
||||
camel_rss_store_summary_set_last_modified (store_summary, folder_path, NULL);
|
||||
|
||||
camel_store_get_folder (store, folder_path, CAMEL_STORE_FOLDER_NONE, G_PRIORITY_DEFAULT, NULL,
|
||||
e_rss_mail_folder_reload_got_folder_cb, shell_view);
|
||||
|
||||
Reference in New Issue
Block a user