1 package org
.asamk
.signal
.commands
;
3 import net
.sourceforge
.argparse4j
.impl
.Arguments
;
4 import net
.sourceforge
.argparse4j
.inf
.Namespace
;
5 import net
.sourceforge
.argparse4j
.inf
.Subparser
;
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
;
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
;
26 import static org
.asamk
.signal
.util
.CommandUtil
.getReceiveConfig
;
28 public class JsonRpcDispatcherCommand
implements LocalCommand
, MultiLocalCommand
{
30 private static final Logger logger
= LoggerFactory
.getLogger(JsonRpcDispatcherCommand
.class);
33 public String
getName() {
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
);
56 public List
<OutputType
> getSupportedOutputTypes() {
57 return List
.of(OutputType
.JSON
);
61 public void handleCommand(
64 final OutputWriter outputWriter
65 ) throws CommandException
{
66 Shutdown
.installHandler();
67 final var receiveMode
= ns
.<ReceiveMode
>get("receive-mode");
68 final var receiveConfig
= getReceiveConfig(ns
);
69 m
.setReceiveConfig(receiveConfig
);
71 final var jsonOutputWriter
= (JsonWriter
) outputWriter
;
72 final var lineSupplier
= getLineSupplier();
74 final var handler
= new SignalJsonRpcDispatcherHandler(jsonOutputWriter
,
76 receiveMode
== ReceiveMode
.MANUAL
);
77 final var thread
= Thread
.currentThread();
78 Shutdown
.registerShutdownListener(thread
::interrupt
);
79 handler
.handleConnection(m
);
83 public void handleCommand(
85 final MultiAccountManager c
,
86 final OutputWriter outputWriter
87 ) throws CommandException
{
88 Shutdown
.installHandler();
89 final var receiveMode
= ns
.<ReceiveMode
>get("receive-mode");
90 final var receiveConfig
= getReceiveConfig(ns
);
91 c
.getManagers().forEach(m
-> m
.setReceiveConfig(receiveConfig
));
92 c
.addOnManagerAddedHandler(m
-> m
.setReceiveConfig(receiveConfig
));
94 final var jsonOutputWriter
= (JsonWriter
) outputWriter
;
95 final var lineSupplier
= getLineSupplier();
97 final var handler
= new SignalJsonRpcDispatcherHandler(jsonOutputWriter
,
99 receiveMode
== ReceiveMode
.MANUAL
);
100 final var thread
= Thread
.currentThread();
101 Shutdown
.registerShutdownListener(thread
::interrupt
);
102 handler
.handleConnection(c
);
105 private static Supplier
<String
> getLineSupplier() {
106 // Use FileChannel for stdin, because System.in is uninterruptible
107 final var stdInCh
= Channels
.newInputStream((new FileInputStream(FileDescriptor
.in)).getChannel());
108 return IOUtils
.getLineSupplier(new InputStreamReader(stdInCh
, IOUtils
.getConsoleCharset()));