aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog29
-rw-r--r--camel/camel-filter-search.c14
-rw-r--r--camel/providers/nntp/camel-nntp-auth.c5
-rw-r--r--camel/providers/nntp/camel-nntp-folder.c50
-rw-r--r--camel/providers/nntp/camel-nntp-folder.h1
-rw-r--r--camel/providers/nntp/camel-nntp-grouplist.c10
-rw-r--r--camel/providers/nntp/camel-nntp-newsrc.c6
-rw-r--r--camel/providers/nntp/camel-nntp-store.c19
-rw-r--r--camel/providers/nntp/camel-nntp-utils.c55
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
}
+
}