Line 1... |
Line 1... |
1 |
/*
|
1 |
/*
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
3 |
*
|
3 |
*
|
4 |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
|
4 |
* Copyright 2011-2019 OpenConcerto, by ILM Informatique. All rights reserved.
|
5 |
*
|
5 |
*
|
6 |
* The contents of this file are subject to the terms of the GNU General Public License Version 3
|
6 |
* The contents of this file are subject to the terms of the GNU General Public License Version 3
|
7 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
|
7 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
|
8 |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
|
8 |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
|
9 |
* language governing permissions and limitations under the License.
|
9 |
* language governing permissions and limitations under the License.
|
Line 18... |
Line 18... |
18 |
import org.openconcerto.utils.DesktopEnvironment.Mac;
|
18 |
import org.openconcerto.utils.DesktopEnvironment.Mac;
|
19 |
import org.openconcerto.utils.DesktopEnvironment.Windows;
|
19 |
import org.openconcerto.utils.DesktopEnvironment.Windows;
|
20 |
import org.openconcerto.utils.DesktopEnvironment.XFCE;
|
20 |
import org.openconcerto.utils.DesktopEnvironment.XFCE;
|
21 |
import org.openconcerto.utils.OSFamily.Unix;
|
21 |
import org.openconcerto.utils.OSFamily.Unix;
|
22 |
import org.openconcerto.utils.io.PercentEncoder;
|
22 |
import org.openconcerto.utils.io.PercentEncoder;
|
- |
|
23 |
import org.openconcerto.utils.system.Powershell;
|
23 |
|
24 |
|
24 |
import java.io.BufferedOutputStream;
|
25 |
import java.io.BufferedOutputStream;
|
25 |
import java.io.BufferedWriter;
|
- |
|
26 |
import java.io.File;
|
26 |
import java.io.File;
|
27 |
import java.io.IOException;
|
27 |
import java.io.IOException;
|
28 |
import java.io.OutputStreamWriter;
|
28 |
import java.io.OutputStream;
|
29 |
import java.io.PrintStream;
|
29 |
import java.io.PrintStream;
|
30 |
import java.io.Writer;
|
30 |
import java.lang.ProcessBuilder.Redirect;
|
31 |
import java.net.URI;
|
31 |
import java.net.URI;
|
32 |
import java.net.URISyntaxException;
|
32 |
import java.net.URISyntaxException;
|
- |
|
33 |
import java.nio.charset.StandardCharsets;
|
33 |
import java.util.ArrayList;
|
34 |
import java.util.ArrayList;
|
34 |
import java.util.Arrays;
|
35 |
import java.util.Arrays;
|
35 |
import java.util.List;
|
36 |
import java.util.List;
|
36 |
import java.util.regex.Matcher;
|
37 |
import java.util.regex.Matcher;
|
37 |
import java.util.regex.Pattern;
|
38 |
import java.util.regex.Pattern;
|
- |
|
39 |
import java.util.stream.Collectors;
|
38 |
|
40 |
|
39 |
public abstract class EmailClient {
|
41 |
public abstract class EmailClient {
|
40 |
|
42 |
|
41 |
public static enum EmailClientType {
|
43 |
public static enum EmailClientType {
|
42 |
Thunderbird, AppleMail, Outlook, XDG
|
44 |
Thunderbird, AppleMail, Outlook, XDG
|
Line 342... |
Line 344... |
342 |
};
|
344 |
};
|
343 |
|
345 |
|
344 |
public static final EmailClient Outlook = new EmailClient(EmailClientType.Outlook) {
|
346 |
public static final EmailClient Outlook = new EmailClient(EmailClientType.Outlook) {
|
345 |
@Override
|
347 |
@Override
|
346 |
protected boolean composeNative(String to, String subject, String body, File... attachments) throws IOException, InterruptedException {
|
348 |
protected boolean composeNative(String to, String subject, String body, File... attachments) throws IOException, InterruptedException {
|
347 |
final DesktopEnvironment de = DesktopEnvironment.getDE();
|
349 |
return composePowershell(to, subject, body, attachments);
|
- |
|
350 |
}
|
- |
|
351 |
|
- |
|
352 |
// only tested with powershell 5.1
|
348 |
final File vbs = FileUtils.getFile(EmailClient.class.getResource("OutlookEmail.vbs"));
|
353 |
protected boolean composePowershell(String to, String subject, String body, File... attachments) throws IOException, InterruptedException {
|
349 |
final List<String> l = new ArrayList<String>(6);
|
354 |
final Powershell pwsh = Powershell.getInstance();
|
- |
|
355 |
|
350 |
l.add("cscript");
|
356 |
// Don't create temporary file :
|
- |
|
357 |
// https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.1
|
- |
|
358 |
String template = new String(StreamUtils.read(EmailClient.class.getResourceAsStream("Outlook.powershell")), StandardCharsets.UTF_8);
|
351 |
l.add(de.quoteParamForExec(vbs.getAbsolutePath()));
|
359 |
template = template.replace("@to@", pwsh.quote(to == null ? "" : to));
|
- |
|
360 |
template = template.replace("@subject@", pwsh.quote(subject == null ? "" : subject));
|
- |
|
361 |
template = template.replace("@attachments@", pwsh.quoteArray(Arrays.asList(attachments).stream().map(File::getAbsolutePath).collect(Collectors.toList())));
|
- |
|
362 |
|
352 |
if (to != null)
|
363 |
final ProcessBuilder pb = new ProcessBuilder();
|
353 |
l.add(createVBParam("to", to));
|
364 |
pb.command().add("powershell");
|
- |
|
365 |
// Apparently piping (i.e. "-Command -") only supports ASCII (and would require
|
354 |
if (subject != null)
|
366 |
// embedding the body in the script).
|
355 |
l.add(createVBParam("subject", subject));
|
367 |
pb.command().add("-EncodedCommand");
|
356 |
// at least set a parameter otherwise the usage get displayed
|
368 |
pb.command().add(pwsh.getEncodedCommand(template));
|
- |
|
369 |
|
- |
|
370 |
pb.inheritIO();
|
357 |
l.add(createVBParam("unicodeStdIn", "1"));
|
371 |
pb.redirectInput(Redirect.PIPE);
|
358 |
for (File attachment : attachments) {
|
372 |
final Process process = pb.start();
|
359 |
l.add(de.quoteParamForExec(attachment.getAbsolutePath()));
|
373 |
try (final OutputStream in = process.getOutputStream()) {
|
- |
|
374 |
in.write(body.getBytes(StandardCharsets.UTF_8));
|
360 |
}
|
375 |
}
|
361 |
|
376 |
|
362 |
final Process process = new ProcessBuilder(l).start();
|
- |
|
363 |
// VBScript only knows ASCII and UTF-16
|
- |
|
364 |
final Writer writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream(), StringUtils.UTF16));
|
- |
|
365 |
writer.write(body);
|
- |
|
366 |
writer.close();
|
- |
|
367 |
final int returnCode = process.waitFor();
|
377 |
final int returnCode = process.waitFor();
|
368 |
if (returnCode != 0)
|
378 |
if (returnCode != 0)
|
369 |
throw new IllegalStateException("Non zero return code: " + returnCode);
|
379 |
throw new IllegalStateException("Non zero return code: " + returnCode);
|
370 |
return true;
|
380 |
return true;
|
371 |
}
|
381 |
}
|