Mercurial Hosting > nabble
comparison src/nabble/view/web/template/EmailNamespace.java @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children | 72765b66e2c3 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:7ecd1a4ef557 |
---|---|
1 package nabble.view.web.template; | |
2 | |
3 import fschmidt.util.java.IoUtils; | |
4 import fschmidt.util.mail.AlternativeMultipartContent; | |
5 import fschmidt.util.mail.Content; | |
6 import fschmidt.util.mail.FileAttachmentContent; | |
7 import fschmidt.util.mail.HtmlTextContent; | |
8 import fschmidt.util.mail.Mail; | |
9 import fschmidt.util.mail.MailAddress; | |
10 import fschmidt.util.mail.MailHome; | |
11 import fschmidt.util.mail.MixedMultipartContent; | |
12 import fschmidt.util.mail.PlainTextContent; | |
13 import fschmidt.util.mail.TextAttachmentContent; | |
14 import fschmidt.util.mail.TextContent; | |
15 import nabble.model.FileUpload; | |
16 import nabble.model.ModelException; | |
17 import nabble.model.ModelHome; | |
18 import nabble.model.Node; | |
19 import nabble.naml.compiler.Command; | |
20 import nabble.naml.compiler.CommandSpec; | |
21 import nabble.naml.compiler.Encoder; | |
22 import nabble.naml.compiler.IPrintWriter; | |
23 import nabble.naml.compiler.Interpreter; | |
24 import nabble.naml.compiler.Namespace; | |
25 import org.slf4j.Logger; | |
26 import org.slf4j.LoggerFactory; | |
27 | |
28 import java.io.ByteArrayInputStream; | |
29 import java.io.ByteArrayOutputStream; | |
30 import java.io.FilterInputStream; | |
31 import java.io.IOException; | |
32 import java.io.InputStream; | |
33 import java.util.ArrayList; | |
34 import java.util.Date; | |
35 import java.util.List; | |
36 import java.util.zip.ZipEntry; | |
37 import java.util.zip.ZipOutputStream; | |
38 | |
39 | |
40 @Namespace( | |
41 name = "email", | |
42 global = true, | |
43 transparent = true | |
44 ) | |
45 public final class EmailNamespace { | |
46 private static final Logger logger = LoggerFactory.getLogger(EmailNamespace.class); | |
47 | |
48 private Mail mail = MailHome.newMail(); | |
49 List<Content> attachments = new ArrayList<Content>(); | |
50 | |
51 public static final CommandSpec set_header = CommandSpec.NO_OUTPUT() | |
52 .parameters("name", "value") | |
53 .build(); | |
54 | |
55 @Command public void set_header(IPrintWriter out, Interpreter interp) { | |
56 String name = interp.getArgString("name"); | |
57 String value = interp.getArgString("value"); | |
58 mail.setHeader(name, value); | |
59 } | |
60 | |
61 public static final CommandSpec add_text_attachment = CommandSpec.DO() | |
62 .parameters("subtype", "text", "filename") | |
63 .build(); | |
64 | |
65 @Command public void add_text_attachment(IPrintWriter out, Interpreter interp) { | |
66 interp.setEncoder(Encoder.TEXT); | |
67 String subtype = interp.getArgString("subtype"); | |
68 String text = interp.getArgString("text"); | |
69 String filename = interp.getArgString("filename"); | |
70 attachments.add(new TextAttachmentContent(subtype, text, filename)); | |
71 } | |
72 | |
73 public static final CommandSpec add_node_as_zip_attachment = CommandSpec.DO() | |
74 .parameters("node_attr") | |
75 .dotParameter("node_attr") | |
76 .build(); | |
77 | |
78 @Command public void add_node_as_zip_attachment(IPrintWriter out, Interpreter interp) { | |
79 NodeNamespace nn = interp.getArgAsNamespace(NodeNamespace.class, "node_attr"); | |
80 final String filename = nn.node().getSubject() + ".zip"; | |
81 final InputStream zippedNode = buildZip(nn.node()); | |
82 FileAttachmentContent content = new FileAttachmentContent("application", "octet-stream") { | |
83 public String getFileName() { return filename; } | |
84 public int getSize() { return -1; } | |
85 public InputStream getInputStream() { return zippedNode; } | |
86 public String getContentID() { return null; } | |
87 }; | |
88 attachments.add(content); | |
89 } | |
90 | |
91 public static final CommandSpec send = new CommandSpec.Builder() | |
92 .parameters("to", "subject", "text_part") | |
93 .optionalParameters("cc", "bcc", "to_name", "from", "from_name", "html_part", "aol_part", "set_headers_for", "bounce_to", "attachments") | |
94 .build(); | |
95 | |
96 @Command public void send(IPrintWriter out, Interpreter interp) | |
97 throws ModelException.EmailFormat | |
98 { | |
99 interp.setEncoder(Encoder.TEXT); | |
100 String to = interp.getArgString("to"); | |
101 if (to == null || !new MailAddress(to).isValid()) | |
102 throw new ModelException.EmailFormat(to); | |
103 | |
104 String cc = interp.getArgString("cc"); | |
105 if (cc != null && !new MailAddress(cc).isValid()) | |
106 throw new ModelException.EmailFormat(cc); | |
107 | |
108 String bcc = interp.getArgString("bcc"); | |
109 if (bcc != null && !new MailAddress(bcc).isValid()) | |
110 throw new ModelException.EmailFormat(bcc); | |
111 | |
112 String fromName = interp.getArgString("from_name"); | |
113 String from = interp.getArgString("from"); | |
114 | |
115 MailAddress fromAddress = from == null ? | |
116 new MailAddress(ModelHome.noReply, fromName == null ? "Nabble" : fromName) : | |
117 fromName == null ? new MailAddress(from) : new MailAddress(from, fromName); | |
118 | |
119 String subject = interp.getArgString("subject"); | |
120 String text = interp.getArgString("text_part"); | |
121 String aol = interp.getArgString("aol_part"); | |
122 interp.setEncoder(Encoder.HTML); | |
123 String html = interp.getArgString("html_part"); | |
124 interp.setEncoder(Encoder.TEXT); | |
125 | |
126 String toName = interp.getArgString("to_name"); | |
127 MailAddress toAddress = toName == null ? new MailAddress(to) : new MailAddress(to, toName); | |
128 | |
129 NodeNamespace nodeNs = interp.getArgAsNamespace(NodeNamespace.class, "set_headers_for"); | |
130 if (nodeNs != null) | |
131 ModelHome.setNodeHeaders(mail, nodeNs.node()); | |
132 | |
133 mail.setFrom(fromAddress); | |
134 mail.setTo(toAddress); | |
135 if (cc != null) | |
136 mail.setCc(new MailAddress(cc)); | |
137 if (bcc != null) | |
138 mail.setBcc(new MailAddress(bcc)); | |
139 mail.setSubject(subject); | |
140 mail.setSentDate(new Date()); | |
141 | |
142 List<Content> alternatives = new ArrayList<Content>(); | |
143 alternatives.add( new PlainTextContent(text) ); | |
144 if( aol != null ) | |
145 alternatives.add( new TextContent("x-aol",aol) ); | |
146 if( html != null ) | |
147 alternatives.add( new HtmlTextContent(html) ); | |
148 | |
149 setMailContents(alternatives); | |
150 | |
151 String bounceTo = interp.getArgString("bounce_to"); | |
152 if (bounceTo == null) | |
153 ModelHome.send(mail); | |
154 else | |
155 ModelHome.send(mail, bounceTo); | |
156 } | |
157 | |
158 private void setMailContents(List<Content> alternatives) { | |
159 Content body = alternatives.size()==1 ? alternatives.get(0) | |
160 : new AlternativeMultipartContent(alternatives.toArray(new Content[alternatives.size()])); | |
161 boolean hasAttachments = attachments != null && attachments.size() > 0; | |
162 if( !hasAttachments ) { | |
163 mail.setContent(body); | |
164 } else { | |
165 List<Content> contents = new ArrayList<Content>(); | |
166 contents.add(body); | |
167 for (Content c : attachments) { | |
168 contents.add(c); | |
169 } | |
170 Content[] contentArray = contents.toArray(new Content[contents.size()]); | |
171 mail.setContent(new MixedMultipartContent(contentArray)); | |
172 } | |
173 } | |
174 | |
175 private static InputStream buildZip(final Node node) { | |
176 return new FilterInputStream(null) { | |
177 | |
178 @Override public int read(byte b[], int off, int len) throws IOException { | |
179 checkIn(); | |
180 return super.read(b,off,len); | |
181 } | |
182 | |
183 @Override public void close() throws IOException { | |
184 checkIn(); | |
185 super.close(); | |
186 } | |
187 | |
188 private void checkIn() { | |
189 if( in == null ) { | |
190 ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
191 ZipOutputStream zout = new ZipOutputStream(baos); | |
192 try { | |
193 zout.putNextEntry(new ZipEntry(node.getId() + ".txt")); | |
194 zout.write(node.getMessage().getRaw().getBytes()); | |
195 | |
196 FileUpload.FileDetails[] details = FileUpload.getFiles(node); | |
197 for (FileUpload.FileDetails d : details) { | |
198 String filename = d.getName(); | |
199 InputStream is = FileUpload.getFileContent(node, filename); | |
200 try { | |
201 byte[] contents = IoUtils.readAll(is); | |
202 zout.putNextEntry(new ZipEntry(filename)); | |
203 zout.write(contents); | |
204 } finally { | |
205 is.close(); | |
206 } | |
207 } | |
208 zout.close(); | |
209 } catch (IOException e) { | |
210 throw new RuntimeException(e); | |
211 } | |
212 in = new ByteArrayInputStream(baos.toByteArray()); | |
213 } | |
214 } | |
215 }; | |
216 } | |
217 } |