]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/commands/ReceiveCommand.java
Use PlainTextWriter for all cli stdout output
[signal-cli] / src / main / java / org / asamk / signal / commands / ReceiveCommand.java
1 package org.asamk.signal.commands;
2
3 import net.sourceforge.argparse4j.impl.Arguments;
4 import net.sourceforge.argparse4j.inf.Namespace;
5 import net.sourceforge.argparse4j.inf.Subparser;
6
7 import org.asamk.Signal;
8 import org.asamk.signal.JsonReceiveMessageHandler;
9 import org.asamk.signal.JsonWriter;
10 import org.asamk.signal.OutputType;
11 import org.asamk.signal.PlainTextWriterImpl;
12 import org.asamk.signal.ReceiveMessageHandler;
13 import org.asamk.signal.json.JsonMessageEnvelope;
14 import org.asamk.signal.manager.Manager;
15 import org.asamk.signal.util.DateUtils;
16 import org.freedesktop.dbus.connections.impl.DBusConnection;
17 import org.freedesktop.dbus.exceptions.DBusException;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 import java.io.IOException;
22 import java.util.Base64;
23 import java.util.Map;
24 import java.util.Set;
25 import java.util.concurrent.TimeUnit;
26
27 import static org.asamk.signal.util.ErrorUtils.handleAssertionError;
28
29 public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
30
31 private final static Logger logger = LoggerFactory.getLogger(ReceiveCommand.class);
32
33 @Override
34 public void attachToSubparser(final Subparser subparser) {
35 subparser.addArgument("-t", "--timeout")
36 .type(double.class)
37 .help("Number of seconds to wait for new messages (negative values disable timeout)");
38 subparser.addArgument("--ignore-attachments")
39 .help("Don’t download attachments of received messages.")
40 .action(Arguments.storeTrue());
41 subparser.addArgument("--json")
42 .help("WARNING: This parameter is now deprecated! Please use the global \"--output=json\" option instead.\n\nOutput received messages in json format, one json object per line.")
43 .action(Arguments.storeTrue());
44 }
45
46 @Override
47 public Set<OutputType> getSupportedOutputTypes() {
48 return Set.of(OutputType.PLAIN_TEXT, OutputType.JSON);
49 }
50
51 public int handleCommand(final Namespace ns, final Signal signal, DBusConnection dbusconnection) {
52 var inJson = ns.get("output") == OutputType.JSON || ns.getBoolean("json");
53
54 // TODO delete later when "json" variable is removed
55 if (ns.getBoolean("json")) {
56 logger.warn("\"--json\" option has been deprecated, please use the global \"--output=json\" instead.");
57 }
58
59 try {
60 if (inJson) {
61 final var jsonWriter = new JsonWriter(System.out);
62
63 dbusconnection.addSigHandler(Signal.MessageReceived.class, messageReceived -> {
64 var envelope = new JsonMessageEnvelope(messageReceived);
65 final var object = Map.of("envelope", envelope);
66 try {
67 jsonWriter.write(object);
68 } catch (IOException e) {
69 logger.error("Failed to write json object: {}", e.getMessage());
70 }
71 });
72
73 dbusconnection.addSigHandler(Signal.ReceiptReceived.class, receiptReceived -> {
74 var envelope = new JsonMessageEnvelope(receiptReceived);
75 final var object = Map.of("envelope", envelope);
76 try {
77 jsonWriter.write(object);
78 } catch (IOException e) {
79 logger.error("Failed to write json object: {}", e.getMessage());
80 }
81 });
82
83 dbusconnection.addSigHandler(Signal.SyncMessageReceived.class, syncReceived -> {
84 var envelope = new JsonMessageEnvelope(syncReceived);
85 final var object = Map.of("envelope", envelope);
86 try {
87 jsonWriter.write(object);
88 } catch (IOException e) {
89 logger.error("Failed to write json object: {}", e.getMessage());
90 }
91 });
92 } else {
93 final var writer = new PlainTextWriterImpl(System.out);
94
95 dbusconnection.addSigHandler(Signal.MessageReceived.class, messageReceived -> {
96 try {
97 writer.println("Envelope from: {}", messageReceived.getSender());
98 writer.println("Timestamp: {}", DateUtils.formatTimestamp(messageReceived.getTimestamp()));
99 writer.println("Body: {}", messageReceived.getMessage());
100 if (messageReceived.getGroupId().length > 0) {
101 writer.println("Group info:");
102 writer.indentedWriter()
103 .println("Id: {}",
104 Base64.getEncoder().encodeToString(messageReceived.getGroupId()));
105 }
106 if (messageReceived.getAttachments().size() > 0) {
107 writer.println("Attachments:");
108 for (var attachment : messageReceived.getAttachments()) {
109 writer.println("- Stored plaintext in: {}", attachment);
110 }
111 }
112 writer.println();
113 } catch (IOException e) {
114 e.printStackTrace();
115 }
116 });
117
118 dbusconnection.addSigHandler(Signal.ReceiptReceived.class, receiptReceived -> {
119 try {
120 writer.println("Receipt from: {}", receiptReceived.getSender());
121 writer.println("Timestamp: {}", DateUtils.formatTimestamp(receiptReceived.getTimestamp()));
122 } catch (IOException e) {
123 e.printStackTrace();
124 }
125 });
126
127 dbusconnection.addSigHandler(Signal.SyncMessageReceived.class, syncReceived -> {
128 try {
129 writer.println("Sync Envelope from: {} to: {}",
130 syncReceived.getSource(),
131 syncReceived.getDestination());
132 writer.println("Timestamp: {}", DateUtils.formatTimestamp(syncReceived.getTimestamp()));
133 writer.println("Body: {}", syncReceived.getMessage());
134 if (syncReceived.getGroupId().length > 0) {
135 writer.println("Group info:");
136 writer.indentedWriter()
137 .println("Id: {}", Base64.getEncoder().encodeToString(syncReceived.getGroupId()));
138 }
139 if (syncReceived.getAttachments().size() > 0) {
140 writer.println("Attachments:");
141 for (var attachment : syncReceived.getAttachments()) {
142 writer.println("- Stored plaintext in: {}", attachment);
143 }
144 }
145 writer.println();
146 } catch (IOException e) {
147 e.printStackTrace();
148 }
149 });
150 }
151 } catch (DBusException e) {
152 e.printStackTrace();
153 return 2;
154 }
155 while (true) {
156 try {
157 Thread.sleep(10000);
158 } catch (InterruptedException e) {
159 return 0;
160 }
161 }
162 }
163
164 @Override
165 public int handleCommand(final Namespace ns, final Manager m) {
166 var inJson = ns.get("output") == OutputType.JSON || ns.getBoolean("json");
167
168 // TODO delete later when "json" variable is removed
169 if (ns.getBoolean("json")) {
170 logger.warn("\"--json\" option has been deprecated, please use the global \"--output=json\" instead.");
171 }
172
173 double timeout = 5;
174 if (ns.getDouble("timeout") != null) {
175 timeout = ns.getDouble("timeout");
176 }
177 var returnOnTimeout = true;
178 if (timeout < 0) {
179 returnOnTimeout = false;
180 timeout = 3600;
181 }
182 boolean ignoreAttachments = ns.getBoolean("ignore_attachments");
183 try {
184 final var handler = inJson ? new JsonReceiveMessageHandler(m) : new ReceiveMessageHandler(m);
185 m.receiveMessages((long) (timeout * 1000),
186 TimeUnit.MILLISECONDS,
187 returnOnTimeout,
188 ignoreAttachments,
189 handler);
190 return 0;
191 } catch (IOException e) {
192 System.err.println("Error while receiving messages: " + e.getMessage());
193 return 3;
194 } catch (AssertionError e) {
195 handleAssertionError(e);
196 return 1;
197 }
198 }
199 }