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))))