From: AsamK Date: Thu, 25 Jul 2024 20:17:46 +0000 (+0200) Subject: Use UploadSpec for attachment uploads X-Git-Tag: v0.13.5~3 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/2db3d3259e1274a6f5ee769186cf53cfdcfe0111 Use UploadSpec for attachment uploads --- diff --git a/graalvm-config-dir/reflect-config.json b/graalvm-config-dir/reflect-config.json index 64efa057..50ed1e48 100644 --- a/graalvm-config-dir/reflect-config.json +++ b/graalvm-config-dir/reflect-config.json @@ -2381,6 +2381,13 @@ "name":"org.whispersystems.signalservice.internal.keybackup.protos.RestoreResponse", "fields":[{"name":"bitField0_"}, {"name":"data_"}, {"name":"status_"}, {"name":"token_"}, {"name":"tries_"}] }, +{ + "name":"org.whispersystems.signalservice.internal.push.AttachmentUploadForm", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["int","java.lang.String","java.util.Map","java.lang.String"] }, {"name":"","parameterTypes":["int","java.lang.String","java.util.Map","java.lang.String","int","kotlin.jvm.internal.DefaultConstructorMarker"] }] +}, { "name":"org.whispersystems.signalservice.internal.push.AttachmentV2UploadAttributes", "allDeclaredFields":true, diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/AttachmentHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/AttachmentHelper.java index 75f0fd4a..951b7c5c 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/AttachmentHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/AttachmentHelper.java @@ -44,7 +44,7 @@ public class AttachmentHelper { } public List uploadAttachments(final List attachments) throws AttachmentInvalidException, IOException { - var attachmentStreams = AttachmentUtils.createAttachmentStreams(attachments); + var attachmentStreams = createAttachmentStreams(attachments); // Upload attachments here, so we only upload once even for multiple recipients var attachmentPointers = new ArrayList(attachmentStreams.size()); @@ -54,8 +54,21 @@ public class AttachmentHelper { return attachmentPointers; } + private List createAttachmentStreams(List attachments) throws AttachmentInvalidException, IOException { + if (attachments == null) { + return null; + } + final var signalServiceAttachments = new ArrayList(attachments.size()); + for (var attachment : attachments) { + final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec().toProto(); + signalServiceAttachments.add(AttachmentUtils.createAttachmentStream(attachment, uploadSpec)); + } + return signalServiceAttachments; + } + public SignalServiceAttachmentPointer uploadAttachment(String attachment) throws IOException, AttachmentInvalidException { - var attachmentStream = AttachmentUtils.createAttachmentStream(attachment); + final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec().toProto(); + var attachmentStream = AttachmentUtils.createAttachmentStream(attachment, uploadSpec); return uploadAttachment(attachmentStream); } diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java index 62291a3a..a1f04775 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java @@ -109,7 +109,8 @@ public class GroupHelper { return Optional.empty(); } - return Optional.of(AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty())); + final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec().toProto(); + return Optional.of(AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty(), uploadSpec)); } public GroupInfoV2 getOrMigrateGroup( diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/SyncHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/SyncHelper.java index 0d516eb6..db8ee935 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/SyncHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/SyncHelper.java @@ -36,6 +36,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOper import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.internal.push.SyncMessage; +import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -115,10 +116,15 @@ public class SyncHelper { if (groupsFile.exists() && groupsFile.length() > 0) { try (var groupsFileStream = new FileInputStream(groupsFile)) { + final var uploadSpec = context.getDependencies() + .getMessageSender() + .getResumableUploadSpec() + .toProto(); var attachmentStream = SignalServiceAttachment.newStreamBuilder() .withStream(groupsFileStream) .withContentType(MimeUtils.OCTET_STREAM) .withLength(groupsFile.length()) + .withResumableUploadSpec(ResumableUploadSpec.from(uploadSpec)) .build(); context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forGroups(attachmentStream)); @@ -158,10 +164,15 @@ public class SyncHelper { if (contactsFile.exists() && contactsFile.length() > 0) { try (var contactsFileStream = new FileInputStream(contactsFile)) { + final var uploadSpec = context.getDependencies() + .getMessageSender() + .getResumableUploadSpec() + .toProto(); var attachmentStream = SignalServiceAttachment.newStreamBuilder() .withStream(contactsFileStream) .withContentType(MimeUtils.OCTET_STREAM) .withLength(contactsFile.length()) + .withResumableUploadSpec(ResumableUploadSpec.from(uploadSpec)) .build(); context.getSendHelper() @@ -400,7 +411,8 @@ public class SyncHelper { return Optional.empty(); } - return Optional.of(AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty())); + final var uploadSpec = context.getDependencies().getMessageSender().getResumableUploadSpec().toProto(); + return Optional.of(AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty(), uploadSpec)); } private void downloadContactAvatar(SignalServiceAttachment avatar, RecipientAddress address) { diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java index 426429da..480fa751 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java @@ -742,8 +742,13 @@ public class ManagerImpl implements Manager { final var additionalAttachments = new ArrayList(); if (message.messageText().length() > 2000) { final var messageBytes = message.messageText().getBytes(StandardCharsets.UTF_8); - final var textAttachment = AttachmentUtils.createAttachmentStream(new StreamDetails(new ByteArrayInputStream( - messageBytes), MimeUtils.LONG_TEXT, messageBytes.length), Optional.empty()); + final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec().toProto(); + final var streamDetails = new StreamDetails(new ByteArrayInputStream(messageBytes), + MimeUtils.LONG_TEXT, + messageBytes.length); + final var textAttachment = AttachmentUtils.createAttachmentStream(streamDetails, + Optional.empty(), + uploadSpec); messageBuilder.withBody(message.messageText().substring(0, 2000)); additionalAttachments.add(context.getAttachmentHelper().uploadAttachment(textAttachment)); } else { @@ -800,11 +805,15 @@ public class ManagerImpl implements Manager { if (streamDetails == null) { throw new InvalidStickerException("Missing local sticker file"); } + final var uploadSpec = dependencies.getMessageSender().getResumableUploadSpec().toProto(); + final var stickerAttachment = AttachmentUtils.createAttachmentStream(streamDetails, + Optional.empty(), + uploadSpec); messageBuilder.withSticker(new SignalServiceDataMessage.Sticker(packId.serialize(), stickerPack.packKey(), stickerId, manifestSticker.emoji(), - AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty()))); + stickerAttachment)); } if (!message.previews().isEmpty()) { final var previews = new ArrayList(message.previews().size()); diff --git a/lib/src/main/java/org/asamk/signal/manager/util/AttachmentUtils.java b/lib/src/main/java/org/asamk/signal/manager/util/AttachmentUtils.java index d06d8745..5504640f 100644 --- a/lib/src/main/java/org/asamk/signal/manager/util/AttachmentUtils.java +++ b/lib/src/main/java/org/asamk/signal/manager/util/AttachmentUtils.java @@ -1,65 +1,44 @@ package org.asamk.signal.manager.util; import org.asamk.signal.manager.api.AttachmentInvalidException; +import org.signal.protos.resumableuploads.ResumableUpload; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream; +import org.whispersystems.signalservice.api.push.exceptions.ResumeLocationInvalidException; import org.whispersystems.signalservice.api.util.StreamDetails; import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import java.util.Optional; import java.util.UUID; public class AttachmentUtils { - public static List createAttachmentStreams(List attachments) throws AttachmentInvalidException { - if (attachments == null) { - return null; - } - final var signalServiceAttachments = new ArrayList(attachments.size()); - for (var attachment : attachments) { - signalServiceAttachments.add(createAttachmentStream(attachment)); - } - return signalServiceAttachments; - } - - public static SignalServiceAttachmentStream createAttachmentStream(String attachment) throws AttachmentInvalidException { + public static SignalServiceAttachmentStream createAttachmentStream( + String attachment, ResumableUpload resumableUpload + ) throws AttachmentInvalidException { try { final var streamDetails = Utils.createStreamDetails(attachment); - return createAttachmentStream(streamDetails.first(), streamDetails.second()); + return createAttachmentStream(streamDetails.first(), streamDetails.second(), resumableUpload); } catch (IOException e) { throw new AttachmentInvalidException(attachment, e); } } public static SignalServiceAttachmentStream createAttachmentStream( - StreamDetails streamDetails, Optional name - ) { + StreamDetails streamDetails, Optional name, ResumableUpload resumableUpload + ) throws ResumeLocationInvalidException { // TODO maybe add a parameter to set the voiceNote, borderless, preview, width, height and caption option final var uploadTimestamp = System.currentTimeMillis(); - Optional preview = Optional.empty(); - Optional caption = Optional.empty(); - Optional blurHash = Optional.empty(); - final Optional resumableUploadSpec = Optional.empty(); - return new SignalServiceAttachmentStream(streamDetails.getStream(), - streamDetails.getContentType(), - streamDetails.getLength(), - name, - false, - false, - false, - false, - preview, - 0, - 0, - uploadTimestamp, - caption, - blurHash, - null, - null, - resumableUploadSpec, - UUID.randomUUID()); + final var resumableUploadSpec = ResumableUploadSpec.from(resumableUpload); + return SignalServiceAttachmentStream.newStreamBuilder() + .withStream(streamDetails.getStream()) + .withContentType(streamDetails.getContentType()) + .withLength(streamDetails.getLength()) + .withFileName(name.orElse(null)) + .withUploadTimestamp(uploadTimestamp) + .withResumableUploadSpec(resumableUploadSpec) + .withUuid(UUID.randomUUID()) + .build(); } }