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
.manager
.Manager
;
8 import org
.asamk
.signal
.manager
.groups
.GroupInviteLinkUrl
;
9 import org
.asamk
.signal
.manager
.storage
.groups
.GroupInfo
;
10 import org
.whispersystems
.signalservice
.api
.push
.SignalServiceAddress
;
12 import com
.fasterxml
.jackson
.annotation
.JsonAutoDetect
;
13 import com
.fasterxml
.jackson
.annotation
.PropertyAccessor
;
14 import com
.fasterxml
.jackson
.core
.JsonGenerator
;
15 import com
.fasterxml
.jackson
.databind
.ObjectMapper
;
17 import java
.io
.IOException
;
18 import java
.util
.ArrayList
;
19 import java
.util
.List
;
21 import java
.util
.stream
.Collectors
;
23 public class ListGroupsCommand
implements LocalCommand
{
25 private static Set
<String
> resolveMembers(Manager m
, Set
<SignalServiceAddress
> addresses
) {
26 return addresses
.stream().map(m
::resolveSignalServiceAddress
)
27 .map(SignalServiceAddress
::getLegacyIdentifier
)
28 .collect(Collectors
.toSet());
31 private static int printGroupsJson(ObjectMapper jsonProcessor
, List
<?
> objects
) {
33 jsonProcessor
.writeValue(System
.out
, objects
);
35 } catch (IOException e
) {
36 System
.err
.println(e
.getMessage());
43 private static void printGroupPlainText(Manager m
, GroupInfo group
, boolean detailed
) {
45 final GroupInviteLinkUrl groupInviteLink
= group
.getGroupInviteLink();
47 System
.out
.println(String
.format(
48 "Id: %s Name: %s Active: %s Blocked: %b Members: %s Pending members: %s Requesting members: %s Link: %s",
49 group
.getGroupId().toBase64(),
51 group
.isMember(m
.getSelfAddress()),
53 resolveMembers(m
, group
.getMembers()),
54 resolveMembers(m
, group
.getPendingMembers()),
55 resolveMembers(m
, group
.getRequestingMembers()),
56 groupInviteLink
== null ?
'-' : groupInviteLink
.getUrl()));
58 System
.out
.println(String
.format("Id: %s Name: %s Active: %s Blocked: %b",
59 group
.getGroupId().toBase64(),
61 group
.isMember(m
.getSelfAddress()),
67 public void attachToSubparser(final Subparser subparser
) {
68 subparser
.addArgument("-d", "--detailed").action(Arguments
.storeTrue())
69 .help("List the members and group invite links of each group. If output=json, then this is always set");
71 subparser
.help("List group information including names, ids, active status, blocked status and members");
75 public int handleCommand(final Namespace ns
, final Manager m
) {
76 if (ns
.getString("output").equals("json")) {
77 final ObjectMapper jsonProcessor
= new ObjectMapper();
78 jsonProcessor
.setVisibility(PropertyAccessor
.ALL
, JsonAutoDetect
.Visibility
.ANY
);
79 jsonProcessor
.disable(JsonGenerator
.Feature
.AUTO_CLOSE_TARGET
);
81 List
<JsonGroup
> objects
= new ArrayList
<>();
82 for (GroupInfo group
: m
.getGroups()) {
83 final GroupInviteLinkUrl groupInviteLink
= group
.getGroupInviteLink();
85 objects
.add(new JsonGroup(group
.getGroupId().toBase64(),
87 group
.isMember(m
.getSelfAddress()),
89 resolveMembers(m
, group
.getMembers()),
90 resolveMembers(m
, group
.getPendingMembers()),
91 resolveMembers(m
, group
.getRequestingMembers()),
92 groupInviteLink
== null ?
null : groupInviteLink
.getUrl()));
94 return printGroupsJson(jsonProcessor
, objects
);
96 boolean detailed
= ns
.getBoolean("detailed");
97 for (GroupInfo group
: m
.getGroups()) {
98 printGroupPlainText(m
, group
, detailed
);
105 private static final class JsonGroup
{
109 public boolean isMember
;
110 public boolean isBlocked
;
112 public Set
<String
> members
;
113 public Set
<String
> pendingMembers
;
114 public Set
<String
> requestingMembers
;
115 public String groupInviteLink
;
117 public JsonGroup(String id
, String name
, boolean isMember
, boolean isBlocked
,
118 Set
<String
> members
, Set
<String
> pendingMembers
,
119 Set
<String
> requestingMembers
, String groupInviteLink
)
123 this.isMember
= isMember
;
124 this.isBlocked
= isBlocked
;
126 this.members
= members
;
127 this.pendingMembers
= pendingMembers
;
128 this.requestingMembers
= requestingMembers
;
129 this.groupInviteLink
= groupInviteLink
;