mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
Refactor ReceiveCommand in dbus mode and remove ExtendedDbusCommand
This commit is contained in:
parent
eec7aec069
commit
32818a8608
16 changed files with 301 additions and 261 deletions
|
@ -25,7 +25,7 @@ public class AttachmentStore {
|
||||||
public void storeAttachment(
|
public void storeAttachment(
|
||||||
final SignalServiceAttachmentRemoteId attachmentId, final AttachmentStorer storer
|
final SignalServiceAttachmentRemoteId attachmentId, final AttachmentStorer storer
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
storeAttachment(getAttachmentFile(attachmentId.toString()), storer);
|
storeAttachment(getAttachmentFile(attachmentId), storer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storeAttachment(final File attachmentFile, final AttachmentStorer storer) throws IOException {
|
private void storeAttachment(final File attachmentFile, final AttachmentStorer storer) throws IOException {
|
||||||
|
@ -39,8 +39,8 @@ public class AttachmentStore {
|
||||||
return new File(attachmentsPath, attachmentId.toString() + ".preview");
|
return new File(attachmentsPath, attachmentId.toString() + ".preview");
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getAttachmentFile(String attachmentId) {
|
public File getAttachmentFile(SignalServiceAttachmentRemoteId attachmentId) {
|
||||||
return new File(attachmentsPath, attachmentId);
|
return new File(attachmentsPath, attachmentId.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAttachmentsDir() throws IOException {
|
private void createAttachmentsDir() throws IOException {
|
||||||
|
|
|
@ -226,8 +226,6 @@ public interface Manager extends Closeable {
|
||||||
|
|
||||||
boolean isContactBlocked(RecipientIdentifier.Single recipient);
|
boolean isContactBlocked(RecipientIdentifier.Single recipient);
|
||||||
|
|
||||||
File getAttachmentFile(String attachmentId);
|
|
||||||
|
|
||||||
void sendContacts() throws IOException;
|
void sendContacts() throws IOException;
|
||||||
|
|
||||||
List<Pair<RecipientAddress, Contact>> getContacts();
|
List<Pair<RecipientAddress, Contact>> getContacts();
|
||||||
|
|
|
@ -1149,11 +1149,6 @@ public class ManagerImpl implements Manager {
|
||||||
return contactHelper.isContactBlocked(recipientId);
|
return contactHelper.isContactBlocked(recipientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public File getAttachmentFile(String attachmentId) {
|
|
||||||
return attachmentHelper.getAttachmentFile(attachmentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendContacts() throws IOException {
|
public void sendContacts() throws IOException {
|
||||||
syncHelper.sendContacts();
|
syncHelper.sendContacts();
|
||||||
|
|
|
@ -6,6 +6,7 @@ import org.asamk.signal.manager.helper.RecipientAddressResolver;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientResolver;
|
import org.asamk.signal.manager.storage.recipients.RecipientResolver;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||||
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentRemoteId;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceContent;
|
import org.whispersystems.signalservice.api.messages.SignalServiceContent;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
|
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
|
||||||
|
@ -29,6 +30,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSy
|
||||||
import org.whispersystems.signalservice.api.messages.multidevice.ViewOnceOpenMessage;
|
import org.whispersystems.signalservice.api.messages.multidevice.ViewOnceOpenMessage;
|
||||||
import org.whispersystems.signalservice.api.messages.multidevice.ViewedMessage;
|
import org.whispersystems.signalservice.api.messages.multidevice.ViewedMessage;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -110,7 +112,8 @@ public record MessageEnvelope(
|
||||||
static Data from(
|
static Data from(
|
||||||
final SignalServiceDataMessage dataMessage,
|
final SignalServiceDataMessage dataMessage,
|
||||||
RecipientResolver recipientResolver,
|
RecipientResolver recipientResolver,
|
||||||
RecipientAddressResolver addressResolver
|
RecipientAddressResolver addressResolver,
|
||||||
|
final AttachmentFileProvider fileProvider
|
||||||
) {
|
) {
|
||||||
return new Data(dataMessage.getTimestamp(),
|
return new Data(dataMessage.getTimestamp(),
|
||||||
Optional.ofNullable(dataMessage.getGroupContext().transform(GroupContext::from).orNull()),
|
Optional.ofNullable(dataMessage.getGroupContext().transform(GroupContext::from).orNull()),
|
||||||
|
@ -125,17 +128,21 @@ public record MessageEnvelope(
|
||||||
.transform(r -> Reaction.from(r, recipientResolver, addressResolver))
|
.transform(r -> Reaction.from(r, recipientResolver, addressResolver))
|
||||||
.orNull()),
|
.orNull()),
|
||||||
Optional.ofNullable(dataMessage.getQuote()
|
Optional.ofNullable(dataMessage.getQuote()
|
||||||
.transform(q -> Quote.from(q, recipientResolver, addressResolver))
|
.transform(q -> Quote.from(q, recipientResolver, addressResolver, fileProvider))
|
||||||
.orNull()),
|
.orNull()),
|
||||||
dataMessage.getAttachments()
|
dataMessage.getAttachments()
|
||||||
.transform(a -> a.stream().map(Attachment::from).collect(Collectors.toList()))
|
.transform(a -> a.stream()
|
||||||
|
.map(as -> Attachment.from(as, fileProvider))
|
||||||
|
.collect(Collectors.toList()))
|
||||||
.or(List.of()),
|
.or(List.of()),
|
||||||
Optional.ofNullable(dataMessage.getRemoteDelete()
|
Optional.ofNullable(dataMessage.getRemoteDelete()
|
||||||
.transform(SignalServiceDataMessage.RemoteDelete::getTargetSentTimestamp)
|
.transform(SignalServiceDataMessage.RemoteDelete::getTargetSentTimestamp)
|
||||||
.orNull()),
|
.orNull()),
|
||||||
Optional.ofNullable(dataMessage.getSticker().transform(Sticker::from).orNull()),
|
Optional.ofNullable(dataMessage.getSticker().transform(Sticker::from).orNull()),
|
||||||
dataMessage.getSharedContacts()
|
dataMessage.getSharedContacts()
|
||||||
.transform(a -> a.stream().map(SharedContact::from).collect(Collectors.toList()))
|
.transform(a -> a.stream()
|
||||||
|
.map(sharedContact -> SharedContact.from(sharedContact, fileProvider))
|
||||||
|
.collect(Collectors.toList()))
|
||||||
.or(List.of()),
|
.or(List.of()),
|
||||||
dataMessage.getMentions()
|
dataMessage.getMentions()
|
||||||
.transform(a -> a.stream()
|
.transform(a -> a.stream()
|
||||||
|
@ -143,7 +150,9 @@ public record MessageEnvelope(
|
||||||
.collect(Collectors.toList()))
|
.collect(Collectors.toList()))
|
||||||
.or(List.of()),
|
.or(List.of()),
|
||||||
dataMessage.getPreviews()
|
dataMessage.getPreviews()
|
||||||
.transform(a -> a.stream().map(Preview::from).collect(Collectors.toList()))
|
.transform(a -> a.stream()
|
||||||
|
.map(preview -> Preview.from(preview, fileProvider))
|
||||||
|
.collect(Collectors.toList()))
|
||||||
.or(List.of()));
|
.or(List.of()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +208,8 @@ public record MessageEnvelope(
|
||||||
static Quote from(
|
static Quote from(
|
||||||
SignalServiceDataMessage.Quote quote,
|
SignalServiceDataMessage.Quote quote,
|
||||||
RecipientResolver recipientResolver,
|
RecipientResolver recipientResolver,
|
||||||
RecipientAddressResolver addressResolver
|
RecipientAddressResolver addressResolver,
|
||||||
|
final AttachmentFileProvider fileProvider
|
||||||
) {
|
) {
|
||||||
return new Quote(quote.getId(),
|
return new Quote(quote.getId(),
|
||||||
addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(quote.getAuthor())),
|
addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(quote.getAuthor())),
|
||||||
|
@ -212,7 +222,10 @@ public record MessageEnvelope(
|
||||||
.collect(Collectors.toList()),
|
.collect(Collectors.toList()),
|
||||||
quote.getAttachments() == null
|
quote.getAttachments() == null
|
||||||
? List.of()
|
? List.of()
|
||||||
: quote.getAttachments().stream().map(Attachment::from).collect(Collectors.toList()));
|
: quote.getAttachments()
|
||||||
|
.stream()
|
||||||
|
.map(a -> Attachment.from(a, fileProvider))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,6 +244,7 @@ public record MessageEnvelope(
|
||||||
|
|
||||||
public record Attachment(
|
public record Attachment(
|
||||||
Optional<String> id,
|
Optional<String> id,
|
||||||
|
Optional<File> file,
|
||||||
Optional<String> fileName,
|
Optional<String> fileName,
|
||||||
String contentType,
|
String contentType,
|
||||||
Optional<Long> uploadTimestamp,
|
Optional<Long> uploadTimestamp,
|
||||||
|
@ -245,10 +259,11 @@ public record MessageEnvelope(
|
||||||
boolean isBorderless
|
boolean isBorderless
|
||||||
) {
|
) {
|
||||||
|
|
||||||
static Attachment from(SignalServiceAttachment attachment) {
|
static Attachment from(SignalServiceAttachment attachment, AttachmentFileProvider fileProvider) {
|
||||||
if (attachment.isPointer()) {
|
if (attachment.isPointer()) {
|
||||||
final var a = attachment.asPointer();
|
final var a = attachment.asPointer();
|
||||||
return new Attachment(Optional.of(a.getRemoteId().toString()),
|
return new Attachment(Optional.of(a.getRemoteId().toString()),
|
||||||
|
Optional.of(fileProvider.getFile(a.getRemoteId())),
|
||||||
Optional.ofNullable(a.getFileName().orNull()),
|
Optional.ofNullable(a.getFileName().orNull()),
|
||||||
a.getContentType(),
|
a.getContentType(),
|
||||||
a.getUploadTimestamp() == 0 ? Optional.empty() : Optional.of(a.getUploadTimestamp()),
|
a.getUploadTimestamp() == 0 ? Optional.empty() : Optional.of(a.getUploadTimestamp()),
|
||||||
|
@ -264,6 +279,7 @@ public record MessageEnvelope(
|
||||||
} else {
|
} else {
|
||||||
final var a = attachment.asStream();
|
final var a = attachment.asStream();
|
||||||
return new Attachment(Optional.empty(),
|
return new Attachment(Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
Optional.ofNullable(a.getFileName().orNull()),
|
Optional.ofNullable(a.getFileName().orNull()),
|
||||||
a.getContentType(),
|
a.getContentType(),
|
||||||
a.getUploadTimestamp() == 0 ? Optional.empty() : Optional.of(a.getUploadTimestamp()),
|
a.getUploadTimestamp() == 0 ? Optional.empty() : Optional.of(a.getUploadTimestamp()),
|
||||||
|
@ -279,14 +295,19 @@ public record MessageEnvelope(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Attachment from(SignalServiceDataMessage.Quote.QuotedAttachment a) {
|
static Attachment from(
|
||||||
|
SignalServiceDataMessage.Quote.QuotedAttachment a, final AttachmentFileProvider fileProvider
|
||||||
|
) {
|
||||||
return new Attachment(Optional.empty(),
|
return new Attachment(Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
Optional.ofNullable(a.getFileName()),
|
Optional.ofNullable(a.getFileName()),
|
||||||
a.getContentType(),
|
a.getContentType(),
|
||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
a.getThumbnail() == null ? Optional.empty() : Optional.of(Attachment.from(a.getThumbnail())),
|
a.getThumbnail() == null
|
||||||
|
? Optional.empty()
|
||||||
|
: Optional.of(Attachment.from(a.getThumbnail(), fileProvider)),
|
||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
Optional.empty(),
|
Optional.empty(),
|
||||||
|
@ -312,9 +333,14 @@ public record MessageEnvelope(
|
||||||
Optional<String> organization
|
Optional<String> organization
|
||||||
) {
|
) {
|
||||||
|
|
||||||
static SharedContact from(org.whispersystems.signalservice.api.messages.shared.SharedContact sharedContact) {
|
static SharedContact from(
|
||||||
|
org.whispersystems.signalservice.api.messages.shared.SharedContact sharedContact,
|
||||||
|
final AttachmentFileProvider fileProvider
|
||||||
|
) {
|
||||||
return new SharedContact(Name.from(sharedContact.getName()),
|
return new SharedContact(Name.from(sharedContact.getName()),
|
||||||
Optional.ofNullable(sharedContact.getAvatar().transform(Avatar::from).orNull()),
|
Optional.ofNullable(sharedContact.getAvatar()
|
||||||
|
.transform(avatar1 -> Avatar.from(avatar1, fileProvider))
|
||||||
|
.orNull()),
|
||||||
sharedContact.getPhone()
|
sharedContact.getPhone()
|
||||||
.transform(p -> p.stream().map(Phone::from).collect(Collectors.toList()))
|
.transform(p -> p.stream().map(Phone::from).collect(Collectors.toList()))
|
||||||
.or(List.of()),
|
.or(List.of()),
|
||||||
|
@ -348,8 +374,11 @@ public record MessageEnvelope(
|
||||||
|
|
||||||
public record Avatar(Attachment attachment, boolean isProfile) {
|
public record Avatar(Attachment attachment, boolean isProfile) {
|
||||||
|
|
||||||
static Avatar from(org.whispersystems.signalservice.api.messages.shared.SharedContact.Avatar avatar) {
|
static Avatar from(
|
||||||
return new Avatar(Attachment.from(avatar.getAttachment()), avatar.isProfile());
|
org.whispersystems.signalservice.api.messages.shared.SharedContact.Avatar avatar,
|
||||||
|
final AttachmentFileProvider fileProvider
|
||||||
|
) {
|
||||||
|
return new Avatar(Attachment.from(avatar.getAttachment(), fileProvider), avatar.isProfile());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,12 +478,16 @@ public record MessageEnvelope(
|
||||||
|
|
||||||
public record Preview(String title, String description, long date, String url, Optional<Attachment> image) {
|
public record Preview(String title, String description, long date, String url, Optional<Attachment> image) {
|
||||||
|
|
||||||
static Preview from(SignalServiceDataMessage.Preview preview) {
|
static Preview from(
|
||||||
|
SignalServiceDataMessage.Preview preview, final AttachmentFileProvider fileProvider
|
||||||
|
) {
|
||||||
return new Preview(preview.getTitle(),
|
return new Preview(preview.getTitle(),
|
||||||
preview.getDescription(),
|
preview.getDescription(),
|
||||||
preview.getDate(),
|
preview.getDate(),
|
||||||
preview.getUrl(),
|
preview.getUrl(),
|
||||||
Optional.ofNullable(preview.getImage().transform(Attachment::from).orNull()));
|
Optional.ofNullable(preview.getImage()
|
||||||
|
.transform(as -> Attachment.from(as, fileProvider))
|
||||||
|
.orNull()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -473,10 +506,11 @@ public record MessageEnvelope(
|
||||||
public static Sync from(
|
public static Sync from(
|
||||||
final SignalServiceSyncMessage syncMessage,
|
final SignalServiceSyncMessage syncMessage,
|
||||||
RecipientResolver recipientResolver,
|
RecipientResolver recipientResolver,
|
||||||
RecipientAddressResolver addressResolver
|
RecipientAddressResolver addressResolver,
|
||||||
|
final AttachmentFileProvider fileProvider
|
||||||
) {
|
) {
|
||||||
return new Sync(Optional.ofNullable(syncMessage.getSent()
|
return new Sync(Optional.ofNullable(syncMessage.getSent()
|
||||||
.transform(s -> Sent.from(s, recipientResolver, addressResolver))
|
.transform(s -> Sent.from(s, recipientResolver, addressResolver, fileProvider))
|
||||||
.orNull()),
|
.orNull()),
|
||||||
Optional.ofNullable(syncMessage.getBlockedList()
|
Optional.ofNullable(syncMessage.getBlockedList()
|
||||||
.transform(b -> Blocked.from(b, recipientResolver, addressResolver))
|
.transform(b -> Blocked.from(b, recipientResolver, addressResolver))
|
||||||
|
@ -512,7 +546,8 @@ public record MessageEnvelope(
|
||||||
static Sent from(
|
static Sent from(
|
||||||
SentTranscriptMessage sentMessage,
|
SentTranscriptMessage sentMessage,
|
||||||
RecipientResolver recipientResolver,
|
RecipientResolver recipientResolver,
|
||||||
RecipientAddressResolver addressResolver
|
RecipientAddressResolver addressResolver,
|
||||||
|
final AttachmentFileProvider fileProvider
|
||||||
) {
|
) {
|
||||||
return new Sent(sentMessage.getTimestamp(),
|
return new Sent(sentMessage.getTimestamp(),
|
||||||
sentMessage.getExpirationStartTimestamp(),
|
sentMessage.getExpirationStartTimestamp(),
|
||||||
|
@ -524,7 +559,7 @@ public record MessageEnvelope(
|
||||||
.stream()
|
.stream()
|
||||||
.map(d -> addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(d)))
|
.map(d -> addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(d)))
|
||||||
.collect(Collectors.toSet()),
|
.collect(Collectors.toSet()),
|
||||||
Data.from(sentMessage.getMessage(), recipientResolver, addressResolver));
|
Data.from(sentMessage.getMessage(), recipientResolver, addressResolver, fileProvider));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,13 +727,6 @@ public record MessageEnvelope(
|
||||||
|
|
||||||
public record Busy(long id) {
|
public record Busy(long id) {
|
||||||
|
|
||||||
static Offer from(OfferMessage offerMessage) {
|
|
||||||
return new Offer(offerMessage.getId(),
|
|
||||||
offerMessage.getSdp(),
|
|
||||||
Offer.Type.from(offerMessage.getType()),
|
|
||||||
offerMessage.getOpaque());
|
|
||||||
}
|
|
||||||
|
|
||||||
static Busy from(BusyMessage busyMessage) {
|
static Busy from(BusyMessage busyMessage) {
|
||||||
return new Busy(busyMessage.getId());
|
return new Busy(busyMessage.getId());
|
||||||
}
|
}
|
||||||
|
@ -763,7 +791,8 @@ public record MessageEnvelope(
|
||||||
SignalServiceEnvelope envelope,
|
SignalServiceEnvelope envelope,
|
||||||
SignalServiceContent content,
|
SignalServiceContent content,
|
||||||
RecipientResolver recipientResolver,
|
RecipientResolver recipientResolver,
|
||||||
RecipientAddressResolver addressResolver
|
RecipientAddressResolver addressResolver,
|
||||||
|
final AttachmentFileProvider fileProvider
|
||||||
) {
|
) {
|
||||||
final var source = !envelope.isUnidentifiedSender() && envelope.hasSourceUuid()
|
final var source = !envelope.isUnidentifiedSender() && envelope.hasSourceUuid()
|
||||||
? recipientResolver.resolveRecipient(envelope.getSourceAddress())
|
? recipientResolver.resolveRecipient(envelope.getSourceAddress())
|
||||||
|
@ -783,10 +812,10 @@ public record MessageEnvelope(
|
||||||
receipt = Optional.ofNullable(content.getReceiptMessage().transform(Receipt::from).orNull());
|
receipt = Optional.ofNullable(content.getReceiptMessage().transform(Receipt::from).orNull());
|
||||||
typing = Optional.ofNullable(content.getTypingMessage().transform(Typing::from).orNull());
|
typing = Optional.ofNullable(content.getTypingMessage().transform(Typing::from).orNull());
|
||||||
data = Optional.ofNullable(content.getDataMessage()
|
data = Optional.ofNullable(content.getDataMessage()
|
||||||
.transform(dataMessage -> Data.from(dataMessage, recipientResolver, addressResolver))
|
.transform(dataMessage -> Data.from(dataMessage, recipientResolver, addressResolver, fileProvider))
|
||||||
.orNull());
|
.orNull());
|
||||||
sync = Optional.ofNullable(content.getSyncMessage()
|
sync = Optional.ofNullable(content.getSyncMessage()
|
||||||
.transform(s -> Sync.from(s, recipientResolver, addressResolver))
|
.transform(s -> Sync.from(s, recipientResolver, addressResolver, fileProvider))
|
||||||
.orNull());
|
.orNull());
|
||||||
call = Optional.ofNullable(content.getCallMessage().transform(Call::from).orNull());
|
call = Optional.ofNullable(content.getCallMessage().transform(Call::from).orNull());
|
||||||
} else {
|
} else {
|
||||||
|
@ -811,4 +840,9 @@ public record MessageEnvelope(
|
||||||
sync,
|
sync,
|
||||||
call);
|
call);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface AttachmentFileProvider {
|
||||||
|
|
||||||
|
File getFile(SignalServiceAttachmentRemoteId attachmentRemoteId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.whispersystems.libsignal.InvalidMessageException;
|
import org.whispersystems.libsignal.InvalidMessageException;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
|
||||||
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentRemoteId;
|
||||||
import org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException;
|
import org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -35,7 +36,7 @@ public class AttachmentHelper {
|
||||||
this.attachmentStore = attachmentStore;
|
this.attachmentStore = attachmentStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getAttachmentFile(String attachmentId) {
|
public File getAttachmentFile(SignalServiceAttachmentRemoteId attachmentId) {
|
||||||
return attachmentStore.getAttachmentFile(attachmentId);
|
return attachmentStore.getAttachmentFile(attachmentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,7 +200,8 @@ public final class IncomingMessageHandler {
|
||||||
handler.handleMessage(MessageEnvelope.from(envelope,
|
handler.handleMessage(MessageEnvelope.from(envelope,
|
||||||
content,
|
content,
|
||||||
recipientResolver,
|
recipientResolver,
|
||||||
account.getRecipientStore()::resolveRecipientAddress), exception);
|
account.getRecipientStore()::resolveRecipientAddress,
|
||||||
|
attachmentHelper::getAttachmentFile), exception);
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import net.sourceforge.argparse4j.inf.Namespace;
|
||||||
import org.asamk.Signal;
|
import org.asamk.Signal;
|
||||||
import org.asamk.signal.commands.Command;
|
import org.asamk.signal.commands.Command;
|
||||||
import org.asamk.signal.commands.Commands;
|
import org.asamk.signal.commands.Commands;
|
||||||
import org.asamk.signal.commands.ExtendedDbusCommand;
|
|
||||||
import org.asamk.signal.commands.LocalCommand;
|
import org.asamk.signal.commands.LocalCommand;
|
||||||
import org.asamk.signal.commands.MultiLocalCommand;
|
import org.asamk.signal.commands.MultiLocalCommand;
|
||||||
import org.asamk.signal.commands.ProvisioningCommand;
|
import org.asamk.signal.commands.ProvisioningCommand;
|
||||||
|
@ -151,20 +150,20 @@ public class App {
|
||||||
? TrustNewIdentity.ON_FIRST_USE
|
? TrustNewIdentity.ON_FIRST_USE
|
||||||
: trustNewIdentityCli == TrustNewIdentityCli.ALWAYS ? TrustNewIdentity.ALWAYS : TrustNewIdentity.NEVER;
|
: trustNewIdentityCli == TrustNewIdentityCli.ALWAYS ? TrustNewIdentity.ALWAYS : TrustNewIdentity.NEVER;
|
||||||
|
|
||||||
if (command instanceof ProvisioningCommand) {
|
if (command instanceof ProvisioningCommand provisioningCommand) {
|
||||||
if (username != null) {
|
if (username != null) {
|
||||||
throw new UserErrorException("You cannot specify a username (phone number) when linking");
|
throw new UserErrorException("You cannot specify a username (phone number) when linking");
|
||||||
}
|
}
|
||||||
|
|
||||||
handleProvisioningCommand((ProvisioningCommand) command, dataPath, serviceEnvironment, outputWriter);
|
handleProvisioningCommand(provisioningCommand, dataPath, serviceEnvironment, outputWriter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
var usernames = Manager.getAllLocalNumbers(dataPath);
|
var usernames = Manager.getAllLocalNumbers(dataPath);
|
||||||
|
|
||||||
if (command instanceof MultiLocalCommand) {
|
if (command instanceof MultiLocalCommand multiLocalCommand) {
|
||||||
handleMultiLocalCommand((MultiLocalCommand) command,
|
handleMultiLocalCommand(multiLocalCommand,
|
||||||
dataPath,
|
dataPath,
|
||||||
serviceEnvironment,
|
serviceEnvironment,
|
||||||
usernames,
|
usernames,
|
||||||
|
@ -185,8 +184,8 @@ public class App {
|
||||||
throw new UserErrorException("Invalid username (phone number), make sure you include the country code.");
|
throw new UserErrorException("Invalid username (phone number), make sure you include the country code.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command instanceof RegistrationCommand) {
|
if (command instanceof RegistrationCommand registrationCommand) {
|
||||||
handleRegistrationCommand((RegistrationCommand) command, username, dataPath, serviceEnvironment);
|
handleRegistrationCommand(registrationCommand, username, dataPath, serviceEnvironment);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,11 +343,9 @@ public class App {
|
||||||
private void handleCommand(
|
private void handleCommand(
|
||||||
Command command, Signal ts, DBusConnection dBusConn, OutputWriter outputWriter
|
Command command, Signal ts, DBusConnection dBusConn, OutputWriter outputWriter
|
||||||
) throws CommandException {
|
) throws CommandException {
|
||||||
if (command instanceof ExtendedDbusCommand) {
|
if (command instanceof LocalCommand localCommand) {
|
||||||
((ExtendedDbusCommand) command).handleCommand(ns, ts, dBusConn, outputWriter);
|
|
||||||
} else if (command instanceof LocalCommand) {
|
|
||||||
try {
|
try {
|
||||||
((LocalCommand) command).handleCommand(ns, new DbusManagerImpl(ts, dBusConn), outputWriter);
|
localCommand.handleCommand(ns, new DbusManagerImpl(ts, dBusConn), outputWriter);
|
||||||
} catch (UnsupportedOperationException e) {
|
} catch (UnsupportedOperationException e) {
|
||||||
throw new UserErrorException("Command is not yet implemented via dbus", e);
|
throw new UserErrorException("Command is not yet implemented via dbus", e);
|
||||||
} catch (DBusExecutionException e) {
|
} catch (DBusExecutionException e) {
|
||||||
|
|
|
@ -113,8 +113,8 @@ public class DbusReceiveMessageHandler implements Manager.ReceiveMessageHandler
|
||||||
var attachments = new ArrayList<String>();
|
var attachments = new ArrayList<String>();
|
||||||
if (message.attachments().size() > 0) {
|
if (message.attachments().size() > 0) {
|
||||||
for (var attachment : message.attachments()) {
|
for (var attachment : message.attachments()) {
|
||||||
if (attachment.id().isPresent()) {
|
if (attachment.file().isPresent()) {
|
||||||
attachments.add(m.getAttachmentFile(attachment.id().get()).getAbsolutePath());
|
attachments.add(attachment.file().get().getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ public class DbusReceiveMessageHandler implements Manager.ReceiveMessageHandler
|
||||||
"author",
|
"author",
|
||||||
new Variant<>(quote.author().getLegacyIdentifier()),
|
new Variant<>(quote.author().getLegacyIdentifier()),
|
||||||
"text",
|
"text",
|
||||||
new Variant<>(quote.text()));
|
new Variant<>(quote.text().orElse("")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Variant<? extends Serializable>> getStickerMap(final MessageEnvelope.Data.Sticker sticker) {
|
private Map<String, Variant<? extends Serializable>> getStickerMap(final MessageEnvelope.Data.Sticker sticker) {
|
||||||
|
@ -184,9 +184,12 @@ public class DbusReceiveMessageHandler implements Manager.ReceiveMessageHandler
|
||||||
) {
|
) {
|
||||||
final var map = new HashMap<String, Variant<?>>();
|
final var map = new HashMap<String, Variant<?>>();
|
||||||
if (a.id().isPresent()) {
|
if (a.id().isPresent()) {
|
||||||
map.put("file", new Variant<>(m.getAttachmentFile(a.id().get()).getAbsolutePath()));
|
|
||||||
map.put("remoteId", new Variant<>(a.id().get()));
|
map.put("remoteId", new Variant<>(a.id().get()));
|
||||||
}
|
}
|
||||||
|
if (a.file().isPresent()) {
|
||||||
|
map.put("file", new Variant<>(a.file().get().getAbsolutePath()));
|
||||||
|
}
|
||||||
|
map.put("contentType", new Variant<>(a.contentType()));
|
||||||
map.put("isVoiceNote", new Variant<>(a.isVoiceNote()));
|
map.put("isVoiceNote", new Variant<>(a.isVoiceNote()));
|
||||||
map.put("isBorderless", new Variant<>(a.isBorderless()));
|
map.put("isBorderless", new Variant<>(a.isBorderless()));
|
||||||
map.put("isGif", new Variant<>(a.isGif()));
|
map.put("isGif", new Variant<>(a.isGif()));
|
||||||
|
|
|
@ -543,8 +543,8 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler {
|
||||||
if (attachment.width().isPresent() || attachment.height().isPresent()) {
|
if (attachment.width().isPresent() || attachment.height().isPresent()) {
|
||||||
writer.println("Dimensions: {}x{}", attachment.width().orElse(0), attachment.height().orElse(0));
|
writer.println("Dimensions: {}x{}", attachment.width().orElse(0), attachment.height().orElse(0));
|
||||||
}
|
}
|
||||||
if (attachment.id().isPresent()) {
|
if (attachment.file().isPresent()) {
|
||||||
var file = m.getAttachmentFile(attachment.id().get());
|
var file = attachment.file().get();
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
writer.println("Stored plaintext in: {}", file);
|
writer.println("Stored plaintext in: {}", file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
package org.asamk.signal.commands;
|
|
||||||
|
|
||||||
import net.sourceforge.argparse4j.inf.Namespace;
|
|
||||||
|
|
||||||
import org.asamk.Signal;
|
|
||||||
import org.asamk.signal.OutputWriter;
|
|
||||||
import org.asamk.signal.commands.exceptions.CommandException;
|
|
||||||
import org.freedesktop.dbus.connections.impl.DBusConnection;
|
|
||||||
|
|
||||||
public interface ExtendedDbusCommand extends CliCommand {
|
|
||||||
|
|
||||||
void handleCommand(
|
|
||||||
Namespace ns, Signal signal, DBusConnection dbusconnection, final OutputWriter outputWriter
|
|
||||||
) throws CommandException;
|
|
||||||
}
|
|
|
@ -4,7 +4,6 @@ import net.sourceforge.argparse4j.impl.Arguments;
|
||||||
import net.sourceforge.argparse4j.inf.Namespace;
|
import net.sourceforge.argparse4j.inf.Namespace;
|
||||||
import net.sourceforge.argparse4j.inf.Subparser;
|
import net.sourceforge.argparse4j.inf.Subparser;
|
||||||
|
|
||||||
import org.asamk.Signal;
|
|
||||||
import org.asamk.signal.JsonReceiveMessageHandler;
|
import org.asamk.signal.JsonReceiveMessageHandler;
|
||||||
import org.asamk.signal.JsonWriter;
|
import org.asamk.signal.JsonWriter;
|
||||||
import org.asamk.signal.OutputType;
|
import org.asamk.signal.OutputType;
|
||||||
|
@ -13,24 +12,15 @@ import org.asamk.signal.PlainTextWriter;
|
||||||
import org.asamk.signal.ReceiveMessageHandler;
|
import org.asamk.signal.ReceiveMessageHandler;
|
||||||
import org.asamk.signal.commands.exceptions.CommandException;
|
import org.asamk.signal.commands.exceptions.CommandException;
|
||||||
import org.asamk.signal.commands.exceptions.IOErrorException;
|
import org.asamk.signal.commands.exceptions.IOErrorException;
|
||||||
import org.asamk.signal.commands.exceptions.UnexpectedErrorException;
|
|
||||||
import org.asamk.signal.json.JsonMessageEnvelope;
|
|
||||||
import org.asamk.signal.manager.Manager;
|
import org.asamk.signal.manager.Manager;
|
||||||
import org.asamk.signal.util.DateUtils;
|
|
||||||
import org.freedesktop.dbus.DBusMap;
|
|
||||||
import org.freedesktop.dbus.connections.impl.DBusConnection;
|
|
||||||
import org.freedesktop.dbus.exceptions.DBusException;
|
|
||||||
import org.freedesktop.dbus.types.Variant;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
|
public class ReceiveCommand implements LocalCommand {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(ReceiveCommand.class);
|
private final static Logger logger = LoggerFactory.getLogger(ReceiveCommand.class);
|
||||||
|
|
||||||
|
@ -56,106 +46,6 @@ public class ReceiveCommand implements ExtendedDbusCommand, LocalCommand {
|
||||||
return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
|
return List.of(OutputType.PLAIN_TEXT, OutputType.JSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleCommand(
|
|
||||||
final Namespace ns, final Signal signal, DBusConnection dbusconnection, final OutputWriter outputWriter
|
|
||||||
) throws CommandException {
|
|
||||||
try {
|
|
||||||
if (outputWriter instanceof JsonWriter jsonWriter) {
|
|
||||||
|
|
||||||
dbusconnection.addSigHandler(Signal.MessageReceived.class, signal, messageReceived -> {
|
|
||||||
var envelope = JsonMessageEnvelope.from(messageReceived);
|
|
||||||
final var object = Map.of("envelope", envelope);
|
|
||||||
jsonWriter.write(object);
|
|
||||||
});
|
|
||||||
|
|
||||||
dbusconnection.addSigHandler(Signal.ReceiptReceived.class, signal, receiptReceived -> {
|
|
||||||
var envelope = JsonMessageEnvelope.from(receiptReceived);
|
|
||||||
final var object = Map.of("envelope", envelope);
|
|
||||||
jsonWriter.write(object);
|
|
||||||
});
|
|
||||||
|
|
||||||
dbusconnection.addSigHandler(Signal.SyncMessageReceived.class, signal, syncReceived -> {
|
|
||||||
var envelope = JsonMessageEnvelope.from(syncReceived);
|
|
||||||
final var object = Map.of("envelope", envelope);
|
|
||||||
jsonWriter.write(object);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
final var writer = (PlainTextWriter) outputWriter;
|
|
||||||
|
|
||||||
dbusconnection.addSigHandler(Signal.MessageReceivedV2.class, signal, messageReceived -> {
|
|
||||||
writer.println("Envelope from: {}", messageReceived.getSender());
|
|
||||||
writer.println("Timestamp: {}", DateUtils.formatTimestamp(messageReceived.getTimestamp()));
|
|
||||||
writer.println("Body: {}", messageReceived.getMessage());
|
|
||||||
if (messageReceived.getGroupId().length > 0) {
|
|
||||||
writer.println("Group info:");
|
|
||||||
writer.indentedWriter()
|
|
||||||
.println("Id: {}", Base64.getEncoder().encodeToString(messageReceived.getGroupId()));
|
|
||||||
}
|
|
||||||
final var extras = messageReceived.getExtras();
|
|
||||||
printMessageExtras(writer, extras);
|
|
||||||
writer.println();
|
|
||||||
});
|
|
||||||
|
|
||||||
dbusconnection.addSigHandler(Signal.ReceiptReceivedV2.class, signal, receiptReceived -> {
|
|
||||||
writer.println("Receipt from: {}", receiptReceived.getSender());
|
|
||||||
writer.println("Timestamp: {}", DateUtils.formatTimestamp(receiptReceived.getTimestamp()));
|
|
||||||
writer.println("Type: {}", receiptReceived.getReceiptType());
|
|
||||||
});
|
|
||||||
|
|
||||||
dbusconnection.addSigHandler(Signal.SyncMessageReceivedV2.class, signal, syncReceived -> {
|
|
||||||
writer.println("Sync Envelope from: {} to: {}",
|
|
||||||
syncReceived.getSource(),
|
|
||||||
syncReceived.getDestination());
|
|
||||||
writer.println("Timestamp: {}", DateUtils.formatTimestamp(syncReceived.getTimestamp()));
|
|
||||||
writer.println("Body: {}", syncReceived.getMessage());
|
|
||||||
if (syncReceived.getGroupId().length > 0) {
|
|
||||||
writer.println("Group info:");
|
|
||||||
writer.indentedWriter()
|
|
||||||
.println("Id: {}", Base64.getEncoder().encodeToString(syncReceived.getGroupId()));
|
|
||||||
}
|
|
||||||
final var extras = syncReceived.getExtras();
|
|
||||||
printMessageExtras(writer, extras);
|
|
||||||
writer.println();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (DBusException e) {
|
|
||||||
logger.error("Dbus client failed", e);
|
|
||||||
throw new UnexpectedErrorException("Dbus client failed", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
double timeout = ns.getDouble("timeout");
|
|
||||||
long timeoutMilliseconds = timeout < 0 ? 10000 : (long) (timeout * 1000);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(timeoutMilliseconds);
|
|
||||||
} catch (InterruptedException ignored) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (timeout >= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void printMessageExtras(final PlainTextWriter writer, final Map<String, Variant<?>> extras) {
|
|
||||||
if (extras.containsKey("attachments")) {
|
|
||||||
final List<DBusMap<String, Variant<?>>> attachments = getValue(extras, "attachments");
|
|
||||||
if (attachments.size() > 0) {
|
|
||||||
writer.println("Attachments:");
|
|
||||||
for (var attachment : attachments) {
|
|
||||||
final String value = getValue(attachment, "file");
|
|
||||||
writer.println("- Stored plaintext in: {}", value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private <T> T getValue(final Map<String, Variant<?>> stringVariantMap, final String field) {
|
|
||||||
return (T) stringVariantMap.get(field).getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleCommand(
|
public void handleCommand(
|
||||||
final Namespace ns, final Manager m, final OutputWriter outputWriter
|
final Namespace ns, final Manager m, final OutputWriter outputWriter
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.asamk.signal.manager.api.Identity;
|
||||||
import org.asamk.signal.manager.api.InactiveGroupLinkException;
|
import org.asamk.signal.manager.api.InactiveGroupLinkException;
|
||||||
import org.asamk.signal.manager.api.InvalidDeviceLinkException;
|
import org.asamk.signal.manager.api.InvalidDeviceLinkException;
|
||||||
import org.asamk.signal.manager.api.Message;
|
import org.asamk.signal.manager.api.Message;
|
||||||
|
import org.asamk.signal.manager.api.MessageEnvelope;
|
||||||
import org.asamk.signal.manager.api.Pair;
|
import org.asamk.signal.manager.api.Pair;
|
||||||
import org.asamk.signal.manager.api.RecipientIdentifier;
|
import org.asamk.signal.manager.api.RecipientIdentifier;
|
||||||
import org.asamk.signal.manager.api.SendGroupMessageResults;
|
import org.asamk.signal.manager.api.SendGroupMessageResults;
|
||||||
|
@ -29,10 +30,13 @@ import org.asamk.signal.manager.groups.NotAGroupMemberException;
|
||||||
import org.asamk.signal.manager.storage.recipients.Contact;
|
import org.asamk.signal.manager.storage.recipients.Contact;
|
||||||
import org.asamk.signal.manager.storage.recipients.Profile;
|
import org.asamk.signal.manager.storage.recipients.Profile;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
||||||
|
import org.freedesktop.dbus.DBusMap;
|
||||||
import org.freedesktop.dbus.DBusPath;
|
import org.freedesktop.dbus.DBusPath;
|
||||||
import org.freedesktop.dbus.connections.impl.DBusConnection;
|
import org.freedesktop.dbus.connections.impl.DBusConnection;
|
||||||
import org.freedesktop.dbus.exceptions.DBusException;
|
import org.freedesktop.dbus.exceptions.DBusException;
|
||||||
import org.freedesktop.dbus.interfaces.DBusInterface;
|
import org.freedesktop.dbus.interfaces.DBusInterface;
|
||||||
|
import org.freedesktop.dbus.interfaces.DBusSigHandler;
|
||||||
|
import org.freedesktop.dbus.types.Variant;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -40,6 +44,7 @@ import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -59,6 +64,11 @@ public class DbusManagerImpl implements Manager {
|
||||||
private final Signal signal;
|
private final Signal signal;
|
||||||
private final DBusConnection connection;
|
private final DBusConnection connection;
|
||||||
|
|
||||||
|
private final Set<ReceiveMessageHandler> messageHandlers = new HashSet<>();
|
||||||
|
private DBusSigHandler<Signal.MessageReceivedV2> dbusMsgHandler;
|
||||||
|
private DBusSigHandler<Signal.ReceiptReceivedV2> dbusRcptHandler;
|
||||||
|
private DBusSigHandler<Signal.SyncMessageReceivedV2> dbusSyncHandler;
|
||||||
|
|
||||||
public DbusManagerImpl(final Signal signal, DBusConnection connection) {
|
public DbusManagerImpl(final Signal signal, DBusConnection connection) {
|
||||||
this.signal = signal;
|
this.signal = signal;
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
|
@ -133,7 +143,7 @@ public class DbusManagerImpl implements Manager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void submitRateLimitRecaptchaChallenge(final String challenge, final String captcha) throws IOException {
|
public void submitRateLimitRecaptchaChallenge(final String challenge, final String captcha) throws IOException {
|
||||||
throw new UnsupportedOperationException();
|
signal.submitRateLimitChallenge(challenge, captcha);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -308,7 +318,7 @@ public class DbusManagerImpl implements Manager {
|
||||||
public void sendViewedReceipt(
|
public void sendViewedReceipt(
|
||||||
final RecipientIdentifier.Single sender, final List<Long> messageIds
|
final RecipientIdentifier.Single sender, final List<Long> messageIds
|
||||||
) throws IOException, UntrustedIdentityException {
|
) throws IOException, UntrustedIdentityException {
|
||||||
throw new UnsupportedOperationException();
|
signal.sendViewedReceipt(sender.getIdentifier(), messageIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -414,39 +424,68 @@ public class DbusManagerImpl implements Manager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addReceiveHandler(final ReceiveMessageHandler handler) {
|
public void addReceiveHandler(final ReceiveMessageHandler handler) {
|
||||||
throw new UnsupportedOperationException();
|
synchronized (messageHandlers) {
|
||||||
|
if (messageHandlers.size() == 0) {
|
||||||
|
installMessageHandlers();
|
||||||
|
}
|
||||||
|
messageHandlers.add(handler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeReceiveHandler(final ReceiveMessageHandler handler) {
|
public void removeReceiveHandler(final ReceiveMessageHandler handler) {
|
||||||
throw new UnsupportedOperationException();
|
synchronized (messageHandlers) {
|
||||||
|
messageHandlers.remove(handler);
|
||||||
|
if (messageHandlers.size() == 0) {
|
||||||
|
try {
|
||||||
|
connection.removeSigHandler(Signal.MessageReceivedV2.class, signal, this.dbusMsgHandler);
|
||||||
|
connection.removeSigHandler(Signal.ReceiptReceivedV2.class, signal, this.dbusRcptHandler);
|
||||||
|
connection.removeSigHandler(Signal.SyncMessageReceivedV2.class, signal, this.dbusSyncHandler);
|
||||||
|
} catch (DBusException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReceiving() {
|
public boolean isReceiving() {
|
||||||
throw new UnsupportedOperationException();
|
synchronized (messageHandlers) {
|
||||||
|
return messageHandlers.size() > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void receiveMessages(final ReceiveMessageHandler handler) throws IOException {
|
public void receiveMessages(final ReceiveMessageHandler handler) throws IOException {
|
||||||
throw new UnsupportedOperationException();
|
addReceiveHandler(handler);
|
||||||
|
try {
|
||||||
|
synchronized (this) {
|
||||||
|
this.wait();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
removeReceiveHandler(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void receiveMessages(
|
public void receiveMessages(
|
||||||
final long timeout, final TimeUnit unit, final ReceiveMessageHandler handler
|
final long timeout, final TimeUnit unit, final ReceiveMessageHandler handler
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
throw new UnsupportedOperationException();
|
addReceiveHandler(handler);
|
||||||
|
try {
|
||||||
|
Thread.sleep(unit.toMillis(timeout));
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
removeReceiveHandler(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIgnoreAttachments(final boolean ignoreAttachments) {
|
public void setIgnoreAttachments(final boolean ignoreAttachments) {
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasCaughtUpWithOldMessages() {
|
public boolean hasCaughtUpWithOldMessages() {
|
||||||
throw new UnsupportedOperationException();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -454,11 +493,6 @@ public class DbusManagerImpl implements Manager {
|
||||||
return signal.isContactBlocked(recipient.getIdentifier());
|
return signal.isContactBlocked(recipient.getIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public File getAttachmentFile(final String attachmentId) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendContacts() throws IOException {
|
public void sendContacts() throws IOException {
|
||||||
signal.sendContacts();
|
signal.sendContacts();
|
||||||
|
@ -592,4 +626,168 @@ public class DbusManagerImpl implements Manager {
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void installMessageHandlers() {
|
||||||
|
try {
|
||||||
|
this.dbusMsgHandler = messageReceived -> {
|
||||||
|
final var extras = messageReceived.getExtras();
|
||||||
|
final var envelope = new MessageEnvelope(Optional.of(new RecipientAddress(null,
|
||||||
|
messageReceived.getSender())),
|
||||||
|
0,
|
||||||
|
messageReceived.getTimestamp(),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.of(new MessageEnvelope.Data(messageReceived.getTimestamp(),
|
||||||
|
messageReceived.getGroupId().length > 0
|
||||||
|
? Optional.of(new MessageEnvelope.Data.GroupContext(GroupId.unknownVersion(
|
||||||
|
messageReceived.getGroupId()), false, 0))
|
||||||
|
: Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.of(messageReceived.getMessage()),
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
getAttachments(extras),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
List.of(),
|
||||||
|
List.of(),
|
||||||
|
List.of())),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty());
|
||||||
|
synchronized (messageHandlers) {
|
||||||
|
for (final var messageHandler : messageHandlers) {
|
||||||
|
messageHandler.handleMessage(envelope, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
connection.addSigHandler(Signal.MessageReceivedV2.class, signal, this.dbusMsgHandler);
|
||||||
|
|
||||||
|
this.dbusRcptHandler = receiptReceived -> {
|
||||||
|
final var type = switch (receiptReceived.getReceiptType()) {
|
||||||
|
case "read" -> MessageEnvelope.Receipt.Type.READ;
|
||||||
|
case "viewed" -> MessageEnvelope.Receipt.Type.VIEWED;
|
||||||
|
case "delivery" -> MessageEnvelope.Receipt.Type.DELIVERY;
|
||||||
|
default -> MessageEnvelope.Receipt.Type.UNKNOWN;
|
||||||
|
};
|
||||||
|
final var envelope = new MessageEnvelope(Optional.of(new RecipientAddress(null,
|
||||||
|
receiptReceived.getSender())),
|
||||||
|
0,
|
||||||
|
receiptReceived.getTimestamp(),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
Optional.of(new MessageEnvelope.Receipt(receiptReceived.getTimestamp(),
|
||||||
|
type,
|
||||||
|
List.of(receiptReceived.getTimestamp()))),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty());
|
||||||
|
synchronized (messageHandlers) {
|
||||||
|
for (final var messageHandler : messageHandlers) {
|
||||||
|
messageHandler.handleMessage(envelope, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
connection.addSigHandler(Signal.ReceiptReceivedV2.class, signal, this.dbusRcptHandler);
|
||||||
|
|
||||||
|
this.dbusSyncHandler = syncReceived -> {
|
||||||
|
final var extras = syncReceived.getExtras();
|
||||||
|
final var envelope = new MessageEnvelope(Optional.of(new RecipientAddress(null,
|
||||||
|
syncReceived.getSource())),
|
||||||
|
0,
|
||||||
|
syncReceived.getTimestamp(),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.of(new MessageEnvelope.Sync(Optional.of(new MessageEnvelope.Sync.Sent(syncReceived.getTimestamp(),
|
||||||
|
syncReceived.getTimestamp(),
|
||||||
|
syncReceived.getDestination().isEmpty()
|
||||||
|
? Optional.empty()
|
||||||
|
: Optional.of(new RecipientAddress(null, syncReceived.getDestination())),
|
||||||
|
Set.of(),
|
||||||
|
new MessageEnvelope.Data(syncReceived.getTimestamp(),
|
||||||
|
syncReceived.getGroupId().length > 0
|
||||||
|
? Optional.of(new MessageEnvelope.Data.GroupContext(GroupId.unknownVersion(
|
||||||
|
syncReceived.getGroupId()), false, 0))
|
||||||
|
: Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.of(syncReceived.getMessage()),
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
getAttachments(extras),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
List.of(),
|
||||||
|
List.of(),
|
||||||
|
List.of()))),
|
||||||
|
Optional.empty(),
|
||||||
|
List.of(),
|
||||||
|
List.of(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty())),
|
||||||
|
Optional.empty());
|
||||||
|
synchronized (messageHandlers) {
|
||||||
|
for (final var messageHandler : messageHandlers) {
|
||||||
|
messageHandler.handleMessage(envelope, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
connection.addSigHandler(Signal.SyncMessageReceivedV2.class, signal, this.dbusSyncHandler);
|
||||||
|
} catch (DBusException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MessageEnvelope.Data.Attachment> getAttachments(final Map<String, Variant<?>> extras) {
|
||||||
|
if (!extras.containsKey("attachments")) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<DBusMap<String, Variant<?>>> attachments = getValue(extras, "attachments");
|
||||||
|
return attachments.stream().map(a -> {
|
||||||
|
final String file = a.containsKey("file") ? getValue(a, "file") : null;
|
||||||
|
return new MessageEnvelope.Data.Attachment(a.containsKey("remoteId")
|
||||||
|
? Optional.of(getValue(a, "remoteId"))
|
||||||
|
: Optional.empty(),
|
||||||
|
file != null ? Optional.of(new File(file)) : Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
getValue(a, "contentType"),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
getValue(a, "isVoiceNote"),
|
||||||
|
getValue(a, "isGif"),
|
||||||
|
getValue(a, "isBorderless"));
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T> T getValue(
|
||||||
|
final Map<String, Variant<?>> stringVariantMap, final String field
|
||||||
|
) {
|
||||||
|
return (T) stringVariantMap.get(field).getValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,12 @@ package org.asamk.signal.json;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
import org.asamk.Signal;
|
|
||||||
import org.asamk.signal.manager.Manager;
|
import org.asamk.signal.manager.Manager;
|
||||||
import org.asamk.signal.manager.UntrustedIdentityException;
|
import org.asamk.signal.manager.UntrustedIdentityException;
|
||||||
import org.asamk.signal.manager.api.InvalidNumberException;
|
import org.asamk.signal.manager.api.InvalidNumberException;
|
||||||
import org.asamk.signal.manager.api.MessageEnvelope;
|
import org.asamk.signal.manager.api.MessageEnvelope;
|
||||||
import org.asamk.signal.manager.api.RecipientIdentifier;
|
import org.asamk.signal.manager.api.RecipientIdentifier;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public record JsonMessageEnvelope(
|
public record JsonMessageEnvelope(
|
||||||
|
@ -78,47 +76,4 @@ public record JsonMessageEnvelope(
|
||||||
receiptMessage,
|
receiptMessage,
|
||||||
typingMessage);
|
typingMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JsonMessageEnvelope from(Signal.MessageReceived messageReceived) {
|
|
||||||
return new JsonMessageEnvelope(messageReceived.getSource(),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
messageReceived.getTimestamp(),
|
|
||||||
JsonDataMessage.from(messageReceived),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JsonMessageEnvelope from(Signal.ReceiptReceived receiptReceived) {
|
|
||||||
return new JsonMessageEnvelope(receiptReceived.getSender(),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
receiptReceived.getTimestamp(),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
JsonReceiptMessage.deliveryReceipt(receiptReceived.getTimestamp(),
|
|
||||||
List.of(receiptReceived.getTimestamp())),
|
|
||||||
null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JsonMessageEnvelope from(Signal.SyncMessageReceived messageReceived) {
|
|
||||||
return new JsonMessageEnvelope(messageReceived.getSource(),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
messageReceived.getTimestamp(),
|
|
||||||
null,
|
|
||||||
JsonSyncMessage.from(messageReceived),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,4 @@ record JsonReceiptMessage(long when, boolean isDelivery, boolean isRead, boolean
|
||||||
final var timestamps = receiptMessage.timestamps();
|
final var timestamps = receiptMessage.timestamps();
|
||||||
return new JsonReceiptMessage(when, isDelivery, isRead, isViewed, timestamps);
|
return new JsonReceiptMessage(when, isDelivery, isRead, isViewed, timestamps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JsonReceiptMessage deliveryReceipt(final long when, final List<Long> timestamps) {
|
|
||||||
return new JsonReceiptMessage(when, true, false, false, timestamps);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.asamk.signal.json;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
||||||
|
|
||||||
import org.asamk.Signal;
|
|
||||||
import org.asamk.signal.manager.api.MessageEnvelope;
|
import org.asamk.signal.manager.api.MessageEnvelope;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -26,11 +25,4 @@ record JsonSyncDataMessage(
|
||||||
return new JsonSyncDataMessage(null, null, null, JsonDataMessage.from(transcriptMessage.message()));
|
return new JsonSyncDataMessage(null, null, null, JsonDataMessage.from(transcriptMessage.message()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static JsonSyncDataMessage from(Signal.SyncMessageReceived messageReceived) {
|
|
||||||
return new JsonSyncDataMessage(messageReceived.getDestination(),
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
JsonDataMessage.from(messageReceived));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.asamk.signal.json;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
import org.asamk.Signal;
|
|
||||||
import org.asamk.signal.manager.api.MessageEnvelope;
|
import org.asamk.signal.manager.api.MessageEnvelope;
|
||||||
import org.asamk.signal.manager.groups.GroupId;
|
import org.asamk.signal.manager.groups.GroupId;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
||||||
|
@ -77,8 +76,4 @@ record JsonSyncMessage(
|
||||||
}
|
}
|
||||||
return new JsonSyncMessage(sentMessage, blockedNumbers, blockedGroupIds, readMessages, type);
|
return new JsonSyncMessage(sentMessage, blockedNumbers, blockedGroupIds, readMessages, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JsonSyncMessage from(Signal.SyncMessageReceived messageReceived) {
|
|
||||||
return new JsonSyncMessage(JsonSyncDataMessage.from(messageReceived), null, null, null, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue