diff options
Diffstat (limited to 'camel/providers/nntp')
-rw-r--r-- | camel/providers/nntp/Makefile.am | 2 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-newsrc.c | 59 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-newsrc.h | 12 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-provider.c | 50 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-store.c | 78 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-store.h | 16 |
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 */ |