]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/commands/JsonRpcDispatcherCommand.java
0eb993512eb8444939261edf01ae24ca530d68d5
[signal-cli] / src / main / java / org / asamk / signal / commands / JsonRpcDispatcherCommand.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.OutputType;
8 import org.asamk.signal.Shutdown;
9 import org.asamk.signal.commands.exceptions.CommandException;
10 import org.asamk.signal.jsonrpc.SignalJsonRpcDispatcherHandler;
11 import org.asamk.signal.manager.Manager;
12 import org.asamk.signal.manager.MultiAccountManager;
13 import org.asamk.signal.output.JsonWriter;
14 import org.asamk.signal.output.OutputWriter;
15 import org.asamk.signal.util.IOUtils;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 import java.io.FileDescriptor;
20 import java.io.FileInputStream;
21 import java.io.InputStreamReader;
22 import java.nio.channels.Channels;
23 import java.util.List;
24 import java.util.function.Supplier;
25
26 import static org.asamk.signal.util.CommandUtil.getReceiveConfig;
27
28 public class JsonRpcDispatcherCommand implements LocalCommand, MultiLocalCommand {
29
30 private static final Logger logger = LoggerFactory.getLogger(JsonRpcDispatcherCommand.class);
31
32 @Override
33 public String getName() {
34 return "jsonRpc";
35 }
36
37 @Override
38 public void attachToSubparser(final Subparser subparser) {
39 subparser.help("Take commands from standard input as line-delimited JSON RPC while receiving messages.");
40 subparser.addArgument("--ignore-attachments")
41 .help("Don’t download attachments of received messages.")
42 .action(Arguments.storeTrue());
43 subparser.addArgument("--ignore-stories")
44 .help("Don’t receive story messages from the server.")
45 .action(Arguments.storeTrue());
46 subparser.addArgument("--send-read-receipts")
47 .help("Send read receipts for all incoming data messages (in addition to the default delivery receipts)")
48 .action(Arguments.storeTrue());
49 subparser.addArgument("--receive-mode")
50 .help("Specify when to start receiving messages.")
51 .type(Arguments.enumStringType(ReceiveMode.class))
52 .setDefault(ReceiveMode.ON_START);
53 }
54
55 @Override
56 public List<OutputType> getSupportedOutputTypes() {
57 return List.of(OutputType.JSON);
58 }
59
60 @Override
61 public void handleCommand(
62 final Namespace ns, final Manager m, final OutputWriter outputWriter
63 ) throws CommandException {
64 Shutdown.installHandler();
65 final var receiveMode = ns.<ReceiveMode>get("receive-mode");
66 final var receiveConfig = getReceiveConfig(ns);
67 m.setReceiveConfig(receiveConfig);
68
69 final var jsonOutputWriter = (JsonWriter) outputWriter;
70 final var lineSupplier = getLineSupplier();
71
72 final var handler = new SignalJsonRpcDispatcherHandler(jsonOutputWriter,
73 lineSupplier,
74 receiveMode == ReceiveMode.MANUAL);
75 final var thread = Thread.currentThread();
76 Shutdown.registerShutdownListener(thread::interrupt);
77 handler.handleConnection(m);
78 }
79
80 @Override
81 public void handleCommand(
82 final Namespace ns, final MultiAccountManager c, final OutputWriter outputWriter
83 ) throws CommandException {
84 Shutdown.installHandler();
85 final var receiveMode = ns.<ReceiveMode>get("receive-mode");
86 final var receiveConfig = getReceiveConfig(ns);
87 c.getManagers().forEach(m -> m.setReceiveConfig(receiveConfig));
88 c.addOnManagerAddedHandler(m -> m.setReceiveConfig(receiveConfig));
89
90 final var jsonOutputWriter = (JsonWriter) outputWriter;
91 final var lineSupplier = getLineSupplier();
92
93 final var handler = new SignalJsonRpcDispatcherHandler(jsonOutputWriter,
94 lineSupplier,
95 receiveMode == ReceiveMode.MANUAL);
96 final var thread = Thread.currentThread();
97 Shutdown.registerShutdownListener(thread::interrupt);
98 handler.handleConnection(c);
99 }
100
101 private static Supplier<String> getLineSupplier() {
102 // Use FileChannel for stdin, because System.in is uninterruptible
103 final var stdInCh = Channels.newInputStream((new FileInputStream(FileDescriptor.in)).getChannel());
104 return IOUtils.getLineSupplier(new InputStreamReader(stdInCh, IOUtils.getConsoleCharset()));
105 }
106 }