mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
parent
8aeaf927e6
commit
e4c5144fbf
4 changed files with 143 additions and 25 deletions
|
@ -849,6 +849,24 @@
|
|||
"queryAllDeclaredConstructors":true,
|
||||
"methods":[{"name":"id","parameterTypes":[] }, {"name":"opaque","parameterTypes":[] }, {"name":"sdp","parameterTypes":[] }, {"name":"type","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
"name":"org.asamk.signal.json.JsonContact",
|
||||
"allDeclaredFields":true,
|
||||
"queryAllDeclaredMethods":true,
|
||||
"methods":[{"name":"color","parameterTypes":[] }, {"name":"familyName","parameterTypes":[] }, {"name":"givenName","parameterTypes":[] }, {"name":"internal","parameterTypes":[] }, {"name":"isBlocked","parameterTypes":[] }, {"name":"isHidden","parameterTypes":[] }, {"name":"messageExpirationTime","parameterTypes":[] }, {"name":"name","parameterTypes":[] }, {"name":"nickFamilyName","parameterTypes":[] }, {"name":"nickGivenName","parameterTypes":[] }, {"name":"nickName","parameterTypes":[] }, {"name":"note","parameterTypes":[] }, {"name":"number","parameterTypes":[] }, {"name":"profile","parameterTypes":[] }, {"name":"profileSharing","parameterTypes":[] }, {"name":"unregistered","parameterTypes":[] }, {"name":"username","parameterTypes":[] }, {"name":"uuid","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
"name":"org.asamk.signal.json.JsonContact$JsonInternal",
|
||||
"allDeclaredFields":true,
|
||||
"queryAllDeclaredMethods":true,
|
||||
"methods":[{"name":"capabilities","parameterTypes":[] }, {"name":"discoverableByPhonenumber","parameterTypes":[] }, {"name":"sharesPhoneNumber","parameterTypes":[] }, {"name":"unidentifiedAccessMode","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
"name":"org.asamk.signal.json.JsonContact$JsonProfile",
|
||||
"allDeclaredFields":true,
|
||||
"queryAllDeclaredMethods":true,
|
||||
"methods":[{"name":"about","parameterTypes":[] }, {"name":"aboutEmoji","parameterTypes":[] }, {"name":"familyName","parameterTypes":[] }, {"name":"givenName","parameterTypes":[] }, {"name":"hasAvatar","parameterTypes":[] }, {"name":"lastUpdateTimestamp","parameterTypes":[] }, {"name":"mobileCoinAddress","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
"name":"org.asamk.signal.json.JsonContactAddress",
|
||||
"allDeclaredFields":true,
|
||||
|
|
|
@ -590,6 +590,12 @@ Specify if only blocked or unblocked contacts should be shown (default: all cont
|
|||
*--name*::
|
||||
Find contacts with the given contact or profile name.
|
||||
|
||||
*--detailed*::
|
||||
List the contacts with more details. If output=json, then this is always set
|
||||
|
||||
*--internal*::
|
||||
Include internal information that's normally not user visible
|
||||
|
||||
=== listIdentities
|
||||
|
||||
List all known identity keys and their trust status, fingerprint and safety number.
|
||||
|
|
|
@ -5,8 +5,10 @@ import net.sourceforge.argparse4j.inf.Namespace;
|
|||
import net.sourceforge.argparse4j.inf.Subparser;
|
||||
|
||||
import org.asamk.signal.commands.exceptions.CommandException;
|
||||
import org.asamk.signal.json.JsonContact;
|
||||
import org.asamk.signal.manager.Manager;
|
||||
import org.asamk.signal.manager.api.Contact;
|
||||
import org.asamk.signal.manager.api.PhoneNumberSharingMode;
|
||||
import org.asamk.signal.manager.api.Profile;
|
||||
import org.asamk.signal.output.JsonWriter;
|
||||
import org.asamk.signal.output.OutputWriter;
|
||||
|
@ -35,6 +37,12 @@ public class ListContactsCommand implements JsonRpcLocalCommand {
|
|||
.type(Boolean.class)
|
||||
.help("Specify if only blocked or unblocked contacts should be shown (default: all contacts)");
|
||||
subparser.addArgument("--name").help("Find contacts with the given contact or profile name.");
|
||||
subparser.addArgument("--detailed")
|
||||
.action(Arguments.storeTrue())
|
||||
.help("List the contacts with more details. If output=json, then this is always set");
|
||||
subparser.addArgument("--internal")
|
||||
.action(Arguments.storeTrue())
|
||||
.help("Include internal information that's normally not user visible");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -51,33 +59,94 @@ public class ListContactsCommand implements JsonRpcLocalCommand {
|
|||
recipientIdentifiers,
|
||||
Optional.ofNullable(name));
|
||||
|
||||
final var detailed = Boolean.TRUE.equals(ns.getBoolean("detailed"));
|
||||
final var internal = Boolean.TRUE.equals(ns.getBoolean("internal"));
|
||||
|
||||
switch (outputWriter) {
|
||||
case PlainTextWriter writer -> {
|
||||
for (var r : recipients) {
|
||||
final var contact = r.getContact() == null ? Contact.newBuilder().build() : r.getContact();
|
||||
final var profile = r.getProfile() == null ? Profile.newBuilder().build() : r.getProfile();
|
||||
writer.println(
|
||||
"Number: {} Name: {} Profile name: {} Username: {} Color: {} Blocked: {} Message expiration: {}",
|
||||
r.getAddress().getLegacyIdentifier(),
|
||||
"Number: {} ACI: {} Name: {} Profile name: {} Username: {} Color: {} Blocked: {} Message expiration: {}",
|
||||
r.getAddress().number().orElse(""),
|
||||
r.getAddress().aci().orElse(""),
|
||||
contact.getName(),
|
||||
profile.getDisplayName(),
|
||||
r.getAddress().username().orElse(""),
|
||||
contact.color(),
|
||||
Optional.ofNullable(contact.color()).orElse(""),
|
||||
contact.isBlocked(),
|
||||
contact.messageExpirationTime() == 0 ? "disabled" : contact.messageExpirationTime() + "s");
|
||||
if (detailed) {
|
||||
writer.indentedWriter()
|
||||
.println(
|
||||
"PNI: {} Given name: {} Family name: {}, Nick name: {} Nick given name: {} Nick family name {} Note: {} Archived: {} Hidden: {} Profile sharing: {} About: {} About Emoji: {} Unregistered: {}",
|
||||
r.getAddress().pni().orElse(""),
|
||||
Optional.ofNullable(r.getContact().givenName()).orElse(""),
|
||||
Optional.ofNullable(r.getContact().familyName()).orElse(""),
|
||||
Optional.ofNullable(r.getContact().nickName()).orElse(""),
|
||||
Optional.ofNullable(r.getContact().nickNameGivenName()).orElse(""),
|
||||
Optional.ofNullable(r.getContact().nickNameFamilyName()).orElse(""),
|
||||
Optional.ofNullable(r.getContact().note()).orElse(""),
|
||||
r.getContact().isArchived(),
|
||||
r.getContact().isHidden(),
|
||||
r.getContact().isProfileSharingEnabled(),
|
||||
Optional.ofNullable(r.getProfile().getAbout()).orElse(""),
|
||||
Optional.ofNullable(r.getProfile().getAboutEmoji()).orElse(""),
|
||||
r.getContact().unregisteredTimestamp() != null);
|
||||
}
|
||||
if (internal) {
|
||||
writer.indentedWriter()
|
||||
.println(
|
||||
"Capabilities: {} Unidentified access mode: {} Shares number: {} Discoverable by number: {}",
|
||||
r.getProfile().getCapabilities().stream().map(Enum::name).toList(),
|
||||
Optional.ofNullable(r.getProfile().getUnidentifiedAccessMode()
|
||||
== Profile.UnidentifiedAccessMode.UNKNOWN
|
||||
? null
|
||||
: r.getProfile().getUnidentifiedAccessMode().name()).orElse(""),
|
||||
r.getProfile().getPhoneNumberSharingMode() == null
|
||||
? ""
|
||||
: String.valueOf(r.getProfile().getPhoneNumberSharingMode()
|
||||
== PhoneNumberSharingMode.EVERYBODY),
|
||||
r.getDiscoverable() == null ? "" : String.valueOf(r.getDiscoverable()));
|
||||
}
|
||||
}
|
||||
}
|
||||
case JsonWriter writer -> {
|
||||
final var jsonContacts = recipients.stream().map(r -> {
|
||||
final var address = r.getAddress();
|
||||
final var contact = r.getContact() == null ? Contact.newBuilder().build() : r.getContact();
|
||||
final var jsonInternal = !internal
|
||||
? null
|
||||
: new JsonContact.JsonInternal(r.getProfile()
|
||||
.getCapabilities()
|
||||
.stream()
|
||||
.map(Enum::name)
|
||||
.toList(),
|
||||
r.getProfile().getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.UNKNOWN
|
||||
? null
|
||||
: r.getProfile().getUnidentifiedAccessMode().name(),
|
||||
r.getProfile().getPhoneNumberSharingMode() == null
|
||||
? null
|
||||
: r.getProfile().getPhoneNumberSharingMode()
|
||||
== PhoneNumberSharingMode.EVERYBODY,
|
||||
r.getDiscoverable());
|
||||
return new JsonContact(address.number().orElse(null),
|
||||
address.uuid().map(UUID::toString).orElse(null),
|
||||
address.username().orElse(null),
|
||||
contact.getName(),
|
||||
contact.givenName(),
|
||||
contact.familyName(),
|
||||
contact.nickName(),
|
||||
contact.nickNameGivenName(),
|
||||
contact.nickNameFamilyName(),
|
||||
contact.note(),
|
||||
contact.color(),
|
||||
contact.isBlocked(),
|
||||
contact.isHidden(),
|
||||
contact.messageExpirationTime(),
|
||||
r.getContact().isProfileSharingEnabled(),
|
||||
r.getContact().unregisteredTimestamp() != null,
|
||||
r.getProfile() == null
|
||||
? null
|
||||
: new JsonContact.JsonProfile(r.getProfile().getLastUpdateTimestamp(),
|
||||
|
@ -85,34 +154,15 @@ public class ListContactsCommand implements JsonRpcLocalCommand {
|
|||
r.getProfile().getFamilyName(),
|
||||
r.getProfile().getAbout(),
|
||||
r.getProfile().getAboutEmoji(),
|
||||
r.getProfile().getAvatarUrlPath() != null,
|
||||
r.getProfile().getMobileCoinAddress() == null
|
||||
? null
|
||||
: Base64.getEncoder()
|
||||
.encodeToString(r.getProfile().getMobileCoinAddress())));
|
||||
.encodeToString(r.getProfile().getMobileCoinAddress())),
|
||||
jsonInternal);
|
||||
}).toList();
|
||||
writer.write(jsonContacts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private record JsonContact(
|
||||
String number,
|
||||
String uuid,
|
||||
String username,
|
||||
String name,
|
||||
String color,
|
||||
boolean isBlocked,
|
||||
int messageExpirationTime,
|
||||
JsonProfile profile
|
||||
) {
|
||||
|
||||
private record JsonProfile(
|
||||
long lastUpdateTimestamp,
|
||||
String givenName,
|
||||
String familyName,
|
||||
String about,
|
||||
String aboutEmoji,
|
||||
String mobileCoinAddress
|
||||
) {}
|
||||
}
|
||||
}
|
||||
|
|
44
src/main/java/org/asamk/signal/json/JsonContact.java
Normal file
44
src/main/java/org/asamk/signal/json/JsonContact.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
package org.asamk.signal.json;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record JsonContact(
|
||||
String number,
|
||||
String uuid,
|
||||
String username,
|
||||
String name,
|
||||
String givenName,
|
||||
String familyName,
|
||||
String nickName,
|
||||
String nickGivenName,
|
||||
String nickFamilyName,
|
||||
String note,
|
||||
String color,
|
||||
boolean isBlocked,
|
||||
boolean isHidden,
|
||||
int messageExpirationTime,
|
||||
boolean profileSharing,
|
||||
boolean unregistered,
|
||||
JsonProfile profile,
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL) JsonInternal internal
|
||||
) {
|
||||
|
||||
public record JsonProfile(
|
||||
long lastUpdateTimestamp,
|
||||
String givenName,
|
||||
String familyName,
|
||||
String about,
|
||||
String aboutEmoji,
|
||||
boolean hasAvatar,
|
||||
String mobileCoinAddress
|
||||
) {}
|
||||
|
||||
public record JsonInternal(
|
||||
List<String> capabilities,
|
||||
String unidentifiedAccessMode,
|
||||
Boolean sharesPhoneNumber,
|
||||
Boolean discoverableByPhonenumber
|
||||
) {}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue