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
.OutputWriter
;
9 import org
.asamk
.signal
.PlainTextWriter
;
10 import org
.asamk
.signal
.commands
.exceptions
.CommandException
;
11 import org
.asamk
.signal
.manager
.Manager
;
12 import org
.asamk
.signal
.manager
.api
.Group
;
13 import org
.asamk
.signal
.manager
.storage
.recipients
.RecipientAddress
;
14 import org
.slf4j
.Logger
;
15 import org
.slf4j
.LoggerFactory
;
18 import java
.util
.UUID
;
19 import java
.util
.stream
.Collectors
;
21 public class ListGroupsCommand
implements JsonRpcLocalCommand
{
23 private final static Logger logger
= LoggerFactory
.getLogger(ListGroupsCommand
.class);
26 public String
getName() {
31 public void attachToSubparser(final Subparser subparser
) {
32 subparser
.help("List group information including names, ids, active status, blocked status and members");
33 subparser
.addArgument("-d", "--detailed")
34 .action(Arguments
.storeTrue())
35 .help("List the members and group invite links of each group. If output=json, then this is always set");
38 private static Set
<String
> resolveMembers(Set
<RecipientAddress
> addresses
) {
39 return addresses
.stream().map(RecipientAddress
::getLegacyIdentifier
).collect(Collectors
.toSet());
42 private static Set
<JsonGroupMember
> resolveJsonMembers(Set
<RecipientAddress
> addresses
) {
43 return addresses
.stream()
44 .map(address
-> new JsonGroupMember(address
.getNumber().orElse(null),
45 address
.getUuid().map(UUID
::toString
).orElse(null)))
46 .collect(Collectors
.toSet());
49 private static void printGroupPlainText(
50 PlainTextWriter writer
, Group group
, boolean detailed
53 final var groupInviteLink
= group
.getGroupInviteLinkUrl();
56 "Id: {} Name: {} Description: {} Active: {} Blocked: {} Members: {} Pending members: {} Requesting members: {} Admins: {} Message expiration: {} Link: {}",
57 group
.getGroupId().toBase64(),
59 group
.getDescription(),
62 resolveMembers(group
.getMembers()),
63 resolveMembers(group
.getPendingMembers()),
64 resolveMembers(group
.getRequestingMembers()),
65 resolveMembers(group
.getAdminMembers()),
66 group
.getMessageExpirationTimer() == 0 ?
"disabled" : group
.getMessageExpirationTimer() + "s",
67 groupInviteLink
== null ?
'-' : groupInviteLink
.getUrl());
69 writer
.println("Id: {} Name: {} Active: {} Blocked: {}",
70 group
.getGroupId().toBase64(),
78 public void handleCommand(
79 final Namespace ns
, final Manager m
, final OutputWriter outputWriter
80 ) throws CommandException
{
81 final var groups
= m
.getGroups();
83 if (outputWriter
instanceof JsonWriter jsonWriter
) {
85 var jsonGroups
= groups
.stream().map(group
-> {
86 final var groupInviteLink
= group
.getGroupInviteLinkUrl();
88 return new JsonGroup(group
.getGroupId().toBase64(),
90 group
.getDescription(),
93 group
.getMessageExpirationTimer(),
94 resolveJsonMembers(group
.getMembers()),
95 resolveJsonMembers(group
.getPendingMembers()),
96 resolveJsonMembers(group
.getRequestingMembers()),
97 resolveJsonMembers(group
.getAdminMembers()),
98 group
.getPermissionAddMember().name(),
99 group
.getPermissionEditDetails().name(),
100 group
.getPermissionSendMessage().name(),
101 groupInviteLink
== null ?
null : groupInviteLink
.getUrl());
102 }).collect(Collectors
.toList());
104 jsonWriter
.write(jsonGroups
);
106 final var writer
= (PlainTextWriter
) outputWriter
;
107 boolean detailed
= Boolean
.TRUE
.equals(ns
.getBoolean("detailed"));
108 for (var group
: groups
) {
109 printGroupPlainText(writer
, group
, detailed
);
114 private static final class JsonGroup
{
116 public final String id
;
117 public final String name
;
118 public final String description
;
119 public final boolean isMember
;
120 public final boolean isBlocked
;
121 public final int messageExpirationTime
;
123 public final Set
<JsonGroupMember
> members
;
124 public final Set
<JsonGroupMember
> pendingMembers
;
125 public final Set
<JsonGroupMember
> requestingMembers
;
126 public final Set
<JsonGroupMember
> admins
;
127 public final String permissionAddMember
;
128 public final String permissionEditDetails
;
129 public final String permissionSendMessage
;
130 public final String groupInviteLink
;
138 final int messageExpirationTime
,
139 Set
<JsonGroupMember
> members
,
140 Set
<JsonGroupMember
> pendingMembers
,
141 Set
<JsonGroupMember
> requestingMembers
,
142 Set
<JsonGroupMember
> admins
,
143 final String permissionAddMember
,
144 final String permissionEditDetails
,
145 final String permissionSendMessage
,
146 String groupInviteLink
150 this.description
= description
;
151 this.isMember
= isMember
;
152 this.isBlocked
= isBlocked
;
153 this.messageExpirationTime
= messageExpirationTime
;
155 this.members
= members
;
156 this.pendingMembers
= pendingMembers
;
157 this.requestingMembers
= requestingMembers
;
158 this.admins
= admins
;
159 this.permissionAddMember
= permissionAddMember
;
160 this.permissionEditDetails
= permissionEditDetails
;
161 this.permissionSendMessage
= permissionSendMessage
;
162 this.groupInviteLink
= groupInviteLink
;
166 private static final class JsonGroupMember
{
168 public final String number
;
169 public final String uuid
;
171 private JsonGroupMember(final String number
, final String uuid
) {
172 this.number
= number
;