Re: [evolution-patches] Patch for the receipt bounty (#127534)



this one :)

On Thu, 2004-08-12 at 10:25, ERDI Gergo wrote:
> On Thu, 12 Aug 2004, Jeffrey Stedfast wrote:
> 
> >> OK, I'll use these specific accessors (I just didn't bother looking for
> >> them)
> >
> > notzed disagreed with me and had some good points, so don't worry about
> > this I guess.
> 
> Umm... which message of NotZed do you refer to here? I seem to have missed 
> it.
--- Begin Message --- On Wed, 2004-08-11 at 16:46 -0400, Jeffrey Stedfast wrote:
On Wed, 2004-08-11 at 21:39 +0200, ERDI Gergo wrote:
> So here's a new version of the patch. The receipt policy setting is still 
> per-account, since I think this is the most flexible approach, and the UI 
> guys haven't stated their opinion yet.
> Oh, and the UI for this is still not yet written, again, I'd like to get 
> the backend stuff right first.
> 

I've talked to Christine and she agrees that the settings for this
should be per-account.
Yuck.
> Index: camel/camel-folder-summary.h
> ===================================================================
> RCS file: /cvs/gnome/evolution/camel/camel-folder-summary.h,v
> retrieving revision 1.78
> diff -u -u -r1.78 camel-folder-summary.h
> --- camel/camel-folder-summary.h        21 May 2004 09:08:09 -
> 0000      1.78
> +++ camel/camel-folder-summary.h        11 Aug 2004 19:31:06 -0000
> @@ -70,6 +70,8 @@
>         CAMEL_MESSAGE_JUNK = 1<<7,
>         CAMEL_MESSAGE_SECURE = 1<<8,
>  
> +       CAMEL_MESSAGE_RECEIPT_HANDLED = 1 << 9,
> +       
>         /* following flags are for the folder, and are not really
> permanent flags */
>         CAMEL_MESSAGE_FOLDER_FLAGGED = 1<<16, /* for use by the folder
> implementation */

This could still be a user flag.  Although i guess there's no harm putting it here.

Although if this was possible to be done as an EPlugin, it wouldn't be able to do this and it would have to use a user-flag instead.

> @@ -528,6 +529,8 @@
>         xmlSetProp (src, "auto-check", account->source->auto_check ?
> "true" : "false");
>         sprintf (buf, "%d", account->source->auto_check_time);
>         xmlSetProp (src, "auto-check-timeout", buf);
> +       sprintf (buf, "%d", account->source->receipt_policy);
> +       xmlSetProp (src, "receipt-policy", buf);

Don't use an integer for an enum.  You should convert it to a representative string.
e.g. "never" "ask" "always".

> +       CamelInternetAddress *addr;
> +       CamelStream *stream;    
> +       CamelFolder *out_folder;
> +       CamelMessageInfo *info; 
> +       const char *message_id = camel_medium_get_header (CAMEL_MEDIUM
> (message), "Message-ID");
> +       const char *message_date = camel_medium_get_header
> (CAMEL_MEDIUM (message), "Date");

I'm not sure I'd use the values gotten from medium_get_header() here...

using camel_mime_message_get_message_id() might be a better way to go as
it has been canonicalised.
I disagree.  There's no need to canonicalise it.  Especially for busted clients which might make a mess of it.  Easier for us to just send exactly what we got, then we can't be blamed for messing it up.

You do have to check that it isn't null though.
along the same lines, might be better to use camel_mime_message_get_date
() and then either use camel_header_format_date() (from camel-mime-
utils.h) to format the time_t/offset to an rfc822 date, or, perhaps,
format that time_t into a more human friendly form?

not sure what the preferred date format would be... perhaps rfc822
format is fine.
Well if it isn't to be translated it should be rfc822 i guess.
> +       const char *message_subject = camel_mime_message_get_subject
> (message);
> +       const char *receipt_address = camel_medium_get_header
> (CAMEL_MEDIUM (message), "Disposition-Notification-To");
> +       char hostname[MAXHOSTNAMELEN + 1];
> +       char *self_address, *receipt_subject;
> +
> +       if (!receipt_address)
> +               return;
> +       
> +       /* Collect information for the receipt */
> +       gethostname (hostname, MAXHOSTNAMELEN);

probably should check the return code from gethostname as it may fail.

also, the hostname may not include the domain. not sure we care?
If it doesn't, its luser error.  Error shoudl be checked though and use "localhost.localdomain" if it errors or returns "".
> +       receipt_subject = g_strdup_printf ("Delivery Notification for:
> \"%s\"", message_subject);

perhaps don't quote the original subject? might look funny if the
original message's subject had quotes in it...
But it will look funny if it isn't.  I think this is fine.

Although it does seem rather long.
> +       camel_mime_message_set_subject (receipt, receipt_subject);
> +       g_free (receipt_subject);
> +       
> +       addr = camel_internet_address_new ();
> +       camel_address_decode (CAMEL_ADDRESS (addr), self_address);
> +       camel_mime_message_set_recipients (receipt,
> CAMEL_RECIPIENT_TYPE_TO, addr);
> +       camel_object_unref (addr);
> +       
> +       addr = camel_internet_address_new ();
> +       camel_address_decode (CAMEL_ADDRESS (addr), receipt_address);
> +       camel_mime_message_set_from (receipt, addr);
> +       camel_object_unref (addr);
> +
> +       camel_medium_set_header (CAMEL_MEDIUM (receipt), "Return-
> Path", "<>");

afaict, this is an illegal header.
Nup, allowed for Return-Path (rfc2822).  Its really only an SMTP header anyway.

> +
> +       /* Send the receipt */
> +       out_folder = mail_component_get_folder(NULL,
> MAIL_COMPONENT_FOLDER_OUTBOX);
> +       info = camel_message_info_new ();
> +       info->flags = CAMEL_MESSAGE_SEEN;
> +       mail_append_mail (out_folder, receipt, info, 0, 0);

Still need to set a 'done' callback, which can queue a send, and needs to free your messageinfo too.

> +       /* camel_object_unref (mail_folder); */
> +}
> +
>  /* Replying to messages... */
>  
>  static GHashTable *
> @@ -1279,8 +1385,8 @@
>         return account;
>  }
>  
> -static EAccount *
> -guess_account (CamelMimeMessage *message, CamelFolder *folder)
> +EAccount *
> +em_utils_guess_account (CamelMimeMessage *message, CamelFolder
> *folder)
>  {
>         GHashTable *account_hash = NULL;
>         EAccount *account = NULL;
> @@ -1749,7 +1855,7 @@
>  
>         g_return_if_fail(message != NULL);
>         
> -       account = guess_account (message, NULL);
> +       account = em_utils_guess_account (message, NULL);
>         flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_SEEN;
>         
>         switch (mode) {
> @@ -1806,7 +1912,7 @@
>         if (message == NULL)
>                 return;
>         
> -       account = guess_account (message, folder);
> +       account = em_utils_guess_account (message, folder);
>         flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_SEEN;
>         
>         get_reply_sender (message, &to, NULL);
> Index: mail/em-composer-utils.h
> ===================================================================
> RCS file: /cvs/gnome/evolution/mail/em-composer-utils.h,v
> retrieving revision 1.7
> diff -u -u -r1.7 em-composer-utils.h
> --- mail/em-composer-utils.h    28 Jul 2004 14:38:50 -0000      1.7
> +++ mail/em-composer-utils.h    11 Aug 2004 19:32:00 -0000
> @@ -34,6 +34,7 @@
>  struct _CamelMimeMessage;
>  struct _EMsgComposer;
>  struct _EMFormat;
> +struct _EAccount;
>  
>  void em_composer_utils_setup_callbacks (struct _EMsgComposer
> *composer, struct _CamelFolder *folder, const char *uid,
>                                         guint32 flags, guint32 set,
> struct _CamelFolder *drafts, const char *drafts_uid);
> @@ -62,6 +63,10 @@
>  
>  void em_utils_redirect_message (struct _CamelMimeMessage *message);
>  void em_utils_redirect_message_by_uid (struct _CamelFolder *folder,
> const char *uid);
> +
> +void em_utils_send_receipt (struct _CamelFolder *folder, struct
> _CamelMimeMessage *message);
> +
> +struct _EAccount * em_utils_guess_account (struct _CamelMimeMessage
> *message, struct _CamelFolder *folder);
>  
>  enum {
>         REPLY_MODE_SENDER,
> Index: mail/em-folder-view.c
> ===================================================================
> RCS file: /cvs/gnome/evolution/mail/em-folder-view.c,v
> retrieving revision 1.85
> diff -u -u -r1.85 em-folder-view.c
> --- mail/em-folder-view.c       28 Jul 2004 14:38:50 -0000      1.85
> +++ mail/em-folder-view.c       11 Aug 2004 19:32:08 -0000
> @@ -29,6 +29,9 @@
>  #include <sys/stat.h>
>  #include <unistd.h>
>  
> +#include <netdb.h>     /* define MAXHOSTNAMELEN on Solaris */
> +#include <sys/param.h> /* define MAXHOSTNAMELEN elsewhere  */
> +
>  #include <gtk/gtkvbox.h>
>  #include <gtk/gtkbutton.h>
>  #include <gtk/gtkvpaned.h>
> @@ -63,6 +66,7 @@
>  #include <bonobo/bonobo-ui-util.h>
>  
>  #include "widgets/misc/e-charset-picker.h"
> +#include "widgets/misc/e-error.h"
>  
>  #include <e-util/e-dialog-utils.h>
>  #include <e-util/e-icon-factory.h>
> @@ -120,6 +124,10 @@
>  static void emfv_on_url_cb(GObject *emitter, const char *url,
> EMFolderView *emfv);
>  static void emfv_on_url(EMFolderView *emfv, const char *uri, const
> char *nice_uri);
>  
> +static void     emfv_set_seen (EMFolderView *emfv, const char *uid);
> +static gboolean emfv_ask_receipt (EMFolderView *emfv,
> CamelMimeMessage *message);
> +static void     emfv_handle_receipt(EMFolderView *emfv, const char
> *uid);
> +
>  static const EMFolderViewEnable emfv_enable_map[];
>  
>  struct _EMFolderViewPrivate {
> @@ -381,6 +389,8 @@
>                         em_folder_view_set_folder((EMFolderView
> *)emmb, emfv->folder, emfv->folder_uri);
>                         em_folder_view_set_message((EMFolderView
> *)emmb, uids->pdata[i], FALSE);
>                         gtk_widget_show(emmb->window);
> +                       
> +                       emfv_handle_receipt (emfv, uids->pdata[i]);
>                 }
>  
>                 message_list_free_uids(emfv->list, uids);
> @@ -1933,7 +1943,7 @@
>         MessageList *list = emfv->list;
>         
>         if (mst->uid && list->cursor_uid && !strcmp (mst->uid, list-
> >cursor_uid))
> -               camel_folder_set_message_flags (emfv->folder, mst-
> >uid, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
> +               emfv_set_seen (emfv, mst->uid);
>         
>         return FALSE;
>  }
> @@ -1949,7 +1959,7 @@
>                 emfv_enable_menus(emfv);
>                 return;
>         }
> -       
> +
>         em_format_format((EMFormat *)emfv->preview, folder, uid, msg);
>         
>         if (emfv->priv->seen_id)
> @@ -1966,7 +1976,7 @@
>                         emfv->priv->seen_id = g_timeout_add_full
> (G_PRIORITY_DEFAULT_IDLE, emfv->mark_seen_timeout,
> 
> (GSourceFunc)do_mark_seen, mst, (GDestroyNotify)mst_free);
>                 } else {
> -                       camel_folder_set_message_flags(emfv->folder,
> uid, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
> +                       emfv_set_seen (emfv, uid);
>                 }
>         }
>         
> @@ -2190,6 +2200,63 @@
>  {
>         g_object_ref(emfv);
>         mail_async_event_emit(emfv->async, MAIL_ASYNC_GUI,
> (MailAsyncFunc)emfv_gui_folder_changed, folder, NULL, emfv);
> +}
> +
> +static void
> +emfv_set_seen(EMFolderView *emfv, const char *uid)

In some cases this is called, the other calls emfv_handle_receipt.  The message-browser should handle the receipt itself, not the code which instantiates it.

this function should:
1. be the only entry point to send the receipt
2. determine if you need to send a receipt itself
3. call send_receipt.

emfv_handle_receipt and emfv_ask_receipt then aren't required at all.

> +{
> +       guint32 old_flags = camel_folder_get_message_flags(emfv-
> >folder, uid);
> +
> +       /* If we're setting the SEEN flag on a message, handle receipt
> +        * requests */
> +       if (!(old_flags & CAMEL_MESSAGE_SEEN))
> +               emfv_handle_receipt(emfv, uid);
> +       
> +       camel_folder_set_message_flags(emfv->folder, uid,
> CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
> +}
> +
> +static gboolean
> +emfv_ask_receipt(EMFolderView *emfv, CamelMimeMessage *message)
> +{

I would rather this was just part of the em_utils_send_receipt function.

Then no need to lookup the account in em-folder-view anywhere
> +       /* Check the account's receipt policy settings, and pop up a
> +        * dialog if the policy is ASK */
> +       
> +       EAccount *account = em_utils_guess_account (message, emfv-
> >folder);
> +       
> +       if (account->source->receipt_policy == E_ACCOUNT_RECEIPT_ASK)
> {
> +               GtkWidget *toplevel = gtk_widget_get_toplevel
> (GTK_WIDGET (emfv));
> +               GtkWindow *dialog_parent = (toplevel && GTK_IS_WINDOW
> (toplevel)) ? GTK_WINDOW (toplevel) : NULL;
> +               const char *receipt_address = camel_medium_get_header
> (CAMEL_MEDIUM (message), "Disposition-Notification-To");
> +               const char *subject = camel_mime_message_get_subject
> (message);
> +               
> +               return (e_error_run (dialog_parent, "mail:ask-
> receipt", receipt_address, subject) == GTK_RESPONSE_YES);
> +       }
> +       
> +       return (account->source->receipt_policy ==
> E_ACCOUNT_RECEIPT_ALWAYS);
> +}
> +       
> +static void
> +emfv_handle_receipt(EMFolderView *emfv, const char *uid)
> +{
> +       guint32 old_flags = camel_folder_get_message_flags(emfv-
> >folder, uid);
> +       CamelMimeMessage *message = camel_folder_get_message(emfv-
> >folder, uid, NULL);
> +
> +       g_return_if_fail (message);
> +
> +       if (old_flags & CAMEL_MESSAGE_RECEIPT_HANDLED)
> +               return;
> +       
> +#if 0
> +       camel_folder_set_message_flags (emfv->folder, uid,
> +                                       CAMEL_MESSAGE_RECEIPT_HANDLED,
> +                                       CAMEL_MESSAGE_RECEIPT_HANDLED);
> +#endif
> +       
> +       if (!camel_medium_get_header(CAMEL_MEDIUM (message),
> "Disposition-Notification-To"))
> +               return;
> +       
> +       if (emfv_ask_receipt (emfv, message))
> +               em_utils_send_receipt(emfv->folder, message);   
>  }
>  
>  /* keep these two tables in sync */
> Index: mail/mail-errors.xml
> ===================================================================
> RCS file: /cvs/gnome/evolution/mail/mail-errors.xml,v
> retrieving revision 1.4
> diff -u -u -r1.4 mail-errors.xml
> --- mail/mail-errors.xml        29 Jul 2004 06:47:31 -0000      1.4
> +++ mail/mail-errors.xml        11 Aug 2004 19:32:09 -0000
> @@ -315,6 +315,13 @@
>   <primary>Could not connect to {0}. Groupwise account setup is
> incomplete. You may need to setup  the account again</primary>
>  </error>
>  
> +  <error id="ask-receipt" type="question" default="GTK_RESPONSE_NO">
> +    <primary>Receipt requested</primary>
> +    <secondary>Send message receipt to {0} about message &quot;
> {1}&quot;?</secondary>
> +    <button stock="gtk-no" response="GTK_RESPONSE_NO"/>
> +    <button stock="gtk-yes" response="GTK_RESPONSE_YES"/>
> +  </error>
> +
>  </error-list>
>  
> Index: ui/ChangeLog
> ===================================================================
> RCS file: /cvs/gnome/evolution/ui/ChangeLog,v
> retrieving revision 1.398
> diff -u -u -r1.398 ChangeLog
> --- ui/ChangeLog        23 Jun 2004 03:59:03 -0000      1.398
> +++ ui/ChangeLog        11 Aug 2004 19:32:23 -0000
> @@ -1,3 +1,8 @@
> +2004-08-06  ERDI Gergo  <cactus cactus rulez org>
> +
> +       * evolution-message-composer.xml: Added new menu item for
> +       requesting message receipts when composing a new message
> +
>  2004-06-22  V Ravi Kumar Raju <vravikr yahoo co uk>
>  
>         * evolution-addressbook.xml: Remove the Menu Seperator in View
> Index: ui/evolution-message-composer.xml
> ===================================================================
> RCS file: /cvs/gnome/evolution/ui/evolution-message-composer.xml,v
> retrieving revision 1.43
> diff -u -u -r1.43 evolution-message-composer.xml
> --- ui/evolution-message-composer.xml   25 May 2004 20:54:01 -
> 0000      1.43
> +++ ui/evolution-message-composer.xml   11 Aug 2004 19:32:24 -0000
> @@ -31,6 +31,10 @@
>                 pixtype="stock" pixname="gtk-delete"
>                 _tip="Delete all but signature"/>
>  
> +               <cmd name="RequestReceipt" _label="Request Receipt"
> +                    _tip="Check to get delivery notification when
> your message is read"
> +                    type="toggle" state="0"/>
> +               
>                 <cmd name="FormatHtml" _label="HT_ML" _tip="Send the
> mail in HTML format"
>                 type="toggle" state="0"/> 
>                 
> @@ -132,6 +136,8 @@
>                         <menuitem name="FileAttach" verb=""
>                         _label="_Attachment..." pixtype="pixbuf"/>
>                         <placeholder name="Component"/>
> +                       <separator f="" name="emailcomposer"/>
> +                       <menuitem name="RequestReceipt" verb=""/>
>                  </submenu>
>                 
>                  <submenu name="Security" _label="_Security">

From rom a quick scan of the rfc, it appears you've missed bits - like
setting the Original-Message-Id, Original-Recipient, Final-Recipient,
the different disposition modes, etc (tho I will admit to not having
read the whole rfc yet).

Jeff

--
Michael Zucchi <notzed ximian com>
"born to die, live to work, it's all downhill from here"
Novell's Evolution and Free Software Developer

--- End Message ---


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]