]> nmode's Git Repositories - signal-cli/commitdiff
Store attachments with a file extension
authorAsamK <asamk@gmx.de>
Sat, 22 Oct 2022 18:32:11 +0000 (20:32 +0200)
committerAsamK <asamk@gmx.de>
Sat, 22 Oct 2022 20:00:31 +0000 (22:00 +0200)
Taken from the filename if present, otherwise guessed from the contentType

lib/src/main/java/org/asamk/signal/manager/AttachmentStore.java
lib/src/main/java/org/asamk/signal/manager/api/MessageEnvelope.java
lib/src/main/java/org/asamk/signal/manager/helper/AttachmentHelper.java

index f983a90b76df7f2905d6ead62836eaff3bf1d900..949e28629f9492202d5af8c36799883892a7ea4e 100644 (file)
@@ -1,12 +1,15 @@
 package org.asamk.signal.manager;
 
 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 java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Optional;
 
 public class AttachmentStore {
 
@@ -17,15 +20,23 @@ public class AttachmentStore {
     }
 
     public void storeAttachmentPreview(
-            final SignalServiceAttachmentRemoteId attachmentId, final AttachmentStorer storer
+            final SignalServiceAttachmentPointer pointer, final AttachmentStorer storer
     ) throws IOException {
-        storeAttachment(getAttachmentPreviewFile(attachmentId), storer);
+        storeAttachment(getAttachmentPreviewFile(pointer.getRemoteId(),
+                pointer.getFileName(),
+                Optional.ofNullable(pointer.getContentType())), storer);
     }
 
     public void storeAttachment(
-            final SignalServiceAttachmentRemoteId attachmentId, final AttachmentStorer storer
+            final SignalServiceAttachmentPointer pointer, final AttachmentStorer storer
     ) 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 {
@@ -35,12 +46,28 @@ public class AttachmentStore {
         }
     }
 
-    private File getAttachmentPreviewFile(SignalServiceAttachmentRemoteId attachmentId) {
-        return new File(attachmentsPath, attachmentId.toString() + ".preview");
+    private File getAttachmentPreviewFile(
+            SignalServiceAttachmentRemoteId attachmentId, Optional<String> filename, Optional<String> contentType
+    ) {
+        final var extension = getAttachmentExtension(filename, contentType);
+        return new File(attachmentsPath, attachmentId.toString() + extension + ".preview");
+    }
+
+    private File getAttachmentFile(
+            SignalServiceAttachmentRemoteId attachmentId, Optional<String> filename, Optional<String> contentType
+    ) {
+        final var extension = getAttachmentExtension(filename, contentType);
+        return new File(attachmentsPath, attachmentId.toString() + extension);
     }
 
-    public File getAttachmentFile(SignalServiceAttachmentRemoteId attachmentId) {
-        return new File(attachmentsPath, attachmentId.toString());
+    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 {
index 2eb0546a07e956363c9118b1a2cbd3eb6da98ed5..9b6a476e50e16f56ea0837cdf0ef5ef0f3dbca1b 100644 (file)
@@ -6,7 +6,7 @@ import org.asamk.signal.manager.helper.RecipientAddressResolver;
 import org.asamk.signal.manager.storage.recipients.RecipientResolver;
 import org.signal.libsignal.metadata.ProtocolException;
 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.SignalServiceDataMessage;
 import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
@@ -281,8 +281,9 @@ public record MessageEnvelope(
             static Attachment from(SignalServiceAttachment attachment, AttachmentFileProvider fileProvider) {
                 if (attachment.isPointer()) {
                     final var a = attachment.asPointer();
-                    return new Attachment(Optional.of(a.getRemoteId().toString()),
-                            Optional.of(fileProvider.getFile(a.getRemoteId())),
+                    final var attachmentFile = fileProvider.getFile(a);
+                    return new Attachment(Optional.of(attachmentFile.getName()),
+                            Optional.of(attachmentFile),
                             a.getFileName(),
                             a.getContentType(),
                             a.getUploadTimestamp() == 0 ? Optional.empty() : Optional.of(a.getUploadTimestamp()),
@@ -918,6 +919,6 @@ public record MessageEnvelope(
 
     public interface AttachmentFileProvider {
 
-        File getFile(SignalServiceAttachmentRemoteId attachmentRemoteId);
+        File getFile(SignalServiceAttachmentPointer pointer);
     }
 }
index 0d560e14e077763b8388c728b1d7fbefe24bd35c..ea5739b385907833d55beb2cea6f4a461a1da6f5 100644 (file)
@@ -11,7 +11,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
 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.push.exceptions.MissingConfigurationException;
 
@@ -35,8 +34,8 @@ public class AttachmentHelper {
         this.attachmentStore = context.getAttachmentStore();
     }
 
-    public File getAttachmentFile(SignalServiceAttachmentRemoteId attachmentId) {
-        return attachmentStore.getAttachmentFile(attachmentId);
+    public File getAttachmentFile(SignalServiceAttachmentPointer pointer) {
+        return attachmentStore.getAttachmentFile(pointer);
     }
 
     public List<SignalServiceAttachment> uploadAttachments(final List<String> attachments) throws AttachmentInvalidException, IOException {
@@ -69,7 +68,7 @@ public class AttachmentHelper {
         if (pointer.getPreview().isPresent()) {
             final var preview = pointer.getPreview().get();
             try {
-                attachmentStore.storeAttachmentPreview(pointer.getRemoteId(),
+                attachmentStore.storeAttachmentPreview(pointer,
                         outputStream -> outputStream.write(preview, 0, preview.length));
             } catch (IOException e) {
                 logger.warn("Failed to download attachment preview, ignoring: {}", e.getMessage());
@@ -77,8 +76,7 @@ public class AttachmentHelper {
         }
 
         try {
-            attachmentStore.storeAttachment(pointer.getRemoteId(),
-                    outputStream -> this.retrieveAttachment(pointer, outputStream));
+            attachmentStore.storeAttachment(pointer, outputStream -> this.retrieveAttachment(pointer, outputStream));
         } catch (IOException e) {
             logger.warn("Failed to download attachment ({}), ignoring: {}", pointer.getRemoteId(), e.getMessage());
         }