X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/221d937eecca5c9b09a3bee7df812203b9927a56..48b2c7ff8ad7b653c3a0cb42775a5850f593d0a0:/src/main/java/org/asamk/signal/App.java diff --git a/src/main/java/org/asamk/signal/App.java b/src/main/java/org/asamk/signal/App.java index 5b2c91c6..33338a4c 100644 --- a/src/main/java/org/asamk/signal/App.java +++ b/src/main/java/org/asamk/signal/App.java @@ -35,6 +35,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import static net.sourceforge.argparse4j.DefaultSettings.VERSION_0_9_0_DEFAULT_SETTINGS; + public class App { private final static Logger logger = LoggerFactory.getLogger(App.class); @@ -42,7 +44,8 @@ public class App { private final Namespace ns; static ArgumentParser buildArgumentParser() { - var parser = ArgumentParsers.newFor("signal-cli") + var parser = ArgumentParsers.newFor("signal-cli", VERSION_0_9_0_DEFAULT_SETTINGS) + .includeArgumentNamesAsKeysInResult(true) .build() .defaultHelp(true) .description("Commandline interface for Signal.") @@ -55,7 +58,7 @@ public class App { parser.addArgument("--config") .help("Set the path, where to store the config (Default: $XDG_DATA_HOME/signal-cli , $HOME/.local/share/signal-cli)."); - parser.addArgument("-u", "--username").help("Specify your phone number, that will be used for verification."); + parser.addArgument("-u", "--username").help("Specify your phone number, that will be your identifier."); var mut = parser.addMutuallyExclusiveGroup(); mut.addArgument("--dbus").help("Make request via user dbus.").action(Arguments.storeTrue()); @@ -66,13 +69,17 @@ public class App { .type(Arguments.enumStringType(OutputType.class)) .setDefault(OutputType.PLAIN_TEXT); + parser.addArgument("--service-environment") + .help("Choose the server environment to use.") + .type(Arguments.enumStringType(ServiceEnvironmentCli.class)) + .setDefault(ServiceEnvironmentCli.LIVE); + var subparsers = parser.addSubparsers().title("subcommands").dest("command"); - final var commands = Commands.getCommands(); - for (var entry : commands.entrySet()) { - var subparser = subparsers.addParser(entry.getKey()); - entry.getValue().attachToSubparser(subparser); - } + Commands.getCommandSubparserAttachers().forEach((key, value) -> { + var subparser = subparsers.addParser(key); + value.attachToSubparser(subparser); + }); return parser; } @@ -82,21 +89,25 @@ public class App { } public void init() throws CommandException { + var outputType = ns.get("output"); + var outputWriter = outputType == OutputType.JSON + ? new JsonWriter(System.out) + : new PlainTextWriterImpl(System.out); + var commandKey = ns.getString("command"); - var command = Commands.getCommand(commandKey); + var command = Commands.getCommand(commandKey, outputWriter); if (command == null) { throw new UserErrorException("Command not implemented!"); } - OutputType outputType = ns.get("output"); if (!command.getSupportedOutputTypes().contains(outputType)) { throw new UserErrorException("Command doesn't support output type " + outputType.toString()); } var username = ns.getString("username"); - final boolean useDbus = ns.getBoolean("dbus"); - final boolean useDbusSystem = ns.getBoolean("dbus_system"); + final var useDbus = ns.getBoolean("dbus"); + final var useDbusSystem = ns.getBoolean("dbus-system"); if (useDbus || useDbusSystem) { // If username is null, it will connect to the default object path initDbusClient(command, username, useDbusSystem); @@ -111,7 +122,10 @@ public class App { dataPath = getDefaultDataPath(); } - final var serviceEnvironment = ServiceEnvironment.LIVE; + final var serviceEnvironmentCli = ns.get("service-environment"); + final var serviceEnvironment = serviceEnvironmentCli == ServiceEnvironmentCli.LIVE + ? ServiceEnvironment.LIVE + : ServiceEnvironment.SANDBOX; if (!ServiceConfig.getCapabilities().isGv2()) { logger.warn("WARNING: Support for new group V2 is disabled," @@ -133,16 +147,15 @@ public class App { if (username == null) { var usernames = Manager.getAllLocalUsernames(dataPath); - if (usernames.size() == 0) { - throw new UserErrorException("No local users found, you first need to register or link an account"); - } if (command instanceof MultiLocalCommand) { handleMultiLocalCommand((MultiLocalCommand) command, dataPath, serviceEnvironment, usernames); return; } - if (usernames.size() > 1) { + if (usernames.size() == 0) { + throw new UserErrorException("No local users found, you first need to register or link an account"); + } else if (usernames.size() > 1) { throw new UserErrorException( "Multiple users found, you need to specify a username (phone number) with -u"); } @@ -181,7 +194,11 @@ public class App { try { manager = RegistrationManager.init(username, dataPath, serviceEnvironment, BaseConfig.USER_AGENT); } catch (Throwable e) { - throw new UnexpectedErrorException("Error loading or creating state file: " + e.getMessage()); + throw new UnexpectedErrorException("Error loading or creating state file: " + + e.getMessage() + + " (" + + e.getClass().getSimpleName() + + ")"); } try (var m = manager) { command.handleCommand(ns, m); @@ -211,7 +228,11 @@ public class App { ) throws CommandException { final var managers = new ArrayList(); for (String u : usernames) { - managers.add(loadManager(u, dataPath, serviceEnvironment)); + try { + managers.add(loadManager(u, dataPath, serviceEnvironment)); + } catch (CommandException e) { + logger.warn("Ignoring {}: {}", u, e.getMessage()); + } } command.handleCommand(ns, managers); @@ -234,7 +255,14 @@ public class App { } catch (NotRegisteredException e) { throw new UserErrorException("User " + username + " is not registered."); } catch (Throwable e) { - throw new UnexpectedErrorException("Error loading state file for user " + username + ": " + e.getMessage()); + logger.debug("Loading state file failed", e); + throw new UnexpectedErrorException("Error loading state file for user " + + username + + ": " + + e.getMessage() + + " (" + + e.getClass().getSimpleName() + + ")"); } try { @@ -280,30 +308,9 @@ public class App { } /** - * Uses $XDG_DATA_HOME/signal-cli if it exists, or if none of the legacy directories exist: - * - $HOME/.config/signal - * - $HOME/.config/textsecure - * - * @return the data directory to be used by signal-cli. + * @return the default data directory to be used by signal-cli. */ private static File getDefaultDataPath() { - var dataPath = new File(IOUtils.getDataHomeDir(), "signal-cli"); - if (dataPath.exists()) { - return dataPath; - } - - var configPath = new File(System.getProperty("user.home"), ".config"); - - var legacySettingsPath = new File(configPath, "signal"); - if (legacySettingsPath.exists()) { - return legacySettingsPath; - } - - legacySettingsPath = new File(configPath, "textsecure"); - if (legacySettingsPath.exists()) { - return legacySettingsPath; - } - - return dataPath; + return new File(IOUtils.getDataHomeDir(), "signal-cli"); } }