RSSyl: do not look at modified time when matching deleted items
[claws.git] / src / plugins / rssyl / rssyl_deleted.c
index d77c0b00cf7246174bf66e7024e91f06f3206230..4da0f83beeca4ddb80b77b0ffde378306cd58172 100644 (file)
@@ -44,7 +44,6 @@ static RDeletedItem *_new_deleted_item()
        ditem->id = NULL;
        ditem->title = NULL;
        ditem->date_published = -1;
-       ditem->date_modified = -1;
 
        return ditem;
 }
@@ -99,18 +98,21 @@ GSList *rssyl_deleted_update(RFolderItem *ritem)
 
        if (!g_file_test(deleted_file, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
                debug_print("RSSyl: '%s' doesn't exist, ignoring\n", deleted_file);
+               g_free(deleted_file);
                return NULL;
        }
 
        g_file_get_contents(deleted_file, &contents, NULL, &error);
 
-       if (error)
-               g_warning("GError: '%s'\n", error->message);
+       if (error) {
+               g_warning("GError: '%s'", error->message);
+               g_error_free(error);
+       }
 
        if (contents != NULL) {
                lines = strsplit_no_copy(contents, '\n');
        } else {
-               g_warning("Couldn't read '%s', ignoring\n", deleted_file);
+               g_warning("Couldn't read '%s', ignoring", deleted_file);
                g_free(deleted_file);
                return NULL;
        }
@@ -127,8 +129,6 @@ GSList *rssyl_deleted_update(RFolderItem *ritem)
                                ditem->title = g_strdup(line[1]);
                        } else if (ditem != NULL && !strcmp(line[0], "DPUB")) {
                                ditem->date_published = atoi(line[1]);
-                       } else if (ditem != NULL && !strcmp(line[0], "DMOD")) {
-                               ditem->date_modified = atoi(line[1]);
                                deleted_items = g_slist_prepend(deleted_items, ditem);
                                ditem = NULL;
                        }
@@ -157,10 +157,9 @@ static void _store_one_deleted_item(gpointer data, gpointer user_data)
        err |= (fprintf(f,
                        "ID: %s\n"
                        "TITLE: %s\n"
-                       "DPUB: %ld\n"
-                       "DMOD: %ld\n",
+                       "DPUB: %lld\n",
                        ditem->id, ditem->title,
-                       ditem->date_published, ditem->date_modified) < 0);
+                       (long long)ditem->date_published) < 0);
 
        if (err)
                debug_print("RSSyl: Error during writing deletion file.\n");
@@ -170,20 +169,25 @@ static void rssyl_deleted_store_internal(GSList *deleted_items, const gchar *del
 {
        FILE *f;
 
-       if (g_file_test(deleted_file, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
-               g_remove(deleted_file);
+       if (g_file_test(deleted_file, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+               if (g_remove(deleted_file) != 0) {
+                       debug_print("RSSyl: Oops, couldn't delete '%s', bailing out\n",
+                                       deleted_file);
+                       return;
+               }
+       }
 
        if (g_slist_length(deleted_items) == 0)
                return;
 
        if ((f = g_fopen(deleted_file, "w")) == NULL) {
-               debug_print("RSSyl: Couldn't open '%s', ignoring.\n", deleted_file);
+               debug_print("RSSyl: Couldn't open '%s', bailing out.\n", deleted_file);
                return;
        }
 
        g_slist_foreach(deleted_items, (GFunc)_store_one_deleted_item,
                        (gpointer)f);
-       
+
        fclose(f);
        debug_print("RSSyl: written and closed deletion file\n");
 }
@@ -196,6 +200,7 @@ void rssyl_deleted_store(RFolderItem *ritem)
 
        path = _deleted_file_path(ritem);
        rssyl_deleted_store_internal(ritem->deleted_items, path);
+       g_free(path);
 }
 
 
@@ -216,7 +221,6 @@ void rssyl_deleted_add(RFolderItem *ritem, gchar *path)
        ditem->title = conv_unmime_header(feed_item_get_title(fitem),
                        CS_UTF_8, FALSE);
        ditem->date_published = feed_item_get_date_published(fitem);
-       ditem->date_modified = feed_item_get_date_modified(fitem);
 
        deleted_items = g_slist_prepend(deleted_items, ditem);
 
@@ -225,6 +229,9 @@ void rssyl_deleted_add(RFolderItem *ritem, gchar *path)
        g_free(deleted_file);
 
        rssyl_deleted_free(deleted_items);
+
+       RFeedCtx *ctx = (RFeedCtx *)fitem->data;
+       g_free(ctx->path);
        feed_item_free(fitem);
 }
 
@@ -232,34 +239,42 @@ static gint _rssyl_deleted_check_func(gconstpointer a, gconstpointer b)
 {
        RDeletedItem *ditem = (RDeletedItem *)a;
        FeedItem *fitem = (FeedItem *)b;
+       gchar *id;
+       gboolean id_match = FALSE;
+       gboolean title_match = FALSE;
+       gboolean pubdate_match = FALSE;
 
        g_return_val_if_fail(ditem != NULL, -10);
        g_return_val_if_fail(fitem != NULL, -20);
 
        /* Following must match:
-        * ID, ... */
-       if (!ditem->id || !feed_item_get_id(fitem) ||
-                       strcmp(ditem->id, feed_item_get_id(fitem)))
-               return -1;
+        * ID, or if there is no ID, the URL, since that's
+        * what would have been stored in .deleted instead
+        * of ID... */
+       if ((id = feed_item_get_id(fitem)) == NULL)
+               id = feed_item_get_url(fitem);
+
+       if (ditem->id && id &&
+                       !strcmp(ditem->id, id))
+               id_match = TRUE;
 
        /* title, ... */
-       if (!ditem->title || !feed_item_get_title(fitem) ||
-                       strcmp(ditem->title, feed_item_get_title(fitem)))
-               return -2;
-
-       /* time of publishing, ... */
-       if (ditem->date_published != -1 &&
-                       ditem->date_published != feed_item_get_date_published(fitem))
-               return -3;
-
-       /* and the time of last modification must be greater
-        * (this means that the item was updated since deletion, and possibly
-        * contains new data, so we add it again) */
-       if (ditem->date_modified != -1 &&
-                       ditem->date_modified < feed_item_get_date_modified(fitem))
-               return -4;
-
-       return 0;
+       if (ditem->title && feed_item_get_title(fitem) &&
+                       !strcmp(ditem->title, feed_item_get_title(fitem)))
+               title_match = TRUE;
+
+       /* ...and time of publishing */
+       if (ditem->date_published == -1 ||
+                       ditem->date_published == feed_item_get_date_published(fitem))
+               pubdate_match = TRUE;
+
+       /* if all three match, it's the same item */
+       if (id_match && title_match && pubdate_match) {
+               return 0;
+       }
+
+       /* not our item */
+       return -1;
 }
 
 /* Returns TRUE if fitem is found among the deleted stuff. */
@@ -284,29 +299,36 @@ static void _rssyl_deleted_expire_func_f(gpointer data, gpointer user_data)
 {
        FeedItem *fitem = (FeedItem *)data;
        RDelExpireCtx *ctx = (RDelExpireCtx *)user_data;
+       gchar *id;
+       gboolean id_match = FALSE;
+       gboolean title_match = FALSE;
+       gboolean pubdate_match = FALSE;
 
        /* Following must match:
-        * ID, ... */
-       if (!ctx->ditem->id || !feed_item_get_id(fitem) ||
-                       strcmp(ctx->ditem->id, feed_item_get_id(fitem)))
-               return;
-
-       /* title, ... */
-       if (!ctx->ditem->title || !feed_item_get_title(fitem) ||
-                       strcmp(ctx->ditem->title, feed_item_get_title(fitem)))
-               return;
+        * ID, or if there is no ID, the URL, since that's
+        * what would have been stored in .deleted instead
+        * of ID... */
+       if ((id = feed_item_get_id(fitem)) == NULL)
+               id = feed_item_get_url(fitem);
 
-       /* time of publishing, ... */
-       if (ctx->ditem->date_published != feed_item_get_date_published(fitem))
-               return;
-
-       /* and the time of last modification must be greater
-        * (this means that the item was updated since deletion, and possibly
-        * contains new data, so we add it again) */
-       if (ctx->ditem->date_modified != feed_item_get_date_modified(fitem))
-               return;
+       if (ctx->ditem->id && id &&
+                       !strcmp(ctx->ditem->id, id))
+               id_match = TRUE;
 
-       ctx->delete = FALSE;
+       /* title, ... */
+       if (ctx->ditem->title && feed_item_get_title(fitem) &&
+                       !strcmp(ctx->ditem->title, feed_item_get_title(fitem)))
+               title_match = TRUE;
+
+       /* time of publishing, if set... */
+       if (ctx->ditem->date_published == -1 ||
+                       ctx->ditem->date_published == feed_item_get_date_published(fitem))
+               pubdate_match = TRUE;
+
+       /* if it's our item, set to NOT delete, since it's obviously
+        * still in the feed */
+       if (id_match && title_match && pubdate_match)
+               ctx->delete = FALSE;
 }
 
 /* Checks each item in deleted items list against feed and removes it if