/* * Copyright (C) 2005 Red Hat, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. * * Authors: * Mark McLouglin */ /* * Compile with: * gcc -g -O2 -Wall $(shell pkg-config --cflags evolution-plugin-2.4) \ * -fPIC -shared -c delete-resolved-bugs.c -o libdelete-resolved-bugs.o * * Add this to delete-resolved-bugs.eplug: * * * * Delete all mails related to bugzilla bugs which have been resolved. * * * * * * * * * * * And copy the .so and the .eplug to /usr/lib/evolution/2.4/plugins */ #include #include #include #include #include enum { INVALID = 0, UNCONFIRMED, NEW, ASSIGNED, NEEDINFO, CLOSED, REOPENED, RESOLVED }; void delete_resolved_bugs (EPlugin *plugin, EMPopupTargetFolder *folder); static int get_bug_status (CamelMimeMessage *message) { const char *header; int status; header = camel_medium_get_header (CAMEL_MEDIUM (message), "X-Bugzilla-Status"); if (!header) return INVALID; status = INVALID; if (strcmp (header, " UNCONFIRMED") == 0) { status = UNCONFIRMED; } else if (strcmp (header, " NEW") == 0) { status = NEW; } else if (strcmp (header, " ASSIGNED") == 0) { status = ASSIGNED; } else if (strcmp (header, " NEEDINFO") == 0) { status = NEEDINFO; } else if (strcmp (header, " CLOSED") == 0) { status = CLOSED; } else if (strcmp (header, " REOPENED") == 0) { status = REOPENED; } else if (strcmp (header, " RESOLVED") == 0) { status = RESOLVED; } return status; } static long get_bug_id (CamelMimeMessage *message) { const char *subject; subject = camel_mime_message_get_subject (message); if (strncmp (subject, "[Bug ", 5) != 0) return 0; return strtol (subject + 5, NULL, 10); } static void free_message_uids (GPtrArray *uids) { int i; for (i = 0; i < uids->len; i++) g_free (uids->pdata[i]); g_ptr_array_free (uids, TRUE); } static GHashTable * get_bug_mails (void) { return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) free_message_uids); } static void queue_bug_mail (GHashTable *bug_mails, long bug_id, const char *uid) { GPtrArray *uids; char *bug_id_str; bug_id_str = g_strdup_printf ("%ld", bug_id); uids = g_hash_table_lookup (bug_mails, bug_id_str); if (uids == NULL) { uids = g_ptr_array_new (); g_hash_table_insert (bug_mails, bug_id_str, uids); } else { g_free (bug_id_str); } g_assert (uids != NULL); g_ptr_array_add (uids, g_strdup (uid)); } static void delete_queued_bug_mails (CamelFolder *folder, GHashTable *bug_mails, long bug_id, const char *uid) { GPtrArray *uids; char *bug_id_str; camel_folder_delete_message (folder, uid); bug_id_str = g_strdup_printf ("%ld", bug_id); uids = g_hash_table_lookup (bug_mails, bug_id_str); if (uids != NULL) { int i; for (i = 0; i < uids->len; i++) { uid = uids->pdata[i]; camel_folder_delete_message (folder, uid); } g_hash_table_remove (bug_mails, bug_id_str); } g_free (bug_id_str); } typedef struct { char *uid; CamelMimeMessage *message; time_t date; } Message; static int sort_by_date (Message **a, Message **b, CamelFolder *folder) { g_assert (a && b); return (*a)->date - (*b)->date; } static void handle_folder (char *uri, CamelFolder *folder, gpointer data) { GHashTable *bug_mails; GPtrArray *uids; Message *messages; int i; bug_mails = get_bug_mails (); camel_folder_freeze (folder); uids = camel_folder_get_uids (folder); messages = g_new0 (Message, uids->len); for (i = 0; i < uids->len; i++) { CamelException ex; messages[i].uid = uids->pdata[i]; camel_exception_init (&ex); messages[i].message = camel_folder_get_message (folder, messages[i].uid, &ex); if (camel_exception_is_set (&ex)) { g_assert (messages[i].message == NULL); g_warning ("Failed to get message %s: %s", messages[i].uid, camel_exception_get_description (&ex)); camel_exception_clear (&ex); } if (messages[i].message != NULL) { time_t date; int offset; date = camel_mime_message_get_date (messages[i].message, &offset); messages[i].date = date + (offset * 60 * 60); } uids->pdata[i] = &messages[i]; } g_ptr_array_sort_with_data (uids, (GCompareDataFunc) sort_by_date, folder); for (i = 0; i < uids->len; i++) { Message *msg = uids->pdata[i]; CamelMimeMessage *message = msg->message; const char *uid = msg->uid; long bug_id; int status; uids->pdata[i] = (char *) uid; if (message == NULL) continue; if (!(bug_id = get_bug_id (message))) { camel_object_unref (message); continue; } switch (status = get_bug_status (message)) { case INVALID: break; case UNCONFIRMED: case NEW: case ASSIGNED: case REOPENED: queue_bug_mail (bug_mails, bug_id, uid); break; case NEEDINFO: case CLOSED: case RESOLVED: delete_queued_bug_mails (folder, bug_mails, bug_id, uid); break; default: g_assert_not_reached (); break; } camel_object_unref (message); } g_free (messages); camel_folder_free_uids (folder, uids); camel_folder_thaw (folder); g_hash_table_destroy (bug_mails); } void delete_resolved_bugs (EPlugin *plugin, EMPopupTargetFolder *folder) { mail_get_folder (folder->uri, 0, handle_folder, NULL, mail_thread_new); }