-
Notifications
You must be signed in to change notification settings - Fork 0
/
mailmurder.lisp
53 lines (44 loc) · 1.93 KB
/
mailmurder.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
;;;; mailmurder.lisp
(in-package #:mailmurder)
(defclass mail ()
((subject :accessor mail-subject
:initarg :subject
:initform "")
(to :accessor mail-to
:initarg :to
:initform (error "At least one recipient needed."))
(attachment :accessor mail-attachment
:initarg :attachment
:initform nil)
(body :accessor mail-body
:initarg :body
:initform (error "Mail body is needed."))))
(defun make-mail (subject recipients body &optional attachment)
(make-instance 'mail :subject subject :body body :to recipients :attachment attachment))
;;; Sending
(defclass mail-sender () ())
(defgeneric send-mail-with-sender (mail sender))
(defvar *mutt-file-counter* 0)
(defparameter *print-commands* nil)
(defclass mutt-mail-sender (mail-sender) ())
(defmethod send-mail-with-sender ((mail mail) (sender mutt-mail-sender))
(let ((mail-body-filepath (format nil "/tmp/mm-mutt-~D" (incf *mutt-file-counter*))))
(with-open-file (body-stream mail-body-filepath
:direction :output :if-does-not-exist :create)
(write-string (mail-body mail) body-stream))
(let* ((subject (format nil "-s \"~A\"" (mail-subject mail)))
(to (with-output-to-string (to-stream)
(dolist (recipient (mail-to mail))
(format to-stream "\"~A\" " recipient))))
(attachment (if (mail-attachment mail)
(format nil "-a \"~A\"" (mail-attachment mail))
""))
(command (format nil "mutt ~A ~A -- ~A < ~A"
subject attachment to mail-body-filepath)))
(when *print-commands*
(write-string command))
(uiop:run-program command))
(delete-file mail-body-filepath)))
(defvar *default-sender* (make-instance 'mutt-mail-sender))
(defun send-mail (mail)
(send-mail-with-sender mail *default-sender*))