2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2004 Hiroyuki Yamamoto
4 * This file (C) 2005 Andrej Kacian <andrej@kacian.sk>
6 * - s-c folderclass callback handler functions
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #include <glib/gi18n.h>
30 #include <curl/curl.h>
32 /* Claws Mail includes */
35 #include <localfolder.h>
40 #include <prefs_common.h>
41 #include <prefs_toolbar.h>
43 #include <file-utils.h>
46 #include "libfeed/feeditem.h"
48 #include "rssyl_deleted.h"
49 #include "rssyl_gtk.h"
50 #include "rssyl_feed.h"
51 #include "rssyl_prefs.h"
52 #include "rssyl_subscribe.h"
53 #include "rssyl_update_feed.h"
54 #include "rssyl_update_format.h"
55 #include "opml_import.h"
56 #include "opml_export.h"
59 FolderClass rssyl_class;
61 static gint rssyl_create_tree(Folder *folder);
62 static gint rssyl_scan_tree(Folder *folder);
64 static gboolean existing_tree_found = FALSE;
66 static void rssyl_init_read_func(FolderItem *item, gpointer data)
68 RFolderItem *ritem = (RFolderItem *)item;
69 RPrefs *rsprefs = NULL;
71 if( !IS_RSSYL_FOLDER_ITEM(item) )
74 existing_tree_found = TRUE;
76 /* Don't do anything if we're on root of our folder tree or on
77 * a regular folder (no feed) */
78 if( folder_item_parent(item) == NULL || ritem->url == NULL )
81 ritem->refresh_id = 0;
83 /* Start automatic refresh timer, if necessary */
84 if( ritem->default_refresh_interval ) {
85 rsprefs = rssyl_prefs_get();
86 if( !rsprefs->refresh_enabled )
89 ritem->refresh_interval = rsprefs->refresh;
92 /* Start the timer, if determined interval is >0 */
93 if( ritem->refresh_interval > 0 )
94 rssyl_feed_start_refresh_timeout(ritem);
97 static void rssyl_make_rc_dir(void)
99 gchar *rssyl_dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, RSSYL_DIR,
102 if( !is_dir_exist(rssyl_dir) ) {
103 if( make_dir(rssyl_dir) < 0 ) {
104 g_warning("couldn't create directory %s", rssyl_dir);
107 debug_print("RSSyl: created directory %s\n", rssyl_dir);
113 static void rssyl_create_default_mailbox(void)
119 root = folder_new(rssyl_folder_get_class(), RSSYL_DEFAULT_MAILBOX, NULL);
121 g_return_if_fail(root != NULL);
124 rssyl_scan_tree(root);
126 /* FIXME: subscribe default feed */
127 // rssyl_subscribe_new_feed(item, RSSYL_DEFAULT_FEED, TRUE);
130 static gboolean rssyl_update_all_feeds_deferred(gpointer data)
132 rssyl_update_all_feeds();
136 static void rssyl_toolbar_cb_refresh_all_feeds(gpointer parent, const gchar *item_name, gpointer data)
138 rssyl_update_all_feeds();
141 void rssyl_init(void)
143 folder_register_class(rssyl_folder_get_class());
150 folder_func_to_all_folders((FolderItemFunc)rssyl_init_read_func, NULL);
152 if( !existing_tree_found )
153 rssyl_create_default_mailbox();
155 rssyl_update_format();
157 prefs_toolbar_register_plugin_item(TOOLBAR_MAIN, PLUGIN_NAME, _("Refresh all feeds"), rssyl_toolbar_cb_refresh_all_feeds, NULL);
159 if( rssyl_prefs_get()->refresh_on_startup &&
160 !prefs_common_get_prefs()->work_offline &&
161 claws_is_starting() )
162 g_timeout_add(2000, rssyl_update_all_feeds_deferred, NULL);
165 void rssyl_done(void)
169 prefs_toolbar_unregister_plugin_item(TOOLBAR_MAIN, PLUGIN_NAME, _("Refresh all feeds"));
174 if( !claws_is_exiting() )
175 folder_unregister_class(rssyl_folder_get_class());
177 debug_print("RSSyl is done\n");
180 static gchar *rssyl_get_new_msg_filename(FolderItem *dest)
185 destpath = folder_item_get_path(dest);
186 g_return_val_if_fail(destpath != NULL, NULL);
188 if( !is_dir_exist(destpath) )
189 make_dir_hier(destpath);
192 destfile = g_strdup_printf("%s%c%d", destpath, G_DIR_SEPARATOR,
194 if( is_file_entry_exist(destfile) ) {
206 static void rssyl_get_last_num(Folder *folder, FolderItem *item)
211 GError *error = NULL;
215 g_return_if_fail(item != NULL);
217 debug_print("rssyl_get_last_num(): Scanning %s ...\n", item->path);
218 path = folder_item_get_path(item);
219 g_return_if_fail(path != NULL);
221 if( (dp = g_dir_open(path, 0, &error)) == NULL ) {
222 FILE_OP_ERROR(item->path, "g_dir_open");
223 debug_print("g_dir_open() failed on \"%s\", error %d (%s).\n",
224 path, error->code, error->message);
232 while( (f = g_dir_read_name(dp)) != NULL) {
233 if ((num = to_number(f)) > 0 &&
234 g_file_test(f, G_FILE_TEST_IS_REGULAR)) {
241 debug_print("Last number in dir %s = %d\n", item->path, max);
242 item->last_num = max;
245 static Folder *rssyl_new_folder(const gchar *name, const gchar *path)
249 debug_print("RSSyl: new_folder: %s (%s)\n", name, path);
253 folder = g_new0(Folder, 1);
254 FOLDER(folder)->klass = &rssyl_class;
255 folder_init(FOLDER(folder), name);
257 return FOLDER(folder);
260 static void rssyl_destroy_folder(Folder *folder)
262 folder_local_folder_destroy(LOCAL_FOLDER(folder));
265 static void rssyl_item_set_xml(Folder *folder, FolderItem *item, XMLTag *tag)
268 RFolderItem *ritem = (RFolderItem *)item;
270 folder_item_set_xml(folder, item, tag);
272 for( cur = tag->attr; cur != NULL; cur = g_list_next(cur)) {
273 XMLAttr *attr = (XMLAttr *) cur->data;
275 if( !attr || !attr->name || !attr->value)
279 if( !strcmp(attr->name, "uri")) {
281 ritem->url = g_strdup(attr->value);
284 if (!strcmp(attr->name, "auth")) {
285 ritem->auth->type = atoi(attr->value);
287 /* (str) Auth user */
288 if (!strcmp(attr->name, "auth_user")) {
289 g_free(ritem->auth->username);
290 ritem->auth->username = g_strdup(attr->value);
292 /* (str) Auth pass - save directly to password store */
293 if (!strcmp(attr->name, "auth_pass")) {
295 guchar *pwd = g_base64_decode(attr->value, &len);
296 memset(attr->value, 0, strlen(attr->value));
297 rssyl_passwd_set(ritem, (gchar *)pwd);
298 memset(pwd, 0, strlen(pwd));
301 /* (str) Official title */
302 if( !strcmp(attr->name, "official_title")) {
303 g_free(ritem->official_title);
304 ritem->official_title = g_strdup(attr->value);
306 /* (bool) Keep old items */
307 if( !strcmp(attr->name, "keep_old"))
308 ritem->keep_old = (atoi(attr->value) == 0 ? FALSE : TRUE );
309 /* (bool) Use default refresh_interval */
310 if( !strcmp(attr->name, "default_refresh_interval"))
311 ritem->default_refresh_interval = (atoi(attr->value) == 0 ? FALSE : TRUE );
312 /* (int) Refresh interval */
313 if( !strcmp(attr->name, "refresh_interval"))
314 ritem->refresh_interval = atoi(attr->value);
315 /* (bool) Fetch comments */
316 if( !strcmp(attr->name, "fetch_comments"))
317 ritem->fetch_comments = (atoi(attr->value) == 0 ? FALSE : TRUE );
318 /* (int) Max age of posts to fetch comments for */
319 if( !strcmp(attr->name, "fetch_comments_max_age"))
320 ritem->fetch_comments_max_age = atoi(attr->value);
321 /* (bool) Write heading */
322 if( !strcmp(attr->name, "write_heading"))
323 ritem->write_heading = (atoi(attr->value) == 0 ? FALSE : TRUE );
324 /* (int) Silent update */
325 if( !strcmp(attr->name, "silent_update"))
326 ritem->silent_update = atoi(attr->value);
327 /* (bool) Ignore title rename */
328 if( !strcmp(attr->name, "ignore_title_rename"))
329 ritem->ignore_title_rename = (atoi(attr->value) == 0 ? FALSE : TRUE );
330 /* (bool) Verify SSL peer */
331 if( !strcmp(attr->name, "ssl_verify_peer"))
332 ritem->ssl_verify_peer = (atoi(attr->value) == 0 ? FALSE : TRUE );
336 static XMLTag *rssyl_item_get_xml(Folder *folder, FolderItem *item)
339 RFolderItem *ri = (RFolderItem *)item;
342 tag = folder_item_get_xml(folder, item);
345 if( ri->url != NULL )
346 xml_tag_add_attr(tag, xml_attr_new("uri", ri->url));
348 tmp = g_strdup_printf("%d", ri->auth->type);
349 xml_tag_add_attr(tag, xml_attr_new("auth", tmp));
351 /* (str) Auth user */
352 if (ri->auth->username != NULL)
353 xml_tag_add_attr(tag, xml_attr_new("auth_user", ri->auth->username));
354 /* (str) Official title */
355 if( ri->official_title != NULL )
356 xml_tag_add_attr(tag, xml_attr_new("official_title", ri->official_title));
357 /* (bool) Keep old items */
358 xml_tag_add_attr(tag, xml_attr_new("keep_old",
359 (ri->keep_old ? "1" : "0")) );
360 /* (bool) Use default refresh interval */
361 xml_tag_add_attr(tag, xml_attr_new("default_refresh_interval",
362 (ri->default_refresh_interval ? "1" : "0")) );
363 /* (int) Refresh interval */
364 tmp = g_strdup_printf("%d", ri->refresh_interval);
365 xml_tag_add_attr(tag, xml_attr_new("refresh_interval", tmp));
367 /* (bool) Fetch comments */
368 xml_tag_add_attr(tag, xml_attr_new("fetch_comments",
369 (ri->fetch_comments ? "1" : "0")) );
370 /* (int) Max age of posts to fetch comments for */
371 tmp = g_strdup_printf("%d", ri->fetch_comments_max_age);
372 xml_tag_add_attr(tag, xml_attr_new("fetch_comments_max_age", tmp));
374 /* (bool) Write heading */
375 xml_tag_add_attr(tag, xml_attr_new("write_heading",
376 (ri->write_heading ? "1" : "0")) );
377 /* (int) Silent update */
378 tmp = g_strdup_printf("%d", ri->silent_update);
379 xml_tag_add_attr(tag, xml_attr_new("silent_update", tmp));
381 /* (bool) Ignore title rename */
382 xml_tag_add_attr(tag, xml_attr_new("ignore_title_rename",
383 (ri->ignore_title_rename ? "1" : "0")) );
384 /* (bool) Verify SSL peer */
385 xml_tag_add_attr(tag, xml_attr_new("ssl_verify_peer",
386 (ri->ssl_verify_peer ? "1" : "0")) );
391 static gint rssyl_scan_tree(Folder *folder)
393 g_return_val_if_fail(folder != NULL, -1);
395 folder->outbox = NULL;
396 folder->draft = NULL;
397 folder->queue = NULL;
398 folder->trash = NULL;
400 debug_print("RSSyl: scanning tree\n");
401 rssyl_create_tree(folder);
406 static gint rssyl_create_tree(Folder *folder)
408 FolderItem *rootitem;
411 g_return_val_if_fail(folder != NULL, -1);
415 if( !folder->node ) {
416 rootitem = folder_item_new(folder, folder->name, NULL);
417 rootitem->folder = folder;
418 rootnode = g_node_new(rootitem);
419 folder->node = rootnode;
420 rootitem->node = rootnode;
423 debug_print("RSSyl: created new rssyl tree\n");
427 static FolderItem *rssyl_item_new(Folder *folder)
429 RFolderItem *ritem = g_new0(RFolderItem, 1);
432 ritem->auth = g_new0(FeedAuth, 1);
433 ritem->auth->type = FEED_AUTH_NONE;
434 ritem->auth->username = NULL;
435 ritem->auth->password = NULL;
436 ritem->official_title = NULL;
437 ritem->source_id = NULL;
439 ritem->deleted_items = NULL;
440 ritem->keep_old = TRUE;
441 ritem->default_refresh_interval = TRUE;
442 ritem->refresh_interval = atoi(PREF_DEFAULT_REFRESH);
443 ritem->fetch_comments = FALSE;
444 ritem->fetch_comments_max_age = -1;
445 ritem->write_heading = TRUE;
446 ritem->fetching_comments = FALSE;
447 ritem->silent_update = 0;
448 ritem->last_update = 0;
449 ritem->ignore_title_rename = FALSE;
450 ritem->ssl_verify_peer = TRUE;
451 ritem->feedprop = NULL;
452 ritem->refresh_id = 0;
454 return (FolderItem *)ritem;
457 static void rssyl_item_destroy(Folder *folder, FolderItem *item)
459 RFolderItem *ritem = (RFolderItem *)item;
461 g_return_if_fail(ritem != NULL);
464 if (ritem->auth->username)
465 g_free(ritem->auth->username);
466 if (ritem->auth->password)
467 g_free(ritem->auth->password);
469 g_free(ritem->official_title);
470 g_slist_free(ritem->items);
472 /* Remove a scheduled refresh, if any */
473 if( ritem->refresh_id != 0)
474 g_source_remove(ritem->refresh_id);
479 static FolderItem *rssyl_create_folder(Folder *folder,
480 FolderItem *parent, const gchar *name)
482 gchar *path = NULL, *basepath = NULL, *itempath = NULL;
483 FolderItem *newitem = NULL;
485 g_return_val_if_fail(folder != NULL, NULL);
486 g_return_val_if_fail(parent != NULL, NULL);
487 g_return_val_if_fail(name != NULL, NULL);
489 path = folder_item_get_path(parent);
490 if( !is_dir_exist(path) ) {
491 if( (make_dir_hier(path) != 0) ) {
492 debug_print("RSSyl: Couldn't create directory (rec) '%s'\n", path);
497 basepath = g_strdelimit(g_strdup(name), G_DIR_SEPARATOR_S, '_');
498 path = g_strconcat(path, G_DIR_SEPARATOR_S, basepath, NULL);
500 if( make_dir(path) < 0 ) {
501 debug_print("RSSyl: Couldn't create directory '%s'\n", path);
508 itempath = g_strconcat((parent->path ? parent->path : ""),
509 G_DIR_SEPARATOR_S, basepath, NULL);
510 newitem = folder_item_new(folder, name, itempath);
514 folder_item_append(parent, newitem);
519 FolderItem *rssyl_get_root_folderitem(FolderItem *item)
523 for( i = item; folder_item_parent(i) != NULL; i = folder_item_parent(i) ) { }
527 static gchar *rssyl_item_get_path(Folder *folder, FolderItem *item)
531 g_return_val_if_fail(folder != NULL, NULL);
532 g_return_val_if_fail(item != NULL, NULL);
534 name = folder_item_get_name(rssyl_get_root_folderitem(item));
535 path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, RSSYL_DIR,
536 G_DIR_SEPARATOR_S, name, item->path, NULL);
542 static gboolean rssyl_rename_folder_func(GNode *node, gpointer data)
544 FolderItem *item = node->data;
545 gchar **paths = data;
546 const gchar *oldpath = paths[0];
547 const gchar *newpath = paths[1];
552 oldpathlen = strlen(oldpath);
553 if (strncmp(oldpath, item->path, oldpathlen) != 0) {
554 g_warning("path doesn't match: %s, %s", oldpath, item->path);
558 base = item->path + oldpathlen;
559 while (*base == G_DIR_SEPARATOR) base++;
561 new_itempath = g_strdup(newpath);
563 new_itempath = g_strconcat(newpath, G_DIR_SEPARATOR_S, base,
566 item->path = new_itempath;
571 static gint rssyl_rename_folder(Folder *folder, FolderItem *item,
576 gchar *newpath, *utf8newpath;
580 g_return_val_if_fail(folder != NULL, -1);
581 g_return_val_if_fail(item != NULL, -1);
582 g_return_val_if_fail(item->path != NULL, -1);
583 g_return_val_if_fail(name != NULL, -1);
585 debug_print("RSSyl: rssyl_rename_folder '%s' -> '%s'\n",
588 if (!strcmp(item->name, name))
591 oldpath = folder_item_get_path(item);
592 if( !is_dir_exist(oldpath) )
593 make_dir_hier(oldpath);
595 dirname = g_path_get_dirname(oldpath);
596 basenewpath = g_strdelimit(g_strdup(name), G_DIR_SEPARATOR_S, '_');
597 newpath = g_strconcat(dirname, G_DIR_SEPARATOR_S, basenewpath, NULL);
601 if( g_rename(oldpath, newpath) < 0 ) {
602 FILE_OP_ERROR(oldpath, "rename");
611 if( strchr(item->path, G_DIR_SEPARATOR) != NULL ) {
612 dirname = g_path_get_dirname(item->path);
613 utf8newpath = g_strconcat(dirname, G_DIR_SEPARATOR_S, name, NULL);
616 utf8newpath = g_strdup(name);
619 item->name = g_strdup(name);
621 paths[0] = g_strdup(item->path);
622 paths[1] = utf8newpath;
623 g_node_traverse(item->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
624 rssyl_rename_folder_func, paths);
632 static gint rssyl_remove_folder(Folder *folder, FolderItem *item)
635 RFolderItem *ritem = (RFolderItem *)item;
637 g_return_val_if_fail(folder != NULL, -1);
638 g_return_val_if_fail(item != NULL, -1);
639 g_return_val_if_fail(item->path != NULL, -1);
640 g_return_val_if_fail(item->stype == F_NORMAL, -1);
642 debug_print("RSSyl: removing folder item %s\n", item->path);
644 path = folder_item_get_path(item);
645 if( remove_dir_recursive(path) < 0 ) {
646 g_warning("can't remove directory '%s'", path);
652 if (ritem->url != NULL)
653 rssyl_passwd_set(ritem, NULL);
655 folder_item_remove(item);
660 static gint rssyl_get_num_list(Folder *folder, FolderItem *item,
661 MsgNumberList **list, gboolean *old_uids_valid)
666 GError *error = NULL;
667 gint num, nummsgs = 0;
669 g_return_val_if_fail(item != NULL, -1);
671 debug_print("RSSyl: get_num_list: scanning '%s'\n", item->path);
673 *old_uids_valid = TRUE;
675 path = folder_item_get_path(item);
676 g_return_val_if_fail(path != NULL, -1);
678 if( (dp = g_dir_open(path, 0, &error)) == NULL ) {
679 debug_print("g_dir_open() failed on \"%s\", error %d (%s).\n",
680 path, error->code, error->message);
688 while( (d = g_dir_read_name(dp)) != NULL ) {
689 if( (num = to_number(d)) > 0 ) {
690 *list = g_slist_prepend(*list, GINT_TO_POINTER(num));
696 debug_print("RSSyl: get_num_list: returning %d\n", nummsgs);
701 static gboolean rssyl_is_msg_changed(Folder *folder, FolderItem *item,
706 gchar *itempath = NULL;
708 g_return_val_if_fail(folder != NULL, FALSE);
709 g_return_val_if_fail(item != NULL, FALSE);
710 g_return_val_if_fail(msginfo != NULL, FALSE);
712 itempath = folder_item_get_path(item);
713 path = g_strconcat(itempath, G_DIR_SEPARATOR_S, itos(msginfo->msgnum), NULL);
716 if (g_stat(path, &s) < 0 ||
717 msginfo->size != s.st_size || (
718 (msginfo->mtime - s.st_mtime != 0) &&
719 (msginfo->mtime - s.st_mtime != 3600) &&
720 (msginfo->mtime - s.st_mtime != -3600))) {
729 static gchar *rssyl_fetch_msg(Folder *folder, FolderItem *item, gint num)
734 g_return_val_if_fail(item != NULL, NULL);
735 g_return_val_if_fail(num > 0, NULL);
737 path = folder_item_get_path(item);
738 file = g_strconcat(path, G_DIR_SEPARATOR_S, itos(num), NULL);
741 debug_print("RSSyl: fetch_msg '%s'\n", file);
743 if( !is_file_exist(file)) {
751 static MsgInfo *rssyl_get_msginfo(Folder *folder, FolderItem *item, gint num)
753 MsgInfo *msginfo = NULL;
757 g_return_val_if_fail(folder != NULL, NULL);
758 g_return_val_if_fail(item != NULL, NULL);
759 g_return_val_if_fail(num > 0, NULL);
761 debug_print("RSSyl: get_msginfo: %d\n", num);
763 file = rssyl_fetch_msg(folder, item, num);
764 g_return_val_if_fail(file != NULL, NULL);
766 flags.perm_flags = 0;
769 msginfo = rssyl_feed_parse_item_to_msginfo(file, flags, TRUE, TRUE, item);
773 msginfo->msgnum = num;
778 static gint rssyl_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
779 GHashTable *relation)
783 MsgFileInfo *fileinfo;
785 g_return_val_if_fail(dest != NULL, -1);
786 g_return_val_if_fail(file_list != NULL, -1);
788 if( dest->last_num < 0 ) {
789 rssyl_get_last_num(folder, dest);
790 if( dest->last_num < 0 ) return -1;
793 for( cur = file_list; cur != NULL; cur = cur->next ) {
794 fileinfo = (MsgFileInfo *)cur->data;
796 destfile = rssyl_get_new_msg_filename(dest);
797 g_return_val_if_fail(destfile != NULL, -1);
798 debug_print("RSSyl: add_msgs: new filename is '%s'\n", destfile);
800 if( copy_file(fileinfo->file, destfile, TRUE) < 0 ) {
801 g_warning("can't copy message %s to %s", fileinfo->file, destfile);
806 if( relation != NULL )
807 g_hash_table_insert(relation, fileinfo->msginfo != NULL ?
808 (gpointer) fileinfo->msginfo : (gpointer) fileinfo,
809 GINT_TO_POINTER(dest->last_num + 1));
815 return dest->last_num;
818 gint rssyl_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
822 MsgFileInfo fileinfo;
824 g_return_val_if_fail(file != NULL, -1);
826 fileinfo.msginfo = NULL;
827 fileinfo.file = (gchar *)file;
828 fileinfo.flags = flags;
829 file_list.data = &fileinfo;
830 file_list.next = NULL;
832 return rssyl_add_msgs(folder, dest, &file_list, NULL);
835 static gint rssyl_remove_msg(Folder *folder, FolderItem *item, gint num)
837 gboolean need_scan = FALSE;
839 RFolderItem *ritem = (RFolderItem *)item;
841 g_return_val_if_fail(item != NULL, -1);
843 file = rssyl_fetch_msg(folder, item, num);
844 g_return_val_if_fail(file != NULL, -1);
846 need_scan = mh_get_class()->scan_required(folder, item);
848 /* are we doing a folder move ? */
849 tmp = g_strdup_printf("%s.tmp", file);
850 if (is_file_exist(tmp)) {
858 rssyl_deleted_update(ritem);
859 rssyl_deleted_add(ritem, file);
860 rssyl_deleted_store(ritem);
861 rssyl_deleted_free(ritem);
863 if( g_unlink(file) < 0 ) {
864 FILE_OP_ERROR(file, "unlink");
870 item->mtime = time(NULL);
876 static gint rssyl_remove_msgs(Folder *folder, FolderItem *item,
877 MsgInfoList *msglist, GHashTable *relation)
879 gboolean need_scan = FALSE;
883 RFolderItem *ritem = (RFolderItem *)item;
885 g_return_val_if_fail(item != NULL, -1);
887 need_scan = mh_get_class()->scan_required(folder, item);
889 rssyl_deleted_update(ritem);
891 for (cur = msglist; cur != NULL; cur = cur->next) {
893 MsgInfo *msginfo = (MsgInfo *)cur->data;
898 file = rssyl_fetch_msg(folder, item, msginfo->msgnum);
902 rssyl_deleted_add(ritem, file);
904 if (claws_unlink(file) < 0) {
905 FILE_OP_ERROR(file, "unlink");
913 rssyl_deleted_store(ritem);
914 rssyl_deleted_free(ritem);
917 item->mtime = time(NULL);
922 static gboolean rssyl_subscribe_uri(Folder *folder, const gchar *uri)
924 if (folder->klass != rssyl_folder_get_class())
926 return (rssyl_subscribe(FOLDER_ITEM(folder->node->data), uri, 0) ?
930 static void rssyl_copy_private_data(Folder *folder, FolderItem *oldi,
933 gchar *dpathold, *dpathnew;
934 RFolderItem *olditem = (RFolderItem *)oldi,
935 *newitem = (RFolderItem *)newi;
937 g_return_if_fail(folder != NULL);
938 g_return_if_fail(olditem != NULL);
939 g_return_if_fail(newitem != NULL);
941 if (olditem->url != NULL) {
942 g_free(newitem->url);
943 newitem->url = g_strdup(olditem->url);
946 if (olditem->auth != NULL) {
947 if (newitem->auth != NULL) {
948 if (newitem->auth->username != NULL) {
949 g_free(newitem->auth->username);
950 newitem->auth->username = NULL;
952 if (newitem->auth->password != NULL) {
953 g_free(newitem->auth->password);
954 newitem->auth->password = NULL;
956 g_free(newitem->auth);
958 newitem->auth = g_new0(FeedAuth, 1);
959 newitem->auth->type = olditem->auth->type;
960 if (olditem->auth->username != NULL)
961 newitem->auth->username = g_strdup(olditem->auth->username);
962 if (olditem->auth->password != NULL)
963 newitem->auth->password = g_strdup(olditem->auth->password);
966 if (olditem->official_title != NULL) {
967 g_free(newitem->official_title);
968 newitem->official_title = g_strdup(olditem->official_title);
971 if (olditem->source_id != NULL) {
972 g_free(newitem->source_id);
973 newitem->source_id = g_strdup(olditem->source_id);
976 newitem->keep_old = olditem->keep_old;
977 newitem->default_refresh_interval = olditem->default_refresh_interval;
978 newitem->refresh_interval = olditem->refresh_interval;
979 newitem->fetch_comments = olditem->fetch_comments;
980 newitem->fetch_comments_max_age = olditem->fetch_comments_max_age;
981 newitem->silent_update = olditem->silent_update;
982 newitem->write_heading = olditem->write_heading;
983 newitem->ignore_title_rename = olditem->ignore_title_rename;
984 newitem->ssl_verify_peer = olditem->ssl_verify_peer;
985 newitem->refresh_id = olditem->refresh_id;
986 newitem->fetching_comments = olditem->fetching_comments;
987 newitem->last_update = olditem->last_update;
989 dpathold = g_strconcat(rssyl_item_get_path(oldi->folder, oldi),
990 G_DIR_SEPARATOR_S, RSSYL_DELETED_FILE, NULL);
991 dpathnew = g_strconcat(rssyl_item_get_path(newi->folder, newi),
992 G_DIR_SEPARATOR_S, RSSYL_DELETED_FILE, NULL);
993 move_file(dpathold, dpathnew, TRUE);
999 /************************************************************************/
1001 FolderClass *rssyl_folder_get_class()
1003 if( rssyl_class.idstr == NULL ) {
1004 rssyl_class.type = F_UNKNOWN;
1005 rssyl_class.idstr = "rssyl";
1006 rssyl_class.uistr = PLUGIN_NAME;
1008 /* Folder functions */
1009 rssyl_class.new_folder = rssyl_new_folder;
1010 rssyl_class.destroy_folder = rssyl_destroy_folder;
1011 rssyl_class.set_xml = folder_set_xml;
1012 rssyl_class.get_xml = folder_get_xml;
1013 rssyl_class.scan_tree = rssyl_scan_tree;
1014 rssyl_class.create_tree = rssyl_create_tree;
1016 /* FolderItem functions */
1017 rssyl_class.item_new = rssyl_item_new;
1018 rssyl_class.item_destroy = rssyl_item_destroy;
1019 rssyl_class.item_get_path = rssyl_item_get_path;
1020 rssyl_class.create_folder = rssyl_create_folder;
1021 rssyl_class.rename_folder = rssyl_rename_folder;
1022 rssyl_class.remove_folder = rssyl_remove_folder;
1023 rssyl_class.get_num_list = rssyl_get_num_list;
1024 rssyl_class.scan_required = mh_get_class()->scan_required;
1025 rssyl_class.item_set_xml = rssyl_item_set_xml;
1026 rssyl_class.item_get_xml = rssyl_item_get_xml;
1028 /* Message functions */
1029 rssyl_class.get_msginfo = rssyl_get_msginfo;
1030 rssyl_class.fetch_msg = rssyl_fetch_msg;
1031 rssyl_class.copy_msg = mh_get_class()->copy_msg;
1032 rssyl_class.copy_msgs = mh_get_class()->copy_msgs;
1033 rssyl_class.add_msg = rssyl_add_msg;
1034 rssyl_class.add_msgs = rssyl_add_msgs;
1035 rssyl_class.remove_msg = rssyl_remove_msg;
1036 rssyl_class.remove_msgs = rssyl_remove_msgs;
1037 rssyl_class.is_msg_changed = rssyl_is_msg_changed;
1038 // rssyl_class.change_flags = rssyl_change_flags;
1039 rssyl_class.change_flags = NULL;
1040 rssyl_class.subscribe = rssyl_subscribe_uri;
1041 rssyl_class.copy_private_data = rssyl_copy_private_data;
1042 rssyl_class.search_msgs = folder_item_search_msgs_local;
1045 return &rssyl_class;