From ac31901f316905e49745a7b5c530abdf12188528 Mon Sep 17 00:00:00 2001 From: david-harley Date: Mon, 11 Jan 2021 10:57:24 +1030 Subject: [PATCH] Added AsamK's suggestions --- man/signal-cli.1.adoc | 16 +-- src/main/java/org/asamk/signal/Main.java | 3 + .../signal/commands/GetUserStatusCommand.java | 5 +- .../signal/commands/ListGroupsCommand.java | 107 +++++------------- .../asamk/signal/commands/ReceiveCommand.java | 7 +- 5 files changed, 40 insertions(+), 98 deletions(-) diff --git a/man/signal-cli.1.adoc b/man/signal-cli.1.adoc index 9d7d97ee..ba0d72d4 100644 --- a/man/signal-cli.1.adoc +++ b/man/signal-cli.1.adoc @@ -44,6 +44,9 @@ Make request via user dbus. *--dbus-system*:: Make request via system dbus. +*-o* OUTPUT-MODE, *--output* OUTPUT-MODE:: +Specify if you want commands to output in either "plain-text" mode or in "json". Defaults to "plain-text" + == Commands === register @@ -126,12 +129,10 @@ Use listDevices to see the deviceIds. === getUserStatus -Uses a list of phone numbers to determine the statuses of those users. Shows if they are registered on the Signal Servers or not. +Uses a list of phone numbers to determine the statuses of those users. Shows if they are registered on the Signal Servers or not. In json mode this is outputted as a list of objects. [NUMBER [NUMBER ...]]:: One or more numbers to check. -*--j*, *--json*:: -Output the statuses as an array of json objects. === send @@ -177,15 +178,13 @@ Remove a reaction. === receive Query the server for new messages. -New messages are printed on standardoutput and attachments are downloaded to the config directory. +New messages are printed on standard output and attachments are downloaded to the config directory. In json mode this is outputted as one json object per line. *-t* TIMEOUT, *--timeout* TIMEOUT:: Number of seconds to wait for new messages (negative values disable timeout). Default is 5 seconds. *--ignore-attachments*:: Don’t download attachments of received messages. -*--j*, *--json*:: -Output received messages in json format, one object per line. === joinGroup @@ -222,14 +221,11 @@ Specify the recipient group ID in base64 encoding. === listGroups -Show a list of known groups and related information. +Show a list of known groups and related information. In json mode this is outputted as an list of objects and is always in detailed mode. *-d*, *--detailed*:: Include the list of members of each group and the group invite link. -*--j*, *--json*:: -Output group information as a list of json objects. - === listIdentities List all known identity keys and their trust status, fingerprint and safety number. diff --git a/src/main/java/org/asamk/signal/Main.java b/src/main/java/org/asamk/signal/Main.java index 6204778d..60716ff3 100644 --- a/src/main/java/org/asamk/signal/Main.java +++ b/src/main/java/org/asamk/signal/Main.java @@ -283,6 +283,9 @@ public class Main { mut.addArgument("--dbus").help("Make request via user dbus.").action(Arguments.storeTrue()); mut.addArgument("--dbus-system").help("Make request via system dbus.").action(Arguments.storeTrue()); + parser.addArgument("-o", "--output").help("Choose to output in plain text or JSON") + .choices("plain-text", "json").setDefault("plain-text"); + Subparsers subparsers = parser.addSubparsers() .title("subcommands") .dest("command") diff --git a/src/main/java/org/asamk/signal/commands/GetUserStatusCommand.java b/src/main/java/org/asamk/signal/commands/GetUserStatusCommand.java index dcd41cfa..64bb02ed 100644 --- a/src/main/java/org/asamk/signal/commands/GetUserStatusCommand.java +++ b/src/main/java/org/asamk/signal/commands/GetUserStatusCommand.java @@ -21,9 +21,6 @@ public class GetUserStatusCommand implements LocalCommand { public void attachToSubparser(final Subparser subparser) { subparser.addArgument("number").help("Phone number").nargs("+"); subparser.help("Check if the specified phone number/s have been registered"); - subparser.addArgument("-j", "--json") - .help("Output received messages in json format, one json object per line.") - .action(Arguments.storeTrue()); } @Override @@ -47,7 +44,7 @@ public class GetUserStatusCommand implements LocalCommand { } // Output - if (ns.getBoolean("json")) { + if (ns.getString("output").equals("json")) { List objects = registered.entrySet() .stream() .map(entry -> new JsonIsRegistered(entry.getKey(), entry.getValue())) diff --git a/src/main/java/org/asamk/signal/commands/ListGroupsCommand.java b/src/main/java/org/asamk/signal/commands/ListGroupsCommand.java index 5493441c..0f212d38 100644 --- a/src/main/java/org/asamk/signal/commands/ListGroupsCommand.java +++ b/src/main/java/org/asamk/signal/commands/ListGroupsCommand.java @@ -16,36 +16,14 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; public class ListGroupsCommand implements LocalCommand { - private enum MembersType { - MEMBERS, - PENDING_MEMBERS, - REQUESTING_MEMBERS, - } - - private static Set getMembersSet(Manager m, GroupInfo group, MembersType type) { - Set members; - switch (type) { - case MEMBERS: - members = group.getMembers(); - break; - case PENDING_MEMBERS: - members = group.getPendingMembers(); - break; - case REQUESTING_MEMBERS: - members = group.getRequestingMembers(); - break; - default: - return Collections.emptySet(); - } - - return members.stream().map(m::resolveSignalServiceAddress) + private static Set resolveMembers(Manager m, Set addresses) { + return addresses.stream().map(m::resolveSignalServiceAddress) .map(SignalServiceAddress::getLegacyIdentifier) .collect(Collectors.toSet()); } @@ -72,9 +50,9 @@ public class ListGroupsCommand implements LocalCommand { group.getTitle(), group.isMember(m.getSelfAddress()), group.isBlocked(), - getMembersSet(m, group, MembersType.MEMBERS), - getMembersSet(m, group, MembersType.PENDING_MEMBERS), - getMembersSet(m, group, MembersType.REQUESTING_MEMBERS), + resolveMembers(m, group.getMembers()), + resolveMembers(m, group.getPendingMembers()), + resolveMembers(m, group.getRequestingMembers()), groupInviteLink == null ? '-' : groupInviteLink.getUrl())); } else { System.out.println(String.format("Id: %s Name: %s Active: %s Blocked: %b", @@ -87,11 +65,10 @@ public class ListGroupsCommand implements LocalCommand { @Override public void attachToSubparser(final Subparser subparser) { - subparser.addArgument("-d", "--detailed").action(Arguments.storeTrue()).help("List members of each group"); - subparser.help("List group name and ids"); - subparser.addArgument("-j", "--json") - .help("Output received messages in json format, one json object per line.") - .action(Arguments.storeTrue()); + subparser.addArgument("-d", "--detailed").action(Arguments.storeTrue()) + .help("List the members and group invite links of each group"); + + subparser.help("List group information including names, ids, active status, blocked status and members"); } @Override @@ -101,42 +78,29 @@ public class ListGroupsCommand implements LocalCommand { return 1; } - List groups = m.getGroups(); - boolean detailed = ns.getBoolean("detailed"); - - if (ns.getBoolean("json")) { + if (ns.getString("output").equals("json")) { final ObjectMapper jsonProcessor = new ObjectMapper(); jsonProcessor.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); jsonProcessor.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET); - if (detailed) { - List objects = new ArrayList<>(); - for (GroupInfo group : groups) { - final GroupInviteLinkUrl groupInviteLink = group.getGroupInviteLink(); + List objects = new ArrayList<>(); + for (GroupInfo group : m.getGroups()) { + final GroupInviteLinkUrl groupInviteLink = group.getGroupInviteLink(); - objects.add(new JsonGroupDetailed(group.getGroupId().toBase64(), - group.getTitle(), - group.isMember(m.getSelfAddress()), - group.isBlocked(), - getMembersSet(m, group, MembersType.MEMBERS), - getMembersSet(m, group, MembersType.PENDING_MEMBERS), - getMembersSet(m, group, MembersType.REQUESTING_MEMBERS), - groupInviteLink == null ? null : groupInviteLink.getUrl())); - } - - return printGroupsJson(jsonProcessor, objects); - } else { - List objects = groups.stream().map( - group -> new JsonGroup(group.getGroupId().toBase64(), - group.getTitle(), - group.isMember(m.getSelfAddress()), - group.isBlocked())) - .collect(Collectors.toList()); - - return printGroupsJson(jsonProcessor, objects); + objects.add(new JsonGroup(group.getGroupId().toBase64(), + group.getTitle(), + group.isMember(m.getSelfAddress()), + group.isBlocked(), + resolveMembers(m, group.getMembers()), + resolveMembers(m, group.getPendingMembers()), + resolveMembers(m, group.getRequestingMembers()), + groupInviteLink == null ? null : groupInviteLink.getUrl())); } + + return printGroupsJson(jsonProcessor, objects); } else { - for (GroupInfo group : groups) { + boolean detailed = ns.getBoolean("detailed"); + for (GroupInfo group : m.getGroups()) { printGroupPlainText(m, group, detailed); } } @@ -151,29 +115,14 @@ public class ListGroupsCommand implements LocalCommand { public boolean isMember; public boolean isBlocked; - public JsonGroup(String id, String name, boolean isMember, boolean isBlocked) { - this.id = id; - this.name = name; - this.isMember = isMember; - this.isBlocked = isBlocked; - } - } - - private static final class JsonGroupDetailed { - - public String id; - public String name; - public boolean isMember; - public boolean isBlocked; - public Set members; public Set pendingMembers; public Set requestingMembers; public String groupInviteLink; - public JsonGroupDetailed(String id, String name, boolean isMember, boolean isBlocked, - Set members, Set pendingMembers, - Set requestingMembers, String groupInviteLink) + public JsonGroup(String id, String name, boolean isMember, boolean isBlocked, + Set members, Set pendingMembers, + Set requestingMembers, String groupInviteLink) { this.id = id; this.name = name; diff --git a/src/main/java/org/asamk/signal/commands/ReceiveCommand.java b/src/main/java/org/asamk/signal/commands/ReceiveCommand.java index 9df55dfb..9bee9358 100644 --- a/src/main/java/org/asamk/signal/commands/ReceiveCommand.java +++ b/src/main/java/org/asamk/signal/commands/ReceiveCommand.java @@ -35,14 +35,11 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand { subparser.addArgument("--ignore-attachments") .help("Don’t download attachments of received messages.") .action(Arguments.storeTrue()); - subparser.addArgument("-j", "--json") - .help("Output received messages in json format, one json object per line.") - .action(Arguments.storeTrue()); } public int handleCommand(final Namespace ns, final Signal signal, DBusConnection dbusconnection) { final ObjectMapper jsonProcessor; - if (ns.getBoolean("json")) { + if (ns.getString("output").equals("json")) { jsonProcessor = new ObjectMapper(); jsonProcessor.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); jsonProcessor.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET); @@ -161,7 +158,7 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand { } boolean ignoreAttachments = ns.getBoolean("ignore_attachments"); try { - final Manager.ReceiveMessageHandler handler = ns.getBoolean("json") + final Manager.ReceiveMessageHandler handler = ns.getString("output").equals("json") ? new JsonReceiveMessageHandler(m) : new ReceiveMessageHandler(m); m.receiveMessages((long) (timeout * 1000),