mirror of
https://github.com/AsamK/signal-cli
synced 2025-09-02 12:30:39 +00:00
Added json output to listGroups and allowed json to be activated with -j
This commit is contained in:
parent
88d81c7a63
commit
38a2da4855
4 changed files with 142 additions and 30 deletions
|
@ -130,7 +130,7 @@ Uses a list of phone numbers to determine the statuses of those users. Shows if
|
||||||
|
|
||||||
[NUMBER [NUMBER ...]]::
|
[NUMBER [NUMBER ...]]::
|
||||||
One or more numbers to check.
|
One or more numbers to check.
|
||||||
*--json*::
|
*--j*, *--json*::
|
||||||
Output the statuses as an array of json objects.
|
Output the statuses as an array of json objects.
|
||||||
|
|
||||||
=== send
|
=== send
|
||||||
|
@ -184,7 +184,7 @@ Number of seconds to wait for new messages (negative values disable timeout).
|
||||||
Default is 5 seconds.
|
Default is 5 seconds.
|
||||||
*--ignore-attachments*::
|
*--ignore-attachments*::
|
||||||
Don’t download attachments of received messages.
|
Don’t download attachments of received messages.
|
||||||
*--json*::
|
*--j*, *--json*::
|
||||||
Output received messages in json format, one object per line.
|
Output received messages in json format, one object per line.
|
||||||
|
|
||||||
=== joinGroup
|
=== joinGroup
|
||||||
|
@ -222,10 +222,13 @@ Specify the recipient group ID in base64 encoding.
|
||||||
|
|
||||||
=== listGroups
|
=== listGroups
|
||||||
|
|
||||||
Show a list of known groups.
|
Show a list of known groups and related information.
|
||||||
|
|
||||||
*-d*, *--detailed*::
|
*-d*, *--detailed*::
|
||||||
Include the list of members of each group.
|
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
|
=== listIdentities
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class GetUserStatusCommand implements LocalCommand {
|
||||||
public void attachToSubparser(final Subparser subparser) {
|
public void attachToSubparser(final Subparser subparser) {
|
||||||
subparser.addArgument("number").help("Phone number").nargs("+");
|
subparser.addArgument("number").help("Phone number").nargs("+");
|
||||||
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("--json")
|
subparser.addArgument("-j", "--json")
|
||||||
.help("Output received messages in json format, one json object per line.")
|
.help("Output received messages in json format, one json object per line.")
|
||||||
.action(Arguments.storeTrue());
|
.action(Arguments.storeTrue());
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,32 +9,61 @@ import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
|
||||||
import org.asamk.signal.manager.storage.groups.GroupInfo;
|
import org.asamk.signal.manager.storage.groups.GroupInfo;
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
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.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ListGroupsCommand implements LocalCommand {
|
public class ListGroupsCommand implements LocalCommand {
|
||||||
|
|
||||||
private static void printGroup(Manager m, GroupInfo group, boolean detailed) {
|
private enum MembersType {
|
||||||
|
MEMBERS,
|
||||||
|
PENDING_MEMBERS,
|
||||||
|
REQUESTING_MEMBERS,
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<String> getMembersSet(Manager m, GroupInfo group, MembersType type) {
|
||||||
|
Set<SignalServiceAddress> 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)
|
||||||
|
.map(SignalServiceAddress::getLegacyIdentifier)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int printGroupsJson(ObjectMapper jsonProcessor, List<?> objects) {
|
||||||
|
try {
|
||||||
|
jsonProcessor.writeValue(System.out, objects);
|
||||||
|
System.out.println();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println(e.getMessage());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printGroupPlainText(Manager m, GroupInfo group, boolean detailed) {
|
||||||
if (detailed) {
|
if (detailed) {
|
||||||
Set<String> members = group.getMembers()
|
|
||||||
.stream()
|
|
||||||
.map(m::resolveSignalServiceAddress)
|
|
||||||
.map(SignalServiceAddress::getLegacyIdentifier)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
Set<String> pendingMembers = group.getPendingMembers()
|
|
||||||
.stream()
|
|
||||||
.map(m::resolveSignalServiceAddress)
|
|
||||||
.map(SignalServiceAddress::getLegacyIdentifier)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
Set<String> requestingMembers = group.getRequestingMembers()
|
|
||||||
.stream()
|
|
||||||
.map(m::resolveSignalServiceAddress)
|
|
||||||
.map(SignalServiceAddress::getLegacyIdentifier)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
final GroupInviteLinkUrl groupInviteLink = group.getGroupInviteLink();
|
final GroupInviteLinkUrl groupInviteLink = group.getGroupInviteLink();
|
||||||
|
|
||||||
System.out.println(String.format(
|
System.out.println(String.format(
|
||||||
|
@ -43,9 +72,9 @@ public class ListGroupsCommand implements LocalCommand {
|
||||||
group.getTitle(),
|
group.getTitle(),
|
||||||
group.isMember(m.getSelfAddress()),
|
group.isMember(m.getSelfAddress()),
|
||||||
group.isBlocked(),
|
group.isBlocked(),
|
||||||
members,
|
getMembersSet(m, group, MembersType.MEMBERS),
|
||||||
pendingMembers,
|
getMembersSet(m, group, MembersType.PENDING_MEMBERS),
|
||||||
requestingMembers,
|
getMembersSet(m, group, MembersType.REQUESTING_MEMBERS),
|
||||||
groupInviteLink == null ? '-' : groupInviteLink.getUrl()));
|
groupInviteLink == null ? '-' : groupInviteLink.getUrl()));
|
||||||
} else {
|
} else {
|
||||||
System.out.println(String.format("Id: %s Name: %s Active: %s Blocked: %b",
|
System.out.println(String.format("Id: %s Name: %s Active: %s Blocked: %b",
|
||||||
|
@ -60,6 +89,9 @@ public class ListGroupsCommand implements LocalCommand {
|
||||||
public void attachToSubparser(final Subparser subparser) {
|
public void attachToSubparser(final Subparser subparser) {
|
||||||
subparser.addArgument("-d", "--detailed").action(Arguments.storeTrue()).help("List members of each group");
|
subparser.addArgument("-d", "--detailed").action(Arguments.storeTrue()).help("List members of each group");
|
||||||
subparser.help("List group name and ids");
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -72,9 +104,86 @@ public class ListGroupsCommand implements LocalCommand {
|
||||||
List<GroupInfo> groups = m.getGroups();
|
List<GroupInfo> groups = m.getGroups();
|
||||||
boolean detailed = ns.getBoolean("detailed");
|
boolean detailed = ns.getBoolean("detailed");
|
||||||
|
|
||||||
for (GroupInfo group : groups) {
|
if (ns.getBoolean("json")) {
|
||||||
printGroup(m, group, detailed);
|
final ObjectMapper jsonProcessor = new ObjectMapper();
|
||||||
|
jsonProcessor.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||||
|
jsonProcessor.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
|
||||||
|
|
||||||
|
if (detailed) {
|
||||||
|
List<JsonListGroupDetailed> objects = new ArrayList<>();
|
||||||
|
for (GroupInfo group : groups) {
|
||||||
|
final GroupInviteLinkUrl groupInviteLink = group.getGroupInviteLink();
|
||||||
|
|
||||||
|
objects.add(new JsonListGroupDetailed(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<JsonListGroup> objects = groups.stream().map(
|
||||||
|
group -> new JsonListGroup(group.getGroupId().toBase64(),
|
||||||
|
group.getTitle(),
|
||||||
|
group.isMember(m.getSelfAddress()),
|
||||||
|
group.isBlocked()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return printGroupsJson(jsonProcessor, objects);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (GroupInfo group : groups) {
|
||||||
|
printGroupPlainText(m, group, detailed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class JsonListGroup {
|
||||||
|
|
||||||
|
public String id;
|
||||||
|
public String name;
|
||||||
|
public boolean isMember;
|
||||||
|
public boolean isBlocked;
|
||||||
|
|
||||||
|
public JsonListGroup(String id, String name, boolean isMember, boolean isBlocked) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.isMember = isMember;
|
||||||
|
this.isBlocked = isBlocked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class JsonListGroupDetailed {
|
||||||
|
|
||||||
|
public String id;
|
||||||
|
public String name;
|
||||||
|
public boolean isMember;
|
||||||
|
public boolean isBlocked;
|
||||||
|
|
||||||
|
public Set<String> members;
|
||||||
|
public Set<String> pendingMembers;
|
||||||
|
public Set<String> requestingMembers;
|
||||||
|
public String groupInviteLink;
|
||||||
|
|
||||||
|
public JsonListGroupDetailed(String id, String name, boolean isMember, boolean isBlocked,
|
||||||
|
Set<String> members, Set<String> pendingMembers,
|
||||||
|
Set<String> requestingMembers, String groupInviteLink)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.isMember = isMember;
|
||||||
|
this.isBlocked = isBlocked;
|
||||||
|
|
||||||
|
this.members = members;
|
||||||
|
this.pendingMembers = pendingMembers;
|
||||||
|
this.requestingMembers = requestingMembers;
|
||||||
|
this.groupInviteLink = groupInviteLink;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
|
||||||
subparser.addArgument("--ignore-attachments")
|
subparser.addArgument("--ignore-attachments")
|
||||||
.help("Don’t download attachments of received messages.")
|
.help("Don’t download attachments of received messages.")
|
||||||
.action(Arguments.storeTrue());
|
.action(Arguments.storeTrue());
|
||||||
subparser.addArgument("--json")
|
subparser.addArgument("-j", "--json")
|
||||||
.help("Output received messages in json format, one json object per line.")
|
.help("Output received messages in json format, one json object per line.")
|
||||||
.action(Arguments.storeTrue());
|
.action(Arguments.storeTrue());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue