Function: diary-icalendar-save-binary-attachment
diary-icalendar-save-binary-attachment is a byte-compiled function
defined in diary-icalendar.el.gz.
Signature
(diary-icalendar-save-binary-attachment BASE64-DATA DIR &optional MIMETYPE)
Documentation
Decode and save BASE64-DATA to a new file in DIR.
The file will be named based on a unique prefix of BASE64-DATA with an
extension based on MIMETYPE. It will be saved in a subdirectory named
DIR of diary-icalendar-attachment-directory, which will be created if
necessary. Returns the (non-directory part of) the saved filename.
Source Code
;; Defined in /usr/src/emacs/lisp/calendar/diary-icalendar.el.gz
(defun di:save-binary-attachment (base64-data dir &optional mimetype)
"Decode and save BASE64-DATA to a new file in DIR.
The file will be named based on a unique prefix of BASE64-DATA with an
extension based on MIMETYPE. It will be saved in a subdirectory named
DIR of `diary-icalendar-attachment-directory', which will be created if
necessary. Returns the (non-directory part of) the saved filename."
(require 'mailcap) ; for `mailcap-mime-type-to-extension'
;; Create the subdirectory for the attachment if necessary:
(unless (and (directory-name-p di:attachment-directory)
(file-writable-p di:attachment-directory))
(di:signal-import-error
(format "Cannot write to directory: %s" di:attachment-directory)))
(make-directory (file-name-concat di:attachment-directory dir) t)
;; Create a unique filename for the attachment. Unfortunately RFC5545
;; has no mechanism for suggesting a filename, so we just use a unique
;; prefix of BASE64-DATA, or a random number as a fallback.
(let* ((nchars 4)
(max-chars (length base64-data))
(prefix (substring base64-data 0 nchars))
(extn (when mimetype
(concat "." (symbol-name
(mailcap-mime-type-to-extension mimetype)))))
(path (file-name-concat di:attachment-directory dir
(concat prefix extn))))
(while (file-exists-p path)
(cl-incf nchars)
(setq prefix (if (< nchars max-chars)
(substring base64-data 0 nchars)
(number-to-string (random max-chars))))
(setq path (file-name-concat di:attachment-directory dir
(concat prefix extn))))
;; Save the file and return its name:
(let ((data (base64-decode-string base64-data))
(coding-system-for-write 'no-conversion))
(write-region data nil path)
(file-name-nondirectory path))))