mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-28 18:10:38 +00:00
Use UploadSpec for attachment uploads
This commit is contained in:
parent
e51b1ee23a
commit
2db3d3259e
6 changed files with 67 additions and 46 deletions
|
@ -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":"<init>","parameterTypes":["int","java.lang.String","java.util.Map","java.lang.String"] }, {"name":"<init>","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,
|
||||
|
|
|
@ -44,7 +44,7 @@ public class AttachmentHelper {
|
|||
}
|
||||
|
||||
public List<SignalServiceAttachment> uploadAttachments(final List<String> 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<SignalServiceAttachment>(attachmentStreams.size());
|
||||
|
@ -54,8 +54,21 @@ public class AttachmentHelper {
|
|||
return attachmentPointers;
|
||||
}
|
||||
|
||||
private List<SignalServiceAttachmentStream> createAttachmentStreams(List<String> attachments) throws AttachmentInvalidException, IOException {
|
||||
if (attachments == null) {
|
||||
return null;
|
||||
}
|
||||
final var signalServiceAttachments = new ArrayList<SignalServiceAttachmentStream>(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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -742,8 +742,13 @@ public class ManagerImpl implements Manager {
|
|||
final var additionalAttachments = new ArrayList<SignalServiceAttachment>();
|
||||
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<SignalServicePreview>(message.previews().size());
|
||||
|
|
|
@ -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<SignalServiceAttachmentStream> createAttachmentStreams(List<String> attachments) throws AttachmentInvalidException {
|
||||
if (attachments == null) {
|
||||
return null;
|
||||
}
|
||||
final var signalServiceAttachments = new ArrayList<SignalServiceAttachmentStream>(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<String> name
|
||||
) {
|
||||
StreamDetails streamDetails, Optional<String> 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<byte[]> preview = Optional.empty();
|
||||
Optional<String> caption = Optional.empty();
|
||||
Optional<String> blurHash = Optional.empty();
|
||||
final Optional<ResumableUploadSpec> 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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue