]> nmode's Git Repositories - signal-cli/commitdiff
Add optional content type to json sticker pack manifest
authorAsamK <asamk@gmx.de>
Sun, 13 Jun 2021 09:23:18 +0000 (11:23 +0200)
committerAsamK <asamk@gmx.de>
Sun, 13 Jun 2021 12:32:58 +0000 (14:32 +0200)
lib/src/main/java/org/asamk/signal/manager/JsonStickerPack.java
lib/src/main/java/org/asamk/signal/manager/util/StickerUtils.java
man/signal-cli.1.adoc

index e5e0e445ce47cf558c9eceef7d6597a61b8dcfcc..3ff40585df7ab66f756c56ed9628d0e195156240 100644 (file)
@@ -25,5 +25,8 @@ public class JsonStickerPack {
 
         @JsonProperty
         public String file;
+
+        @JsonProperty
+        public String contentType;
     }
 }
index 2fa8bc97b847c195da1b719dc28427e7cbbef295..4c7fd58e58b737617ea2f19d55c39cacaab4bf09 100644 (file)
@@ -8,10 +8,12 @@ import org.whispersystems.libsignal.util.Pair;
 import org.whispersystems.libsignal.util.guava.Optional;
 import org.whispersystems.signalservice.api.messages.SignalServiceStickerManifestUpload;
 
+import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URLConnection;
 import java.util.ArrayList;
 import java.util.zip.ZipFile;
 
@@ -54,7 +56,9 @@ public class StickerUtils {
                 throw new StickerPackInvalidException("Could not find find " + sticker.file);
             }
 
-            var contentType = Utils.getFileMimeType(new File(sticker.file), null);
+            var contentType = sticker.contentType != null && !sticker.contentType.isEmpty()
+                    ? sticker.contentType
+                    : getContentType(rootPath, zip, sticker.file);
             var stickerInfo = new SignalServiceStickerManifestUpload.StickerInfo(data.first(),
                     data.second(),
                     Optional.fromNullable(sticker.emoji).or(""),
@@ -75,7 +79,9 @@ public class StickerUtils {
                 throw new StickerPackInvalidException("Could not find find " + pack.cover.file);
             }
 
-            var contentType = Utils.getFileMimeType(new File(pack.cover.file), null);
+            var contentType = pack.cover.contentType != null && !pack.cover.contentType.isEmpty()
+                    ? pack.cover.contentType
+                    : getContentType(rootPath, zip, pack.cover.file);
             cover = new SignalServiceStickerManifestUpload.StickerInfo(data.first(),
                     data.second(),
                     Optional.fromNullable(pack.cover.emoji).or(""),
@@ -107,4 +113,17 @@ public class StickerUtils {
         }
     }
 
+    private static String getContentType(
+            final String rootPath, final ZipFile zip, final String subfile
+    ) throws IOException {
+        if (zip != null) {
+            final var entry = zip.getEntry(subfile);
+            try (InputStream bufferedStream = new BufferedInputStream(zip.getInputStream(entry))) {
+                return URLConnection.guessContentTypeFromStream(bufferedStream);
+            }
+        } else {
+            final var file = new File(rootPath, subfile);
+            return Utils.getFileMimeType(file, null);
+        }
+    }
 }
index e30a196539b22ce5012f550fd9751b63a1864593..a821d2a8237f031f05464d5cfeb78b252bd474ba 100644 (file)
@@ -412,7 +412,13 @@ group lists.
 
 === uploadStickerPack
 
-Upload a new sticker pack, consisting of a manifest file and the stickers in WebP format (maximum size for a sticker file is 100KiB).
+Upload a new sticker pack, consisting of a manifest file and the sticker images.
+Images must conform to the following specification: (see https://support.signal.org/hc/en-us/articles/360031836512-Stickers#sticker_reqs )
+- Static stickers in PNG or WebP format
+- Animated stickers in APNG format,
+- Maximum file size for a sticker file is 300KiB
+- Image resolution of 512 x 512 px
+
 The required manifest.json has the following format:
 
 [source,json]
@@ -421,12 +427,14 @@ The required manifest.json has the following format:
   "title": "<STICKER_PACK_TITLE>",
   "author": "<STICKER_PACK_AUTHOR>",
   "cover": { // Optional cover, by default the first sticker is used as cover
-    "file": "<name of webp file, mandatory>",
+    "file": "<name of image file, mandatory>",
+    "contentType": "<optional>",
     "emoji": "<optional>"
   },
   "stickers": [
     {
-      "file": "<name of webp file, mandatory>",
+      "file": "<name of image file, mandatory>",
+      "contentType": "<optional>",
       "emoji": "<optional>"
     }
     ...