X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-tny-send-queue.c;h=42823a4d9f441efa70dac43d74f2302703fadc3d;hp=e84423528bfc409df3a129d54110a946d1a47d71;hb=8b6cff6e0692434e7fac9669b742552ece5a3f86;hpb=a31dec20c9a41110bbeb7ffb5c5b9cb04430b365 diff --git a/src/modest-tny-send-queue.c b/src/modest-tny-send-queue.c index e844235..42823a4 100644 --- a/src/modest-tny-send-queue.c +++ b/src/modest-tny-send-queue.c @@ -40,6 +40,7 @@ #include #include #include +#include #include /* strcmp */ /* 'private'/'protected' functions */ @@ -48,12 +49,28 @@ static void modest_tny_send_queue_finalize (GObject *obj); static void modest_tny_send_queue_instance_init (GTypeInstance *instance, gpointer g_class); /* Signal handlers */ -static void _on_msg_start_sending (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, int done, int total, gpointer user_data); -static void _on_msg_has_been_sent (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, int done, int total, gpointer user_data); -static void _on_msg_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, gpointer user_data); - -static TnyFolder*modest_tny_send_queue_get_outbox (TnySendQueue *self); -static TnyFolder*modest_tny_send_queue_get_sentbox (TnySendQueue *self); +static void _on_msg_start_sending (TnySendQueue *self, + TnyHeader *header, + TnyMsg *msg, + int done, + int total, + gpointer user_data); + +static void _on_msg_has_been_sent (TnySendQueue *self, + TnyHeader *header, + TnyMsg *msg, + int done, + int total, + gpointer user_data); + +static void _on_msg_error_happened (TnySendQueue *self, + TnyHeader *header, + TnyMsg *msg, + GError *err, + gpointer user_data); + +static TnyFolder* modest_tny_send_queue_get_outbox (TnySendQueue *self); +static TnyFolder* modest_tny_send_queue_get_sentbox (TnySendQueue *self); /* list my signals */ enum { @@ -94,7 +111,7 @@ static guint signals[LAST_SIGNAL] = {0}; */ static int -on_modest_tny_send_queue_compare_id(gconstpointer info, gconstpointer msg_id) +on_modest_tny_send_queue_compare_id (gconstpointer info, gconstpointer msg_id) { g_return_val_if_fail (info && ((SendInfo*)info)->msg_id && msg_id, -1); @@ -102,7 +119,7 @@ on_modest_tny_send_queue_compare_id(gconstpointer info, gconstpointer msg_id) } static void -modest_tny_send_queue_info_free(SendInfo *info) +modest_tny_send_queue_info_free (SendInfo *info) { g_free(info->msg_id); g_slice_free(SendInfo, info); @@ -113,10 +130,53 @@ modest_tny_send_queue_lookup_info (ModestTnySendQueue *self, const gchar *msg_id { ModestTnySendQueuePrivate *priv; priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); - + return g_queue_find_custom (priv->queue, msg_id, on_modest_tny_send_queue_compare_id); } + +static void +queue_item_to_string (gpointer data, gchar **user_data) +{ + SendInfo *info = (SendInfo*)data; + const gchar *status; + gchar *tmp; + + if (!(user_data && *user_data)) + return; + + switch (info->status) { + case MODEST_TNY_SEND_QUEUE_UNKNOWN: status = "UNKNOWN"; break; + case MODEST_TNY_SEND_QUEUE_WAITING: status = "WAITING"; break; + case MODEST_TNY_SEND_QUEUE_SUSPENDED: status = "SUSPENDED"; break; + case MODEST_TNY_SEND_QUEUE_SENDING: status = "SENDING"; break; + case MODEST_TNY_SEND_QUEUE_FAILED: status = "FAILED"; break; + default: status= "UNEXPECTED"; break; + } + + tmp = g_strdup_printf ("%s\"%s\" => [%s]\n", + *user_data, info->msg_id, status); + g_free (*user_data); + *user_data = tmp; +} + +gchar* +modest_tny_send_queue_to_string (ModestTnySendQueue *self) +{ + gchar *str; + ModestTnySendQueuePrivate *priv; + + g_return_val_if_fail (MODEST_IS_TNY_SEND_QUEUE(self), NULL); + priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); + + str = g_strdup_printf ("items in the send queue: %d\n", + g_queue_get_length (priv->queue)); + + g_queue_foreach (priv->queue, (GFunc)queue_item_to_string, &str); + + return str; +} + static void modest_tny_send_queue_cancel (TnySendQueue *self, gboolean remove, GError **err) { @@ -143,14 +203,17 @@ modest_tny_send_queue_cancel (TnySendQueue *self, gboolean remove, GError **err) /* Set flags to supend sending operaiton (if removed, this is not necessary) */ if (!remove) { outbox = modest_tny_send_queue_get_outbox (TNY_SEND_QUEUE(self)); + if (!outbox) { + g_warning ("%s: modest_tny_send_queue_get_outbox(..) returned NULL\n", __FUNCTION__); + goto frees; + } tny_folder_get_headers (outbox, headers, TRUE, err); if (err != NULL) goto frees; iter = tny_list_create_iterator (headers); while (!tny_iterator_is_done (iter)) { header = TNY_HEADER (tny_iterator_get_current (iter)); - if (header) { - tny_header_unset_flags (header, TNY_HEADER_FLAG_PRIORITY); - tny_header_set_flags (header, TNY_HEADER_FLAG_SUSPENDED_PRIORITY); + if (header) { + tny_header_set_flag (header, TNY_HEADER_FLAG_SUSPENDED); tny_iterator_next (iter); g_object_unref (header); } @@ -174,13 +237,14 @@ modest_tny_send_queue_cancel (TnySendQueue *self, gboolean remove, GError **err) } static void -_on_added_to_outbox (TnySendQueue *self, gboolean cancelled, TnyMsg *msg, GError *err, gpointer user_data) +_on_added_to_outbox (TnySendQueue *self, gboolean cancelled, TnyMsg *msg, GError *err, + gpointer user_data) { ModestTnySendQueuePrivate *priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE(self); TnyHeader *header = NULL; SendInfo *info = NULL; GList* existing = NULL; - const gchar* msg_id = NULL; + gchar* msg_id = NULL; g_return_if_fail (TNY_IS_SEND_QUEUE(self)); g_return_if_fail (TNY_IS_CAMEL_MSG(msg)); @@ -192,20 +256,12 @@ _on_added_to_outbox (TnySendQueue *self, gboolean cancelled, TnyMsg *msg, GError /* Put newly added message in WAITING state */ existing = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE(self), msg_id); - if(existing != NULL) - { - //g_assert(info->status == MODEST_TNY_SEND_QUEUE_SUSPENDED || - // info->status == MODEST_TNY_SEND_QUEUE_FAILED); - + if(existing != NULL) { info = existing->data; info->status = MODEST_TNY_SEND_QUEUE_WAITING; - } - else - { - + } else { info = g_slice_new (SendInfo); - - info->msg_id = strdup(msg_id); + info->msg_id = msg_id; info->status = MODEST_TNY_SEND_QUEUE_WAITING; g_queue_push_tail (priv->queue, info); } @@ -222,10 +278,10 @@ modest_tny_send_queue_add (ModestTnySendQueue *self, TnyMsg *msg, GError **err) g_return_if_fail (TNY_IS_CAMEL_MSG(msg)); tny_camel_send_queue_add_async (TNY_CAMEL_SEND_QUEUE(self), - msg, - _on_added_to_outbox, - NULL, - NULL); + msg, + _on_added_to_outbox, + NULL, + NULL); } @@ -237,7 +293,7 @@ _add_message (ModestTnySendQueue *self, TnyHeader *header) SendInfo *info = NULL; GList* existing = NULL; gchar* msg_uid = NULL; - ModestTnySendQueueStatus status = MODEST_TNY_SEND_QUEUE_WAITING; + ModestTnySendQueueStatus status = MODEST_TNY_SEND_QUEUE_UNKNOWN; gboolean editing = FALSE; g_return_if_fail (TNY_IS_SEND_QUEUE(self)); @@ -248,12 +304,10 @@ _add_message (ModestTnySendQueue *self, TnyHeader *header) msg_uid = modest_tny_send_queue_get_msg_id (header); status = modest_tny_send_queue_get_msg_status (self, msg_uid); switch (status) { - case MODEST_TNY_SEND_QUEUE_UNKNONW: + case MODEST_TNY_SEND_QUEUE_UNKNOWN: case MODEST_TNY_SEND_QUEUE_SUSPENDED: case MODEST_TNY_SEND_QUEUE_FAILED: - if (status != MODEST_TNY_SEND_QUEUE_SUSPENDED) - tny_header_unset_flags (header, TNY_HEADER_FLAG_PRIORITY); - + /* Check if it already exists on queue */ existing = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE(self), msg_uid); if(existing != NULL) @@ -439,6 +493,8 @@ modest_tny_send_queue_try_to_send (ModestTnySendQueue* self) TnyHeader *header = NULL; GError *err = NULL; + g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE(self)); + outbox = modest_tny_send_queue_get_outbox (TNY_SEND_QUEUE(self)); if (!outbox) return; @@ -486,6 +542,9 @@ gboolean modest_tny_send_queue_sending_in_progress (ModestTnySendQueue* self) { ModestTnySendQueuePrivate *priv; + + g_return_val_if_fail (MODEST_IS_TNY_SEND_QUEUE(self), FALSE); + priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); return priv->current != NULL; @@ -494,33 +553,32 @@ modest_tny_send_queue_sending_in_progress (ModestTnySendQueue* self) ModestTnySendQueueStatus modest_tny_send_queue_get_msg_status (ModestTnySendQueue *self, const gchar *msg_id) { - GList *item; - item = modest_tny_send_queue_lookup_info (self, msg_id); - if(item == NULL) return MODEST_TNY_SEND_QUEUE_UNKNONW; - return ((SendInfo*)item->data)->status; + GList *item; + + g_return_val_if_fail (MODEST_IS_TNY_SEND_QUEUE(self), MODEST_TNY_SEND_QUEUE_UNKNOWN); + g_return_val_if_fail (msg_id, MODEST_TNY_SEND_QUEUE_UNKNOWN); + + item = modest_tny_send_queue_lookup_info (self, msg_id); + if (!item) + return MODEST_TNY_SEND_QUEUE_UNKNOWN; + else + return ((SendInfo*)item->data)->status; } gchar * modest_tny_send_queue_get_msg_id (TnyHeader *header) { - const gchar *uid = NULL; gchar* msg_uid = NULL; - gchar **tmp = NULL; + const gchar *subject; + time_t date_received; + g_return_val_if_fail (header && TNY_IS_HEADER(header), NULL); + /* Get message uid */ - uid = tny_header_get_uid (header); - if (uid) - tmp = g_strsplit (uid, "__", 2); - - if (tmp) { - if (tmp[1] != NULL) - msg_uid = g_strconcat (tmp[0], "_", NULL); - else - msg_uid = g_strdup(tmp[0]); - - /* free */ - g_strfreev(tmp); - } + subject = tny_header_get_subject (header); + date_received = tny_header_get_date_received (header); + + msg_uid = g_strdup_printf ("%s %d", subject, (int) date_received); return msg_uid; } @@ -547,7 +605,8 @@ _on_msg_start_sending (TnySendQueue *self, /* Get status info */ item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id); if (!item) - g_warning ("%s: item should not be NULL", __FUNCTION__); + g_warning ("%s: item (%s) should not be NULL", + __FUNCTION__, msg_id ? msg_id : ""); else { info = item->data; info->status = MODEST_TNY_SEND_QUEUE_SENDING; @@ -570,20 +629,20 @@ _on_msg_has_been_sent (TnySendQueue *self, gpointer user_data) { ModestTnySendQueuePrivate *priv; - GList *item; gchar *msg_id = NULL; + GList *item; priv = MODEST_TNY_SEND_QUEUE_GET_PRIVATE (self); /* Get message uid */ msg_id = modest_tny_send_queue_get_msg_id (header); - + + tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN); + /* Get status info */ item = modest_tny_send_queue_lookup_info (MODEST_TNY_SEND_QUEUE (self), msg_id); - if (!item) - g_warning ("%s: item should not be NULL", __FUNCTION__); - else { - + if (item) { + /* Remove status info */ modest_tny_send_queue_info_free (item->data); g_queue_delete_link (priv->queue, item); @@ -616,7 +675,7 @@ _on_msg_error_happened (TnySendQueue *self, msg_uid); if (item == NULL) { info = g_slice_new (SendInfo); - info->msg_id = strdup(msg_uid); + info->msg_id = (msg_uid != NULL)? strdup(msg_uid) : NULL; g_queue_push_tail (priv->queue, info); } else info = item->data; @@ -624,6 +683,7 @@ _on_msg_error_happened (TnySendQueue *self, /* Keep in queue so that we remember that the opertion has failed */ /* and was not just cancelled */ info->status = MODEST_TNY_SEND_QUEUE_FAILED; + priv->current = NULL; /* Notify status has changed */ g_signal_emit (self, signals[STATUS_CHANGED], 0, info->msg_id, info->status); @@ -631,3 +691,74 @@ _on_msg_error_happened (TnySendQueue *self, /* free */ g_free(msg_uid); } + +static void +fill_list_of_caches (gpointer key, gpointer value, gpointer userdata) +{ + GSList **send_queues = (GSList **) userdata; + *send_queues = g_slist_prepend (*send_queues, value); +} + +ModestTnySendQueueStatus +modest_tny_all_send_queues_get_msg_status (TnyHeader *header) +{ + ModestCacheMgr *cache_mgr = NULL; + GHashTable *send_queue_cache = NULL; + ModestTnyAccountStore *accounts_store = NULL; + TnyList *accounts = NULL; + TnyIterator *iter = NULL; + TnyTransportAccount *account = NULL; + GSList *send_queues = NULL, *node; + /* get_msg_status returns suspended by default, so we want to detect changes */ + ModestTnySendQueueStatus status = MODEST_TNY_SEND_QUEUE_UNKNOWN; + ModestTnySendQueueStatus queue_status = MODEST_TNY_SEND_QUEUE_UNKNOWN; + gchar *msg_uid = NULL; + ModestTnySendQueue *send_queue = NULL; + + g_return_val_if_fail (TNY_IS_HEADER(header), MODEST_TNY_SEND_QUEUE_UNKNOWN); + + msg_uid = modest_tny_send_queue_get_msg_id (header); + cache_mgr = modest_runtime_get_cache_mgr (); + send_queue_cache = modest_cache_mgr_get_cache (cache_mgr, + MODEST_CACHE_MGR_CACHE_TYPE_SEND_QUEUE); + + g_hash_table_foreach (send_queue_cache, (GHFunc) fill_list_of_caches, &send_queues); + if (send_queues == NULL) { + accounts = tny_simple_list_new (); + accounts_store = modest_runtime_get_account_store (); + tny_account_store_get_accounts (TNY_ACCOUNT_STORE(accounts_store), + accounts, + TNY_ACCOUNT_STORE_TRANSPORT_ACCOUNTS); + + iter = tny_list_create_iterator (accounts); + while (!tny_iterator_is_done (iter)) { + account = TNY_TRANSPORT_ACCOUNT(tny_iterator_get_current (iter)); + send_queue = modest_runtime_get_send_queue(TNY_TRANSPORT_ACCOUNT(account)); + g_object_unref(account); + + queue_status = modest_tny_send_queue_get_msg_status (send_queue, msg_uid); + if (queue_status != MODEST_TNY_SEND_QUEUE_UNKNOWN) { + status = queue_status; + break; + } + tny_iterator_next (iter); + } + g_object_unref (iter); + g_object_unref (accounts); + } + else { + for (node = send_queues; node != NULL; node = g_slist_next (node)) { + send_queue = MODEST_TNY_SEND_QUEUE (node->data); + + queue_status = modest_tny_send_queue_get_msg_status (send_queue, msg_uid); + if (queue_status != MODEST_TNY_SEND_QUEUE_UNKNOWN) { + status = queue_status; + break; + } + } + } + + g_free(msg_uid); + g_slist_free (send_queues); + return status; +}