1 package org
.asamk
.signal
.commands
;
3 import net
.sourceforge
.argparse4j
.impl
.Arguments
;
4 import net
.sourceforge
.argparse4j
.inf
.Namespace
;
5 import net
.sourceforge
.argparse4j
.inf
.Subparser
;
7 import org
.asamk
.signal
.JsonWriter
;
8 import org
.asamk
.signal
.OutputType
;
9 import org
.asamk
.signal
.OutputWriter
;
10 import org
.asamk
.signal
.PlainTextWriter
;
11 import org
.asamk
.signal
.commands
.exceptions
.CommandException
;
12 import org
.asamk
.signal
.manager
.Manager
;
13 import org
.asamk
.signal
.manager
.storage
.groups
.GroupInfo
;
14 import org
.asamk
.signal
.manager
.storage
.recipients
.RecipientId
;
15 import org
.asamk
.signal
.util
.Util
;
16 import org
.slf4j
.Logger
;
17 import org
.slf4j
.LoggerFactory
;
20 import java
.util
.stream
.Collectors
;
22 public class ListGroupsCommand
implements LocalCommand
{
24 private final static Logger logger
= LoggerFactory
.getLogger(ListGroupsCommand
.class);
26 public static void attachToSubparser(final Subparser subparser
) {
27 subparser
.help("List group information including names, ids, active status, blocked status and members");
28 subparser
.addArgument("-d", "--detailed")
29 .action(Arguments
.storeTrue())
30 .help("List the members and group invite links of each group. If output=json, then this is always set");
33 private static Set
<String
> resolveMembers(Manager m
, Set
<RecipientId
> addresses
) {
34 return addresses
.stream()
35 .map(m
::resolveSignalServiceAddress
)
36 .map(Util
::getLegacyIdentifier
)
37 .collect(Collectors
.toSet());
40 private static void printGroupPlainText(
41 PlainTextWriter writer
, Manager m
, GroupInfo group
, boolean detailed
44 final var groupInviteLink
= group
.getGroupInviteLink();
47 "Id: {} Name: {} Description: {} Active: {} Blocked: {} Members: {} Pending members: {} Requesting members: {} Admins: {} Link: {}",
48 group
.getGroupId().toBase64(),
50 group
.getDescription(),
51 group
.isMember(m
.getSelfRecipientId()),
53 resolveMembers(m
, group
.getMembers()),
54 resolveMembers(m
, group
.getPendingMembers()),
55 resolveMembers(m
, group
.getRequestingMembers()),
56 resolveMembers(m
, group
.getAdminMembers()),
57 groupInviteLink
== null ?
'-' : groupInviteLink
.getUrl());
59 writer
.println("Id: {} Name: {} Active: {} Blocked: {}",
60 group
.getGroupId().toBase64(),
62 group
.isMember(m
.getSelfRecipientId()),
67 private final OutputWriter outputWriter
;
69 public ListGroupsCommand(final OutputWriter outputWriter
) {
70 this.outputWriter
= outputWriter
;
74 public Set
<OutputType
> getSupportedOutputTypes() {
75 return Set
.of(OutputType
.PLAIN_TEXT
, OutputType
.JSON
);
79 public void handleCommand(final Namespace ns
, final Manager m
) throws CommandException
{
80 final var groups
= m
.getGroups();
82 if (outputWriter
instanceof JsonWriter
) {
83 final var jsonWriter
= (JsonWriter
) outputWriter
;
85 var jsonGroups
= groups
.stream().map(group
-> {
86 final var groupInviteLink
= group
.getGroupInviteLink();
88 return new JsonGroup(group
.getGroupId().toBase64(),
90 group
.getDescription(),
91 group
.isMember(m
.getSelfRecipientId()),
93 resolveMembers(m
, group
.getMembers()),
94 resolveMembers(m
, group
.getPendingMembers()),
95 resolveMembers(m
, group
.getRequestingMembers()),
96 resolveMembers(m
, group
.getAdminMembers()),
97 groupInviteLink
== null ?
null : groupInviteLink
.getUrl());
98 }).collect(Collectors
.toList());
100 jsonWriter
.write(jsonGroups
);
102 final var writer
= (PlainTextWriter
) outputWriter
;
103 boolean detailed
= ns
.getBoolean("detailed");
104 for (var group
: groups
) {
105 printGroupPlainText(writer
, m
, group
, detailed
);
110 private static final class JsonGroup
{
114 public String description
;
115 public boolean isMember
;
116 public boolean isBlocked
;
118 public Set
<String
> members
;
119 public Set
<String
> pendingMembers
;
120 public Set
<String
> requestingMembers
;
121 public Set
<String
> admins
;
122 public String groupInviteLink
;
131 Set
<String
> pendingMembers
,
132 Set
<String
> requestingMembers
,
134 String groupInviteLink
138 this.description
= description
;
139 this.isMember
= isMember
;
140 this.isBlocked
= isBlocked
;
142 this.members
= members
;
143 this.pendingMembers
= pendingMembers
;
144 this.requestingMembers
= requestingMembers
;
145 this.admins
= admins
;
146 this.groupInviteLink
= groupInviteLink
;