Subject: bug#49995: 28.0.50; EBDB Anniversaries do not appear marked in calendar

From: Eric Abrahamsen <[email-masked]>
Date: Tue, 17 Aug 2021 12:45:58 -0700

On 08/17/21 19:16 PM, Michael Heerdegen wrote:
> Eric Abrahamsen <[email-masked]> writes:
>
>> And, because I apparently have nothing else to do on a weekend, here's a
>> version that just calls a function directly, nothing fancy. Some overlap
>> with `diary-anniversary', but nothing terrible. This is probably the
>> best approach.
>
> Yes, looks like more or less what I had suggested.  Hope it turns out it
> was the right advice.

I'm sure it will, I just had to waste a few hours trying out alternate
approaches first :)

>> -;; `ebdb-field-anniv-diary-entry' is defined below.
>> +(defun ebdb-diary-anniversaries (&optional mark)
>> +  (with-no-warnings
>> +    (defvar date)
>> +    (defvar original-date))
>> +  (when-let ((entries (gethash (seq-subseq date 0 2) ebdb-diary-entries)))
>> +    (cons mark
>> +	  (mapconcat (pcase-lambda (`(,field ,record))
>> +		       (if (bound-and-true-p original-date)
>> +			   ;; If we have `original-date', we're
>> +			   ;; displaying the diary list, so we need
>> +			   ;; the detailed string.
>> +			   (ebdb-field-anniv-diary-entry
>> +			    field record (nth 2 date))
>> +			 ;; If not, we're just marking dates on the
>> +			 ;; calendar, so any non-nil response value is
>> +			 ;; fine.
>> +			 entry))
>> +		     entries "; "))))
>
> Do you really expect that this if-clause has a measurable effect on
> performance?  Most people will not have thousands of anniversaries in
> their database (and even then, they probably don't want to have them all
> listed).  OTOH you now need to rely on an internal aspect of the
> implementation.

Dunno, I just figured that, when marking, the function gets called ~90
times in a row, potentially over and over again as the user scrolls the
Calendar. Other diary functions come with warnings about potential
slowdowns during marking, and the user might have a large number of
these various functions, so I thought I'd just try to make this as
polite as possible. Probably I'm over-thinking it, but on the other
hand, the code's already written...

> Some more thoughts about this matter:
>
> Do have a version for the Org agenda?  I see BBDB has
> `org-bbdb-anniversaries'.  It handles the 2/29 problem btw.

Oops, I've already handled the 2/29 problem, it just didn't make it into
the diff because I hadn't committed that bit yet.

There's nothing explicit for the agenda, I guess
`ebdb-diary-anniversaries' behaves pretty much the same as
`org-bbdb-anniversaries': you can either stick it in your diary file, if
you use the diary, or in an Org file, if you don't.

> What I as a user would wish (for the Diary and Org) would be a way to
> control on a per-field basis (1) which anniversaries are listed, (2) how
> they are presented and (3) a way to allow reminders for some (I might
> need some weeks time to buy a present for some people, while I only want
> to congratulate others so I don't need a reminder for most).

Okay, thanks for these suggestions! There are many, many aspects of EBDB
where I know I could be doing more, and it's great to have some explicit
requests.

I'm thinking about how best to separate concerns. The user might want
notifications about EBDB contacts, and might be using the diary, or Org,
or maybe neither of those. EBDB fields should store basic information
like: notify or don't notify, an optional custom notification string,
and an optional number of days in advance to notify. If a field has a
number of advance days, it puts itself in the hash table twice: on its
own date, and on its advance date.

Then there's a `ebdb-use-notifications' option: if non-nil, EBDB
displays messages itself, at load time and also record display time.

Otherwise, `ebdb-diary-anniversaries' works the way it does now, for
only the diary, or in Org.

Maybe, additionally, we provide a `ebdb-export-to-org' command that
writes an Org file holding all our anniversaries as headings, with
advance notifications implemented as DEADLINE lines with a warning
period. I could use custom properties to identify headlines, so running
the command multiple times would only add headings that aren't there
already, allowing the user to edit the headlines or add more stuff after
export.

How does all of that sound?

In the meantime, I'll get this code in and a new EBDB version released.
I'm sure Pankaj has been thrilled to get dragged through this long
thread, but that's no reason to delay :)

Eric