diff options
-rw-r--r-- | camel/ChangeLog | 29 | ||||
-rw-r--r-- | camel/camel-filter-search.c | 14 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-auth.c | 5 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-folder.c | 50 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-folder.h | 1 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-grouplist.c | 10 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-newsrc.c | 6 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-store.c | 19 | ||||
-rw-r--r-- | camel/providers/nntp/camel-nntp-utils.c | 55 |
9 files changed, 156 insertions, 33 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 716ea76016..7b5a045284 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,32 @@ +2001-07-02 Sam Creasey <sammy@oh.verio.com> + + * providers/nntp/camel-nntp-folder.c: Implemented + nntp_folder_search_by_expression and + nntp_folder_search_free. Basic search functionality e.g. unread + marking now works for NNTP folders. + + * camel_filter_search.c (get_size): Added get-size sexp directive + to get the size of a message for filters. + + * providers/nntp/camel-nntp-folder.c (camel_nntp_folder_new): + Always check with the NNTP server after summary load -- this + function now always expires old summary entries and syncs with + the news server. + + * providers/nntp/camel-nntp-utils.c (camel_nntp_get_headers): + Only fetch headers for articles not already logged in + the summary file. + + * providers/nntp/camel-nntp-grouplist.c + (camel_nntp_get_grouplist_from_*): change from g_list_append() + to g_list_prepend() + g_list_reverse. Traversing 40,000 + element linked lists sucks. + + * providers/nntp/camel-nntp-store.c (camel_nntp_command): + Should the NNTP connection die with + CAMEL_EXCEPTION_SERVICE_NOT_CONNECTED, make a single retry + attempt. Timing out the NNTP link is less painful this way. + 2001-07-02 Peter Williams <peterw@ximian.com> * README (Introduction): Add comment noting that Camel actually diff --git a/camel/camel-filter-search.c b/camel/camel-filter-search.c index 5396550d8f..b4651f67fc 100644 --- a/camel/camel-filter-search.c +++ b/camel/camel-filter-search.c @@ -73,6 +73,7 @@ static ESExpResult *get_received_date (struct _ESExp *f, int argc, struct _ESExp static ESExpResult *get_current_date (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *get_score (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); static ESExpResult *get_source (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); +static ESExpResult *get_size (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms); /* builtin functions */ static struct { @@ -100,6 +101,7 @@ static struct { { "get-current-date", (ESExpFunc *) get_current_date, 0 }, { "get-score", (ESExpFunc *) get_score, 0 }, { "get-source", (ESExpFunc *) get_source, 0 }, + { "get-size", (ESExpFunc *) get_size, 0 }, }; static ESExpResult * @@ -407,6 +409,18 @@ get_source (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessag return r; } +/* remember, the size comparisons are done at Kbytes */ +static ESExpResult * +get_size (struct _ESExp *f, int argc, struct _ESExpResult **argv, FilterMessageSearch *fms) +{ + ESExpResult *r; + + r = e_sexp_result_new(f, ESEXP_RES_INT); + r->value.number = fms->info->size / 1024; + + return r; +} + gboolean camel_filter_search_match (CamelMimeMessage *message, CamelMessageInfo *info, const char *source, const char *expression, CamelException *ex) diff --git a/camel/providers/nntp/camel-nntp-auth.c b/camel/providers/nntp/camel-nntp-auth.c index d11ca83860..6eba6cc066 100644 --- a/camel/providers/nntp/camel-nntp-auth.c +++ b/camel/providers/nntp/camel-nntp-auth.c @@ -45,9 +45,8 @@ camel_nntp_auth_authenticate (CamelNNTPStore *store, CamelException *ex) prompt = g_strdup_printf (_("Please enter the NNTP password for %s@%s"), service->url->user, service->url->host); service->url->passwd = - camel_session_query_authenticator (session, - CAMEL_AUTHENTICATOR_ASK, prompt, - TRUE, service, "password", ex); + camel_session_get_password (session, prompt, + TRUE, service, "password", ex); g_free (prompt); if (!service->url->passwd) { diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c index 4d27771c2c..0f981be643 100644 --- a/camel/providers/nntp/camel-nntp-folder.c +++ b/camel/providers/nntp/camel-nntp-folder.c @@ -46,6 +46,7 @@ #include "camel-data-wrapper.h" #include "camel-mime-message.h" #include "camel-folder-summary.h" +#include "camel-folder-search.h" #include "camel-exception.h" @@ -183,8 +184,30 @@ nntp_folder_get_message (CamelFolder *folder, const gchar *uid, CamelException * static GPtrArray* nntp_folder_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex) { - g_assert (0); - return NULL; + CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder); + GPtrArray *matches, *summary; + + if(nntp_folder->search == NULL) + nntp_folder->search = camel_folder_search_new(); + + camel_folder_search_set_folder(nntp_folder->search, folder); + summary = camel_folder_get_summary(folder); + camel_folder_search_set_summary(nntp_folder->search, summary); + + matches = camel_folder_search_execute_expression(nntp_folder->search, expression, ex); + + camel_folder_free_summary(folder, summary); + + return matches; +} + +static void +nntp_folder_search_free(CamelFolder *folder, GPtrArray *result) +{ + CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder); + + camel_folder_search_free_result(nntp_folder->search, result); + } static void @@ -209,6 +232,7 @@ camel_nntp_folder_class_init (CamelNNTPFolderClass *camel_nntp_folder_class) camel_folder_class->set_message_flags = nntp_folder_set_message_flags; camel_folder_class->get_message = nntp_folder_get_message; camel_folder_class->search_by_expression = nntp_folder_search_by_expression; + camel_folder_class->search_free = nntp_folder_search_free; } CamelType @@ -238,6 +262,7 @@ camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelExcepti camel_folder_construct (folder, parent, folder_name, folder_name); folder->has_summary_capability = TRUE; + folder->has_search_capability = TRUE; root_dir_path = camel_nntp_store_get_toplevel_dir (CAMEL_NNTP_STORE(folder->parent_store)); nntp_folder->summary_file_path = g_strdup_printf ("%s/%s-ev-summary", @@ -248,18 +273,17 @@ camel_nntp_folder_new (CamelStore *parent, const char *folder_name, CamelExcepti camel_folder_summary_set_filename (folder->summary, nntp_folder->summary_file_path); - if (-1 == camel_folder_summary_load (folder->summary)) { - /* Bad or nonexistant summary file */ - camel_nntp_get_headers (CAMEL_FOLDER( folder )->parent_store, - nntp_folder, ex); - if (camel_exception_get_id (ex)) { - camel_object_unref (CAMEL_OBJECT (folder)); - return NULL; - } - - /* XXX check return value */ - camel_folder_summary_save (folder->summary); + camel_folder_summary_load (folder->summary); + + camel_nntp_get_headers (CAMEL_FOLDER( folder )->parent_store, + nntp_folder, ex); + if (camel_exception_get_id (ex)) { + camel_object_unref (CAMEL_OBJECT (folder)); + return NULL; } + /* XXX check return value */ + camel_folder_summary_save (folder->summary); + return folder; } diff --git a/camel/providers/nntp/camel-nntp-folder.h b/camel/providers/nntp/camel-nntp-folder.h index e81ab00a98..add53cd987 100644 --- a/camel/providers/nntp/camel-nntp-folder.h +++ b/camel/providers/nntp/camel-nntp-folder.h @@ -48,6 +48,7 @@ typedef struct { gchar *summary_file_path; /* contains the messages summary */ CamelFolderSummary *summary; + CamelFolderSearch *search; } CamelNNTPFolder; diff --git a/camel/providers/nntp/camel-nntp-grouplist.c b/camel/providers/nntp/camel-nntp-grouplist.c index 8969f651b3..e77a28821c 100644 --- a/camel/providers/nntp/camel-nntp-grouplist.c +++ b/camel/providers/nntp/camel-nntp-grouplist.c @@ -52,8 +52,10 @@ camel_nntp_get_grouplist_from_server (CamelNNTPStore *store, CamelException *ex) while (!done) { char *line; - if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &line, ex) < 0) + if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &line, ex) < 0) { + list->group_list = g_list_reverse(list->group_list); return list; + } if (*line == '.') { done = TRUE; @@ -68,10 +70,11 @@ camel_nntp_get_grouplist_from_server (CamelNNTPStore *store, CamelException *ex) g_strfreev (split_line); - list->group_list = g_list_append (list->group_list, entry); + list->group_list = g_list_prepend (list->group_list, entry); } } + list->group_list = g_list_reverse(list->group_list); return list; } @@ -123,11 +126,12 @@ camel_nntp_get_grouplist_from_file (CamelNNTPStore *store, CamelException *ex) g_strfreev (split_line); - list->group_list = g_list_append (list->group_list, entry); + list->group_list = g_list_prepend (list->group_list, entry); } fclose (fp); + list->group_list = g_list_reverse(list->group_list); return list; } diff --git a/camel/providers/nntp/camel-nntp-newsrc.c b/camel/providers/nntp/camel-nntp-newsrc.c index b1bc865068..37f052cc9e 100644 --- a/camel/providers/nntp/camel-nntp-newsrc.c +++ b/camel/providers/nntp/camel-nntp-newsrc.c @@ -225,9 +225,7 @@ camel_nntp_newsrc_get_num_articles_read (CamelNNTPNewsrc *newsrc, const char *gr void camel_nntp_newsrc_mark_article_read (CamelNNTPNewsrc *newsrc, const char *group_name, int num) { - NEWSRC_LOCK(newsrc, lock); camel_nntp_newsrc_mark_range_read (newsrc, group_name, num, num); - NEWSRC_UNLOCK(newsrc, lock); } void @@ -474,8 +472,10 @@ camel_nntp_newsrc_write(CamelNNTPNewsrc *newsrc) NEWSRC_LOCK(newsrc, lock); - if (!newsrc->dirty) + if (!newsrc->dirty) { + NEWSRC_UNLOCK(newsrc, lock); return; + } if ((fp = fopen(newsrc->filename, "w")) == NULL) { g_warning ("Couldn't open newsrc file '%s'.\n", newsrc->filename); diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c index e4e115cea4..d72db9b6b3 100644 --- a/camel/providers/nntp/camel-nntp-store.c +++ b/camel/providers/nntp/camel-nntp-store.c @@ -298,7 +298,7 @@ static CamelServiceAuthType password_authtype = { }; static GList * -nntp_store_query_auth_types (CamelService *service, gboolean connect, CamelException *ex) +nntp_store_query_auth_types (CamelService *service, CamelException *ex) { GList *prev; @@ -313,8 +313,6 @@ nntp_store_get_folder (CamelStore *store, const gchar *folder_name, { CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); - printf ("get_folder called on folder_name=%s\n", folder_name); - /* if we haven't already read our .newsrc, read it now */ if (!nntp_store->newsrc) nntp_store->newsrc = @@ -468,8 +466,7 @@ build_folder_info_from_grouplist (CamelNNTPStore *nntp_store, const char *top) static CamelFolderInfo * nntp_store_get_folder_info (CamelStore *store, const char *top, - gboolean fast, gboolean recursive, - gboolean subscribed_only, + guint32 flags, CamelException *ex) { CamelURL *url = CAMEL_SERVICE (store)->url; @@ -491,7 +488,7 @@ nntp_store_get_folder_info (CamelStore *store, const char *top, return NULL; } - if (!subscribed_only) { + if (!(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)) { if (!nntp_store->group_list) nntp_store->group_list = camel_nntp_grouplist_fetch (nntp_store, ex); if (camel_exception_is_set (ex)) { @@ -716,6 +713,16 @@ camel_nntp_command (CamelNNTPStore *store, CamelException *ex, char **ret, char resp_code = camel_nntp_command_send_recv (store, ex, ret, cmdbuf); + if(camel_exception_get_id(ex) == + CAMEL_EXCEPTION_SERVICE_NOT_CONNECTED) { + /* the connect might have timed out, give it another shot.. */ + camel_exception_clear(ex); + if(nntp_store_connect(CAMEL_SERVICE(store), ex)) + resp_code = + camel_nntp_command_send_recv (store, ex, ret, cmdbuf); + /* that's it, no more tries */ + } + g_free (cmdbuf); return resp_code; diff --git a/camel/providers/nntp/camel-nntp-utils.c b/camel/providers/nntp/camel-nntp-utils.c index 3bff5bfb58..ed0482a109 100644 --- a/camel/providers/nntp/camel-nntp-utils.c +++ b/camel/providers/nntp/camel-nntp-utils.c @@ -64,7 +64,7 @@ get_XOVER_headers(CamelNNTPStore *nntp_store, CamelFolder *folder, g_print ("done\n"); } else { - CamelMessageInfo *new_info = camel_folder_summary_info_new(nntp_folder->summary); + CamelMessageInfo *new_info = camel_folder_summary_info_new(folder->summary); char **split_line = g_strsplit (line, "\t", 7); char *subject, *from, *date, *message_id, *bytes; char *uid; @@ -74,7 +74,7 @@ get_XOVER_headers(CamelNNTPStore *nntp_store, CamelFolder *folder, date = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_DATE].index]; message_id = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_MESSAGE_ID].index]; bytes = split_line [nntp_store->overview_field [CAMEL_NNTP_OVER_BYTES].index]; - + /* if the overview format flagged this field as "full", skip over the preceding field name and colon */ @@ -109,7 +109,7 @@ get_XOVER_headers(CamelNNTPStore *nntp_store, CamelFolder *folder, atoi (split_line[0]))) new_info->flags |= CAMEL_MESSAGE_SEEN; - camel_folder_summary_add (nntp_folder->summary, new_info); + camel_folder_summary_add (folder->summary, new_info); g_strfreev (split_line); } g_free (line); @@ -217,6 +217,33 @@ get_HEAD_headers(CamelNNTPStore *nntp_store, CamelFolder *folder, } #endif +static inline int +uid_num (CamelFolderSummary *summary, int index) +{ + char *tmp; + char *brk; + CamelMessageInfo *minfo; + int ret; + + minfo = camel_folder_summary_index(summary, index); + if(minfo == NULL) + return 0; + + tmp = g_strdup(camel_message_info_uid(minfo)); + camel_message_info_free(minfo); + + if((brk = strchr(tmp, ',')) == NULL) + ret = 0; + else { + *brk = 0; + ret = atoi(tmp); + } + + g_free(tmp); + + return ret; +} + void camel_nntp_get_headers (CamelStore *store, CamelNNTPFolder *nntp_folder, @@ -225,15 +252,32 @@ camel_nntp_get_headers (CamelStore *store, CamelNNTPStore *nntp_store = CAMEL_NNTP_STORE (store); CamelFolder *folder = CAMEL_FOLDER (nntp_folder); char *ret; - int first_message, nb_message, last_message; + int first_message, nb_message, last_message, last_summary; int status; + int i; status = camel_nntp_command (nntp_store, ex, &ret, "GROUP %s", folder->name); - sscanf (ret, "%d %d %d", &nb_message, &first_message, &last_message); g_free (ret); + i = camel_folder_summary_count(folder->summary); + if(i != 0) { + last_summary = uid_num(folder->summary, i-1); + + if(last_summary < first_message) + camel_folder_summary_clear(folder->summary); + else { + while(uid_num(folder->summary, 0) < first_message) + camel_folder_summary_remove_index(folder->summary, 0); + + if(last_summary >= last_message) + return; + + first_message = last_summary; + } + } + if (status == NNTP_NO_SUCH_GROUP) { /* XXX throw invalid group exception */ camel_exception_setv (ex, @@ -253,4 +297,5 @@ camel_nntp_get_headers (CamelStore *store, get_HEAD_headers (nntp_store, folder, first_message, last_message, ex); #endif } + } |