]> nmode's Git Repositories - signal-cli/commitdiff
Extend listContacts command with profiles and filtering
authorAsamK <asamk@gmx.de>
Fri, 20 May 2022 09:46:03 +0000 (11:46 +0200)
committerAsamK <asamk@gmx.de>
Fri, 20 May 2022 09:53:33 +0000 (11:53 +0200)
graalvm-config-dir/reflect-config.json
graalvm-config-dir/resource-config.json
lib/src/main/java/org/asamk/signal/manager/Manager.java
lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java
lib/src/main/java/org/asamk/signal/manager/helper/ProfileHelper.java
lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java
lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java
lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java
src/main/java/org/asamk/signal/commands/ListContactsCommand.java
src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java
src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java

index f9fe367f05a5a48d8f6dda84b110dd687de03af4..69b19703958dd36e804aea6280bd0ee5e3ded233 100644 (file)
   "allDeclaredMethods":true,
   "allDeclaredConstructors":true
 },
+{
+  "name":"org.asamk.signal.commands.ListContactsCommand$JsonContact$JsonProfile",
+  "allDeclaredFields":true,
+  "queryAllDeclaredMethods":true,
+  "queryAllDeclaredConstructors":true,
+  "methods":[
+    {"name":"about","parameterTypes":[] }, 
+    {"name":"aboutEmoji","parameterTypes":[] }, 
+    {"name":"familyName","parameterTypes":[] }, 
+    {"name":"givenName","parameterTypes":[] }, 
+    {"name":"lastUpdateTimestamp","parameterTypes":[] }, 
+    {"name":"paymentAddress","parameterTypes":[] }
+  ]
+},
 {
   "name":"org.asamk.signal.commands.ListDevicesCommand$JsonDevice",
   "allDeclaredFields":true,
     {"name":"userId_"}
   ]
 },
+{
+  "name":"org.signal.storageservice.protos.groups.GroupChanges",
+  "fields":[{"name":"groupChanges_"}]
+},
+{
+  "name":"org.signal.storageservice.protos.groups.GroupChanges$GroupChangeState",
+  "fields":[
+    {"name":"groupChange_"}, 
+    {"name":"groupState_"}
+  ]
+},
 {
   "name":"org.signal.storageservice.protos.groups.GroupInviteLink",
   "fields":[
index 08a9dcc50d69ed3673b6b3aef58c81b68fc07240..542c8f31b5cfe1c20f265e1cfa9107fd0bc557c6 100644 (file)
@@ -73,6 +73,9 @@
     {
       "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DE\\E"
     }, 
+    {
+      "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_DK\\E"
+    }, 
     {
       "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_EC\\E"
     }, 
index 8f49126fc724c7754cef07e9736bed6702371581..cc3ce0ce1da3061d0ccef3109b9bbf7a0cbb2a42 100644 (file)
@@ -28,9 +28,8 @@ import org.asamk.signal.manager.groups.GroupNotFoundException;
 import org.asamk.signal.manager.groups.GroupSendingNotAllowedException;
 import org.asamk.signal.manager.groups.LastGroupAdminException;
 import org.asamk.signal.manager.groups.NotAGroupMemberException;
-import org.asamk.signal.manager.storage.recipients.Contact;
 import org.asamk.signal.manager.storage.recipients.Profile;
-import org.asamk.signal.manager.storage.recipients.RecipientAddress;
+import org.asamk.signal.manager.storage.recipients.Recipient;
 import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
 
 import java.io.Closeable;
@@ -215,7 +214,12 @@ public interface Manager extends Closeable {
 
     void sendContacts() throws IOException;
 
-    List<Pair<RecipientAddress, Contact>> getContacts();
+    List<Recipient> getRecipients(
+            boolean onlyContacts,
+            Optional<Boolean> blocked,
+            Collection<RecipientIdentifier.Single> address,
+            Optional<String> name
+    );
 
     String getContactOrProfileName(RecipientIdentifier.Single recipient);
 
index b3e6a0ae7b02461943d1bb7e996197bcba2ce851..f2d080fd91e829bf40adfc27da5e64fdf796bbbb 100644 (file)
@@ -51,9 +51,8 @@ import org.asamk.signal.manager.helper.Context;
 import org.asamk.signal.manager.storage.SignalAccount;
 import org.asamk.signal.manager.storage.groups.GroupInfo;
 import org.asamk.signal.manager.storage.identities.IdentityInfo;
-import org.asamk.signal.manager.storage.recipients.Contact;
 import org.asamk.signal.manager.storage.recipients.Profile;
-import org.asamk.signal.manager.storage.recipients.RecipientAddress;
+import org.asamk.signal.manager.storage.recipients.Recipient;
 import org.asamk.signal.manager.storage.recipients.RecipientId;
 import org.asamk.signal.manager.storage.stickerPacks.JsonStickerPack;
 import org.asamk.signal.manager.storage.stickerPacks.StickerPackStore;
@@ -84,6 +83,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
@@ -101,7 +101,6 @@ class ManagerImpl implements Manager {
     private final static Logger logger = LoggerFactory.getLogger(ManagerImpl.class);
 
     private SignalAccount account;
-    private AccountFileUpdater accountFileUpdater;
     private final SignalDependencies dependencies;
     private final Context context;
 
@@ -123,7 +122,6 @@ class ManagerImpl implements Manager {
             String userAgent
     ) {
         this.account = account;
-        this.accountFileUpdater = accountFileUpdater;
 
         final var sessionLock = new SignalSessionLock() {
             private final ReentrantLock LEGACY_LOCK = new ReentrantLock();
@@ -337,7 +335,7 @@ class ManagerImpl implements Manager {
     }
 
     @Override
-    public Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException {
+    public Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws UnregisteredRecipientException {
         return context.getProfileHelper().getRecipientProfile(context.getRecipientHelper().resolveRecipient(recipient));
     }
 
@@ -495,7 +493,7 @@ class ManagerImpl implements Manager {
     @Override
     public SendMessageResults sendReadReceipt(
             RecipientIdentifier.Single sender, List<Long> messageIds
-    ) throws IOException {
+    ) {
         final var timestamp = System.currentTimeMillis();
         var receiptMessage = new SignalServiceReceiptMessage(SignalServiceReceiptMessage.Type.READ,
                 messageIds,
@@ -507,7 +505,7 @@ class ManagerImpl implements Manager {
     @Override
     public SendMessageResults sendViewedReceipt(
             RecipientIdentifier.Single sender, List<Long> messageIds
-    ) throws IOException {
+    ) {
         final var timestamp = System.currentTimeMillis();
         var receiptMessage = new SignalServiceReceiptMessage(SignalServiceReceiptMessage.Type.VIEWED,
                 messageIds,
@@ -520,7 +518,7 @@ class ManagerImpl implements Manager {
             final RecipientIdentifier.Single sender,
             final long timestamp,
             final SignalServiceReceiptMessage receiptMessage
-    ) throws IOException {
+    ) {
         try {
             final var result = context.getSendHelper()
                     .sendReceiptMessage(receiptMessage, context.getRecipientHelper().resolveRecipient(sender));
@@ -592,7 +590,7 @@ class ManagerImpl implements Manager {
         }
     }
 
-    private ArrayList<SignalServiceDataMessage.Mention> resolveMentions(final List<Message.Mention> mentionList) throws IOException, UnregisteredRecipientException {
+    private ArrayList<SignalServiceDataMessage.Mention> resolveMentions(final List<Message.Mention> mentionList) throws UnregisteredRecipientException {
         final var mentions = new ArrayList<SignalServiceDataMessage.Mention>();
         for (final var m : mentionList) {
             final var recipientId = context.getRecipientHelper().resolveRecipient(m.recipient());
@@ -676,7 +674,7 @@ class ManagerImpl implements Manager {
     @Override
     public void setContactName(
             RecipientIdentifier.Single recipient, String name
-    ) throws NotMasterDeviceException, IOException, UnregisteredRecipientException {
+    ) throws NotMasterDeviceException, UnregisteredRecipientException {
         if (!account.isMasterDevice()) {
             throw new NotMasterDeviceException();
         }
@@ -932,7 +930,7 @@ class ManagerImpl implements Manager {
         final RecipientId recipientId;
         try {
             recipientId = context.getRecipientHelper().resolveRecipient(recipient);
-        } catch (IOException | UnregisteredRecipientException e) {
+        } catch (UnregisteredRecipientException e) {
             return false;
         }
         return context.getContactHelper().isContactBlocked(recipientId);
@@ -944,12 +942,22 @@ class ManagerImpl implements Manager {
     }
 
     @Override
-    public List<Pair<RecipientAddress, Contact>> getContacts() {
-        return account.getContactStore()
-                .getContacts()
-                .stream()
-                .map(p -> new Pair<>(account.getRecipientStore().resolveRecipientAddress(p.first()), p.second()))
-                .toList();
+    public List<Recipient> getRecipients(
+            boolean onlyContacts,
+            Optional<Boolean> blocked,
+            Collection<RecipientIdentifier.Single> recipients,
+            Optional<String> name
+    ) {
+        final var recipientIds = recipients.stream().map(a -> {
+            try {
+                return context.getRecipientHelper().resolveRecipient(a);
+            } catch (UnregisteredRecipientException e) {
+                return null;
+            }
+        }).filter(Objects::nonNull).collect(Collectors.toSet());
+        // refresh profiles of explicitly given recipients
+        context.getProfileHelper().refreshRecipientProfiles(recipientIds);
+        return account.getRecipientStore().getRecipients(onlyContacts, blocked, recipientIds, name);
     }
 
     @Override
@@ -957,7 +965,7 @@ class ManagerImpl implements Manager {
         final RecipientId recipientId;
         try {
             recipientId = context.getRecipientHelper().resolveRecipient(recipient);
-        } catch (IOException | UnregisteredRecipientException e) {
+        } catch (UnregisteredRecipientException e) {
             return null;
         }
 
@@ -1007,7 +1015,7 @@ class ManagerImpl implements Manager {
         try {
             identity = account.getIdentityKeyStore()
                     .getIdentity(context.getRecipientHelper().resolveRecipient(recipient));
-        } catch (IOException | UnregisteredRecipientException e) {
+        } catch (UnregisteredRecipientException e) {
             identity = null;
         }
         return identity == null ? List.of() : List.of(toIdentity(identity));
@@ -1044,12 +1052,7 @@ class ManagerImpl implements Manager {
     private boolean trustIdentity(
             RecipientIdentifier.Single recipient, Function<RecipientId, Boolean> trustMethod
     ) throws UnregisteredRecipientException {
-        RecipientId recipientId;
-        try {
-            recipientId = context.getRecipientHelper().resolveRecipient(recipient);
-        } catch (IOException e) {
-            return false;
-        }
+        final var recipientId = context.getRecipientHelper().resolveRecipient(recipient);
         final var updated = trustMethod.apply(recipientId);
         if (updated && this.isReceiving()) {
             context.getReceiveHelper().setNeedsToRetryFailedMessages(true);
index 4bc00317e65d6acda3c88a0bffa5df5ab94b5178..8a64c8b7ec04530c86d80a66f19841c46334be46 100644 (file)
@@ -36,6 +36,7 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.file.Files;
 import java.util.Base64;
+import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
@@ -94,10 +95,18 @@ public final class ProfileHelper {
         return getRecipientProfile(recipientId, false);
     }
 
+    public List<Profile> getRecipientProfiles(Collection<RecipientId> recipientIds) {
+        return getRecipientProfiles(recipientIds, false);
+    }
+
     public void refreshRecipientProfile(RecipientId recipientId) {
         getRecipientProfile(recipientId, true);
     }
 
+    public void refreshRecipientProfiles(Collection<RecipientId> recipientIds) {
+        getRecipientProfiles(recipientIds, true);
+    }
+
     public List<ProfileKeyCredential> getRecipientProfileKeyCredential(List<RecipientId> recipientIds) {
         try {
             account.getRecipientStore().setBulkUpdating(true);
@@ -216,11 +225,12 @@ public final class ProfileHelper {
         return getRecipientProfile(account.getSelfRecipientId());
     }
 
-    public List<Profile> getRecipientProfile(List<RecipientId> recipientIds) {
+    private List<Profile> getRecipientProfiles(Collection<RecipientId> recipientIds, boolean force) {
+        final var profileStore = account.getProfileStore();
         try {
             account.getRecipientStore().setBulkUpdating(true);
             final var profileFetches = Flowable.fromIterable(recipientIds)
-                    .filter(recipientId -> isProfileRefreshRequired(account.getProfileStore().getProfile(recipientId)))
+                    .filter(recipientId -> force || isProfileRefreshRequired(profileStore.getProfile(recipientId)))
                     .map(recipientId -> retrieveProfile(recipientId,
                             SignalServiceProfile.RequestType.PROFILE).onErrorComplete());
             Maybe.merge(profileFetches, 10).blockingSubscribe();
@@ -228,7 +238,7 @@ public final class ProfileHelper {
             account.getRecipientStore().setBulkUpdating(false);
         }
 
-        return recipientIds.stream().map(r -> account.getProfileStore().getProfile(r)).toList();
+        return recipientIds.stream().map(profileStore::getProfile).toList();
     }
 
     private Profile getRecipientProfile(RecipientId recipientId, boolean force) {
index 15508cd483f6cc23af54abc8b19acb72e2463a25..c253d602bd8a7d11503cf17ea31ef1a3df6b5e58 100644 (file)
@@ -69,7 +69,7 @@ public class RecipientHelper {
         return account.getRecipientStore().resolveRecipient(address);
     }
 
-    public Set<RecipientId> resolveRecipients(Collection<RecipientIdentifier.Single> recipients) throws IOException, UnregisteredRecipientException {
+    public Set<RecipientId> resolveRecipients(Collection<RecipientIdentifier.Single> recipients) throws UnregisteredRecipientException {
         final var recipientIds = new HashSet<RecipientId>(recipients.size());
         for (var number : recipients) {
             final var recipientId = resolveRecipient(number);
@@ -78,7 +78,7 @@ public class RecipientHelper {
         return recipientIds;
     }
 
-    public RecipientId resolveRecipient(final RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException {
+    public RecipientId resolveRecipient(final RecipientIdentifier.Single recipient) throws UnregisteredRecipientException {
         if (recipient instanceof RecipientIdentifier.Uuid uuidRecipient) {
             return account.getRecipientStore().resolveRecipient(ServiceId.from(uuidRecipient.uuid()));
         } else {
index a2e2379b73a645c1c217ef19b383b8c38d1a182a..8b2a054efbb1f8edab75cf914102a4788099c1a8 100644 (file)
@@ -475,7 +475,7 @@ public class SendHelper {
 
         final var senderKeyTargets = new HashSet<RecipientId>();
         final var recipientList = new ArrayList<>(recipientIds);
-        final var profiles = context.getProfileHelper().getRecipientProfile(recipientList).iterator();
+        final var profiles = context.getProfileHelper().getRecipientProfiles(recipientList).iterator();
         for (final var recipientId : recipientList) {
             final var profile = profiles.next();
             if (profile == null || !profile.getCapabilities().contains(Profile.Capability.senderKey)) {
index 299a398073f3c44cecc1370f604bb6b21d708589..850b62703df88871f25a97b7a429dc8349767fde 100644 (file)
@@ -277,6 +277,24 @@ public class RecipientStore implements RecipientResolver, ContactsStore, Profile
                 .toList();
     }
 
+    public List<Recipient> getRecipients(
+            boolean onlyContacts, Optional<Boolean> blocked, Set<RecipientId> recipientIds, Optional<String> name
+    ) {
+        return recipients.values()
+                .stream()
+                .filter(r -> !onlyContacts || r.getContact() != null)
+                .filter(r -> blocked.isEmpty() || (
+                        blocked.get() == (
+                                r.getContact() != null && r.getContact().isBlocked()
+                        )
+                ))
+                .filter(r -> recipientIds.isEmpty() || (recipientIds.contains(r.getRecipientId())))
+                .filter(r -> name.isEmpty()
+                        || (r.getContact() != null && name.get().equals(r.getContact().getName()))
+                        || (r.getProfile() != null && name.get().equals(r.getProfile().getDisplayName())))
+                .toList();
+    }
+
     @Override
     public void deleteContact(RecipientId recipientId) {
         synchronized (recipients) {
index b83440ec61377f338a2cab1fe663185cc422d1ba..0bfc7ab9a377c99134dd4a8c2e1d831112c896a1 100644 (file)
@@ -1,13 +1,20 @@
 package org.asamk.signal.commands;
 
+import net.sourceforge.argparse4j.impl.Arguments;
 import net.sourceforge.argparse4j.inf.Namespace;
 import net.sourceforge.argparse4j.inf.Subparser;
 
+import org.asamk.signal.commands.exceptions.CommandException;
 import org.asamk.signal.manager.Manager;
+import org.asamk.signal.manager.storage.recipients.Contact;
+import org.asamk.signal.manager.storage.recipients.Profile;
 import org.asamk.signal.output.JsonWriter;
 import org.asamk.signal.output.OutputWriter;
 import org.asamk.signal.output.PlainTextWriter;
+import org.asamk.signal.util.CommandUtil;
 
+import java.util.Base64;
+import java.util.Optional;
 import java.util.UUID;
 
 public class ListContactsCommand implements JsonRpcLocalCommand {
@@ -19,19 +26,39 @@ public class ListContactsCommand implements JsonRpcLocalCommand {
 
     @Override
     public void attachToSubparser(final Subparser subparser) {
-        subparser.help("Show a list of known contacts with names.");
+        subparser.help("Show a list of known contacts with names and profiles.");
+        subparser.addArgument("recipient").help("Specify one ore more phone numbers to show.").nargs("*");
+        subparser.addArgument("-a", "--all-recipients")
+                .action(Arguments.storeTrue())
+                .help("Include all known recipients, not only contacts.");
+        subparser.addArgument("--blocked")
+                .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.");
     }
 
     @Override
-    public void handleCommand(final Namespace ns, final Manager m, final OutputWriter outputWriter) {
-        var contacts = m.getContacts();
+    public void handleCommand(
+            final Namespace ns, final Manager m, final OutputWriter outputWriter
+    ) throws CommandException {
+        final var allRecipients = Boolean.TRUE.equals(ns.getBoolean("all-recipients"));
+        final var blocked = ns.getBoolean("blocked");
+        final var recipientStrings = ns.<String>getList("recipient");
+        final var recipientIdentifiers = CommandUtil.getSingleRecipientIdentifiers(recipientStrings, m.getSelfNumber());
+        final var name = ns.getString("name");
+        final var recipients = m.getRecipients(!allRecipients,
+                Optional.ofNullable(blocked),
+                recipientIdentifiers,
+                Optional.ofNullable(name));
 
         if (outputWriter instanceof PlainTextWriter writer) {
-            for (var c : contacts) {
-                final var contact = c.second();
-                writer.println("Number: {} Name: {} Blocked: {} Message expiration: {}",
-                        c.first().getLegacyIdentifier(),
+            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: {} Blocked: {} Message expiration: {}",
+                        r.getAddress().getLegacyIdentifier(),
                         contact.getName(),
+                        profile.getDisplayName(),
                         contact.isBlocked(),
                         contact.getMessageExpirationTime() == 0
                                 ? "disabled"
@@ -39,19 +66,47 @@ public class ListContactsCommand implements JsonRpcLocalCommand {
             }
         } else {
             final var writer = (JsonWriter) outputWriter;
-            final var jsonContacts = contacts.stream().map(contactPair -> {
-                final var address = contactPair.first();
-                final var contact = contactPair.second();
+            final var jsonContacts = recipients.stream().map(r -> {
+                final var address = r.getAddress();
+                final var contact = r.getContact() == null ? Contact.newBuilder().build() : r.getContact();
                 return new JsonContact(address.number().orElse(null),
                         address.uuid().map(UUID::toString).orElse(null),
                         contact.getName(),
                         contact.isBlocked(),
-                        contact.getMessageExpirationTime());
+                        contact.getMessageExpirationTime(),
+                        r.getProfile() == null
+                                ? null
+                                : new JsonContact.JsonProfile(r.getProfile().getLastUpdateTimestamp(),
+                                        r.getProfile().getGivenName(),
+                                        r.getProfile().getFamilyName(),
+                                        r.getProfile().getAbout(),
+                                        r.getProfile().getAboutEmoji(),
+                                        r.getProfile().getPaymentAddress() == null
+                                                ? null
+                                                : Base64.getEncoder()
+                                                        .encodeToString(r.getProfile().getPaymentAddress())));
             }).toList();
 
             writer.write(jsonContacts);
         }
     }
 
-    private record JsonContact(String number, String uuid, String name, boolean isBlocked, int messageExpirationTime) {}
+    private record JsonContact(
+            String number,
+            String uuid,
+            String name,
+            boolean isBlocked,
+            int messageExpirationTime,
+            JsonProfile profile
+    ) {
+
+        private record JsonProfile(
+                long lastUpdateTimestamp,
+                String givenName,
+                String familyName,
+                String about,
+                String aboutEmoji,
+                String paymentAddress
+        ) {}
+    }
 }
index 5b33b039ab86708a470d10b7d5476d0677208dc4..11800be2a3e0069a40d6e160d52c5b9d5809e288 100644 (file)
@@ -32,6 +32,7 @@ import org.asamk.signal.manager.groups.LastGroupAdminException;
 import org.asamk.signal.manager.groups.NotAGroupMemberException;
 import org.asamk.signal.manager.storage.recipients.Contact;
 import org.asamk.signal.manager.storage.recipients.Profile;
+import org.asamk.signal.manager.storage.recipients.Recipient;
 import org.asamk.signal.manager.storage.recipients.RecipientAddress;
 import org.freedesktop.dbus.DBusMap;
 import org.freedesktop.dbus.DBusPath;
@@ -547,14 +548,32 @@ public class DbusManagerImpl implements Manager {
     }
 
     @Override
-    public List<Pair<RecipientAddress, Contact>> getContacts() {
-        return signal.listNumbers().stream().map(n -> {
+    public List<Recipient> getRecipients(
+            final boolean onlyContacts,
+            final Optional<Boolean> blocked,
+            final Collection<RecipientIdentifier.Single> addresses,
+            final Optional<String> name
+    ) {
+        final var numbers = addresses.stream()
+                .filter(s -> s instanceof RecipientIdentifier.Number)
+                .map(s -> ((RecipientIdentifier.Number) s).number())
+                .collect(Collectors.toSet());
+        return signal.listNumbers().stream().filter(n -> addresses.isEmpty() || numbers.contains(n)).map(n -> {
+            final var contactBlocked = signal.isContactBlocked(n);
+            if (blocked.isPresent() && blocked.get() != contactBlocked) {
+                return null;
+            }
             final var contactName = signal.getContactName(n);
-            if (contactName.length() == 0) {
+            if (onlyContacts && contactName.length() == 0) {
+                return null;
+            }
+            if (name.isPresent() && !name.get().equals(contactName)) {
                 return null;
             }
-            return new Pair<>(new RecipientAddress(null, n),
-                    new Contact(contactName, null, 0, signal.isContactBlocked(n), false, false));
+            return Recipient.newBuilder()
+                    .withAddress(new RecipientAddress(null, n))
+                    .withContact(new Contact(contactName, null, 0, contactBlocked, false, false))
+                    .build();
         }).filter(Objects::nonNull).toList();
     }
 
index b4485e3293bfa7523fbcc181d713e4df8917f851..f4a9cda832d322f6fb3c1437c4cd77a453e45387 100644 (file)
@@ -4,14 +4,12 @@ import org.asamk.Signal;
 import org.asamk.signal.BaseConfig;
 import org.asamk.signal.manager.Manager;
 import org.asamk.signal.manager.api.AttachmentInvalidException;
-import org.asamk.signal.manager.api.Identity;
 import org.asamk.signal.manager.api.InactiveGroupLinkException;
 import org.asamk.signal.manager.api.InvalidDeviceLinkException;
 import org.asamk.signal.manager.api.InvalidNumberException;
 import org.asamk.signal.manager.api.InvalidStickerException;
 import org.asamk.signal.manager.api.Message;
 import org.asamk.signal.manager.api.NotMasterDeviceException;
-import org.asamk.signal.manager.api.Pair;
 import org.asamk.signal.manager.api.RecipientIdentifier;
 import org.asamk.signal.manager.api.SendMessageResult;
 import org.asamk.signal.manager.api.SendMessageResults;
@@ -28,7 +26,6 @@ import org.asamk.signal.manager.groups.GroupPermission;
 import org.asamk.signal.manager.groups.GroupSendingNotAllowedException;
 import org.asamk.signal.manager.groups.LastGroupAdminException;
 import org.asamk.signal.manager.groups.NotAGroupMemberException;
-import org.asamk.signal.manager.storage.recipients.Profile;
 import org.asamk.signal.manager.storage.recipients.RecipientAddress;
 import org.asamk.signal.util.SendMessageResultUtils;
 import org.freedesktop.dbus.DBusPath;
@@ -55,7 +52,6 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 public class DbusSignalImpl implements Signal {
 
@@ -719,9 +715,9 @@ public class DbusSignalImpl implements Signal {
     // all numbers the system knows
     @Override
     public List<String> listNumbers() {
-        return Stream.concat(m.getIdentities().stream().map(Identity::recipient),
-                        m.getContacts().stream().map(Pair::first))
-                .map(a -> a.number().orElse(null))
+        return m.getRecipients(false, Optional.empty(), Set.of(), Optional.empty())
+                .stream()
+                .map(r -> r.getAddress().number().orElse(null))
                 .filter(Objects::nonNull)
                 .distinct()
                 .toList();
@@ -729,30 +725,10 @@ public class DbusSignalImpl implements Signal {
 
     @Override
     public List<String> getContactNumber(final String name) {
-        // Contact names have precedence.
-        var numbers = new ArrayList<String>();
-        var contacts = m.getContacts();
-        for (var c : contacts) {
-            if (name.equals(c.second().getName())) {
-                numbers.add(c.first().getLegacyIdentifier());
-            }
-        }
-        // Try profiles if no contact name was found
-        for (var identity : m.getIdentities()) {
-            final var address = identity.recipient();
-            var number = address.number().orElse(null);
-            if (number != null) {
-                Profile profile = null;
-                try {
-                    profile = m.getRecipientProfile(RecipientIdentifier.Single.fromAddress(address));
-                } catch (IOException | UnregisteredRecipientException ignored) {
-                }
-                if (profile != null && profile.getDisplayName().equals(name)) {
-                    numbers.add(number);
-                }
-            }
-        }
-        return numbers;
+        return m.getRecipients(false, Optional.empty(), Set.of(), Optional.of(name))
+                .stream()
+                .map(r -> r.getAddress().getLegacyIdentifier())
+                .toList();
     }
 
     @Override