mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
Store attachments with a file extension
Taken from the filename if present, otherwise guessed from the contentType
This commit is contained in:
parent
0084a2e722
commit
e0c2f58e8d
3 changed files with 44 additions and 18 deletions
|
@ -1,12 +1,15 @@
|
||||||
package org.asamk.signal.manager;
|
package org.asamk.signal.manager;
|
||||||
|
|
||||||
import org.asamk.signal.manager.util.IOUtils;
|
import org.asamk.signal.manager.util.IOUtils;
|
||||||
|
import org.asamk.signal.manager.util.MimeUtils;
|
||||||
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentRemoteId;
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentRemoteId;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class AttachmentStore {
|
public class AttachmentStore {
|
||||||
|
|
||||||
|
@ -17,15 +20,23 @@ public class AttachmentStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void storeAttachmentPreview(
|
public void storeAttachmentPreview(
|
||||||
final SignalServiceAttachmentRemoteId attachmentId, final AttachmentStorer storer
|
final SignalServiceAttachmentPointer pointer, final AttachmentStorer storer
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
storeAttachment(getAttachmentPreviewFile(attachmentId), storer);
|
storeAttachment(getAttachmentPreviewFile(pointer.getRemoteId(),
|
||||||
|
pointer.getFileName(),
|
||||||
|
Optional.ofNullable(pointer.getContentType())), storer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void storeAttachment(
|
public void storeAttachment(
|
||||||
final SignalServiceAttachmentRemoteId attachmentId, final AttachmentStorer storer
|
final SignalServiceAttachmentPointer pointer, final AttachmentStorer storer
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
storeAttachment(getAttachmentFile(attachmentId), storer);
|
storeAttachment(getAttachmentFile(pointer), storer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getAttachmentFile(final SignalServiceAttachmentPointer pointer) {
|
||||||
|
return getAttachmentFile(pointer.getRemoteId(),
|
||||||
|
pointer.getFileName(),
|
||||||
|
Optional.ofNullable(pointer.getContentType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void storeAttachment(final File attachmentFile, final AttachmentStorer storer) throws IOException {
|
private void storeAttachment(final File attachmentFile, final AttachmentStorer storer) throws IOException {
|
||||||
|
@ -35,12 +46,28 @@ public class AttachmentStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getAttachmentPreviewFile(SignalServiceAttachmentRemoteId attachmentId) {
|
private File getAttachmentPreviewFile(
|
||||||
return new File(attachmentsPath, attachmentId.toString() + ".preview");
|
SignalServiceAttachmentRemoteId attachmentId, Optional<String> filename, Optional<String> contentType
|
||||||
|
) {
|
||||||
|
final var extension = getAttachmentExtension(filename, contentType);
|
||||||
|
return new File(attachmentsPath, attachmentId.toString() + extension + ".preview");
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getAttachmentFile(SignalServiceAttachmentRemoteId attachmentId) {
|
private File getAttachmentFile(
|
||||||
return new File(attachmentsPath, attachmentId.toString());
|
SignalServiceAttachmentRemoteId attachmentId, Optional<String> filename, Optional<String> contentType
|
||||||
|
) {
|
||||||
|
final var extension = getAttachmentExtension(filename, contentType);
|
||||||
|
return new File(attachmentsPath, attachmentId.toString() + extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getAttachmentExtension(
|
||||||
|
final Optional<String> filename, final Optional<String> contentType
|
||||||
|
) {
|
||||||
|
return filename.filter(f -> f.contains("."))
|
||||||
|
.map(f -> f.substring(f.lastIndexOf(".") + 1))
|
||||||
|
.or(() -> contentType.flatMap(MimeUtils::guessExtensionFromMimeType))
|
||||||
|
.map(ext -> "." + ext)
|
||||||
|
.orElse("");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAttachmentsDir() throws IOException {
|
private void createAttachmentsDir() throws IOException {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import org.asamk.signal.manager.helper.RecipientAddressResolver;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientResolver;
|
import org.asamk.signal.manager.storage.recipients.RecipientResolver;
|
||||||
import org.signal.libsignal.metadata.ProtocolException;
|
import org.signal.libsignal.metadata.ProtocolException;
|
||||||
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.SignalServiceAttachmentPointer;
|
||||||
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;
|
||||||
|
@ -281,8 +281,9 @@ public record MessageEnvelope(
|
||||||
static Attachment from(SignalServiceAttachment attachment, AttachmentFileProvider fileProvider) {
|
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()),
|
final var attachmentFile = fileProvider.getFile(a);
|
||||||
Optional.of(fileProvider.getFile(a.getRemoteId())),
|
return new Attachment(Optional.of(attachmentFile.getName()),
|
||||||
|
Optional.of(attachmentFile),
|
||||||
a.getFileName(),
|
a.getFileName(),
|
||||||
a.getContentType(),
|
a.getContentType(),
|
||||||
a.getUploadTimestamp() == 0 ? Optional.empty() : Optional.of(a.getUploadTimestamp()),
|
a.getUploadTimestamp() == 0 ? Optional.empty() : Optional.of(a.getUploadTimestamp()),
|
||||||
|
@ -918,6 +919,6 @@ public record MessageEnvelope(
|
||||||
|
|
||||||
public interface AttachmentFileProvider {
|
public interface AttachmentFileProvider {
|
||||||
|
|
||||||
File getFile(SignalServiceAttachmentRemoteId attachmentRemoteId);
|
File getFile(SignalServiceAttachmentPointer pointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
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.messages.SignalServiceAttachmentStream;
|
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
|
||||||
import org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException;
|
import org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException;
|
||||||
|
|
||||||
|
@ -35,8 +34,8 @@ public class AttachmentHelper {
|
||||||
this.attachmentStore = context.getAttachmentStore();
|
this.attachmentStore = context.getAttachmentStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getAttachmentFile(SignalServiceAttachmentRemoteId attachmentId) {
|
public File getAttachmentFile(SignalServiceAttachmentPointer pointer) {
|
||||||
return attachmentStore.getAttachmentFile(attachmentId);
|
return attachmentStore.getAttachmentFile(pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SignalServiceAttachment> uploadAttachments(final List<String> attachments) throws AttachmentInvalidException, IOException {
|
public List<SignalServiceAttachment> uploadAttachments(final List<String> attachments) throws AttachmentInvalidException, IOException {
|
||||||
|
@ -69,7 +68,7 @@ public class AttachmentHelper {
|
||||||
if (pointer.getPreview().isPresent()) {
|
if (pointer.getPreview().isPresent()) {
|
||||||
final var preview = pointer.getPreview().get();
|
final var preview = pointer.getPreview().get();
|
||||||
try {
|
try {
|
||||||
attachmentStore.storeAttachmentPreview(pointer.getRemoteId(),
|
attachmentStore.storeAttachmentPreview(pointer,
|
||||||
outputStream -> outputStream.write(preview, 0, preview.length));
|
outputStream -> outputStream.write(preview, 0, preview.length));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to download attachment preview, ignoring: {}", e.getMessage());
|
logger.warn("Failed to download attachment preview, ignoring: {}", e.getMessage());
|
||||||
|
@ -77,8 +76,7 @@ public class AttachmentHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
attachmentStore.storeAttachment(pointer.getRemoteId(),
|
attachmentStore.storeAttachment(pointer, outputStream -> this.retrieveAttachment(pointer, outputStream));
|
||||||
outputStream -> this.retrieveAttachment(pointer, outputStream));
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to download attachment ({}), ignoring: {}", pointer.getRemoteId(), e.getMessage());
|
logger.warn("Failed to download attachment ({}), ignoring: {}", pointer.getRemoteId(), e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue