Refactor command creation

This commit is contained in:
AsamK 2021-08-20 18:42:38 +02:00
parent 47143a90e1
commit af292d8f0e
45 changed files with 436 additions and 282 deletions

View file

@ -96,7 +96,7 @@ public class App {
: new PlainTextWriterImpl(System.out); : new PlainTextWriterImpl(System.out);
var commandKey = ns.getString("command"); var commandKey = ns.getString("command");
var command = Commands.getCommand(commandKey, outputWriter); var command = Commands.getCommand(commandKey);
if (command == null) { if (command == null) {
throw new UserErrorException("Command not implemented!"); throw new UserErrorException("Command not implemented!");
} }
@ -111,7 +111,7 @@ public class App {
final var useDbusSystem = ns.getBoolean("dbus-system"); final var useDbusSystem = ns.getBoolean("dbus-system");
if (useDbus || useDbusSystem) { if (useDbus || useDbusSystem) {
// If username is null, it will connect to the default object path // If username is null, it will connect to the default object path
initDbusClient(command, username, useDbusSystem); initDbusClient(command, username, useDbusSystem, outputWriter);
return; return;
} }
@ -142,7 +142,7 @@ public class App {
throw new UserErrorException("You cannot specify a username (phone number) when linking"); throw new UserErrorException("You cannot specify a username (phone number) when linking");
} }
handleProvisioningCommand((ProvisioningCommand) command, dataPath, serviceEnvironment); handleProvisioningCommand((ProvisioningCommand) command, dataPath, serviceEnvironment, outputWriter);
return; return;
} }
@ -150,7 +150,11 @@ public class App {
var usernames = Manager.getAllLocalUsernames(dataPath); var usernames = Manager.getAllLocalUsernames(dataPath);
if (command instanceof MultiLocalCommand) { if (command instanceof MultiLocalCommand) {
handleMultiLocalCommand((MultiLocalCommand) command, dataPath, serviceEnvironment, usernames); handleMultiLocalCommand((MultiLocalCommand) command,
dataPath,
serviceEnvironment,
usernames,
outputWriter);
return; return;
} }
@ -175,14 +179,17 @@ public class App {
throw new UserErrorException("Command only works via dbus"); throw new UserErrorException("Command only works via dbus");
} }
handleLocalCommand((LocalCommand) command, username, dataPath, serviceEnvironment); handleLocalCommand((LocalCommand) command, username, dataPath, serviceEnvironment, outputWriter);
} }
private void handleProvisioningCommand( private void handleProvisioningCommand(
final ProvisioningCommand command, final File dataPath, final ServiceEnvironment serviceEnvironment final ProvisioningCommand command,
final File dataPath,
final ServiceEnvironment serviceEnvironment,
final OutputWriter outputWriter
) throws CommandException { ) throws CommandException {
var pm = ProvisioningManager.init(dataPath, serviceEnvironment, BaseConfig.USER_AGENT); var pm = ProvisioningManager.init(dataPath, serviceEnvironment, BaseConfig.USER_AGENT);
command.handleCommand(ns, pm); command.handleCommand(ns, pm, outputWriter);
} }
private void handleRegistrationCommand( private void handleRegistrationCommand(
@ -212,10 +219,11 @@ public class App {
final LocalCommand command, final LocalCommand command,
final String username, final String username,
final File dataPath, final File dataPath,
final ServiceEnvironment serviceEnvironment final ServiceEnvironment serviceEnvironment,
final OutputWriter outputWriter
) throws CommandException { ) throws CommandException {
try (var m = loadManager(username, dataPath, serviceEnvironment)) { try (var m = loadManager(username, dataPath, serviceEnvironment)) {
command.handleCommand(ns, m); command.handleCommand(ns, m, outputWriter);
} catch (IOException e) { } catch (IOException e) {
logger.warn("Cleanup failed", e); logger.warn("Cleanup failed", e);
} }
@ -225,7 +233,8 @@ public class App {
final MultiLocalCommand command, final MultiLocalCommand command,
final File dataPath, final File dataPath,
final ServiceEnvironment serviceEnvironment, final ServiceEnvironment serviceEnvironment,
final List<String> usernames final List<String> usernames,
final OutputWriter outputWriter
) throws CommandException { ) throws CommandException {
final var managers = new ArrayList<Manager>(); final var managers = new ArrayList<Manager>();
for (String u : usernames) { for (String u : usernames) {
@ -246,7 +255,7 @@ public class App {
public RegistrationManager getNewRegistrationManager(String username) throws IOException { public RegistrationManager getNewRegistrationManager(String username) throws IOException {
return RegistrationManager.init(username, dataPath, serviceEnvironment, BaseConfig.USER_AGENT); return RegistrationManager.init(username, dataPath, serviceEnvironment, BaseConfig.USER_AGENT);
} }
}); }, outputWriter);
for (var m : managers) { for (var m : managers) {
try { try {
@ -286,7 +295,7 @@ public class App {
} }
private void initDbusClient( private void initDbusClient(
final Command command, final String username, final boolean systemBus final Command command, final String username, final boolean systemBus, final OutputWriter outputWriter
) throws CommandException { ) throws CommandException {
try { try {
DBusConnection.DBusBusType busType; DBusConnection.DBusBusType busType;
@ -300,7 +309,7 @@ public class App {
DbusConfig.getObjectPath(username), DbusConfig.getObjectPath(username),
Signal.class); Signal.class);
handleCommand(command, ts, dBusConn); handleCommand(command, ts, dBusConn, outputWriter);
} }
} catch (DBusException | IOException e) { } catch (DBusException | IOException e) {
logger.error("Dbus client failed", e); logger.error("Dbus client failed", e);
@ -308,11 +317,13 @@ public class App {
} }
} }
private void handleCommand(Command command, Signal ts, DBusConnection dBusConn) throws CommandException { private void handleCommand(
Command command, Signal ts, DBusConnection dBusConn, OutputWriter outputWriter
) throws CommandException {
if (command instanceof ExtendedDbusCommand) { if (command instanceof ExtendedDbusCommand) {
((ExtendedDbusCommand) command).handleCommand(ns, ts, dBusConn); ((ExtendedDbusCommand) command).handleCommand(ns, ts, dBusConn, outputWriter);
} else if (command instanceof DbusCommand) { } else if (command instanceof DbusCommand) {
((DbusCommand) command).handleCommand(ns, ts); ((DbusCommand) command).handleCommand(ns, ts, outputWriter);
} else { } else {
throw new UserErrorException("Command is not yet implemented via dbus"); throw new UserErrorException("Command is not yet implemented via dbus");
} }

View file

@ -21,18 +21,23 @@ public class AddDeviceCommand implements JsonRpcLocalCommand {
private final static Logger logger = LoggerFactory.getLogger(AddDeviceCommand.class); private final static Logger logger = LoggerFactory.getLogger(AddDeviceCommand.class);
public static void attachToSubparser(final Subparser subparser) { @Override
public String getName() {
return "addDevice";
}
@Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Link another device to this device. Only works, if this is the master device."); subparser.help("Link another device to this device. Only works, if this is the master device.");
subparser.addArgument("--uri") subparser.addArgument("--uri")
.required(true) .required(true)
.help("Specify the uri contained in the QR code shown by the new device."); .help("Specify the uri contained in the QR code shown by the new device.");
} }
public AddDeviceCommand(final OutputWriter outputWriter) {
}
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
try { try {
m.addDeviceLink(new URI(ns.getString("uri"))); m.addDeviceLink(new URI(ns.getString("uri")));
} catch (IOException e) { } catch (IOException e) {

View file

@ -19,17 +19,22 @@ public class BlockCommand implements JsonRpcLocalCommand {
private final static Logger logger = LoggerFactory.getLogger(BlockCommand.class); private final static Logger logger = LoggerFactory.getLogger(BlockCommand.class);
public static void attachToSubparser(final Subparser subparser) { @Override
public String getName() {
return "block";
}
@Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Block the given contacts or groups (no messages will be received)"); subparser.help("Block the given contacts or groups (no messages will be received)");
subparser.addArgument("contact").help("Contact number").nargs("*"); subparser.addArgument("contact").help("Contact number").nargs("*");
subparser.addArgument("-g", "--group-id", "--group").help("Group ID").nargs("*"); subparser.addArgument("-g", "--group-id", "--group").help("Group ID").nargs("*");
} }
public BlockCommand(final OutputWriter outputWriter) {
}
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
for (var contactNumber : ns.<String>getList("contact")) { for (var contactNumber : ns.<String>getList("contact")) {
try { try {
m.setContactBlocked(contactNumber, true); m.setContactBlocked(contactNumber, true);

View file

@ -0,0 +1,8 @@
package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Subparser;
public interface CliCommand extends Command {
void attachToSubparser(Subparser subparser);
}

View file

@ -2,11 +2,13 @@ package org.asamk.signal.commands;
import org.asamk.signal.OutputType; import org.asamk.signal.OutputType;
import java.util.Set; import java.util.List;
public interface Command { public interface Command {
default Set<OutputType> getSupportedOutputTypes() { String getName();
return Set.of(OutputType.PLAIN_TEXT);
default List<OutputType> getSupportedOutputTypes() {
return List.of(OutputType.PLAIN_TEXT);
} }
} }

View file

@ -1,74 +1,65 @@
package org.asamk.signal.commands; package org.asamk.signal.commands;
import org.asamk.signal.OutputWriter;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
public class Commands { public class Commands {
private static final Map<String, CommandConstructor> commands = new HashMap<>(); private static final Map<String, Command> commands = new HashMap<>();
private static final Map<String, SubparserAttacher> commandSubparserAttacher = new TreeMap<>(); private static final Map<String, SubparserAttacher> commandSubparserAttacher = new TreeMap<>();
static { static {
addCommand("addDevice", AddDeviceCommand::new, AddDeviceCommand::attachToSubparser); addCommand(new AddDeviceCommand());
addCommand("block", BlockCommand::new, BlockCommand::attachToSubparser); addCommand(new BlockCommand());
addCommand("daemon", DaemonCommand::new, DaemonCommand::attachToSubparser); addCommand(new DaemonCommand());
addCommand("getUserStatus", GetUserStatusCommand::new, GetUserStatusCommand::attachToSubparser); addCommand(new GetUserStatusCommand());
addCommand("jsonRpc", JsonRpcDispatcherCommand::new, JsonRpcDispatcherCommand::attachToSubparser); addCommand(new JoinGroupCommand());
addCommand("link", LinkCommand::new, LinkCommand::attachToSubparser); addCommand(new JsonRpcDispatcherCommand());
addCommand("listContacts", ListContactsCommand::new, ListContactsCommand::attachToSubparser); addCommand(new LinkCommand());
addCommand("listDevices", ListDevicesCommand::new, ListDevicesCommand::attachToSubparser); addCommand(new ListContactsCommand());
addCommand("listGroups", ListGroupsCommand::new, ListGroupsCommand::attachToSubparser); addCommand(new ListDevicesCommand());
addCommand("listIdentities", ListIdentitiesCommand::new, ListIdentitiesCommand::attachToSubparser); addCommand(new ListGroupsCommand());
addCommand("joinGroup", JoinGroupCommand::new, JoinGroupCommand::attachToSubparser); addCommand(new ListIdentitiesCommand());
addCommand("quitGroup", QuitGroupCommand::new, QuitGroupCommand::attachToSubparser); addCommand(new QuitGroupCommand());
addCommand("receive", ReceiveCommand::new, ReceiveCommand::attachToSubparser); addCommand(new ReceiveCommand());
addCommand("register", RegisterCommand::new, RegisterCommand::attachToSubparser); addCommand(new RegisterCommand());
addCommand("removeDevice", RemoveDeviceCommand::new, RemoveDeviceCommand::attachToSubparser); addCommand(new RemoveDeviceCommand());
addCommand("remoteDelete", RemoteDeleteCommand::new, RemoteDeleteCommand::attachToSubparser); addCommand(new RemoteDeleteCommand());
addCommand("removePin", RemovePinCommand::new, RemovePinCommand::attachToSubparser); addCommand(new RemovePinCommand());
addCommand("send", SendCommand::new, SendCommand::attachToSubparser); addCommand(new SendCommand());
addCommand("sendContacts", SendContactsCommand::new, SendContactsCommand::attachToSubparser); addCommand(new SendContactsCommand());
addCommand("sendReaction", SendReactionCommand::new, SendReactionCommand::attachToSubparser); addCommand(new SendReactionCommand());
addCommand("sendSyncRequest", SendSyncRequestCommand::new, SendSyncRequestCommand::attachToSubparser); addCommand(new SendSyncRequestCommand());
addCommand("sendTyping", SendTypingCommand::new, SendTypingCommand::attachToSubparser); addCommand(new SendTypingCommand());
addCommand("setPin", SetPinCommand::new, SetPinCommand::attachToSubparser); addCommand(new SetPinCommand());
addCommand("trust", TrustCommand::new, TrustCommand::attachToSubparser); addCommand(new TrustCommand());
addCommand("unblock", UnblockCommand::new, UnblockCommand::attachToSubparser); addCommand(new UnblockCommand());
addCommand("unregister", UnregisterCommand::new, UnregisterCommand::attachToSubparser); addCommand(new UnregisterCommand());
addCommand("updateAccount", UpdateAccountCommand::new, UpdateAccountCommand::attachToSubparser); addCommand(new UpdateAccountCommand());
addCommand("updateContact", UpdateContactCommand::new, UpdateContactCommand::attachToSubparser); addCommand(new UpdateContactCommand());
addCommand("updateGroup", UpdateGroupCommand::new, UpdateGroupCommand::attachToSubparser); addCommand(new UpdateGroupCommand());
addCommand("updateProfile", UpdateProfileCommand::new, UpdateProfileCommand::attachToSubparser); addCommand(new UpdateProfileCommand());
addCommand("uploadStickerPack", UploadStickerPackCommand::new, UploadStickerPackCommand::attachToSubparser); addCommand(new UploadStickerPackCommand());
addCommand("verify", VerifyCommand::new, VerifyCommand::attachToSubparser); addCommand(new VerifyCommand());
addCommand("version", VersionCommand::new, null); addCommand(new VersionCommand());
} }
public static Map<String, SubparserAttacher> getCommandSubparserAttachers() { public static Map<String, SubparserAttacher> getCommandSubparserAttachers() {
return commandSubparserAttacher; return commandSubparserAttacher;
} }
public static Command getCommand(String commandKey, OutputWriter outputWriter) { public static Command getCommand(String commandKey) {
if (!commands.containsKey(commandKey)) { if (!commands.containsKey(commandKey)) {
return null; return null;
} }
return commands.get(commandKey).constructCommand(outputWriter); return commands.get(commandKey);
} }
private static void addCommand( private static void addCommand(Command command) {
String name, CommandConstructor commandConstructor, SubparserAttacher subparserAttacher commands.put(command.getName(), command);
) { if (command instanceof CliCommand) {
commands.put(name, commandConstructor); commandSubparserAttacher.put(command.getName(), ((CliCommand) command)::attachToSubparser);
if (subparserAttacher != null) {
commandSubparserAttacher.put(name, subparserAttacher);
} }
} }
private interface CommandConstructor {
Command constructCommand(OutputWriter outputWriter);
}
} }

View file

@ -23,15 +23,19 @@ import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class DaemonCommand implements MultiLocalCommand { public class DaemonCommand implements MultiLocalCommand {
private final static Logger logger = LoggerFactory.getLogger(DaemonCommand.class); private final static Logger logger = LoggerFactory.getLogger(DaemonCommand.class);
private final OutputWriter outputWriter;
public static void attachToSubparser(final Subparser subparser) { @Override
public String getName() {
return "daemon";
}
@Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Run in daemon mode and provide an experimental dbus interface."); subparser.help("Run in daemon mode and provide an experimental dbus interface.");
subparser.addArgument("--system") subparser.addArgument("--system")
.action(Arguments.storeTrue()) .action(Arguments.storeTrue())
@ -41,17 +45,15 @@ public class DaemonCommand implements MultiLocalCommand {
.action(Arguments.storeTrue()); .action(Arguments.storeTrue());
} }
public DaemonCommand(final OutputWriter outputWriter) { @Override
this.outputWriter = outputWriter; public List<OutputType> getSupportedOutputTypes() {
return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
} }
@Override @Override
public Set<OutputType> getSupportedOutputTypes() { public void handleCommand(
return Set.of(OutputType.PLAIN_TEXT, OutputType.JSON); final Namespace ns, final Manager m, final OutputWriter outputWriter
} ) throws CommandException {
@Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
boolean ignoreAttachments = ns.getBoolean("ignore-attachments"); boolean ignoreAttachments = ns.getBoolean("ignore-attachments");
DBusConnection.DBusBusType busType; DBusConnection.DBusBusType busType;
@ -63,7 +65,7 @@ public class DaemonCommand implements MultiLocalCommand {
try (var conn = DBusConnection.getConnection(busType)) { try (var conn = DBusConnection.getConnection(busType)) {
var objectPath = DbusConfig.getObjectPath(); var objectPath = DbusConfig.getObjectPath();
var t = run(conn, objectPath, m, ignoreAttachments); var t = run(conn, objectPath, m, outputWriter, ignoreAttachments);
conn.requestBusName(DbusConfig.getBusname()); conn.requestBusName(DbusConfig.getBusname());
@ -79,7 +81,7 @@ public class DaemonCommand implements MultiLocalCommand {
@Override @Override
public void handleCommand( public void handleCommand(
final Namespace ns, final List<Manager> managers, SignalCreator c final Namespace ns, final List<Manager> managers, final SignalCreator c, final OutputWriter outputWriter
) throws CommandException { ) throws CommandException {
boolean ignoreAttachments = ns.getBoolean("ignore-attachments"); boolean ignoreAttachments = ns.getBoolean("ignore-attachments");
@ -94,7 +96,7 @@ public class DaemonCommand implements MultiLocalCommand {
final var signalControl = new DbusSignalControlImpl(c, m -> { final var signalControl = new DbusSignalControlImpl(c, m -> {
try { try {
final var objectPath = DbusConfig.getObjectPath(m.getUsername()); final var objectPath = DbusConfig.getObjectPath(m.getUsername());
return run(conn, objectPath, m, ignoreAttachments); return run(conn, objectPath, m, outputWriter, ignoreAttachments);
} catch (DBusException e) { } catch (DBusException e) {
logger.error("Failed to export object", e); logger.error("Failed to export object", e);
return null; return null;
@ -116,7 +118,7 @@ public class DaemonCommand implements MultiLocalCommand {
} }
private Thread run( private Thread run(
DBusConnection conn, String objectPath, Manager m, boolean ignoreAttachments DBusConnection conn, String objectPath, Manager m, OutputWriter outputWriter, boolean ignoreAttachments
) throws DBusException { ) throws DBusException {
conn.exportObject(new DbusSignalImpl(m, objectPath)); conn.exportObject(new DbusSignalImpl(m, objectPath));

View file

@ -3,15 +3,18 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import org.asamk.Signal; import org.asamk.Signal;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.dbus.DbusSignalImpl; import org.asamk.signal.dbus.DbusSignalImpl;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
public interface DbusCommand extends LocalCommand { public interface DbusCommand extends LocalCommand {
void handleCommand(Namespace ns, Signal signal) throws CommandException; void handleCommand(Namespace ns, Signal signal, OutputWriter outputWriter) throws CommandException;
default void handleCommand(final Namespace ns, final Manager m) throws CommandException { default void handleCommand(
handleCommand(ns, new DbusSignalImpl(m, null)); final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
handleCommand(ns, new DbusSignalImpl(m, null), outputWriter);
} }
} }

View file

@ -3,10 +3,13 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import org.asamk.Signal; import org.asamk.Signal;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.commands.exceptions.CommandException;
import org.freedesktop.dbus.connections.impl.DBusConnection; import org.freedesktop.dbus.connections.impl.DBusConnection;
public interface ExtendedDbusCommand extends Command { public interface ExtendedDbusCommand extends CliCommand {
void handleCommand(Namespace ns, Signal signal, DBusConnection dbusconnection) throws CommandException; void handleCommand(
Namespace ns, Signal signal, DBusConnection dbusconnection, final OutputWriter outputWriter
) throws CommandException;
} }

View file

@ -20,19 +20,22 @@ import java.util.stream.Collectors;
public class GetUserStatusCommand implements JsonRpcLocalCommand { public class GetUserStatusCommand implements JsonRpcLocalCommand {
private final static Logger logger = LoggerFactory.getLogger(GetUserStatusCommand.class); private final static Logger logger = LoggerFactory.getLogger(GetUserStatusCommand.class);
private final OutputWriter outputWriter;
public static void attachToSubparser(final Subparser subparser) { @Override
public String getName() {
return "getUserStatus";
}
@Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Check if the specified phone number/s have been registered"); subparser.help("Check if the specified phone number/s have been registered");
subparser.addArgument("number").help("Phone number").nargs("+"); subparser.addArgument("number").help("Phone number").nargs("+");
} }
public GetUserStatusCommand(final OutputWriter outputWriter) {
this.outputWriter = outputWriter;
}
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
// Get a map of registration statuses // Get a map of registration statuses
Map<String, Boolean> registered; Map<String, Boolean> registered;
try { try {

View file

@ -23,19 +23,21 @@ import static org.asamk.signal.util.ErrorUtils.handleSendMessageResults;
public class JoinGroupCommand implements JsonRpcLocalCommand { public class JoinGroupCommand implements JsonRpcLocalCommand {
private final OutputWriter outputWriter; @Override
public String getName() {
public JoinGroupCommand(final OutputWriter outputWriter) { return "joinGroup";
this.outputWriter = outputWriter;
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Join a group via an invitation link."); subparser.help("Join a group via an invitation link.");
subparser.addArgument("--uri").required(true).help("Specify the uri with the group invitation link."); subparser.addArgument("--uri").required(true).help("Specify the uri with the group invitation link.");
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
final GroupInviteLinkUrl linkUrl; final GroupInviteLinkUrl linkUrl;
var uri = ns.getString("uri"); var uri = ns.getString("uri");
try { try {

View file

@ -3,10 +3,11 @@ package org.asamk.signal.commands;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.asamk.signal.OutputType; import org.asamk.signal.OutputType;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import java.util.Set; import java.util.List;
public interface JsonRpcCommand<T> extends Command { public interface JsonRpcCommand<T> extends Command {
@ -14,9 +15,9 @@ public interface JsonRpcCommand<T> extends Command {
return null; return null;
} }
void handleCommand(T request, Manager m) throws CommandException; void handleCommand(T request, Manager m, OutputWriter outputWriter) throws CommandException;
default Set<OutputType> getSupportedOutputTypes() { default List<OutputType> getSupportedOutputTypes() {
return Set.of(OutputType.JSON); return List.of(OutputType.JSON);
} }
} }

View file

@ -31,8 +31,8 @@ import org.slf4j.LoggerFactory;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class JsonRpcDispatcherCommand implements LocalCommand { public class JsonRpcDispatcherCommand implements LocalCommand {
@ -43,26 +43,28 @@ public class JsonRpcDispatcherCommand implements LocalCommand {
private static final int IO_ERROR = -3; private static final int IO_ERROR = -3;
private static final int UNTRUSTED_KEY_ERROR = -4; private static final int UNTRUSTED_KEY_ERROR = -4;
private final OutputWriter outputWriter; @Override
public String getName() {
return "jsonRpc";
}
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Take commands from standard input as line-delimited JSON RPC while receiving messages."); subparser.help("Take commands from standard input as line-delimited JSON RPC while receiving messages.");
subparser.addArgument("--ignore-attachments") subparser.addArgument("--ignore-attachments")
.help("Dont download attachments of received messages.") .help("Dont download attachments of received messages.")
.action(Arguments.storeTrue()); .action(Arguments.storeTrue());
} }
public JsonRpcDispatcherCommand(final OutputWriter outputWriter) { @Override
this.outputWriter = outputWriter; public List<OutputType> getSupportedOutputTypes() {
return List.of(OutputType.JSON);
} }
@Override @Override
public Set<OutputType> getSupportedOutputTypes() { public void handleCommand(
return Set.of(OutputType.JSON); final Namespace ns, final Manager m, final OutputWriter outputWriter
} ) throws CommandException {
@Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException {
final boolean ignoreAttachments = ns.getBoolean("ignore-attachments"); final boolean ignoreAttachments = ns.getBoolean("ignore-attachments");
final var objectMapper = Util.createJsonObjectMapper(); final var objectMapper = Util.createJsonObjectMapper();
@ -104,7 +106,7 @@ public class JsonRpcDispatcherCommand implements LocalCommand {
result[0] = s; result[0] = s;
}; };
var command = Commands.getCommand(method, commandOutputWriter); var command = Commands.getCommand(method);
if (!(command instanceof JsonRpcCommand)) { if (!(command instanceof JsonRpcCommand)) {
throw new JsonRpcException(new JsonRpcResponse.Error(JsonRpcResponse.Error.METHOD_NOT_FOUND, throw new JsonRpcException(new JsonRpcResponse.Error(JsonRpcResponse.Error.METHOD_NOT_FOUND,
"Method not implemented", "Method not implemented",
@ -112,7 +114,7 @@ public class JsonRpcDispatcherCommand implements LocalCommand {
} }
try { try {
parseParamsAndRunCommand(m, objectMapper, params, (JsonRpcCommand<?>) command); parseParamsAndRunCommand(m, objectMapper, params, commandOutputWriter, (JsonRpcCommand<?>) command);
} catch (JsonMappingException e) { } catch (JsonMappingException e) {
throw new JsonRpcException(new JsonRpcResponse.Error(JsonRpcResponse.Error.INVALID_REQUEST, throw new JsonRpcException(new JsonRpcResponse.Error(JsonRpcResponse.Error.INVALID_REQUEST,
e.getMessage(), e.getMessage(),
@ -135,7 +137,11 @@ public class JsonRpcDispatcherCommand implements LocalCommand {
} }
private <T> void parseParamsAndRunCommand( private <T> void parseParamsAndRunCommand(
final Manager m, final ObjectMapper objectMapper, final TreeNode params, final JsonRpcCommand<T> command final Manager m,
final ObjectMapper objectMapper,
final TreeNode params,
final OutputWriter outputWriter,
final JsonRpcCommand<T> command
) throws CommandException, JsonMappingException { ) throws CommandException, JsonMappingException {
T requestParams = null; T requestParams = null;
final var requestType = command.getRequestType(); final var requestType = command.getRequestType();
@ -148,7 +154,7 @@ public class JsonRpcDispatcherCommand implements LocalCommand {
throw new AssertionError(e); throw new AssertionError(e);
} }
} }
command.handleCommand(requestParams, m); command.handleCommand(requestParams, m, outputWriter);
} }
private Thread receiveMessages( private Thread receiveMessages(

View file

@ -5,13 +5,13 @@ import com.fasterxml.jackson.core.type.TypeReference;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import org.asamk.signal.OutputType; import org.asamk.signal.OutputType;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
import org.asamk.signal.util.Util; import org.asamk.signal.util.Util;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
public interface JsonRpcLocalCommand extends JsonRpcCommand<Map<String, Object>>, LocalCommand { public interface JsonRpcLocalCommand extends JsonRpcCommand<Map<String, Object>>, LocalCommand {
@ -20,13 +20,15 @@ public interface JsonRpcLocalCommand extends JsonRpcCommand<Map<String, Object>>
}; };
} }
default void handleCommand(Map<String, Object> request, Manager m) throws CommandException { default void handleCommand(
Map<String, Object> request, Manager m, OutputWriter outputWriter
) throws CommandException {
Namespace commandNamespace = new JsonRpcNamespace(request == null ? Map.of() : request); Namespace commandNamespace = new JsonRpcNamespace(request == null ? Map.of() : request);
handleCommand(commandNamespace, m); handleCommand(commandNamespace, m, outputWriter);
} }
default Set<OutputType> getSupportedOutputTypes() { default List<OutputType> getSupportedOutputTypes() {
return Set.of(OutputType.PLAIN_TEXT, OutputType.JSON); return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
} }
/** /**

View file

@ -19,19 +19,22 @@ import java.util.concurrent.TimeoutException;
public class LinkCommand implements ProvisioningCommand { public class LinkCommand implements ProvisioningCommand {
private final static Logger logger = LoggerFactory.getLogger(LinkCommand.class); private final static Logger logger = LoggerFactory.getLogger(LinkCommand.class);
private final OutputWriter outputWriter;
public LinkCommand(final OutputWriter outputWriter) { @Override
this.outputWriter = outputWriter; public String getName() {
return "link";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Link to an existing device, instead of registering a new number."); subparser.help("Link to an existing device, instead of registering a new number.");
subparser.addArgument("-n", "--name").help("Specify a name to describe this new device."); subparser.addArgument("-n", "--name").help("Specify a name to describe this new device.");
} }
@Override @Override
public void handleCommand(final Namespace ns, final ProvisioningManager m) throws CommandException { public void handleCommand(
final Namespace ns, final ProvisioningManager m, final OutputWriter outputWriter
) throws CommandException {
final var writer = (PlainTextWriter) outputWriter; final var writer = (PlainTextWriter) outputWriter;
var deviceName = ns.getString("name"); var deviceName = ns.getString("name");

View file

@ -11,18 +11,18 @@ import static org.asamk.signal.util.Util.getLegacyIdentifier;
public class ListContactsCommand implements LocalCommand { public class ListContactsCommand implements LocalCommand {
private final OutputWriter outputWriter; @Override
public String getName() {
public ListContactsCommand(final OutputWriter outputWriter) { return "listContacts";
this.outputWriter = outputWriter;
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Show a list of known contacts with names."); subparser.help("Show a list of known contacts with names.");
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) { public void handleCommand(final Namespace ns, final Manager m, final OutputWriter outputWriter) {
final var writer = (PlainTextWriter) outputWriter; final var writer = (PlainTextWriter) outputWriter;
var contacts = m.getContacts(); var contacts = m.getContacts();

View file

@ -19,18 +19,21 @@ import java.util.List;
public class ListDevicesCommand implements LocalCommand { public class ListDevicesCommand implements LocalCommand {
private final static Logger logger = LoggerFactory.getLogger(ListDevicesCommand.class); private final static Logger logger = LoggerFactory.getLogger(ListDevicesCommand.class);
private final OutputWriter outputWriter;
public ListDevicesCommand(final OutputWriter outputWriter) { @Override
this.outputWriter = outputWriter; public String getName() {
return "listDevices";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Show a list of linked devices."); subparser.help("Show a list of linked devices.");
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
final var writer = (PlainTextWriter) outputWriter; final var writer = (PlainTextWriter) outputWriter;
List<Device> devices; List<Device> devices;

View file

@ -22,7 +22,13 @@ public class ListGroupsCommand implements JsonRpcLocalCommand {
private final static Logger logger = LoggerFactory.getLogger(ListGroupsCommand.class); private final static Logger logger = LoggerFactory.getLogger(ListGroupsCommand.class);
public static void attachToSubparser(final Subparser subparser) { @Override
public String getName() {
return "listGroups";
}
@Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("List group information including names, ids, active status, blocked status and members"); subparser.help("List group information including names, ids, active status, blocked status and members");
subparser.addArgument("-d", "--detailed") subparser.addArgument("-d", "--detailed")
.action(Arguments.storeTrue()) .action(Arguments.storeTrue())
@ -63,14 +69,10 @@ public class ListGroupsCommand implements JsonRpcLocalCommand {
} }
} }
private final OutputWriter outputWriter;
public ListGroupsCommand(final OutputWriter outputWriter) {
this.outputWriter = outputWriter;
}
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
final var groups = m.getGroups(); final var groups = m.getGroups();
if (outputWriter instanceof JsonWriter) { if (outputWriter instanceof JsonWriter) {

View file

@ -21,10 +21,10 @@ import java.util.List;
public class ListIdentitiesCommand implements LocalCommand { public class ListIdentitiesCommand implements LocalCommand {
private final static Logger logger = LoggerFactory.getLogger(ListIdentitiesCommand.class); private final static Logger logger = LoggerFactory.getLogger(ListIdentitiesCommand.class);
private final OutputWriter outputWriter;
public ListIdentitiesCommand(final OutputWriter outputWriter) { @Override
this.outputWriter = outputWriter; public String getName() {
return "listIdentities";
} }
private static void printIdentityFingerprint(PlainTextWriter writer, Manager m, IdentityInfo theirId) { private static void printIdentityFingerprint(PlainTextWriter writer, Manager m, IdentityInfo theirId) {
@ -38,13 +38,16 @@ public class ListIdentitiesCommand implements LocalCommand {
digits); digits);
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("List all known identity keys and their trust status, fingerprint and safety number."); subparser.help("List all known identity keys and their trust status, fingerprint and safety number.");
subparser.addArgument("-n", "--number").help("Only show identity keys for the given phone number."); subparser.addArgument("-n", "--number").help("Only show identity keys for the given phone number.");
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
final var writer = (PlainTextWriter) outputWriter; final var writer = (PlainTextWriter) outputWriter;
var number = ns.getString("number"); var number = ns.getString("number");

View file

@ -2,10 +2,11 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
public interface LocalCommand extends Command { public interface LocalCommand extends CliCommand {
void handleCommand(Namespace ns, Manager m) throws CommandException; void handleCommand(Namespace ns, Manager m, OutputWriter outputWriter) throws CommandException;
} }

View file

@ -2,6 +2,7 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.Manager;
@ -9,10 +10,14 @@ import java.util.List;
public interface MultiLocalCommand extends LocalCommand { public interface MultiLocalCommand extends LocalCommand {
void handleCommand(Namespace ns, List<Manager> m, final SignalCreator c) throws CommandException; void handleCommand(
Namespace ns, List<Manager> m, SignalCreator c, OutputWriter outputWriter
) throws CommandException;
@Override @Override
default void handleCommand(final Namespace ns, final Manager m) throws CommandException { default void handleCommand(
handleCommand(ns, List.of(m), null); final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
handleCommand(ns, List.of(m), null, outputWriter);
} }
} }

View file

@ -2,10 +2,11 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.manager.ProvisioningManager; import org.asamk.signal.manager.ProvisioningManager;
public interface ProvisioningCommand extends Command { public interface ProvisioningCommand extends CliCommand {
void handleCommand(Namespace ns, ProvisioningManager m) throws CommandException; void handleCommand(Namespace ns, ProvisioningManager m, final OutputWriter outputWriter) throws CommandException;
} }

View file

@ -31,13 +31,14 @@ import static org.asamk.signal.util.ErrorUtils.handleSendMessageResults;
public class QuitGroupCommand implements JsonRpcLocalCommand { public class QuitGroupCommand implements JsonRpcLocalCommand {
private final static Logger logger = LoggerFactory.getLogger(QuitGroupCommand.class); private final static Logger logger = LoggerFactory.getLogger(QuitGroupCommand.class);
private final OutputWriter outputWriter;
public QuitGroupCommand(final OutputWriter outputWriter) { @Override
this.outputWriter = outputWriter; public String getName() {
return "quitGroup";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Send a quit group message to all group members and remove self from member list."); subparser.help("Send a quit group message to all group members and remove self from member list.");
subparser.addArgument("-g", "--group-id", "--group").required(true).help("Specify the recipient group ID."); subparser.addArgument("-g", "--group-id", "--group").required(true).help("Specify the recipient group ID.");
subparser.addArgument("--delete") subparser.addArgument("--delete")
@ -49,7 +50,9 @@ public class QuitGroupCommand implements JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
final GroupId groupId; final GroupId groupId;
try { try {
groupId = Util.decodeGroupId(ns.getString("group-id")); groupId = Util.decodeGroupId(ns.getString("group-id"));
@ -64,7 +67,7 @@ public class QuitGroupCommand implements JsonRpcLocalCommand {
final var results = m.sendQuitGroupMessage(groupId, final var results = m.sendQuitGroupMessage(groupId,
groupAdmins == null ? Set.of() : new HashSet<>(groupAdmins)); groupAdmins == null ? Set.of() : new HashSet<>(groupAdmins));
final var timestamp = results.first(); final var timestamp = results.first();
outputResult(timestamp); outputResult(outputWriter, timestamp);
handleSendMessageResults(results.second()); handleSendMessageResults(results.second());
} catch (NotAGroupMemberException e) { } catch (NotAGroupMemberException e) {
logger.info("User is not a group member"); logger.info("User is not a group member");
@ -84,7 +87,7 @@ public class QuitGroupCommand implements JsonRpcLocalCommand {
} }
} }
private void outputResult(final long timestamp) { private void outputResult(final OutputWriter outputWriter, final long timestamp) {
if (outputWriter instanceof PlainTextWriter) { if (outputWriter instanceof PlainTextWriter) {
final var writer = (PlainTextWriter) outputWriter; final var writer = (PlainTextWriter) outputWriter;
writer.println("{}", timestamp); writer.println("{}", timestamp);

View file

@ -24,16 +24,21 @@ import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.util.Base64; import java.util.Base64;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand { public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
private final static Logger logger = LoggerFactory.getLogger(ReceiveCommand.class); private final static Logger logger = LoggerFactory.getLogger(ReceiveCommand.class);
private final OutputWriter outputWriter;
public static void attachToSubparser(final Subparser subparser) { @Override
public String getName() {
return "receive";
}
@Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Query the server for new messages."); subparser.help("Query the server for new messages.");
subparser.addArgument("-t", "--timeout") subparser.addArgument("-t", "--timeout")
.type(double.class) .type(double.class)
@ -44,17 +49,13 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
.action(Arguments.storeTrue()); .action(Arguments.storeTrue());
} }
public ReceiveCommand(final OutputWriter outputWriter) {
this.outputWriter = outputWriter;
}
@Override @Override
public Set<OutputType> getSupportedOutputTypes() { public List<OutputType> getSupportedOutputTypes() {
return Set.of(OutputType.PLAIN_TEXT, OutputType.JSON); return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
} }
public void handleCommand( public void handleCommand(
final Namespace ns, final Signal signal, DBusConnection dbusconnection final Namespace ns, final Signal signal, DBusConnection dbusconnection, final OutputWriter outputWriter
) throws CommandException { ) throws CommandException {
try { try {
if (outputWriter instanceof JsonWriter) { if (outputWriter instanceof JsonWriter) {
@ -137,7 +138,9 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
double timeout = ns.getDouble("timeout"); double timeout = ns.getDouble("timeout");
var returnOnTimeout = true; var returnOnTimeout = true;
if (timeout < 0) { if (timeout < 0) {

View file

@ -4,7 +4,6 @@ import net.sourceforge.argparse4j.impl.Arguments;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.commands.exceptions.IOErrorException; import org.asamk.signal.commands.exceptions.IOErrorException;
import org.asamk.signal.commands.exceptions.UserErrorException; import org.asamk.signal.commands.exceptions.UserErrorException;
@ -15,10 +14,13 @@ import java.io.IOException;
public class RegisterCommand implements RegistrationCommand { public class RegisterCommand implements RegistrationCommand {
public RegisterCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "register";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Register a phone number with SMS or voice verification."); subparser.help("Register a phone number with SMS or voice verification.");
subparser.addArgument("-v", "--voice") subparser.addArgument("-v", "--voice")
.help("The verification should be done over voice, not SMS.") .help("The verification should be done over voice, not SMS.")

View file

@ -5,7 +5,7 @@ import net.sourceforge.argparse4j.inf.Namespace;
import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.manager.RegistrationManager; import org.asamk.signal.manager.RegistrationManager;
public interface RegistrationCommand extends Command { public interface RegistrationCommand extends CliCommand {
void handleCommand(Namespace ns, RegistrationManager m) throws CommandException; void handleCommand(Namespace ns, RegistrationManager m) throws CommandException;
} }

View file

@ -22,13 +22,13 @@ import java.util.Map;
public class RemoteDeleteCommand implements DbusCommand, JsonRpcLocalCommand { public class RemoteDeleteCommand implements DbusCommand, JsonRpcLocalCommand {
private final OutputWriter outputWriter; @Override
public String getName() {
public RemoteDeleteCommand(final OutputWriter outputWriter) { return "remoteDelete";
this.outputWriter = outputWriter;
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Remotely delete a previously sent message."); subparser.help("Remotely delete a previously sent message.");
subparser.addArgument("-t", "--target-timestamp") subparser.addArgument("-t", "--target-timestamp")
.required(true) .required(true)
@ -39,7 +39,9 @@ public class RemoteDeleteCommand implements DbusCommand, JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Signal signal) throws CommandException { public void handleCommand(
final Namespace ns, final Signal signal, final OutputWriter outputWriter
) throws CommandException {
final List<String> recipients = ns.getList("recipient"); final List<String> recipients = ns.getList("recipient");
final var groupIdString = ns.getString("group-id"); final var groupIdString = ns.getString("group-id");
@ -69,7 +71,7 @@ public class RemoteDeleteCommand implements DbusCommand, JsonRpcLocalCommand {
} else { } else {
timestamp = signal.sendRemoteDeleteMessage(targetTimestamp, recipients); timestamp = signal.sendRemoteDeleteMessage(targetTimestamp, recipients);
} }
outputResult(timestamp); outputResult(outputWriter, timestamp);
} catch (UnknownObject e) { } catch (UnknownObject e) {
throw new UserErrorException("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage()); throw new UserErrorException("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage());
} catch (Signal.Error.InvalidNumber e) { } catch (Signal.Error.InvalidNumber e) {
@ -82,11 +84,13 @@ public class RemoteDeleteCommand implements DbusCommand, JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
handleCommand(ns, new DbusSignalImpl(m, null)); final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
handleCommand(ns, new DbusSignalImpl(m, null), outputWriter);
} }
private void outputResult(final long timestamp) { private void outputResult(final OutputWriter outputWriter, final long timestamp) {
if (outputWriter instanceof PlainTextWriter) { if (outputWriter instanceof PlainTextWriter) {
final var writer = (PlainTextWriter) outputWriter; final var writer = (PlainTextWriter) outputWriter;
writer.println("{}", timestamp); writer.println("{}", timestamp);

View file

@ -12,10 +12,13 @@ import java.io.IOException;
public class RemoveDeviceCommand implements JsonRpcLocalCommand { public class RemoveDeviceCommand implements JsonRpcLocalCommand {
public RemoveDeviceCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "removeDevice";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Remove a linked device."); subparser.help("Remove a linked device.");
subparser.addArgument("-d", "--device-id", "--deviceId") subparser.addArgument("-d", "--device-id", "--deviceId")
.type(int.class) .type(int.class)
@ -24,7 +27,9 @@ public class RemoveDeviceCommand implements JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
try { try {
int deviceId = ns.getInt("device-id"); int deviceId = ns.getInt("device-id");
m.removeLinkedDevices(deviceId); m.removeLinkedDevices(deviceId);

View file

@ -15,15 +15,20 @@ import java.io.IOException;
public class RemovePinCommand implements JsonRpcLocalCommand { public class RemovePinCommand implements JsonRpcLocalCommand {
public RemovePinCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "removePin";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Remove the registration lock pin."); subparser.help("Remove the registration lock pin.");
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
try { try {
m.setRegistrationLockPin(Optional.absent()); m.setRegistrationLockPin(Optional.absent());
} catch (UnauthenticatedResponseException e) { } catch (UnauthenticatedResponseException e) {

View file

@ -30,13 +30,14 @@ import java.util.Map;
public class SendCommand implements DbusCommand, JsonRpcLocalCommand { public class SendCommand implements DbusCommand, JsonRpcLocalCommand {
private final static Logger logger = LoggerFactory.getLogger(SendCommand.class); private final static Logger logger = LoggerFactory.getLogger(SendCommand.class);
private final OutputWriter outputWriter;
public SendCommand(final OutputWriter outputWriter) { @Override
this.outputWriter = outputWriter; public String getName() {
return "send";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Send a message to another user or group."); subparser.help("Send a message to another user or group.");
subparser.addArgument("recipient").help("Specify the recipients' phone number.").nargs("*"); subparser.addArgument("recipient").help("Specify the recipients' phone number.").nargs("*");
final var mutuallyExclusiveGroup = subparser.addMutuallyExclusiveGroup(); final var mutuallyExclusiveGroup = subparser.addMutuallyExclusiveGroup();
@ -53,7 +54,9 @@ public class SendCommand implements DbusCommand, JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Signal signal) throws CommandException { public void handleCommand(
final Namespace ns, final Signal signal, final OutputWriter outputWriter
) throws CommandException {
final List<String> recipients = ns.getList("recipient"); final List<String> recipients = ns.getList("recipient");
final var isEndSession = ns.getBoolean("end-session"); final var isEndSession = ns.getBoolean("end-session");
final var groupIdString = ns.getString("group-id"); final var groupIdString = ns.getString("group-id");
@ -106,7 +109,7 @@ public class SendCommand implements DbusCommand, JsonRpcLocalCommand {
try { try {
var timestamp = signal.sendGroupMessage(messageText, attachments, groupId); var timestamp = signal.sendGroupMessage(messageText, attachments, groupId);
outputResult(timestamp); outputResult(outputWriter, timestamp);
return; return;
} catch (DBusExecutionException e) { } catch (DBusExecutionException e) {
throw new UnexpectedErrorException("Failed to send group message: " + e.getMessage()); throw new UnexpectedErrorException("Failed to send group message: " + e.getMessage());
@ -116,7 +119,7 @@ public class SendCommand implements DbusCommand, JsonRpcLocalCommand {
if (isNoteToSelf) { if (isNoteToSelf) {
try { try {
var timestamp = signal.sendNoteToSelfMessage(messageText, attachments); var timestamp = signal.sendNoteToSelfMessage(messageText, attachments);
outputResult(timestamp); outputResult(outputWriter, timestamp);
return; return;
} catch (Signal.Error.UntrustedIdentity e) { } catch (Signal.Error.UntrustedIdentity e) {
throw new UntrustedKeyErrorException("Failed to send message: " + e.getMessage()); throw new UntrustedKeyErrorException("Failed to send message: " + e.getMessage());
@ -127,7 +130,7 @@ public class SendCommand implements DbusCommand, JsonRpcLocalCommand {
try { try {
var timestamp = signal.sendMessage(messageText, attachments, recipients); var timestamp = signal.sendMessage(messageText, attachments, recipients);
outputResult(timestamp); outputResult(outputWriter, timestamp);
} catch (UnknownObject e) { } catch (UnknownObject e) {
throw new UserErrorException("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage()); throw new UserErrorException("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage());
} catch (Signal.Error.UntrustedIdentity e) { } catch (Signal.Error.UntrustedIdentity e) {
@ -137,7 +140,7 @@ public class SendCommand implements DbusCommand, JsonRpcLocalCommand {
} }
} }
private void outputResult(final long timestamp) { private void outputResult(final OutputWriter outputWriter, final long timestamp) {
if (outputWriter instanceof PlainTextWriter) { if (outputWriter instanceof PlainTextWriter) {
final var writer = (PlainTextWriter) outputWriter; final var writer = (PlainTextWriter) outputWriter;
writer.println("{}", timestamp); writer.println("{}", timestamp);
@ -148,7 +151,9 @@ public class SendCommand implements DbusCommand, JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
handleCommand(ns, new DbusSignalImpl(m, null)); final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
handleCommand(ns, new DbusSignalImpl(m, null), outputWriter);
} }
} }

View file

@ -14,15 +14,20 @@ import java.io.IOException;
public class SendContactsCommand implements JsonRpcLocalCommand { public class SendContactsCommand implements JsonRpcLocalCommand {
public SendContactsCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "sendContacts";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Send a synchronization message with the local contacts list to all linked devices."); subparser.help("Send a synchronization message with the local contacts list to all linked devices.");
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
try { try {
m.sendContacts(); m.sendContacts();
} catch (UntrustedIdentityException e) { } catch (UntrustedIdentityException e) {

View file

@ -23,13 +23,13 @@ import java.util.Map;
public class SendReactionCommand implements DbusCommand, JsonRpcLocalCommand { public class SendReactionCommand implements DbusCommand, JsonRpcLocalCommand {
private final OutputWriter outputWriter; @Override
public String getName() {
public SendReactionCommand(final OutputWriter outputWriter) { return "sendReaction";
this.outputWriter = outputWriter;
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Send reaction to a previously received or sent message."); subparser.help("Send reaction to a previously received or sent message.");
subparser.addArgument("-g", "--group-id", "--group").help("Specify the recipient group ID."); subparser.addArgument("-g", "--group-id", "--group").help("Specify the recipient group ID.");
subparser.addArgument("recipient").help("Specify the recipients' phone number.").nargs("*"); subparser.addArgument("recipient").help("Specify the recipients' phone number.").nargs("*");
@ -47,7 +47,9 @@ public class SendReactionCommand implements DbusCommand, JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Signal signal) throws CommandException { public void handleCommand(
final Namespace ns, final Signal signal, final OutputWriter outputWriter
) throws CommandException {
final List<String> recipients = ns.getList("recipient"); final List<String> recipients = ns.getList("recipient");
final var groupIdString = ns.getString("group-id"); final var groupIdString = ns.getString("group-id");
@ -80,7 +82,7 @@ public class SendReactionCommand implements DbusCommand, JsonRpcLocalCommand {
} else { } else {
timestamp = signal.sendMessageReaction(emoji, isRemove, targetAuthor, targetTimestamp, recipients); timestamp = signal.sendMessageReaction(emoji, isRemove, targetAuthor, targetTimestamp, recipients);
} }
outputResult(timestamp); outputResult(outputWriter, timestamp);
} catch (UnknownObject e) { } catch (UnknownObject e) {
throw new UserErrorException("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage()); throw new UserErrorException("Failed to find dbus object, maybe missing the -u flag: " + e.getMessage());
} catch (Signal.Error.InvalidNumber e) { } catch (Signal.Error.InvalidNumber e) {
@ -93,11 +95,13 @@ public class SendReactionCommand implements DbusCommand, JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
handleCommand(ns, new DbusSignalImpl(m, null)); final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
handleCommand(ns, new DbusSignalImpl(m, null), outputWriter);
} }
private void outputResult(final long timestamp) { private void outputResult(final OutputWriter outputWriter, final long timestamp) {
if (outputWriter instanceof PlainTextWriter) { if (outputWriter instanceof PlainTextWriter) {
final var writer = (PlainTextWriter) outputWriter; final var writer = (PlainTextWriter) outputWriter;
writer.println("{}", timestamp); writer.println("{}", timestamp);

View file

@ -12,15 +12,20 @@ import java.io.IOException;
public class SendSyncRequestCommand implements JsonRpcLocalCommand { public class SendSyncRequestCommand implements JsonRpcLocalCommand {
public SendSyncRequestCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "sendSyncRequest";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Send a synchronization request message to master device (for group, contacts, ...)."); subparser.help("Send a synchronization request message to master device (for group, contacts, ...).");
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
try { try {
m.requestAllSyncData(); m.requestAllSyncData();
} catch (IOException e) { } catch (IOException e) {

View file

@ -22,10 +22,13 @@ import java.util.HashSet;
public class SendTypingCommand implements JsonRpcLocalCommand { public class SendTypingCommand implements JsonRpcLocalCommand {
public SendTypingCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "sendTyping";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help( subparser.help(
"Send typing message to trigger a typing indicator for the recipient. Indicator will be shown for 15seconds unless a typing STOP message is sent first."); "Send typing message to trigger a typing indicator for the recipient. Indicator will be shown for 15seconds unless a typing STOP message is sent first.");
subparser.addArgument("-g", "--group-id", "--group").help("Specify the recipient group ID."); subparser.addArgument("-g", "--group-id", "--group").help("Specify the recipient group ID.");
@ -34,7 +37,9 @@ public class SendTypingCommand implements JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
final var recipients = ns.<String>getList("recipient"); final var recipients = ns.<String>getList("recipient");
final var groupIdString = ns.getString("group-id"); final var groupIdString = ns.getString("group-id");

View file

@ -15,17 +15,22 @@ import java.io.IOException;
public class SetPinCommand implements JsonRpcLocalCommand { public class SetPinCommand implements JsonRpcLocalCommand {
public SetPinCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "setPin";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Set a registration lock pin, to prevent others from registering this number."); subparser.help("Set a registration lock pin, to prevent others from registering this number.");
subparser.addArgument("pin") subparser.addArgument("pin")
.help("The registration lock PIN, that will be required for new registrations (resets after 7 days of inactivity)"); .help("The registration lock PIN, that will be required for new registrations (resets after 7 days of inactivity)");
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
try { try {
var registrationLockPin = ns.getString("pin"); var registrationLockPin = ns.getString("pin");
m.setRegistrationLockPin(Optional.of(registrationLockPin)); m.setRegistrationLockPin(Optional.of(registrationLockPin));

View file

@ -15,10 +15,13 @@ import java.util.Locale;
public class TrustCommand implements JsonRpcLocalCommand { public class TrustCommand implements JsonRpcLocalCommand {
public TrustCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "trust";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Set the trust level of a given number."); subparser.help("Set the trust level of a given number.");
subparser.addArgument("number").help("Specify the phone number, for which to set the trust.").required(true); subparser.addArgument("number").help("Specify the phone number, for which to set the trust.").required(true);
var mutTrust = subparser.addMutuallyExclusiveGroup(); var mutTrust = subparser.addMutuallyExclusiveGroup();
@ -30,7 +33,9 @@ public class TrustCommand implements JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
var number = ns.getString("number"); var number = ns.getString("number");
if (ns.getBoolean("trust-all-known-keys")) { if (ns.getBoolean("trust-all-known-keys")) {
boolean res; boolean res;

View file

@ -19,17 +19,22 @@ public class UnblockCommand implements JsonRpcLocalCommand {
private final static Logger logger = LoggerFactory.getLogger(UnblockCommand.class); private final static Logger logger = LoggerFactory.getLogger(UnblockCommand.class);
public UnblockCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "unblock";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Unblock the given contacts or groups (messages will be received again)"); subparser.help("Unblock the given contacts or groups (messages will be received again)");
subparser.addArgument("contact").help("Contact number").nargs("*"); subparser.addArgument("contact").help("Contact number").nargs("*");
subparser.addArgument("-g", "--group-id", "--group").help("Group ID").nargs("*"); subparser.addArgument("-g", "--group-id", "--group").help("Group ID").nargs("*");
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
for (var contactNumber : ns.<String>getList("contact")) { for (var contactNumber : ns.<String>getList("contact")) {
try { try {
m.setContactBlocked(contactNumber, false); m.setContactBlocked(contactNumber, false);

View file

@ -13,10 +13,13 @@ import java.io.IOException;
public class UnregisterCommand implements LocalCommand { public class UnregisterCommand implements LocalCommand {
public UnregisterCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "unregister";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Unregister the current device from the signal server."); subparser.help("Unregister the current device from the signal server.");
subparser.addArgument("--delete-account") subparser.addArgument("--delete-account")
.help("Delete account completely from server. CAUTION: Only do this if you won't use this number again!") .help("Delete account completely from server. CAUTION: Only do this if you won't use this number again!")
@ -24,7 +27,9 @@ public class UnregisterCommand implements LocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
try { try {
if (ns.getBoolean("delete-account")) { if (ns.getBoolean("delete-account")) {
m.deleteAccount(); m.deleteAccount();

View file

@ -12,15 +12,20 @@ import java.io.IOException;
public class UpdateAccountCommand implements JsonRpcLocalCommand { public class UpdateAccountCommand implements JsonRpcLocalCommand {
public UpdateAccountCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "updateAccount";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Update the account attributes on the signal server."); subparser.help("Update the account attributes on the signal server.");
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
try { try {
m.updateAccountAttributes(); m.updateAccountAttributes();
} catch (IOException e) { } catch (IOException e) {

View file

@ -15,10 +15,13 @@ import java.io.IOException;
public class UpdateContactCommand implements JsonRpcLocalCommand { public class UpdateContactCommand implements JsonRpcLocalCommand {
public UpdateContactCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "updateContact";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Update the details of a given contact"); subparser.help("Update the details of a given contact");
subparser.addArgument("number").help("Contact number"); subparser.addArgument("number").help("Contact number");
subparser.addArgument("-n", "--name").help("New contact name"); subparser.addArgument("-n", "--name").help("New contact name");
@ -26,7 +29,9 @@ public class UpdateContactCommand implements JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
var number = ns.getString("number"); var number = ns.getString("number");
try { try {

View file

@ -35,13 +35,14 @@ import java.util.List;
public class UpdateGroupCommand implements DbusCommand, JsonRpcLocalCommand { public class UpdateGroupCommand implements DbusCommand, JsonRpcLocalCommand {
private final static Logger logger = LoggerFactory.getLogger(UpdateGroupCommand.class); private final static Logger logger = LoggerFactory.getLogger(UpdateGroupCommand.class);
private final OutputWriter outputWriter;
public UpdateGroupCommand(final OutputWriter outputWriter) { @Override
this.outputWriter = outputWriter; public String getName() {
return "updateGroup";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Create or update a group."); subparser.help("Create or update a group.");
subparser.addArgument("-g", "--group-id", "--group").help("Specify the group ID."); subparser.addArgument("-g", "--group-id", "--group").help("Specify the group ID.");
subparser.addArgument("-n", "--name").help("Specify the new group name."); subparser.addArgument("-n", "--name").help("Specify the new group name.");
@ -107,7 +108,9 @@ public class UpdateGroupCommand implements DbusCommand, JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
GroupId groupId = null; GroupId groupId = null;
final var groupIdString = ns.getString("group-id"); final var groupIdString = ns.getString("group-id");
if (groupIdString != null) { if (groupIdString != null) {
@ -163,7 +166,7 @@ public class UpdateGroupCommand implements DbusCommand, JsonRpcLocalCommand {
timestamp = results.first(); timestamp = results.first();
ErrorUtils.handleSendMessageResults(results.second()); ErrorUtils.handleSendMessageResults(results.second());
} }
outputResult(timestamp, isNewGroup ? groupId : null); outputResult(outputWriter, timestamp, isNewGroup ? groupId : null);
} catch (AttachmentInvalidException e) { } catch (AttachmentInvalidException e) {
throw new UserErrorException("Failed to add avatar attachment for group\": " + e.getMessage()); throw new UserErrorException("Failed to add avatar attachment for group\": " + e.getMessage());
} catch (GroupNotFoundException e) { } catch (GroupNotFoundException e) {
@ -178,7 +181,9 @@ public class UpdateGroupCommand implements DbusCommand, JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Signal signal) throws CommandException { public void handleCommand(
final Namespace ns, final Signal signal, final OutputWriter outputWriter
) throws CommandException {
byte[] groupId = null; byte[] groupId = null;
if (ns.getString("group-id") != null) { if (ns.getString("group-id") != null) {
try { try {
@ -209,7 +214,7 @@ public class UpdateGroupCommand implements DbusCommand, JsonRpcLocalCommand {
try { try {
var newGroupId = signal.updateGroup(groupId, groupName, groupMembers, groupAvatar); var newGroupId = signal.updateGroup(groupId, groupName, groupMembers, groupAvatar);
if (groupId.length != newGroupId.length) { if (groupId.length != newGroupId.length) {
outputResult(null, GroupId.unknownVersion(newGroupId)); outputResult(outputWriter, null, GroupId.unknownVersion(newGroupId));
} }
} catch (Signal.Error.AttachmentInvalid e) { } catch (Signal.Error.AttachmentInvalid e) {
throw new UserErrorException("Failed to add avatar attachment for group\": " + e.getMessage()); throw new UserErrorException("Failed to add avatar attachment for group\": " + e.getMessage());
@ -218,7 +223,7 @@ public class UpdateGroupCommand implements DbusCommand, JsonRpcLocalCommand {
} }
} }
private void outputResult(final Long timestamp, final GroupId groupId) { private void outputResult(final OutputWriter outputWriter, final Long timestamp, final GroupId groupId) {
if (outputWriter instanceof PlainTextWriter) { if (outputWriter instanceof PlainTextWriter) {
final var writer = (PlainTextWriter) outputWriter; final var writer = (PlainTextWriter) outputWriter;
if (groupId != null) { if (groupId != null) {

View file

@ -15,10 +15,13 @@ import java.io.IOException;
public class UpdateProfileCommand implements JsonRpcLocalCommand { public class UpdateProfileCommand implements JsonRpcLocalCommand {
public UpdateProfileCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "updateProfile";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Set a name, about and avatar image for the user profile"); subparser.help("Set a name, about and avatar image for the user profile");
subparser.addArgument("--given-name", "--name").help("New profile (given) name"); subparser.addArgument("--given-name", "--name").help("New profile (given) name");
subparser.addArgument("--family-name").help("New profile family name (optional)"); subparser.addArgument("--family-name").help("New profile family name (optional)");
@ -31,7 +34,9 @@ public class UpdateProfileCommand implements JsonRpcLocalCommand {
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
var givenName = ns.getString("given-name"); var givenName = ns.getString("given-name");
var familyName = ns.getString("family-name"); var familyName = ns.getString("family-name");
var about = ns.getString("about"); var about = ns.getString("about");

View file

@ -19,20 +19,23 @@ import java.io.IOException;
public class UploadStickerPackCommand implements LocalCommand { public class UploadStickerPackCommand implements LocalCommand {
private final static Logger logger = LoggerFactory.getLogger(UploadStickerPackCommand.class); private final static Logger logger = LoggerFactory.getLogger(UploadStickerPackCommand.class);
private final OutputWriter outputWriter;
public UploadStickerPackCommand(final OutputWriter outputWriter) { @Override
this.outputWriter = outputWriter; public String getName() {
return "uploadStickerPack";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Upload a new sticker pack, consisting of a manifest file and the stickers images."); subparser.help("Upload a new sticker pack, consisting of a manifest file and the stickers images.");
subparser.addArgument("path") subparser.addArgument("path")
.help("The path of the manifest.json or a zip file containing the sticker pack you wish to upload."); .help("The path of the manifest.json or a zip file containing the sticker pack you wish to upload.");
} }
@Override @Override
public void handleCommand(final Namespace ns, final Manager m) throws CommandException { public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
final var writer = (PlainTextWriter) outputWriter; final var writer = (PlainTextWriter) outputWriter;
var path = new File(ns.getString("path")); var path = new File(ns.getString("path"));

View file

@ -3,7 +3,6 @@ package org.asamk.signal.commands;
import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser; import net.sourceforge.argparse4j.inf.Subparser;
import org.asamk.signal.OutputWriter;
import org.asamk.signal.commands.exceptions.CommandException; import org.asamk.signal.commands.exceptions.CommandException;
import org.asamk.signal.commands.exceptions.IOErrorException; import org.asamk.signal.commands.exceptions.IOErrorException;
import org.asamk.signal.commands.exceptions.UnexpectedErrorException; import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
@ -17,10 +16,13 @@ import java.io.IOException;
public class VerifyCommand implements RegistrationCommand { public class VerifyCommand implements RegistrationCommand {
public VerifyCommand(final OutputWriter outputWriter) { @Override
public String getName() {
return "verify";
} }
public static void attachToSubparser(final Subparser subparser) { @Override
public void attachToSubparser(final Subparser subparser) {
subparser.help("Verify the number using the code received via SMS or voice."); subparser.help("Verify the number using the code received via SMS or voice.");
subparser.addArgument("verificationCode").help("The verification code you received via sms or voice call."); subparser.addArgument("verificationCode").help("The verification code you received via sms or voice call.");
subparser.addArgument("-p", "--pin").help("The registration lock PIN, that was set by the user (Optional)"); subparser.addArgument("-p", "--pin").help("The registration lock PIN, that was set by the user (Optional)");

View file

@ -10,14 +10,15 @@ import java.util.Map;
public class VersionCommand implements JsonRpcCommand<Void> { public class VersionCommand implements JsonRpcCommand<Void> {
private final OutputWriter outputWriter; @Override
public String getName() {
public VersionCommand(final OutputWriter outputWriter) { return "version";
this.outputWriter = outputWriter;
} }
@Override @Override
public void handleCommand(final Void request, final Manager m) throws CommandException { public void handleCommand(
final Void request, final Manager m, final OutputWriter outputWriter
) throws CommandException {
final var jsonWriter = (JsonWriter) outputWriter; final var jsonWriter = (JsonWriter) outputWriter;
jsonWriter.write(Map.of("version", BaseConfig.PROJECT_VERSION)); jsonWriter.write(Map.of("version", BaseConfig.PROJECT_VERSION));
} }