Subject: 29.0.91; gnus-icalendar does not update timestamp when description is empty

From: Reindert-Jan Ekker <[email-masked]>
Date: Mon, 12 Jun 2023 17:48:27 +0200

I use mu4e for my email and org-mode for managing my calendar.

When I accept a calendar invitation that has *no description* using
gnus-icalendar, and later I receive an update for that invitation, the
code that updates the corresponding org element will remove the
timestamp completely.

This is quite common for invitations from e.g. thunderbird, that have
only a summary but where the description field has been left empty.

To show this in action we would need a complete mu4e and gnus-icalendar
setup, but we can recreate the effect as follows:

we have an org file in "~/test.org" containing an event exported from an
icalendar invitation:

----- contents of test.org -----
* Test
:PROPERTIES:
:ICAL_EVENT: t
:ID:       xxx-11-yyy
:ORGANIZER: Me
:LOCATION:
:PARTICIPATION_TYPE: non-participant
:REQ_PARTICIPANTS:
:OPT_PARTICIPANTS:
:RRULE:
:REPLY:    Not replied yet
:END:

  <2023-08-01 01:00-01:00>
----- end of test.org -----

We can now call the function to update this event to a new date as
follows (this works with emacs -Q):

(require 'gnus-icalendar)
(let ((ev (gnus-icalendar-event :organizer "Me" :summary "Test"
                                :start-time (encode-time '(0 0 0 1 9 2023 nil nil nil))
                                :end-time (encode-time '(0 0 0 1 9 2023 nil nil nil))
                                :uid "xxx-11-yyy"
                                :recur nil
                                :description nil)))
  (gnus-icalendar--update-org-event ev nil (list (expand-file-name "~/test.org"))))

This results in the following:

----- new contents of test.org -----
* [#C] Test ()
:PROPERTIES:
:ICAL_EVENT: t
:ID:       xxx-11-yyy
:ORGANIZER: Me
:PARTICIPATION_TYPE: non-participant
:REPLY:    Not replied yet
:END:
----- end of test.org -----

Note how the timestamp has not been updated but completely erased.

This is because in gnus-icalendar--update-org-event, the code for
updating the timestamp is inside "(when description ...)", causing it to
only be run when the description is not empty.

-----

In GNU Emacs 29.0.91 (build 1, aarch64-apple-darwin21.6.0, NS
 appkit-2113.60 Version 12.6.5 (Build 21G531)) of 2023-05-31 built on
 CodeSensei-Mac-mini.local
Windowing system distributor 'Apple', version 10.3.2299
System Description:  macOS 13.4

Configured using:
 'configure --disable-dependency-tracking --disable-silent-rules
 --enable-locallisppath=/opt/homebrew/share/emacs/site-lisp
 --infodir=/opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/info/emacs
 --prefix=/opt/homebrew/Cellar/emacs-plus@29/29.0.90 --with-xml2
 --with-gnutls --without-compress-install --without-dbus
 --without-imagemagick --with-modules --with-rsvg --with-ns
 --disable-ns-self-contained 'CFLAGS=-Os -w -pipe
 -mmacosx-version-min=12
 -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk
 -DFD_SETSIZE=10000 -DDARWIN_UNLIMITED_SELECT'
 'CPPFLAGS=-I/opt/homebrew/opt/icu4c/include
 -I/opt/homebrew/opt/[email-masked]/include -isystem/opt/homebrew/include
 -F/opt/homebrew/Frameworks
 -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk'
 'LDFLAGS=-L/opt/homebrew/opt/icu4c/lib
 -L/opt/homebrew/opt/[email-masked]/lib -L/opt/homebrew/lib
 -F/opt/homebrew/Frameworks -Wl,-headerpad_max_install_names
 -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk''

Configured features:
ACL GIF GLIB GMP GNUTLS JPEG JSON LCMS2 LIBXML2 MODULES NOTIFY KQUEUE NS
PDUMPER PNG RSVG SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER
WEBP XIM ZLIB

Important settings:
  value of $LC_ALL: en_US.UTF-8
  value of $LC_CTYPE: UTF-8
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: elisp

Minor modes in effect:
  windmove-mode: t
  csv-field-index-mode: t
  global-diff-hl-mode: t
  diff-hl-mode: t
  global-anzu-mode: t
  anzu-mode: t
  volatile-highlights-mode: t
  simple-modeline-mode: t
  winner-mode: t
  burly-tabs-mode: t
  rainbow-delimiters-mode: t
  global-flycheck-mode: t
  flycheck-mode: t
  global-company-mode: t
  company-mode: t
  marginalia-mode: t
  vertico-buffer-mode: t
  vertico-mode: t
  dimmer-mode: t
  global-hl-line-mode: t
  show-smartparens-global-mode: t
  show-smartparens-mode: t
  smartparens-strict-mode: t
  smartparens-mode: t
  global-undo-tree-mode: t
  undo-tree-mode: t
  super-save-mode: t
  recentf-mode: t
  savehist-mode: t
  save-place-mode: t
  override-global-mode: t
  magit-wip-initial-backup-mode: t
  magit-wip-before-change-mode: t
  magit-wip-after-apply-mode: t
  magit-wip-after-save-mode: t
  magit-wip-mode: t
  global-git-commit-mode: t
  magit-auto-revert-mode: t
  shell-dirtrack-mode: t
  server-mode: t
  global-auto-revert-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  buffer-read-only: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
/Users/reindert/.emacs.d/elpa/transient-20221127.2242/transient hides /opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/emacs/29.0.91/lisp/transient
~/.emacs.d/rje/custom hides /opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/emacs/29.0.91/lisp/custom
/Users/reindert/.emacs.d/elpa/use-package-20221127.2217/use-package-jump hides /opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/emacs/29.0.91/lisp/use-package/use-package-jump
/Users/reindert/.emacs.d/elpa/use-package-20221127.2217/use-package-diminish hides /opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/emacs/29.0.91/lisp/use-package/use-package-diminish
/Users/reindert/.emacs.d/elpa/use-package-20221127.2217/use-package hides /opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/emacs/29.0.91/lisp/use-package/use-package
/Users/reindert/.emacs.d/elpa/use-package-20221127.2217/use-package-delight hides /opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/emacs/29.0.91/lisp/use-package/use-package-delight
/Users/reindert/.emacs.d/elpa/use-package-20221127.2217/use-package-lint hides /opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/emacs/29.0.91/lisp/use-package/use-package-lint
/Users/reindert/.emacs.d/elpa/bind-key-20221117.1610/bind-key hides /opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/emacs/29.0.91/lisp/use-package/bind-key
/Users/reindert/.emacs.d/elpa/use-package-20221127.2217/use-package-core hides /opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/emacs/29.0.91/lisp/use-package/use-package-core
/Users/reindert/.emacs.d/elpa/use-package-20221127.2217/use-package-ensure hides /opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/emacs/29.0.91/lisp/use-package/use-package-ensure
/Users/reindert/.emacs.d/elpa/use-package-20221127.2217/use-package-bind-key hides /opt/homebrew/Cellar/emacs-plus@29/29.0.90/share/emacs/29.0.91/lisp/use-package/use-package-bind-key

Features:
(shadow so-long view emacsbug windmove cl-print debug backtrace pulse
consult-xref help-fns radix-tree hippie-exp ace-window avy csv-mode sort
oc-basic bibtex ol-w3m org-inlinetask ol-info ol-eww eww url-queue
mm-url ol-doi org-link-doi ol-docview doc-view jka-compr image-mode exif
org-ctags dired-aux vc-hg vc-git vc-bzr vc-src vc-sccs vc-svn vc-cvs
vc-rcs diff-hl-dired embark-consult consult-vertico consult compat-28
vertico-directory cursor-sensor warnings rje-ical-export rje-looks
diff-hl log-view vc-dir ewoc vc vc-dispatcher anzu etags fileloop xref
volatile-highlights whitespace simple-modeline simple-modeline-segments
simple-modeline-core rje-windows winner rje-keys rje-tab-bar burly-tabs
burly frameset move-text rje-dired dired-x rje-programming
rainbow-delimiters flycheck embark ffap hl-todo rje-project eshell
esh-cmd esh-ext esh-opt esh-proc esh-io esh-arg esh-module esh-groups
esh-util rje-vterm rje-company company-oddmuse company-keywords
company-dabbrev-code company-dabbrev company-files company-capf
company-cmake company rje-pass password-store auth-source-pass
rje-agenda mu4e-icalendar gnus-icalendar icalendar diary-lib
diary-loaddefs org-capture rje-vertico-embark marginalia orderless
vertico-buffer vertico rje-theme dimmer color rje-mail mixed-pitch
face-remap cus-edit mu4e mu4e-org mu4e-notification mu4e-main mu4e-view
gnus-art mm-uu mml2015 mm-view mml-smime smime gnutls dig gnus-sum
gnus-group gnus-undo gnus-start gnus-dbus gnus-cloud nnimap nnmail
mail-source utf7 nnoo gnus-spec gnus-int gnus-range gnus-win gnus
nnheader range mu4e-headers mu4e-compose mu4e-draft mu4e-actions
smtpmail mu4e-search mu4e-lists mu4e-bookmarks mu4e-mark mu4e-message
shr pixel-fill kinsoku url-file svg dom flow-fill hl-line mu4e-contacts
mu4e-update mu4e-folders mu4e-context mu4e-query-items mu4e-server
mu4e-modeline mu4e-vars mu4e-helpers mu4e-config mu4e-window ido
mu4e-obsolete f f-shortdoc shortdoc rje-edit zop-to-char sudo-edit
smartparens-config smartparens-org smartparens-text smartparens-python
smartparens advice thingatpt rje-org-sync rje-notify s notifications
dbus xml rje-org imenu-list hideshow ox-odt rng-loc rng-uri rng-parse
rng-match rng-dt rng-util rng-pttrn nxml-parse nxml-ns nxml-enc xmltok
nxml-util ox-latex ox-icalendar org-agenda ox-html table ox-ascii
ox-publish ox org-element org-persist xdg avl-tree generator yasnippet
org-journal org-crypt cal-iso org-tempo tempo rje-savefiles tramp
tramp-loaddefs trampver tramp-integration files-x tramp-compat
parse-time iso8601 ls-lisp nsm undo-tree queue super-save recentf
tree-widget wid-edit bookmark pp savehist org-id org-refile org
org-macro org-pcomplete org-list org-footnote org-faces org-entities
noutline outline icons ob-clojure ob-emacs-lisp ob-plantuml ob-ditaa
ob-python python project pcase treesit ob-shell ob ob-tangle org-src
ob-ref ob-lob ob-table ob-exp ob-comint ob-core ob-eval org-cycle
org-table ol org-fold org-fold-core org-keys oc org-loaddefs find-func
cal-menu calendar cal-loaddefs org-compat org-version org-macs saveplace
use-package use-package-ensure use-package-delight use-package-diminish
use-package-bind-key bind-key use-package-core rje-packages finder-inf
epl rje-vars magit-wip magit-log which-func imenu magit-diff smerge-mode
diff diff-mode easy-mmode git-commit log-edit message sendmail
yank-media puny dired dired-loaddefs rfc822 mml mml-sec epa derived epg
rfc6068 epg-config gnus-util text-property-search time-date mm-decode
mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 mm-util
ietf-drums mail-prsvr mailabbrev mail-utils gmm-utils mailheader
pcvs-util add-log magit-core magit-autorevert magit-margin
magit-transient magit-process with-editor shell pcomplete comint
ansi-osc ring server ansi-color magit-mode transient cl-extra edmacro
kmacro help-mode magit-git magit-base magit-section format-spec crm dash
compat-27 compat-26 compat compat-macs autorevert filenotify delsel
cus-load pyvenv-auto-autoloads pyvenv-autoloads org-ai-autoloads rx info
package browse-url url url-proxy url-privacy url-expand url-methods
url-history url-cookie generate-lisp-file url-domsuf url-util mailcap
url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs
password-cache json subr-x map byte-opt gv bytecomp byte-compile
url-vars cl-loaddefs cl-lib rmc iso-transl tooltip cconv eldoc paren
electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/ns-win ns-win ucs-normalize mule-util term/common-win tool-bar dnd
fontset image regexp-opt fringe tabulated-list replace newcomment
text-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow
isearch easymenu timer select scroll-bar mouse jit-lock font-lock syntax
font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
theme-loaddefs faces cus-face macroexp files window text-properties
overlay sha1 md5 base64 format env code-pages mule custom widget keymap
hashtable-print-readable backquote threads kqueue cocoa ns lcms2
multi-tty make-network-process emacs)

Memory information:
((conses 16 530456 111783)
 (symbols 48 43929 20)
 (strings 32 161589 6958)
 (string-bytes 1 5371169)
 (vectors 16 91381)
 (vector-slots 8 1399605 44059)
 (floats 8 673 442)
 (intervals 56 11004 1871)
 (buffers 984 26))

-- 
Reindert-Jan Ekker
Code Sensei