aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/nntp
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers/nntp')
-rw-r--r--camel/providers/nntp/Makefile.am2
-rw-r--r--camel/providers/nntp/camel-nntp-newsrc.c59
-rw-r--r--camel/providers/nntp/camel-nntp-newsrc.h12
-rw-r--r--camel/providers/nntp/camel-nntp-provider.c50
-rw-r--r--camel/providers/nntp/camel-nntp-store.c78
-rw-r--r--camel/providers/nntp/camel-nntp-store.h16
6 files changed, 194 insertions, 23 deletions
diff --git a/camel/providers/nntp/Makefile.am b/camel/providers/nntp/Makefile.am
index 6e304d8412..7feccd8bda 100644
--- a/camel/providers/nntp/Makefile.am
+++ b/camel/providers/nntp/Makefile.am
@@ -20,6 +20,7 @@ INCLUDES = -I../.. \
libcamelnntp_la_SOURCES = \
camel-nntp-auth.c \
camel-nntp-folder.c \
+ camel-nntp-grouplist.c \
camel-nntp-newsrc.c \
camel-nntp-provider.c \
camel-nntp-store.c \
@@ -29,6 +30,7 @@ libcamelnntpinclude_HEADERS = \
camel-nntp-auth.h \
camel-nntp-resp-codes.h \
camel-nntp-folder.h \
+ camel-nntp-grouplist.h \
camel-nntp-newsrc.h \
camel-nntp-store.h \
camel-nntp-utils.h
diff --git a/camel/providers/nntp/camel-nntp-newsrc.c b/camel/providers/nntp/camel-nntp-newsrc.c
index a44e42c910..5c92074000 100644
--- a/camel/providers/nntp/camel-nntp-newsrc.c
+++ b/camel/providers/nntp/camel-nntp-newsrc.c
@@ -45,12 +45,11 @@ typedef struct {
struct CamelNNTPNewsrc {
gchar *filename;
GHashTable *groups;
- GHashTable *subscribed_groups;
gboolean dirty;
} ;
static NewsrcGroup *
-camel_nntp_newsrc_group_add (CamelNNTPNewsrc *newsrc, char *group_name, gboolean subscribed)
+camel_nntp_newsrc_group_add (CamelNNTPNewsrc *newsrc, const char *group_name, gboolean subscribed)
{
NewsrcGroup *new_group = g_malloc(sizeof(NewsrcGroup));
@@ -59,8 +58,6 @@ camel_nntp_newsrc_group_add (CamelNNTPNewsrc *newsrc, char *group_name, gboolean
new_group->ranges = g_array_new (FALSE, FALSE, sizeof (ArticleRange));
g_hash_table_insert (newsrc->groups, new_group->name, new_group);
- if (subscribed)
- g_hash_table_insert (newsrc->subscribed_groups, new_group->name, new_group);
newsrc->dirty = TRUE;
@@ -162,7 +159,7 @@ camel_nntp_newsrc_group_mark_range_read(CamelNNTPNewsrc *newsrc, NewsrcGroup *gr
}
int
-camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, char *group_name)
+camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, const char *group_name)
{
NewsrcGroup *group;
@@ -172,13 +169,13 @@ camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, char *group
}
void
-camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc, char *group_name, int num)
+camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc, const char *group_name, int num)
{
camel_nntp_newsrc_mark_range_read (newsrc, group_name, num, num);
}
void
-camel_nntp_newsrc_mark_range_read(CamelNNTPNewsrc *newsrc, char *group_name, long low, long high)
+camel_nntp_newsrc_mark_range_read(CamelNNTPNewsrc *newsrc, const char *group_name, long low, long high)
{
NewsrcGroup *group;
@@ -197,7 +194,7 @@ camel_nntp_newsrc_mark_range_read(CamelNNTPNewsrc *newsrc, char *group_name, lon
}
gboolean
-camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc, char *group_name, long num)
+camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc, const char *group_name, long num)
{
int i;
NewsrcGroup *group;
@@ -214,6 +211,49 @@ camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc, char *group_name, lo
return FALSE;
}
+gboolean
+camel_nntp_newsrc_group_is_subscribed (CamelNNTPNewsrc *newsrc, const char *group_name)
+{
+ NewsrcGroup *group = g_hash_table_lookup (newsrc->groups, group_name);
+
+ if (group) {
+ return group->subscribed;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+void
+camel_nntp_newsrc_subscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name)
+{
+ NewsrcGroup *group = g_hash_table_lookup (newsrc->groups, group_name);
+
+ if (group) {
+ if (!group->subscribed)
+ newsrc->dirty = TRUE;
+ group->subscribed = TRUE;
+ }
+ else {
+ camel_nntp_newsrc_group_add (newsrc, group_name, TRUE);
+ }
+}
+
+void
+camel_nntp_newsrc_unsubscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name)
+{
+ NewsrcGroup *group = g_hash_table_lookup (newsrc->groups, group_name);
+
+ if (group) {
+ if (group->subscribed)
+ newsrc->dirty = TRUE;
+ group->subscribed = FALSE;
+ }
+ else {
+ camel_nntp_newsrc_group_add (newsrc, group_name, FALSE);
+ }
+}
+
struct newsrc_ptr_array {
GPtrArray *ptr_array;
gboolean subscribed_only;
@@ -237,7 +277,7 @@ camel_nntp_newsrc_get_subscribed_group_names (CamelNNTPNewsrc *newsrc)
npa.ptr_array = g_ptr_array_new();
npa.subscribed_only = TRUE;
- g_hash_table_foreach (newsrc->subscribed_groups,
+ g_hash_table_foreach (newsrc->groups,
(GHFunc)get_group_foreach, &npa);
return npa.ptr_array;
@@ -451,7 +491,6 @@ camel_nntp_newsrc_read_for_server (const char *server)
newsrc = g_new0(CamelNNTPNewsrc, 1);
newsrc->filename = filename;
newsrc->groups = g_hash_table_new (g_str_hash, g_str_equal);
- newsrc->subscribed_groups = g_hash_table_new (g_str_hash, g_str_equal);
if ((fp = fopen(filename, "r")) == NULL) {
g_warning ("~/.newsrc-%s not present.\n", server);
diff --git a/camel/providers/nntp/camel-nntp-newsrc.h b/camel/providers/nntp/camel-nntp-newsrc.h
index 47539a6f80..6a202f8a01 100644
--- a/camel/providers/nntp/camel-nntp-newsrc.h
+++ b/camel/providers/nntp/camel-nntp-newsrc.h
@@ -7,14 +7,18 @@
typedef struct CamelNNTPNewsrc CamelNNTPNewsrc;
-int camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, char *group_name);
+int camel_nntp_newsrc_get_highest_article_read (CamelNNTPNewsrc *newsrc, const char *group_name);
void camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc,
- char *group_name, int num);
+ const char *group_name, int num);
void camel_nntp_newsrc_mark_range_read (CamelNNTPNewsrc *newsrc,
- char *group_name, long low, long high);
+ const char *group_name, long low, long high);
gboolean camel_nntp_newsrc_article_is_read (CamelNNTPNewsrc *newsrc,
- char *group_name, long num);
+ const char *group_name, long num);
+
+gboolean camel_nntp_newsrc_group_is_subscribed (CamelNNTPNewsrc *newsrc, const char *group_name);
+void camel_nntp_newsrc_subscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name);
+void camel_nntp_newsrc_unsubscribe_group (CamelNNTPNewsrc *newsrc, const char *group_name);
GPtrArray *camel_nntp_newsrc_get_subscribed_group_names (CamelNNTPNewsrc *newsrc);
GPtrArray *camel_nntp_newsrc_get_all_group_names (CamelNNTPNewsrc *newsrc);
diff --git a/camel/providers/nntp/camel-nntp-provider.c b/camel/providers/nntp/camel-nntp-provider.c
index f8e8916865..7041c81c31 100644
--- a/camel/providers/nntp/camel-nntp-provider.c
+++ b/camel/providers/nntp/camel-nntp-provider.c
@@ -28,6 +28,11 @@
#include "camel-provider.h"
#include "camel-session.h"
+static void add_hash (guint *hash, char *s);
+static guint nntp_url_hash (gconstpointer key);
+static gint check_equal (char *s1, char *s2);
+static gint nntp_url_equal (gconstpointer a, gconstpointer b);
+
static CamelProvider news_provider = {
"nntp",
"USENET news",
@@ -50,10 +55,53 @@ camel_provider_module_init (CamelSession *session)
news_provider.object_types[CAMEL_PROVIDER_STORE] =
camel_nntp_store_get_type();
- news_provider.service_cache = g_hash_table_new (camel_url_hash, camel_url_equal);
+ news_provider.service_cache = g_hash_table_new (nntp_url_hash, nntp_url_equal);
camel_session_register_provider (session, &news_provider);
}
+static void
+add_hash (guint *hash, char *s)
+{
+ if (s)
+ *hash ^= g_str_hash(s);
+}
+
+static guint
+nntp_url_hash (gconstpointer key)
+{
+ const CamelURL *u = (CamelURL *)key;
+ guint hash = 0;
+
+ add_hash (&hash, u->user);
+ add_hash (&hash, u->host);
+ hash ^= u->port;
+
+ return hash;
+}
+
+static gint
+check_equal (char *s1, char *s2)
+{
+ if (s1 == NULL) {
+ if (s2 == NULL)
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ if (s2 == NULL)
+ return FALSE;
+ return strcmp (s1, s2) == 0;
+}
+static gint
+nntp_url_equal (gconstpointer a, gconstpointer b)
+{
+ const CamelURL *u1 = a, *u2 = b;
+
+ return check_equal (u1->user, u2->user)
+ && check_equal (u1->host, u2->host)
+ && u1->port == u2->port;
+}
diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c
index 52ed2d4966..7f0f09ec27 100644
--- a/camel/providers/nntp/camel-nntp-store.c
+++ b/camel/providers/nntp/camel-nntp-store.c
@@ -38,6 +38,7 @@
#include "camel-nntp-resp-codes.h"
#include "camel-folder-summary.h"
#include "camel-nntp-store.h"
+#include "camel-nntp-grouplist.h"
#include "camel-nntp-folder.h"
#include "camel-nntp-auth.h"
#include "camel-exception.h"
@@ -336,8 +337,39 @@ nntp_store_get_folder (CamelStore *store, const gchar *folder_name,
}
static CamelFolderInfo *
+build_folder_info_from_grouplist (CamelNNTPStore *nntp_store)
+{
+ CamelURL *url = CAMEL_SERVICE (nntp_store)->url;
+ CamelFolderInfo *groups = NULL, *last = NULL, *fi;
+ GList *g;
+
+ for (g = nntp_store->group_list->group_list; g; g = g_list_next (g)) {
+ CamelNNTPGroupListEntry *entry = g->data;
+
+ fi = g_new0 (CamelFolderInfo, 1);
+ fi->name = g_strdup (entry->group_name);
+ fi->full_name = g_strdup (entry->group_name);
+ fi->url = g_strdup_printf ("nntp://%s%s%s/%s",
+ url->user ? url->user : "",
+ url->user ? "@" : "",
+ url->host, (char *)entry->group_name);
+ /* FIXME */
+ fi->message_count = fi->unread_message_count = -1;
+
+ if (last)
+ last->sibling = fi;
+ else
+ groups = fi;
+ last = fi;
+ }
+
+ return groups;
+}
+
+static CamelFolderInfo *
nntp_store_get_folder_info (CamelStore *store, const char *top,
gboolean fast, gboolean recursive,
+ gboolean subscribed_only,
CamelException *ex)
{
CamelURL *url = CAMEL_SERVICE (store)->url;
@@ -359,6 +391,19 @@ nntp_store_get_folder_info (CamelStore *store, const char *top,
return NULL;
}
+ if (top == NULL && !subscribed_only) {
+ if (!nntp_store->group_list)
+ nntp_store->group_list = camel_nntp_grouplist_fetch (nntp_store, ex);
+ if (camel_exception_is_set (ex)) {
+ return NULL;
+ }
+ else {
+ fi = build_folder_info_from_grouplist (nntp_store);
+ return fi;
+ }
+
+ }
+
if (top == NULL) {
/* return the list of groups */
names = camel_nntp_newsrc_get_subscribed_group_names (nntp_store->newsrc);
@@ -403,6 +448,32 @@ nntp_store_get_root_folder_name (CamelStore *store, CamelException *ex)
return g_strdup ("");
}
+static gboolean
+nntp_store_folder_subscribed (CamelStore *store, const char *folder_name)
+{
+ CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
+
+ return camel_nntp_newsrc_group_is_subscribed (nntp_store->newsrc, folder_name);
+}
+
+static void
+nntp_store_subscribe_folder (CamelStore *store, const char *folder_name,
+ CamelException *ex)
+{
+ CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
+
+ camel_nntp_newsrc_subscribe_group (nntp_store->newsrc, folder_name);
+}
+
+static void
+nntp_store_unsubscribe_folder (CamelStore *store, const char *folder_name,
+ CamelException *ex)
+{
+ CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store);
+
+ camel_nntp_newsrc_unsubscribe_group (nntp_store->newsrc, folder_name);
+}
+
static void
finalize (CamelObject *object)
{
@@ -437,6 +508,10 @@ camel_nntp_store_class_init (CamelNNTPStoreClass *camel_nntp_store_class)
camel_store_class->get_root_folder_name = nntp_store_get_root_folder_name;
camel_store_class->get_folder_info = nntp_store_get_folder_info;
camel_store_class->free_folder_info = camel_store_free_folder_info_full;
+
+ camel_store_class->folder_subscribed = nntp_store_folder_subscribed;
+ camel_store_class->subscribe_folder = nntp_store_subscribe_folder;
+ camel_store_class->unsubscribe_folder = nntp_store_unsubscribe_folder;
}
@@ -446,12 +521,15 @@ camel_nntp_store_init (gpointer object, gpointer klass)
{
CamelService *service = CAMEL_SERVICE (object);
CamelRemoteStore *remote_store = CAMEL_REMOTE_STORE (object);
+ CamelStore *store = CAMEL_STORE (object);
service->url_flags = (CAMEL_SERVICE_URL_NEED_HOST
| CAMEL_SERVICE_URL_ALLOW_USER
| CAMEL_SERVICE_URL_ALLOW_PASSWORD
| CAMEL_SERVICE_URL_ALLOW_AUTH);
remote_store->default_port = NNTP_PORT;
+
+ store->flags = CAMEL_STORE_SUBSCRIPTIONS;
}
CamelType
diff --git a/camel/providers/nntp/camel-nntp-store.h b/camel/providers/nntp/camel-nntp-store.h
index 0d30a38097..0566967fd7 100644
--- a/camel/providers/nntp/camel-nntp-store.h
+++ b/camel/providers/nntp/camel-nntp-store.h
@@ -33,6 +33,7 @@ extern "C" {
#include "camel-remote-store.h"
#include "camel-nntp-newsrc.h"
+#include "camel-nntp-types.h"
#define CAMEL_NNTP_STORE_TYPE (camel_nntp_store_get_type ())
#define CAMEL_NNTP_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_NNTP_STORE_TYPE, CamelNNTPStore))
@@ -51,13 +52,13 @@ enum {
CAMEL_NNTP_OVER_LAST
};
-typedef struct {
+struct CamelNNTPOverField {
int index;
gboolean full; /* full in the OVER sense - the field name
precedes the ':' in the XOVER list. */
-} CamelNNTPOverField;
+};
-typedef struct {
+struct CamelNNTPStore {
CamelRemoteStore parent_object;
#define CAMEL_NNTP_EXT_SEARCH (1<<0)
@@ -76,15 +77,14 @@ typedef struct {
CamelNNTPOverField overview_field[ CAMEL_NNTP_OVER_LAST ];
CamelNNTPNewsrc *newsrc;
+ CamelNNTPGroupList *group_list;
-} CamelNNTPStore;
-
-
+};
-typedef struct {
+struct CamelNNTPStoreClass {
CamelRemoteStoreClass parent_class;
-} CamelNNTPStoreClass;
+};
/* public methods */