/* * haze-connection-mail.h - MailNotification interface implementation of * HazeConnection * Copyright (C) 2010 Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include "extensions/extensions.h" #include #include #include "connection.h" #include "connection-mail.h" #include "debug.h" enum { PROP_MAIL_NOTIFICATION_FLAGS, PROP_UNREAD_MAIL_COUNT, PROP_UNREAD_MAILS, PROP_MAIL_ADDRESS, NUM_OF_PROP, }; static GPtrArray empty_array = { 0 }; static void haze_connection_mail_request_inbox_url ( TpSvcConnectionInterfaceMailNotification *iface, DBusGMethodInvocation *context) { GError e = {TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, "LibPurple does not provide Inbox URL"}; dbus_g_method_return_error (context, &e); } static void haze_connection_mail_request_mail_url ( TpSvcConnectionInterfaceMailNotification *iface, const gchar *in_id, const GValue *in_url_data, DBusGMethodInvocation *context) { GValueArray *result; if (!G_VALUE_HOLDS_STRING (in_url_data)) { GError e = {TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Wrong type for url-data"}; dbus_g_method_return_error (context, &e); return; } result = tp_value_array_build (3, G_TYPE_STRING, g_value_get_string (in_url_data), G_TYPE_UINT, TP_HTTP_METHOD_GET, TP_ARRAY_TYPE_HTTP_POST_DATA_LIST, &empty_array, G_TYPE_INVALID); tp_svc_connection_interface_mail_notification_return_from_request_inbox_url ( context, result); g_value_array_free (result); } void haze_connection_mail_init (GObject *conn) { /* nothing to do */ } void haze_connection_mail_iface_init (gpointer g_iface, gpointer iface_data) { TpSvcConnectionInterfaceMailNotificationClass *klass = g_iface; #define IMPLEMENT(x) tp_svc_connection_interface_mail_notification_implement_##x (\ klass, haze_connection_mail_##x) IMPLEMENT(request_inbox_url); IMPLEMENT(request_mail_url); #undef IMPLEMENT } static gchar *_get_email (PurpleAccount *account) { const gchar *username = purple_account_get_username (account); gchar *email; if (!g_utf8_strchr (username, -1, '@')) { /* Here we have per-protocol quark for e-mail. */ const gchar *protocol = purple_account_get_protocol_id (account); if (!tp_strdiff (protocol, "prpl-yahoo")) { email = g_strdup_printf ("%s@yahoo.com", username); } else { /* We make sure that the e-mail at least look like * one and that it is discriminated by protocol */ email = g_strdup_printf ("%s@%s", username, protocol); } } else { email = g_strdup (username); } return email; } void haze_connection_mail_properties_getter (GObject *object, GQuark interface, GQuark name, GValue *value, gpointer getter_data) { static GQuark prop_quarks[NUM_OF_PROP] = {0}; HazeConnection *conn = HAZE_CONNECTION (object); if (G_UNLIKELY (prop_quarks[0] == 0)) { prop_quarks[PROP_MAIL_NOTIFICATION_FLAGS] = g_quark_from_static_string ("MailNotificationFlags"); prop_quarks[PROP_UNREAD_MAIL_COUNT] = g_quark_from_static_string ("UnreadMailCount"); prop_quarks[PROP_UNREAD_MAILS] = g_quark_from_static_string ("UnreadMails"); prop_quarks[PROP_MAIL_ADDRESS] = g_quark_from_static_string ("MailAddress"); } DEBUG ("MailNotification get property %s", g_quark_to_string (name)); if (name == prop_quarks[PROP_MAIL_NOTIFICATION_FLAGS]) g_value_set_uint (value, TP_MAIL_NOTIFICATION_FLAG_EMITS_MAILS_RECEIVED | TP_MAIL_NOTIFICATION_FLAG_SUPPORTS_REQUEST_MAIL_URL); else if (name == prop_quarks[PROP_UNREAD_MAIL_COUNT]) g_value_set_uint (value, 0); else if (name == prop_quarks[PROP_UNREAD_MAILS]) g_value_set_boxed (value, &empty_array); else if (name == prop_quarks[PROP_MAIL_ADDRESS]) g_value_take_string (value, _get_email (conn->account)); else g_assert (!"Unknown mail notification property, please file a bug."); } static inline const gchar * _account_name (PurpleConnection *pc) { return purple_account_get_username (purple_connection_get_account (pc)); } gpointer haze_connection_mail_notify_email (PurpleConnection *pc, const char *subject, const char *from, const char *to, const char *url) { return haze_connection_mail_notify_emails (pc, 1, TRUE, &subject, &from, &to, &url); } static GPtrArray * wrap_mail_address (const char *name_str, const char *addr_str) { GPtrArray *addr_array; GType addr_type = TP_STRUCT_TYPE_MAIL_ADDRESS; GValue addr = {0}; addr_array = g_ptr_array_new (); g_value_init (&addr, addr_type); g_value_set_static_boxed (&addr, dbus_g_type_specialized_construct (addr_type)); dbus_g_type_struct_set (&addr, 0, name_str, 1, addr_str, G_MAXUINT); g_ptr_array_add (addr_array, g_value_get_boxed(&addr)); g_value_unset (&addr); return addr_array; } gpointer haze_connection_mail_notify_emails (PurpleConnection *pc, size_t count, gboolean detailed, const char **subjects, const char **froms, const char **tos, const char **urls) { GPtrArray *mails; TpSvcConnectionInterfaceMailNotification *conn = TP_SVC_CONNECTION_INTERFACE_MAIL_NOTIFICATION ( ACCOUNT_GET_TP_BASE_CONNECTION ( purple_connection_get_account (pc))); DEBUG ("[%s] %" G_GSIZE_FORMAT " new emails", _account_name (pc), count); /* FIXME: Count is broken in libpurple, until it's fixed, just ignore * messages wihout details. */ if (!detailed) return NULL; /* For consitency, ignore messages without subject, from or url */ if (subjects == NULL || froms == NULL || urls == NULL) return NULL; mails = g_ptr_array_new_with_free_func ( (GDestroyNotify)g_hash_table_destroy); for (; count; count--) { const char *from, *to, *subject, *url; from = *froms; to = *tos; subject = *subjects; url = *urls; DEBUG ("[%s] from: %s; to: %s; subject: %s; url: %s", _account_name (pc), from, to, subject, url); /* Filter out any aberations */ if (from && to && subject && url) { GType addr_list_type = TP_ARRAY_TYPE_MAIL_ADDRESS_LIST; GPtrArray *senders, *recipients; GHashTable *mail; if (g_utf8_strchr(from, -1, '@')) senders = wrap_mail_address ("", from); else senders = wrap_mail_address (from, ""); if (g_utf8_strchr(to, -1, '@')) recipients = wrap_mail_address ("", to); else recipients = wrap_mail_address (to, ""); mail = tp_asv_new ( "url-data", G_TYPE_STRING, url, "senders", addr_list_type, senders, "to-address", addr_list_type, recipients, "subject", G_TYPE_STRING, subject, NULL); g_ptr_array_add (mails, mail); g_ptr_array_unref (senders); g_ptr_array_unref (recipients); froms++; tos++; subject++; /* Some protocols only set one URL (the inbox URL), so * reuse previous URL if next one does not exist */ if (count > 1 && urls[1] != NULL) urls++; } } tp_svc_connection_interface_mail_notification_emit_mails_received ( conn, mails); g_ptr_array_unref (mails); return NULL; }