currently, it is only possible to add attachments from the file. However, sometimes it could be useful to attach files from classpath resources which might be within JAR files.
The patch below adds support for this.
From f11da6cd47fd9ce28cca3278f908f094499741bd Mon Sep 17 00:00:00 2001
From: Modestas Vainius <modestas@vainius.eu>
Date: Sun, 1 Dec 2013 20:51:54 +0200
Subject: [PATCH] Support attachments from URLs.
This commit adds support for adding attachments from URLs. Up until now
only files (and file: URLs) were supported. Paths without protocol
string are still assumed to be files on the local file system as before.
This is mainly for adding attachments from resources which might be
within JAR files (as returned by clojure.java.io/resource).
---
src/postal/message.clj | 15 ++++++++++++---
test/postal/test/message.clj | 31 ++++++++++++++++++++++++++++++-
2 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/src/postal/message.clj b/src/postal/message.clj
index 929757f..7293222 100644
--- a/src/postal/message.clj
+++ b/src/postal/message.clj
@@ -23,10 +23,12 @@
(ns postal.message
(:use [clojure.set :only [difference]]
- [clojure.java.io :only [file]]
+ [clojure.java.io :only [as-url as-file]]
[postal.date :only [make-date]]
[postal.support :only [do-when make-props message-id user-agent]])
(:import [java.util UUID]
+ [java.net MalformedURLException]
+ [javax.activation DataHandler]
[javax.mail Session Message$RecipientType]
[javax.mail.internet MimeMessage InternetAddress
AddressException]
@@ -61,6 +63,11 @@
(into-array InternetAddress (map #(make-address % charset)
addresses))))
+(defn- make-url [x]
+ (try (as-url x)
+ (catch MalformedURLException e
+ (as-url (as-file x)))))
+
(defn message->str [msg]
(with-open [out (java.io.ByteArrayOutputStream.)]
(let [^javax.mail.Message jmsg (if (instance? MimeMessage msg)
@@ -97,8 +104,10 @@
(defn eval-bodypart [part]
(condp (fn [test type] (some #(= % type) test)) (:type part)
[:inline :attachment]
- (let [attachment-part (doto (javax.mail.internet.MimeBodyPart.)
- (.attachFile (file (:content part)))
+ (let [url (make-url (:content part))
+ attachment-part (doto (javax.mail.internet.MimeBodyPart.)
+ (.setDataHandler (DataHandler. url))
+ (.setFileName (re-find #"[^/]+$" (.getPath url)))
(.setDisposition (name (:type part))))]
(when (:content-type part)
diff --git a/test/postal/test/message.clj b/test/postal/test/message.clj
index 64784c5..ef05240 100644
--- a/test/postal/test/message.clj
+++ b/test/postal/test/message.clj
@@ -24,11 +24,13 @@
(ns postal.test.message
(:use [postal.message]
[clojure.test :only [run-tests deftest is]]
+ [clojure.java.io :as io]
[postal.date :only [make-date]])
(:import [java.util Properties UUID]
[javax.mail Session Message$RecipientType]
[javax.mail.internet MimeMessage InternetAddress
- AddressException]))
+ AddressException]
+ [java.util.zip ZipOutputStream ZipEntry]))
(deftest test-simple
(let [m (message->str
@@ -81,8 +83,35 @@
{:type :attachment
:content f2}]})]
(is (.contains m "tempfile"))
+ (is (.contains m (.getName f1)))
+ (is (.contains m "resolv.conf"))
+ (is (not (.contains m "etc")))
(.delete f1)))
+(deftest test-attachments-from-url
+ (let [jar (doto (java.io.File/createTempFile "_postal-" ".jar"))
+ _ (with-open [zip-out (ZipOutputStream. (io/output-stream jar))
+ zip-w (writer zip-out)]
+ (.putNextEntry zip-out (ZipEntry. "test-directory/test-filename.txt"))
+ (binding [*out* zip-w]
+ (println "tempfile contents")))
+ jar-url (str "jar:file:" (.getPath jar) "!/test-directory/test-filename.txt")
+ f-url "file:///etc/resolv.conf"
+ m (message->str
+ {:from "foo@bar.dom"
+ :to "baz@bar.dom"
+ :subject "Test"
+ :body [{:type :attachment
+ :content jar-url}
+ {:type :attachment
+ :content f-url}]})]
+ (is (.contains m "tempfile"))
+ (is (.contains m "test-filename.txt"))
+ (is (not (.contains m "test-directory")))
+ (is (.contains m "resolv.conf"))
+ (is (not (.contains m "etc")))
+ (.delete jar)))
+
(deftest test-attachment-with-custom-name-and-description
(let [f1 (doto (java.io.File/createTempFile "_postal-" ".txt"))
_ (doto (java.io.PrintWriter. f1)
--
1.8.5
Hello,
currently, it is only possible to add attachments from the file. However, sometimes it could be useful to attach files from classpath resources which might be within JAR files.
The patch below adds support for this.