diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2009-09-14 05:27:03 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2009-09-14 05:27:03 +0000 |
commit | a94ab16492fbcd9c4b568a237bd21df8aed78763 (patch) | |
tree | 5754ccb1f4239963572ccb449842d8dc610a444c /libsylph | |
parent | 5ca8acc55bfcd804401e885f863f0f88ddfacdcb (diff) |
update summary caches on receiving.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@2247 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'libsylph')
-rw-r--r-- | libsylph/filter.c | 13 | ||||
-rw-r--r-- | libsylph/folder.c | 33 | ||||
-rw-r--r-- | libsylph/folder.h | 19 | ||||
-rw-r--r-- | libsylph/imap.c | 44 | ||||
-rw-r--r-- | libsylph/mh.c | 126 | ||||
-rw-r--r-- | libsylph/news.c | 4 | ||||
-rw-r--r-- | libsylph/procmsg.c | 183 | ||||
-rw-r--r-- | libsylph/procmsg.h | 11 | ||||
-rw-r--r-- | libsylph/virtual.c | 4 |
9 files changed, 419 insertions, 18 deletions
diff --git a/libsylph/filter.c b/libsylph/filter.c index fb2cd1ea..9ea834ff 100644 --- a/libsylph/filter.c +++ b/libsylph/filter.c @@ -1,6 +1,6 @@ /* * LibSylph -- E-Mail client library - * Copyright (C) 1999-2007 Hiroyuki Yamamoto + * Copyright (C) 1999-2009 Hiroyuki Yamamoto * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -244,12 +244,17 @@ gint filter_action_exec(FilterRule *rule, MsgInfo *msginfo, const gchar *file, fltinfo->actions[action->type] = TRUE; } } else { - if (folder_item_add_msg(dest_folder, file, - &fltinfo->flags, - FALSE) < 0) { + MsgFlags save_flags; + + save_flags = msginfo->flags; + msginfo->flags = fltinfo->flags; + if (folder_item_add_msg_msginfo + (dest_folder, msginfo, FALSE) < 0) { + msginfo->flags = save_flags; fltinfo->error = FLT_ERROR_ERROR; return -1; } + msginfo->flags = save_flags; fltinfo->actions[action->type] = TRUE; } diff --git a/libsylph/folder.c b/libsylph/folder.c index 0f6d054c..10562362 100644 --- a/libsylph/folder.c +++ b/libsylph/folder.c @@ -1,6 +1,6 @@ /* * LibSylph -- E-Mail client library - * Copyright (C) 1999-2007 Hiroyuki Yamamoto + * Copyright (C) 1999-2009 Hiroyuki Yamamoto * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1143,6 +1143,37 @@ gint folder_item_add_msgs(FolderItem *dest, GSList *file_list, first); } +gint folder_item_add_msg_msginfo(FolderItem *dest, MsgInfo *msginfo, + gboolean remove_source) +{ + Folder *folder; + + g_return_val_if_fail(dest != NULL, -1); + g_return_val_if_fail(msginfo != NULL, -1); + g_return_val_if_fail(msginfo->file_path != NULL, -1); + g_return_val_if_fail(dest->folder->klass->add_msg_msginfo != NULL, -1); + + folder = dest->folder; + + return folder->klass->add_msg_msginfo(folder, dest, msginfo, + remove_source); +} + +gint folder_item_add_msgs_msginfo(FolderItem *dest, GSList *msglist, + gboolean remove_source, gint *first) +{ + Folder *folder; + + g_return_val_if_fail(dest != NULL, -1); + g_return_val_if_fail(msglist != NULL, -1); + g_return_val_if_fail(dest->folder->klass->add_msgs_msginfo != NULL, -1); + + folder = dest->folder; + + return folder->klass->add_msgs_msginfo(folder, dest, msglist, + remove_source, first); +} + gint folder_item_move_msg(FolderItem *dest, MsgInfo *msginfo) { Folder *folder; diff --git a/libsylph/folder.h b/libsylph/folder.h index db9c3bf9..d8bfc8b4 100644 --- a/libsylph/folder.h +++ b/libsylph/folder.h @@ -1,6 +1,6 @@ /* * LibSylph -- E-Mail client library - * Copyright (C) 1999-2007 Hiroyuki Yamamoto + * Copyright (C) 1999-2009 Hiroyuki Yamamoto * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -179,6 +179,15 @@ struct _FolderClass GSList *file_list, gboolean remove_source, gint *first); + gint (*add_msg_msginfo) (Folder *folder, + FolderItem *dest, + MsgInfo *msginfo, + gboolean remove_source); + gint (*add_msgs_msginfo) (Folder *folder, + FolderItem *dest, + GSList *msginfo_list, + gboolean remove_source, + gint *first); gint (*move_msg) (Folder *folder, FolderItem *dest, MsgInfo *msginfo); @@ -296,6 +305,7 @@ struct _FolderItem gboolean trim_summary_subject; gboolean trim_compose_subject; + GSList *cache_queue; GSList *mark_queue; guint last_selected; @@ -395,6 +405,13 @@ gint folder_item_add_msgs (FolderItem *dest, GSList *file_list, gboolean remove_source, gint *first); +gint folder_item_add_msg_msginfo (FolderItem *dest, + MsgInfo *msginfo, + gboolean remove_source); +gint folder_item_add_msgs_msginfo (FolderItem *dest, + GSList *msginfo_list, + gboolean remove_source, + gint *first); gint folder_item_move_msg (FolderItem *dest, MsgInfo *msginfo); gint folder_item_move_msgs (FolderItem *dest, diff --git a/libsylph/imap.c b/libsylph/imap.c index 6213f273..10f9a273 100644 --- a/libsylph/imap.c +++ b/libsylph/imap.c @@ -1,6 +1,6 @@ /* * LibSylph -- E-Mail client library - * Copyright (C) 1999-2008 Hiroyuki Yamamoto + * Copyright (C) 1999-2009 Hiroyuki Yamamoto * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -119,6 +119,15 @@ static gint imap_add_msgs (Folder *folder, GSList *file_list, gboolean remove_source, gint *first); +static gint imap_add_msg_msginfo (Folder *folder, + FolderItem *dest, + MsgInfo *msginfo, + gboolean remove_source); +static gint imap_add_msgs_msginfo (Folder *folder, + FolderItem *dest, + GSList *msglist, + gboolean remove_source, + gint *first); static gint imap_move_msg (Folder *folder, FolderItem *dest, @@ -396,6 +405,8 @@ static FolderClass imap_class = imap_get_msginfo, imap_add_msg, imap_add_msgs, + imap_add_msg_msginfo, + imap_add_msgs_msginfo, imap_move_msg, imap_move_msgs, imap_copy_msg, @@ -1337,6 +1348,37 @@ static gint imap_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list, return last_uid; } +static gint imap_add_msg_msginfo(Folder *folder, FolderItem *dest, + MsgInfo *msginfo, gboolean remove_source) +{ + GSList msglist; + + g_return_val_if_fail(msginfo != NULL, -1); + + msglist.data = msginfo; + msglist.next = NULL; + + return imap_add_msgs_msginfo(folder, dest, &msglist, remove_source, + NULL); +} + +static gint imap_add_msgs_msginfo(Folder *folder, FolderItem *dest, + GSList *msglist, gboolean remove_source, + gint *first) +{ + GSList *file_list; + gint ret; + + file_list = procmsg_get_message_file_list(msglist); + g_return_val_if_fail(file_list != NULL, -1); + + ret = imap_add_msgs(folder, dest, file_list, remove_source, first); + + procmsg_message_file_list_free(file_list); + + return ret; +} + static gint imap_do_copy_msgs(Folder *folder, FolderItem *dest, GSList *msglist, gboolean remove_source) { diff --git a/libsylph/mh.c b/libsylph/mh.c index 5852e7c8..46e4b714 100644 --- a/libsylph/mh.c +++ b/libsylph/mh.c @@ -75,6 +75,15 @@ static gint mh_add_msgs (Folder *folder, GSList *file_list, gboolean remove_source, gint *first); +static gint mh_add_msg_msginfo (Folder *folder, + FolderItem *dest, + MsgInfo *msginfo, + gboolean remove_source); +static gint mh_add_msgs_msginfo (Folder *folder, + FolderItem *dest, + GSList *msglist, + gboolean remove_source, + gint *first); static gint mh_move_msg (Folder *folder, FolderItem *dest, MsgInfo *msginfo); @@ -151,6 +160,8 @@ static FolderClass mh_class = mh_get_msginfo, mh_add_msg, mh_add_msgs, + mh_add_msg_msginfo, + mh_add_msgs_msginfo, mh_move_msg, mh_move_msgs, mh_copy_msg, @@ -517,6 +528,117 @@ static gint mh_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list, return dest->last_num; } + +static gint mh_add_msg_msginfo(Folder *folder, FolderItem *dest, + MsgInfo *msginfo, gboolean remove_source) +{ + GSList msglist; + + g_return_val_if_fail(msginfo != NULL, -1); + + msglist.data = msginfo; + msglist.next = NULL; + + return mh_add_msgs_msginfo(folder, dest, &msglist, remove_source, NULL); +} + +static gint mh_add_msgs_msginfo(Folder *folder, FolderItem *dest, + GSList *msglist, gboolean remove_source, + gint *first) +{ + GSList *cur; + MsgInfo *msginfo; + gchar *srcfile; + gchar *destfile; + gint first_ = 0; + FILE *fp = NULL; + + g_return_val_if_fail(dest != NULL, -1); + g_return_val_if_fail(msglist != NULL, -1); + + if (dest->last_num < 0) { + mh_scan_folder(folder, dest); + if (dest->last_num < 0) return -1; + } + + if (!dest->opened) { + if ((fp = procmsg_open_mark_file(dest, DATA_APPEND)) == NULL) + g_warning("mh_add_msgs_msginfo: can't open mark file."); + } + + for (cur = msglist; cur != NULL; cur = cur->next) { + msginfo = (MsgInfo *)cur->data; + + destfile = mh_get_new_msg_filename(dest); + if (!destfile) { + if (fp) fclose(fp); + return -1; + } + if (first_ == 0 || first_ > dest->last_num + 1) + first_ = dest->last_num + 1; + + srcfile = procmsg_get_message_file(msginfo); + if (!srcfile) { + if (fp) fclose(fp); + g_free(destfile); + return -1; + } + if (syl_link(srcfile, destfile) < 0) { + if (copy_file(srcfile, destfile, TRUE) < 0) { + g_warning("mh_add_msgs_msginfo: can't copy message %s to %s", srcfile, destfile); + g_free(srcfile); + g_free(destfile); + if (fp) fclose(fp); + return -1; + } + } + + g_signal_emit_by_name(syl_app_get(), "add-msg", dest, destfile, dest->last_num + 1); + + g_free(srcfile); + g_free(destfile); + dest->last_num++; + dest->total++; + dest->updated = TRUE; + dest->mtime = 0; + + if (MSG_IS_RECEIVED(msginfo->flags)) { + if (dest->unmarked_num == 0) + dest->new = 0; + dest->unmarked_num++; + procmsg_add_mark_queue(dest, dest->last_num, + msginfo->flags); + procmsg_add_cache_queue(dest, dest->last_num, + msginfo); + } else { + SET_DEST_MSG_FLAGS(fp, dest, dest->last_num, + msginfo->flags); + } + if (MSG_IS_NEW(msginfo->flags)) + dest->new++; + if (MSG_IS_UNREAD(msginfo->flags)) + dest->unread++; + } + + if (fp) fclose(fp); + + if (first) + *first = first_; + + if (remove_source) { + for (cur = msglist; cur != NULL; cur = cur->next) { + msginfo = (MsgInfo *)cur->data; + srcfile = procmsg_get_message_file(msginfo); + if (g_unlink(srcfile) < 0) + FILE_OP_ERROR(srcfile, "unlink"); + g_free(srcfile); + } + } + + return dest->last_num; +} + + static gint mh_do_move_msgs(Folder *folder, FolderItem *dest, GSList *msglist) { FolderItem *src; @@ -960,6 +1082,10 @@ static gint mh_scan_folder_full(Folder *folder, FolderItem *item, item->new = new; item->unread = unread; item->total = n_msg; + + if (item->cache_queue && !item->opened) { + procmsg_flush_cache_queue(item, NULL); + } } item->updated = TRUE; diff --git a/libsylph/news.c b/libsylph/news.c index a331d4b5..498d283e 100644 --- a/libsylph/news.c +++ b/libsylph/news.c @@ -1,6 +1,6 @@ /* * LibSylph -- E-Mail client library - * Copyright (C) 1999-2007 Hiroyuki Yamamoto + * Copyright (C) 1999-2009 Hiroyuki Yamamoto * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -147,6 +147,8 @@ static FolderClass news_class = NULL, NULL, NULL, + NULL, + NULL, news_close, news_scan_group, diff --git a/libsylph/procmsg.c b/libsylph/procmsg.c index 1be7d722..d22bcd9d 100644 --- a/libsylph/procmsg.c +++ b/libsylph/procmsg.c @@ -1,6 +1,6 @@ /* * LibSylph -- E-Mail client library - * Copyright (C) 1999-2007 Hiroyuki Yamamoto + * Copyright (C) 1999-2009 Hiroyuki Yamamoto * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -34,6 +34,9 @@ #include "folder.h" #include "codeconv.h" +static GSList *procmsg_read_cache_queue (FolderItem *item, + gboolean scan_file); + static void mark_sum_func (gpointer key, gpointer value, gpointer data); @@ -227,7 +230,7 @@ GSList *procmsg_read_cache(FolderItem *item, gboolean scan_file) return NULL; } - debug_print("Reading summary cache..."); + debug_print("Reading summary cache...\n"); while (fread(&num, sizeof(num), 1, fp) == 1) { msginfo = g_new0(MsgInfo, 1); @@ -282,6 +285,12 @@ GSList *procmsg_read_cache(FolderItem *item, gboolean scan_file) fclose(fp); + if (item->cache_queue) { + GSList *qlist; + qlist = procmsg_read_cache_queue(item, scan_file); + mlist = g_slist_concat(mlist, qlist); + } + debug_print("done.\n"); return mlist; @@ -290,6 +299,59 @@ GSList *procmsg_read_cache(FolderItem *item, gboolean scan_file) #undef READ_CACHE_DATA #undef READ_CACHE_DATA_INT +static GSList *procmsg_read_cache_queue(FolderItem *item, gboolean scan_file) +{ + FolderType type; + MsgInfo *msginfo; + MsgFlags default_flags; + GSList *cur; + GSList *qlist = NULL; + GSList *last = NULL; + + g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(item->folder != NULL, NULL); + + if (!item->cache_queue) + return NULL; + + debug_print("Reading cache queue...\n"); + + type = FOLDER_TYPE(item->folder); + default_flags.perm_flags = MSG_NEW|MSG_UNREAD; + default_flags.tmp_flags = 0; + + for (cur = item->cache_queue; cur != NULL; cur = cur->next) { + msginfo = (MsgInfo *)cur->data; + + debug_print("read cache queue: %s/%d\n", + item->path, msginfo->msgnum); + + MSG_SET_PERM_FLAGS(msginfo->flags, default_flags.perm_flags); + MSG_SET_TMP_FLAGS(msginfo->flags, default_flags.tmp_flags); + + if ((type == F_MH && scan_file && + folder_item_is_msg_changed(item, msginfo))) { + procmsg_msginfo_free(msginfo); + item->cache_dirty = TRUE; + } else { + msginfo->folder = item; + + if (!qlist) + last = qlist = g_slist_append(NULL, msginfo); + else { + last = g_slist_append(last, msginfo); + last = last->next; + } + } + } + + g_slist_free(item->cache_queue); + item->cache_queue = NULL; + item->cache_dirty = TRUE; + + return qlist; +} + static void mark_unset_new_func(gpointer key, gpointer value, gpointer data) { MSG_UNSET_PERM_FLAGS(*((MsgFlags *)value), MSG_NEW); @@ -535,6 +597,9 @@ void procmsg_write_cache_list(FolderItem *item, GSList *mlist) procmsg_write_cache(msginfo, fp); } + if (item->cache_queue) + procmsg_flush_cache_queue(item, fp); + fclose(fp); item->cache_dirty = FALSE; } @@ -613,12 +678,20 @@ void procmsg_write_flags_for_multiple_folders(GSList *mlist) void procmsg_flush_mark_queue(FolderItem *item, FILE *fp) { MsgInfo *flaginfo; + gboolean append = FALSE; g_return_if_fail(item != NULL); - g_return_if_fail(fp != NULL); - if (item->mark_queue) - debug_print("flushing mark_queue...\n"); + if (!item->mark_queue) + return; + + debug_print("flushing mark_queue: %s...\n", item->path); + + if (!fp) { + append = TRUE; + fp = procmsg_open_mark_file(item, DATA_APPEND); + g_return_if_fail(fp != NULL); + } while (item->mark_queue != NULL) { flaginfo = (MsgInfo *)item->mark_queue->data; @@ -626,6 +699,9 @@ void procmsg_flush_mark_queue(FolderItem *item, FILE *fp) procmsg_msginfo_free(flaginfo); item->mark_queue = g_slist_remove(item->mark_queue, flaginfo); } + + if (append) + fclose(fp); } void procmsg_add_mark_queue(FolderItem *item, gint num, MsgFlags flags) @@ -635,9 +711,100 @@ void procmsg_add_mark_queue(FolderItem *item, gint num, MsgFlags flags) queue_msginfo = g_new0(MsgInfo, 1); queue_msginfo->msgnum = num; queue_msginfo->flags = flags; - item->mark_queue = g_slist_append - (item->mark_queue, queue_msginfo); - return; + item->mark_queue = g_slist_append(item->mark_queue, queue_msginfo); +} + +void procmsg_flush_cache_queue(FolderItem *item, FILE *fp) +{ + MsgInfo *msginfo; + gboolean append = FALSE; + + g_return_if_fail(item != NULL); + + if (!item->cache_queue) + return; + + debug_print("flushing cache_queue: %s ...\n", item->path); + + if (!fp) { + append = TRUE; + fp = procmsg_open_cache_file(item, DATA_APPEND); + g_return_if_fail(fp != NULL); + } + + while (item->cache_queue != NULL) { + msginfo = (MsgInfo *)item->cache_queue->data; + debug_print("flush cache queue: %s/%d\n", item->path, msginfo->msgnum); + procmsg_write_cache(msginfo, fp); + procmsg_msginfo_free(msginfo); + item->cache_queue = g_slist_remove(item->cache_queue, msginfo); + } + + if (append) + fclose(fp); +} + +void procmsg_add_cache_queue(FolderItem *item, gint num, MsgInfo *msginfo) +{ + MsgInfo *queue_msginfo; + + g_return_if_fail(msginfo != NULL); + + queue_msginfo = procmsg_msginfo_copy(msginfo); + queue_msginfo->msgnum = num; + if (queue_msginfo->file_path) { + g_free(queue_msginfo->file_path); + queue_msginfo->file_path = NULL; + } + + debug_print("procmsg_add_cache_queue: add msg cache: %s/%d\n", + item->path, num); + item->cache_queue = g_slist_append(item->cache_queue, queue_msginfo); +} + +gboolean procmsg_flush_folder(FolderItem *item) +{ + gboolean flushed = FALSE; + gint n_new, n_unread, n_total, n_min, n_max; + + g_return_val_if_fail(item != NULL, FALSE); + g_return_val_if_fail(item->folder != NULL, FALSE); + + if (FOLDER_TYPE(item->folder) != F_MH || item->last_num < 0) { + folder_item_scan(item); + return TRUE; + } + + if (item->mark_queue && !item->opened) + flushed = TRUE; + procmsg_get_mark_sum(item, &n_new, &n_unread, &n_total, &n_min, &n_max, + 0); + item->unmarked_num = 0; + item->new = n_new; + item->unread = n_unread; + item->total = n_total; + + if (item->cache_queue && !item->opened) { + procmsg_flush_cache_queue(item, NULL); + flushed = TRUE; + } + + if (flushed) + debug_print("procmsg_flush_folder: flushed %s\n", item->path); + + return flushed; +} + +static void procmsg_flush_folder_foreach_func(gpointer key, gpointer val, + gpointer data) +{ + procmsg_flush_folder(FOLDER_ITEM(key)); +} + +void procmsg_flush_folder_foreach(GHashTable *folder_table) +{ + g_hash_table_foreach(folder_table, procmsg_flush_folder_foreach_func, + NULL); } void procmsg_add_flags(FolderItem *item, gint num, MsgFlags flags) diff --git a/libsylph/procmsg.h b/libsylph/procmsg.h index 34a63bb0..a83dde0e 100644 --- a/libsylph/procmsg.h +++ b/libsylph/procmsg.h @@ -1,6 +1,6 @@ /* * LibSylph -- E-Mail client library - * Copyright (C) 1999-2007 Hiroyuki Yamamoto + * Copyright (C) 1999-2009 Hiroyuki Yamamoto * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -252,6 +252,15 @@ void procmsg_flush_mark_queue (FolderItem *item, void procmsg_add_mark_queue (FolderItem *item, gint num, MsgFlags flags); +void procmsg_flush_cache_queue (FolderItem *item, + FILE *fp); +void procmsg_add_cache_queue (FolderItem *item, + gint num, + MsgInfo *msginfo); + +gboolean procmsg_flush_folder (FolderItem *item); +void procmsg_flush_folder_foreach (GHashTable *folder_table); + void procmsg_add_flags (FolderItem *item, gint num, MsgFlags flags); diff --git a/libsylph/virtual.c b/libsylph/virtual.c index 26f9e2be..5452d1da 100644 --- a/libsylph/virtual.c +++ b/libsylph/virtual.c @@ -1,6 +1,6 @@ /* * LibSylph -- E-Mail client library - * Copyright (C) 1999-2007 Hiroyuki Yamamoto + * Copyright (C) 1999-2009 Hiroyuki Yamamoto * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -135,6 +135,8 @@ static FolderClass virtual_class = NULL, NULL, NULL, + NULL, + NULL, virtual_close, virtual_scan_folder, |