/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Claws-Mail-- a GTK+ based, lightweight, and fast e-mail client
* Copyright (C) 1999-2004 Hiroyuki Yamamoto
* This file (C) 2005 Andrej Kacian <andrej@kacian.sk>
*
#ifdef HAVE_CONFIG_H
# include "config.h"
-#include "claws-features.h"
#endif
+/* Global includes */
#include <glib.h>
#include <glib/gi18n.h>
-
-#ifdef G_OS_WIN32
-# include <w32lib.h>
-#endif
-
-#include <glib.h>
#include <curl/curl.h>
-#include "folder.h"
-#include "localfolder.h"
-
-#include "procheader.h"
-#include "common/utils.h"
-#include "toolbar.h"
-#include "prefs_toolbar.h"
-
-#include "main.h"
-
-#include "feed.h"
-#include "feedprops.h"
-#include "opml.h"
+/* Claws Mail includes */
+#include <folder.h>
+#include <procmsg.h>
+#include <localfolder.h>
+#include <common/utils.h>
+#include <main.h>
+#include <mh.h>
+#include <xml.h>
+#include <toolbar.h>
+#include <prefs_toolbar.h>
+#include <utils.h>
+
+/* Local includes */
+#include "libfeed/feeditem.h"
#include "rssyl.h"
+#include "rssyl_deleted.h"
#include "rssyl_gtk.h"
+#include "rssyl_feed.h"
#include "rssyl_prefs.h"
-#include "strreplace.h"
+#include "rssyl_update_feed.h"
+#include "rssyl_update_format.h"
+#include "opml_import.h"
+#include "opml_export.h"
+#include "strutils.h"
+
+FolderClass rssyl_class;
static gint rssyl_create_tree(Folder *folder);
+static gint rssyl_scan_tree(Folder *folder);
static gboolean existing_tree_found = FALSE;
static void rssyl_init_read_func(FolderItem *item, gpointer data)
{
+ RFolderItem *ritem = (RFolderItem *)item;
+ RPrefs *rsprefs = NULL;
+
if( !IS_RSSYL_FOLDER_ITEM(item) )
return;
existing_tree_found = TRUE;
- if( folder_item_parent(item) == NULL )
+ /* Don't do anything if we're on root of our folder tree or on
+ * a regular folder (no feed) */
+ if( folder_item_parent(item) == NULL || ritem->url == NULL )
return;
- rssyl_get_feed_props((RSSylFolderItem *)item);
+ ritem->refresh_id = 0;
+
+ /* Start automatic refresh timer, if necessary */
+ if( ritem->default_refresh_interval ) {
+ rsprefs = rssyl_prefs_get();
+ if( !rsprefs->refresh_enabled )
+ return;
+
+ ritem->refresh_interval = rsprefs->refresh;
+ }
+
+ /* Start the timer, if determined interval is >0 */
+ if( ritem->refresh_interval > 0 )
+ rssyl_feed_start_refresh_timeout(ritem);
}
static void rssyl_make_rc_dir(void)
g_warning("couldn't create directory %s\n", rssyl_dir);
}
- debug_print("created directorty %s\n", rssyl_dir);
+ debug_print("RSSyl: created directory %s\n", rssyl_dir);
}
g_free(rssyl_dir);
static void rssyl_create_default_mailbox(void)
{
Folder *root = NULL;
- FolderItem *item;
rssyl_make_rc_dir();
g_return_if_fail(root != NULL);
folder_add(root);
- item = FOLDER_ITEM(root->node->data);
+ rssyl_scan_tree(root);
- rssyl_subscribe_new_feed(item, RSSYL_DEFAULT_FEED, TRUE);
+ /* FIXME: subscribe default feed */
+// rssyl_subscribe_new_feed(item, RSSYL_DEFAULT_FEED, TRUE);
}
-static gboolean rssyl_refresh_all_feeds_deferred(gpointer data)
+static gboolean rssyl_update_all_feeds_deferred(gpointer data)
{
- rssyl_refresh_all_feeds();
+ rssyl_update_all_feeds();
return FALSE;
}
-static void rssyl_toolbar_cb_refresh_all(gpointer parent, const gchar *item_name, gpointer data)
+static void rssyl_toolbar_cb_refresh_all_feeds(gpointer parent, const gchar *item_name, gpointer data)
{
- rssyl_refresh_all_feeds();
+ rssyl_update_all_feeds();
}
void rssyl_init(void)
folder_register_class(rssyl_folder_get_class());
rssyl_gtk_init();
-
rssyl_make_rc_dir();
rssyl_prefs_init();
folder_func_to_all_folders((FolderItemFunc)rssyl_init_read_func, NULL);
- if( existing_tree_found == FALSE )
+ if( !existing_tree_found )
rssyl_create_default_mailbox();
+ else
+ rssyl_update_format();
- prefs_toolbar_register_plugin_item(TOOLBAR_MAIN, "RSSyl",
- _("Refresh all feeds"), rssyl_toolbar_cb_refresh_all, NULL);
-
- rssyl_opml_export();
+ prefs_toolbar_register_plugin_item(TOOLBAR_MAIN, "RSSyl", _("Refresh all feeds"), rssyl_toolbar_cb_refresh_all_feeds, NULL);
if( rssyl_prefs_get()->refresh_on_startup &&
claws_is_starting() )
- g_timeout_add(2000, rssyl_refresh_all_feeds_deferred, NULL);
+ g_timeout_add(2000, rssyl_update_all_feeds_deferred, NULL);
}
void rssyl_done(void)
{
- prefs_toolbar_unregister_plugin_item(TOOLBAR_MAIN, "RSSyl",
- _("Refresh all feeds"));
+ rssyl_opml_export();
+
+ prefs_toolbar_unregister_plugin_item(TOOLBAR_MAIN, "RSSyl", _("Refresh all feeds"));
+
rssyl_prefs_done();
rssyl_gtk_done();
- if (!claws_is_exiting())
+
+ if( !claws_is_exiting() )
folder_unregister_class(rssyl_folder_get_class());
+
+ debug_print("RSSyl is done\n");
}
static gchar *rssyl_get_new_msg_filename(FolderItem *dest)
static void rssyl_get_last_num(Folder *folder, FolderItem *item)
{
gchar *path;
- DIR *dp;
- struct dirent *d;
+ const char *f;
+ GDir *dp;
+ GError *error = NULL;
gint max = 0;
gint num;
debug_print("rssyl_get_last_num(): Scanning %s ...\n", item->path);
path = folder_item_get_path(item);
g_return_if_fail(path != NULL);
- if( change_dir(path) < 0 ) {
+
+ if( (dp = g_dir_open(path, 0, &error)) == NULL ) {
+ FILE_OP_ERROR(item->path, "g_dir_open");
+ debug_print("g_dir_open() failed on \"%s\", error %d (%s).\n",
+ path, error->code, error->message);
+ g_error_free(error);
g_free(path);
return;
}
- g_free(path);
- if( (dp = opendir(".")) == NULL ) {
- FILE_OP_ERROR(item->path, "opendir");
- return;
- }
+ g_free(path);
- while( (d = readdir(dp)) != NULL ) {
- if( (num = to_number(d->d_name)) > 0 && dirent_is_regular_file(d) ) {
+ while( (f = g_dir_read_name(dp)) != NULL) {
+ if ((num = to_number(f)) > 0 &&
+ g_file_test(f, G_FILE_TEST_IS_REGULAR)) {
if( max < num )
max = num;
}
}
- closedir(dp);
+ g_dir_close(dp);
debug_print("Last number in dir %s = %d\n", item->path, max);
item->last_num = max;
}
-struct _RSSylFolder {
- LocalFolder folder;
-};
-
-typedef struct _RSSylFolder RSSylFolder;
-
-FolderClass rssyl_class;
-
static Folder *rssyl_new_folder(const gchar *name, const gchar *path)
{
- RSSylFolder *folder;
+ Folder *folder;
- debug_print("RSSyl: new_folder\n");
+ debug_print("RSSyl: new_folder: %s (%s)\n", name, path);
rssyl_make_rc_dir();
- folder = g_new0(RSSylFolder, 1);
+ folder = g_new0(Folder, 1);
FOLDER(folder)->klass = &rssyl_class;
folder_init(FOLDER(folder), name);
return FOLDER(folder);
}
-static void rssyl_destroy_folder(Folder *_folder)
+static void rssyl_destroy_folder(Folder *folder)
{
- RSSylFolder *folder = (RSSylFolder *)_folder;
-
folder_local_folder_destroy(LOCAL_FOLDER(folder));
}
+static void rssyl_item_set_xml(Folder *folder, FolderItem *item, XMLTag *tag)
+{
+ GList *cur;
+ RFolderItem *ritem = (RFolderItem *)item;
+
+ folder_item_set_xml(folder, item, tag);
+
+ for( cur = tag->attr; cur != NULL; cur = g_list_next(cur)) {
+ XMLAttr *attr = (XMLAttr *) cur->data;
+
+ if( !attr || !attr->name || !attr->value)
+ continue;
+
+ /* (str) URL */
+ if( !strcmp(attr->name, "uri")) {
+ g_free(ritem->url);
+ ritem->url = g_strdup(attr->value);
+ }
+ /* (int) URL auth */
+ if (!strcmp(attr->name, "auth")) {
+ ritem->auth->type = atoi(attr->value);
+ }
+ /* (str) Auth user */
+ if (!strcmp(attr->name, "auth_user")) {
+ g_free(ritem->auth->username);
+ ritem->auth->username = g_strdup(attr->value);
+ }
+ /* (str) Auth pass */
+ if (!strcmp(attr->name, "auth_pass")) {
+ gsize len = 0;
+ guchar *pwd = g_base64_decode(attr->value, &len);
+ g_free(ritem->auth->password);
+ ritem->auth->password = (gchar *)pwd;
+ }
+ /* (str) Official title */
+ if( !strcmp(attr->name, "official_title")) {
+ g_free(ritem->official_title);
+ ritem->official_title = g_strdup(attr->value);
+ }
+ /* (bool) Keep old items */
+ if( !strcmp(attr->name, "keep_old"))
+ ritem->keep_old = (atoi(attr->value) == 0 ? FALSE : TRUE );
+ /* (bool) Use default refresh_interval */
+ if( !strcmp(attr->name, "default_refresh_interval"))
+ ritem->default_refresh_interval = (atoi(attr->value) == 0 ? FALSE : TRUE );
+ /* (int) Refresh interval */
+ if( !strcmp(attr->name, "refresh_interval"))
+ ritem->refresh_interval = atoi(attr->value);
+ /* (bool) Fetch comments */
+ if( !strcmp(attr->name, "fetch_comments"))
+ ritem->fetch_comments = (atoi(attr->value) == 0 ? FALSE : TRUE );
+ /* (int) Max age of posts to fetch comments for */
+ if( !strcmp(attr->name, "fetch_comments_max_age"))
+ ritem->fetch_comments_max_age = atoi(attr->value);
+ /* (bool) Write heading */
+ if( !strcmp(attr->name, "write_heading"))
+ ritem->write_heading = (atoi(attr->value) == 0 ? FALSE : TRUE );
+ /* (int) Silent update */
+ if( !strcmp(attr->name, "silent_update"))
+ ritem->silent_update = atoi(attr->value);
+ /* (bool) Ignore title rename */
+ if( !strcmp(attr->name, "ignore_title_rename"))
+ ritem->ignore_title_rename = (atoi(attr->value) == 0 ? FALSE : TRUE );
+ /* (bool) Verify SSL peer */
+ if( !strcmp(attr->name, "ssl_verify_peer"))
+ ritem->ssl_verify_peer = (atoi(attr->value) == 0 ? FALSE : TRUE );
+ }
+}
+
+static XMLTag *rssyl_item_get_xml(Folder *folder, FolderItem *item)
+{
+ XMLTag *tag;
+ RFolderItem *ri = (RFolderItem *)item;
+ gchar *tmp = NULL;
+
+ tag = folder_item_get_xml(folder, item);
+
+ /* (str) URL */
+ if( ri->url != NULL )
+ xml_tag_add_attr(tag, xml_attr_new("uri", ri->url));
+ /* (int) Auth */
+ tmp = g_strdup_printf("%d", ri->auth->type);
+ xml_tag_add_attr(tag, xml_attr_new("auth", tmp));
+ g_free(tmp);
+ /* (str) Auth user */
+ if (ri->auth->username != NULL)
+ xml_tag_add_attr(tag, xml_attr_new("auth_user", ri->auth->username));
+ /* (str) Auth pass */
+ if (ri->auth->password != NULL) {
+ gchar *pwd = g_base64_encode(ri->auth->password, strlen(ri->auth->password));
+ xml_tag_add_attr(tag, xml_attr_new("auth_pass", pwd));
+ g_free(pwd);
+ }
+ /* (str) Official title */
+ if( ri->official_title != NULL )
+ xml_tag_add_attr(tag, xml_attr_new("official_title", ri->official_title));
+ /* (bool) Keep old items */
+ xml_tag_add_attr(tag, xml_attr_new("keep_old",
+ (ri->keep_old ? "1" : "0")) );
+ /* (bool) Use default refresh interval */
+ xml_tag_add_attr(tag, xml_attr_new("default_refresh_interval",
+ (ri->default_refresh_interval ? "1" : "0")) );
+ /* (int) Refresh interval */
+ tmp = g_strdup_printf("%d", ri->refresh_interval);
+ xml_tag_add_attr(tag, xml_attr_new("refresh_interval", tmp));
+ g_free(tmp);
+ /* (bool) Fetch comments */
+ xml_tag_add_attr(tag, xml_attr_new("fetch_comments",
+ (ri->fetch_comments ? "1" : "0")) );
+ /* (int) Max age of posts to fetch comments for */
+ tmp = g_strdup_printf("%d", ri->fetch_comments_max_age);
+ xml_tag_add_attr(tag, xml_attr_new("fetch_comments_max_age", tmp));
+ g_free(tmp);
+ /* (bool) Write heading */
+ xml_tag_add_attr(tag, xml_attr_new("write_heading",
+ (ri->write_heading ? "1" : "0")) );
+ /* (int) Silent update */
+ tmp = g_strdup_printf("%d", ri->silent_update);
+ xml_tag_add_attr(tag, xml_attr_new("silent_update", tmp));
+ g_free(tmp);
+ /* (bool) Ignore title rename */
+ xml_tag_add_attr(tag, xml_attr_new("ignore_title_rename",
+ (ri->ignore_title_rename ? "1" : "0")) );
+ /* (bool) Verify SSL peer */
+ xml_tag_add_attr(tag, xml_attr_new("ssl_verify_peer",
+ (ri->ssl_verify_peer ? "1" : "0")) );
+
+ return tag;
+}
+
static gint rssyl_scan_tree(Folder *folder)
{
g_return_val_if_fail(folder != NULL, -1);
FolderItem *rootitem;
GNode *rootnode;
+ g_return_val_if_fail(folder != NULL, -1);
+
rssyl_make_rc_dir();
if( !folder->node ) {
rootnode = g_node_new(rootitem);
folder->node = rootnode;
rootitem->node = rootnode;
- } else {
- rootitem = FOLDER_ITEM(folder->node->data);
- rootnode = folder->node;
}
debug_print("RSSyl: created new rssyl tree\n");
static FolderItem *rssyl_item_new(Folder *folder)
{
- RSSylFolderItem *ritem;
-
- debug_print("RSSyl: item_new\n");
-
- ritem = g_new0(RSSylFolderItem, 1);
+ RFolderItem *ritem = g_new0(RFolderItem, 1);
ritem->url = NULL;
+ ritem->auth = g_new0(FeedAuth, 1);
+ ritem->auth->type = FEED_AUTH_NONE;
+ ritem->auth->username = NULL;
+ ritem->auth->password = NULL;
+ ritem->official_title = NULL;
+ ritem->source_id = NULL;
+ ritem->items = NULL;
+ ritem->keep_old = FALSE;
ritem->default_refresh_interval = TRUE;
- ritem->default_expired_num = TRUE;
+ ritem->refresh_interval = atoi(PREF_DEFAULT_REFRESH);
ritem->fetch_comments = FALSE;
- ritem->fetch_comments_for = -1;
+ ritem->fetch_comments_max_age = -1;
+ ritem->write_heading = TRUE;
+ ritem->fetching_comments = FALSE;
ritem->silent_update = 0;
- ritem->refresh_interval = rssyl_prefs_get()->refresh;
- ritem->refresh_id = 0;
- ritem->expired_num = rssyl_prefs_get()->expired;
- ritem->last_count = 0;
-
- ritem->contents = NULL;
- ritem->feedprop = NULL;
+ ritem->last_update = 0;
+ ritem->ignore_title_rename = FALSE;
return (FolderItem *)ritem;
}
static void rssyl_item_destroy(Folder *folder, FolderItem *item)
{
- RSSylFolderItem *ritem = (RSSylFolderItem *)item;
+ RFolderItem *ritem = (RFolderItem *)item;
g_return_if_fail(ritem != NULL);
- /* Silently remove feed refresh timeouts */
- if( ritem->refresh_id != 0 )
- g_source_remove(ritem->refresh_id);
-
g_free(ritem->url);
- g_free(ritem->official_name);
- g_slist_free(ritem->contents);
+ if (ritem->auth->username)
+ g_free(ritem->auth->username);
+ if (ritem->auth->password)
+ g_free(ritem->auth->password);
+ g_free(ritem->auth);
+ g_free(ritem->official_title);
+ g_slist_free(ritem->items);
+
+ /* Remove a scheduled refresh, if any */
+ if( ritem->refresh_id != 0)
+ g_source_remove(ritem->refresh_id);
- g_free(item);
+ g_free(ritem);
}
static FolderItem *rssyl_create_folder(Folder *folder,
FolderItem *parent, const gchar *name)
{
- gchar *path = NULL, *tmp;
+ gchar *path = NULL, *basepath = NULL, *itempath = NULL;
FolderItem *newitem = NULL;
g_return_val_if_fail(folder != NULL, NULL);
g_return_val_if_fail(parent != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL);
- tmp = rssyl_feed_title_to_dir((gchar *)name);
- path = g_strconcat((parent->path != NULL) ? parent->path : "", ".",
- tmp, NULL);
- g_free(tmp);
- newitem = folder_item_new(folder, name, path);
- folder_item_append(parent, newitem);
+
+ path = folder_item_get_path(parent);
+ if( !is_dir_exist(path) ) {
+ if( (make_dir_hier(path) != 0) ) {
+ debug_print("RSSyl: Couldn't create directory (rec) '%s'\n", path);
+ return NULL;
+ }
+ }
+
+ basepath = g_strdelimit(g_strdup(name), G_DIR_SEPARATOR_S, '_');
+ path = g_strconcat(path, G_DIR_SEPARATOR_S, basepath, NULL);
+
+ if( make_dir(path) < 0 ) {
+ debug_print("RSSyl: Couldn't create directory '%s'\n", path);
+ g_free(path);
+ g_free(basepath);
+ return NULL;
+ }
g_free(path);
+ itempath = g_strconcat((parent->path ? parent->path : ""),
+ G_DIR_SEPARATOR_S, basepath, NULL);
+ newitem = folder_item_new(folder, name, itempath);
+ g_free(itempath);
+ g_free(basepath);
+
+ folder_item_append(parent, newitem);
+
return newitem;
}
+FolderItem *rssyl_get_root_folderitem(FolderItem *item)
+{
+ FolderItem *i;
+
+ for( i = item; folder_item_parent(i) != NULL; i = folder_item_parent(i) ) { }
+ return i;
+}
+
static gchar *rssyl_item_get_path(Folder *folder, FolderItem *item)
{
- gchar *result, *tmp;
- tmp = rssyl_feed_title_to_dir(item->name);
- result = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, RSSYL_DIR,
- G_DIR_SEPARATOR_S, tmp, NULL);
- g_free(tmp);
- return result;
+ gchar *path, *name;
+
+ g_return_val_if_fail(folder != NULL, NULL);
+ g_return_val_if_fail(item != NULL, NULL);
+
+ debug_print("RSSyl: item_get_path\n");
+
+ name = folder_item_get_name(rssyl_get_root_folderitem(item));
+ path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, RSSYL_DIR,
+ G_DIR_SEPARATOR_S, name, G_DIR_SEPARATOR_S, item->path, NULL);
+ g_free(name);
+
+ return path;
+}
+
+static gboolean rssyl_rename_folder_func(GNode *node, gpointer data)
+{
+ FolderItem *item = node->data;
+ gchar **paths = data;
+ const gchar *oldpath = paths[0];
+ const gchar *newpath = paths[1];
+ gchar *base;
+ gchar *new_itempath;
+ gint oldpathlen;
+
+ oldpathlen = strlen(oldpath);
+ if (strncmp(oldpath, item->path, oldpathlen) != 0) {
+ g_warning("path doesn't match: %s, %s\n", oldpath, item->path);
+ return TRUE;
+ }
+
+ base = item->path + oldpathlen;
+ while (*base == G_DIR_SEPARATOR) base++;
+ if (*base == '\0')
+ new_itempath = g_strdup(newpath);
+ else
+ new_itempath = g_strconcat(newpath, G_DIR_SEPARATOR_S, base,
+ NULL);
+ g_free(item->path);
+ item->path = new_itempath;
+
+ return FALSE;
}
static gint rssyl_rename_folder(Folder *folder, FolderItem *item,
const gchar *name)
{
- gchar *oldname = NULL, *oldpath = NULL, *newpath = NULL;
- RSSylFolderItem *ritem = NULL;
+ gchar *oldpath;
+ gchar *dirname;
+ gchar *newpath, *utf8newpath;
+ gchar *basenewpath;
+ gchar *paths[2];
+
g_return_val_if_fail(folder != NULL, -1);
g_return_val_if_fail(item != NULL, -1);
g_return_val_if_fail(item->path != NULL, -1);
g_return_val_if_fail(name != NULL, -1);
- debug_print("RSSyl: renaming folder '%s' to '%s'\n", item->path, name);
+ debug_print("RSSyl: rssyl_rename_folder '%s' -> '%s'\n",
+ item->name, name);
- oldpath = rssyl_item_get_path(folder, item);
-
- /* now get the new path using the new name */
- oldname = item->name;
- item->name = g_strdup(name);
- newpath = rssyl_item_get_path(folder, item);
-
- /* put back the old name in case the rename fails */
- g_free(item->name);
- item->name = oldname;
-
- if (g_rename(oldpath, newpath) < 0) {
+ if (!strcmp(item->name, name))
+ return 0;
+
+ oldpath = folder_item_get_path(item);
+ if( !is_dir_exist(oldpath) )
+ make_dir_hier(oldpath);
+
+ dirname = g_path_get_dirname(oldpath);
+ basenewpath = g_strdelimit(g_strdup(name), G_DIR_SEPARATOR_S, '_');
+ newpath = g_strconcat(dirname, G_DIR_SEPARATOR_S, basenewpath, NULL);
+ g_free(basenewpath);
+
+ if( g_rename(oldpath, newpath) < 0 ) {
FILE_OP_ERROR(oldpath, "rename");
g_free(oldpath);
g_free(newpath);
return -1;
}
-
- g_free(item->path);
- item->path = g_strdup_printf(".%s", name);
-
- ritem = (RSSylFolderItem *)item;
-
- if (ritem->url)
- rssyl_props_update_name(ritem, (gchar *)name);
-
+
+ g_free(oldpath);
+ g_free(newpath);
+
+ if( strchr(item->path, G_DIR_SEPARATOR) != NULL ) {
+ dirname = g_path_get_dirname(item->path);
+ utf8newpath = g_strconcat(dirname, G_DIR_SEPARATOR_S, name, NULL);
+ g_free(dirname);
+ } else
+ utf8newpath = g_strdup(name);
+
g_free(item->name);
item->name = g_strdup(name);
-
- folder_write_list();
+
+ paths[0] = g_strdup(item->path);
+ paths[1] = utf8newpath;
+ g_node_traverse(item->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
+ rssyl_rename_folder_func, paths);
+
+ g_free(paths[0]);
+ g_free(paths[1]);
return 0;
}
static gint rssyl_remove_folder(Folder *folder, FolderItem *item)
{
+ gchar *path = NULL;
+
g_return_val_if_fail(folder != NULL, -1);
g_return_val_if_fail(item != NULL, -1);
g_return_val_if_fail(item->path != NULL, -1);
debug_print("RSSyl: removing folder item %s\n", item->path);
+ path = folder_item_get_path(item);
+ if( remove_dir_recursive(path) < 0 ) {
+ g_warning("can't remove directory '%s'\n", path);
+ g_free(path);
+ return -1;
+ }
+
+ g_free(path);
folder_item_remove(item);
return 0;
MsgNumberList **list, gboolean *old_uids_valid)
{
gchar *path;
- DIR *dp;
- struct dirent *d;
+ GDir *dp;
+ const gchar *d;
+ GError *error = NULL;
gint num, nummsgs = 0;
- RSSylFolderItem *ritem = (RSSylFolderItem *)item;
g_return_val_if_fail(item != NULL, -1);
- debug_print("RSSyl: scanning '%s'...\n", item->path);
-
- rssyl_get_feed_props(ritem);
-
- if (ritem->url == NULL)
- return -1;
+ debug_print("RSSyl: get_num_list: scanning '%s'\n", item->path);
*old_uids_valid = TRUE;
-
+
path = folder_item_get_path(item);
g_return_val_if_fail(path != NULL, -1);
- if( change_dir(path) < 0 ) {
+
+ if( (dp = g_dir_open(path, 0, &error)) == NULL ) {
+ debug_print("g_dir_open() failed on \"%s\", error %d (%s).\n",
+ path, error->code, error->message);
+ g_error_free(error);
g_free(path);
return -1;
}
- g_free(path);
- if( (dp = opendir(".")) == NULL ) {
- FILE_OP_ERROR(item->path, "opendir");
- return -1;
- }
+ g_free(path);
- while( (d = readdir(dp)) != NULL ) {
- if( (num = to_number(d->d_name)) > 0 ) {
+ while( (d = g_dir_read_name(dp)) != NULL ) {
+ if( (num = to_number(d)) > 0 ) {
*list = g_slist_prepend(*list, GINT_TO_POINTER(num));
nummsgs++;
}
}
- closedir(dp);
+ g_dir_close(dp);
+
+ debug_print("RSSyl: get_num_list: returning %d\n", nummsgs);
return nummsgs;
}
-static gboolean rssyl_scan_required(Folder *folder, FolderItem *item)
+static gboolean rssyl_is_msg_changed(Folder *folder, FolderItem *item,
+ MsgInfo *msginfo)
{
- return TRUE;
+ GStatBuf s;
+ gchar *path = NULL;
+ gchar *itempath = NULL;
+
+ g_return_val_if_fail(folder != NULL, FALSE);
+ g_return_val_if_fail(item != NULL, FALSE);
+ g_return_val_if_fail(msginfo != NULL, FALSE);
+
+ itempath = folder_item_get_path(item);
+ path = g_strconcat(itempath, G_DIR_SEPARATOR_S, itos(msginfo->msgnum), NULL);
+ g_free(itempath);
+
+ if (g_stat(path, &s) < 0 ||
+ msginfo->size != s.st_size || (
+ (msginfo->mtime - s.st_mtime != 0) &&
+ (msginfo->mtime - s.st_mtime != 3600) &&
+ (msginfo->mtime - s.st_mtime != -3600))) {
+ g_free(path);
+ return TRUE;
+ }
+
+ g_free(path);
+ return FALSE;
}
static gchar *rssyl_fetch_msg(Folder *folder, FolderItem *item, gint num)
{
- gchar *snum = g_strdup_printf("%d", num);
- gchar *tmp = rssyl_feed_title_to_dir(item->name);
- gchar *file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, RSSYL_DIR,
- G_DIR_SEPARATOR_S, tmp,
- G_DIR_SEPARATOR_S, snum, NULL);
- g_free(tmp);
- debug_print("RSSyl: fetch_msg: '%s'\n", file);
+ gchar *path;
+ gchar *file;
+
+ g_return_val_if_fail(item != NULL, NULL);
+ g_return_val_if_fail(num > 0, NULL);
- g_free(snum);
+ path = folder_item_get_path(item);
+ file = g_strconcat(path, G_DIR_SEPARATOR_S, itos(num), NULL);
+ g_free(path);
+
+ debug_print("RSSyl: fetch_msg '%s'\n", file);
+
+ if( !is_file_exist(file)) {
+ g_free(file);
+ return NULL;
+ }
return file;
}
gchar *file;
MsgFlags flags;
- debug_print("RSSyl: get_msginfo: %d\n", num);
-
g_return_val_if_fail(folder != NULL, NULL);
g_return_val_if_fail(item != NULL, NULL);
g_return_val_if_fail(num > 0, NULL);
+ debug_print("RSSyl: get_msginfo: %d\n", num);
+
file = rssyl_fetch_msg(folder, item, num);
g_return_val_if_fail(file != NULL, NULL);
- flags.perm_flags = MSG_NEW | MSG_UNREAD;
+ flags.perm_flags = 0;
flags.tmp_flags = 0;
- msginfo = rssyl_parse_feed_item_to_msginfo(file, flags, TRUE, TRUE, item);
+ msginfo = rssyl_feed_parse_item_to_msginfo(file, flags, TRUE, TRUE, item);
+ g_free(file);
if( msginfo )
msginfo->msgnum = num;
- g_free(file);
-
return msginfo;
}
destfile = rssyl_get_new_msg_filename(dest);
g_return_val_if_fail(destfile != NULL, -1);
+ debug_print("RSSyl: add_msgs: new filename is '%s'\n", destfile);
-#ifdef G_OS_UNIX
- if( link(fileinfo->file, destfile) < 0 )
-#endif
- if( copy_file(fileinfo->file, destfile, TRUE) < 0 ) {
- g_warning("can't copy message %s to %s\n", fileinfo->file, destfile);
- g_free(destfile);
- return -1;
- }
+ if( copy_file(fileinfo->file, destfile, TRUE) < 0 ) {
+ g_warning("can't copy message %s to %s\n", fileinfo->file, destfile);
+ g_free(destfile);
+ return -1;
+ }
if( relation != NULL )
- g_hash_table_insert(relation, fileinfo,
- GINT_TO_POINTER(dest->last_num + 1) );
+ g_hash_table_insert(relation, fileinfo->msginfo != NULL ?
+ (gpointer) fileinfo->msginfo : (gpointer) fileinfo,
+ GINT_TO_POINTER(dest->last_num + 1));
g_free(destfile);
dest->last_num++;
}
+
return dest->last_num;
}
static gint rssyl_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
MsgFlags *flags)
{
- gint ret;
GSList file_list;
MsgFileInfo fileinfo;
file_list.data = &fileinfo;
file_list.next = NULL;
- ret = rssyl_add_msgs(folder, dest, &file_list, NULL);
- return ret;
+ return rssyl_add_msgs(folder, dest, &file_list, NULL);
}
-static gint rssyl_dummy_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *info)
-{
- if (info->folder == NULL || info->folder->folder != dest->folder) {
- return -1;
- }
- if (info->folder && info->folder->name && dest->name
- && !strcmp(info->folder->name, dest->name)) {
- /* this is a folder move */
- gchar *file = procmsg_get_message_file(info);
- gchar *tmp = g_strdup_printf("%s.tmp", file);
- copy_file(file, tmp, TRUE);
- g_free(file);
- g_free(tmp);
- return info->msgnum;
- } else {
- return -1;
- }
-}
static gint rssyl_remove_msg(Folder *folder, FolderItem *item, gint num)
{
gboolean need_scan = FALSE;
file = rssyl_fetch_msg(folder, item, num);
g_return_val_if_fail(file != NULL, -1);
- need_scan = rssyl_scan_required(folder, item);
+ need_scan = mh_get_class()->scan_required(folder, item);
/* are we doing a folder move ? */
tmp = g_strdup_printf("%s.tmp", file);
if (is_file_exist(tmp)) {
- claws_unlink(tmp);
+ g_unlink(tmp);
g_free(tmp);
g_free(file);
return 0;
}
g_free(tmp);
- if( claws_unlink(file) < 0 ) {
+
+ rssyl_deleted_add((RFolderItem *)item, file);
+
+ if( g_unlink(file) < 0 ) {
FILE_OP_ERROR(file, "unlink");
g_free(file);
return -1;
{
if (folder->klass != rssyl_folder_get_class())
return FALSE;
-
- if( rssyl_subscribe_new_feed(
- FOLDER_ITEM(folder->node->data), uri, FALSE) != NULL )
- return TRUE;
- return FALSE;
+ return (rssyl_feed_subscribe_new(FOLDER_ITEM(folder->node->data), uri, FALSE) ?
+ TRUE : FALSE);
+}
+
+static void rssyl_copy_private_data(Folder *folder, FolderItem *oldi,
+ FolderItem *newi)
+{
+ gchar *dpathold, *dpathnew;
+ RFolderItem *olditem = (RFolderItem *)oldi,
+ *newitem = (RFolderItem *)newi;
+
+ g_return_if_fail(folder != NULL);
+ g_return_if_fail(olditem != NULL);
+ g_return_if_fail(newitem != NULL);
+
+ if (olditem->url != NULL) {
+ g_free(newitem->url);
+ newitem->url = g_strdup(olditem->url);
+ }
+
+ if (olditem->auth != NULL) {
+ if (newitem->auth != NULL) {
+ if (newitem->auth->username != NULL) {
+ g_free(newitem->auth->username);
+ newitem->auth->username = NULL;
+ }
+ if (newitem->auth->password != NULL) {
+ g_free(newitem->auth->password);
+ newitem->auth->password = NULL;
+ }
+ g_free(newitem->auth);
+ }
+ newitem->auth = g_new0(FeedAuth, 1);
+ newitem->auth->type = olditem->auth->type;
+ if (olditem->auth->username != NULL)
+ newitem->auth->username = g_strdup(olditem->auth->username);
+ if (olditem->auth->password != NULL)
+ newitem->auth->password = g_strdup(olditem->auth->password);
+ }
+
+ if (olditem->official_title != NULL) {
+ g_free(newitem->official_title);
+ newitem->official_title = g_strdup(olditem->official_title);
+ }
+
+ if (olditem->source_id != NULL) {
+ g_free(newitem->source_id);
+ newitem->source_id = g_strdup(olditem->source_id);
+ }
+
+ newitem->keep_old = olditem->keep_old;
+ newitem->default_refresh_interval = olditem->default_refresh_interval;
+ newitem->refresh_interval = olditem->refresh_interval;
+ newitem->fetch_comments = olditem->fetch_comments;
+ newitem->fetch_comments_max_age = olditem->fetch_comments_max_age;
+ newitem->silent_update = olditem->silent_update;
+ newitem->write_heading = olditem->write_heading;
+ newitem->ignore_title_rename = olditem->ignore_title_rename;
+ newitem->ssl_verify_peer = olditem->ssl_verify_peer;
+ newitem->refresh_id = olditem->refresh_id;
+ newitem->fetching_comments = olditem->fetching_comments;
+ newitem->last_update = olditem->last_update;
+
+ dpathold = g_strconcat(rssyl_item_get_path(oldi->folder, oldi),
+ G_DIR_SEPARATOR_S, RSSYL_DELETED_FILE, NULL);
+ dpathnew = g_strconcat(rssyl_item_get_path(newi->folder, newi),
+ G_DIR_SEPARATOR_S, RSSYL_DELETED_FILE, NULL);
+ move_file(dpathold, dpathnew, TRUE);
+ g_free(dpathold);
+ g_free(dpathnew);
+
}
/************************************************************************/
rssyl_class.rename_folder = rssyl_rename_folder;
rssyl_class.remove_folder = rssyl_remove_folder;
rssyl_class.get_num_list = rssyl_get_num_list;
- rssyl_class.scan_required = rssyl_scan_required;
+ rssyl_class.scan_required = mh_get_class()->scan_required;
+ rssyl_class.item_set_xml = rssyl_item_set_xml;
+ rssyl_class.item_get_xml = rssyl_item_get_xml;
/* Message functions */
rssyl_class.get_msginfo = rssyl_get_msginfo;
rssyl_class.fetch_msg = rssyl_fetch_msg;
- rssyl_class.copy_msg = rssyl_dummy_copy_msg;
+ rssyl_class.copy_msg = mh_get_class()->copy_msg;
+ rssyl_class.copy_msgs = mh_get_class()->copy_msgs;
rssyl_class.add_msg = rssyl_add_msg;
rssyl_class.add_msgs = rssyl_add_msgs;
rssyl_class.remove_msg = rssyl_remove_msg;
rssyl_class.remove_msgs = NULL;
+ rssyl_class.is_msg_changed = rssyl_is_msg_changed;
// rssyl_class.change_flags = rssyl_change_flags;
rssyl_class.change_flags = NULL;
rssyl_class.subscribe = rssyl_subscribe_uri;
- debug_print("RSSyl: registered folderclass\n");
+ rssyl_class.copy_private_data = rssyl_copy_private_data;
+ rssyl_class.search_msgs = folder_item_search_msgs_local;
}
return &rssyl_class;