]> nmode's Git Repositories - signal-cli/commitdiff
Add sticker pack url to list output
authorAsamK <asamk@gmx.de>
Mon, 3 Jan 2022 17:50:27 +0000 (18:50 +0100)
committerAsamK <asamk@gmx.de>
Mon, 3 Jan 2022 17:50:27 +0000 (18:50 +0100)
graalvm-config-dir/reflect-config.json
lib/src/main/java/org/asamk/signal/manager/DeviceLinkInfo.java
lib/src/main/java/org/asamk/signal/manager/Manager.java
lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java
lib/src/main/java/org/asamk/signal/manager/api/StickerPack.java
lib/src/main/java/org/asamk/signal/manager/api/StickerPackUrl.java [new file with mode: 0644]
lib/src/main/java/org/asamk/signal/manager/util/Utils.java
src/main/java/org/asamk/signal/commands/ListStickerPacksCommand.java
src/main/java/org/asamk/signal/commands/UploadStickerPackCommand.java
src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java

index 68af8ab4b7e70f877bd0a601e75a0050cfa2a304..a9065791d1c7141ff710a739cb5554341ab613f3 100644 (file)
     {"name":"installed","parameterTypes":[] }, 
     {"name":"packId","parameterTypes":[] }, 
     {"name":"stickers","parameterTypes":[] }, 
     {"name":"installed","parameterTypes":[] }, 
     {"name":"packId","parameterTypes":[] }, 
     {"name":"stickers","parameterTypes":[] }, 
-    {"name":"title","parameterTypes":[] }
+    {"name":"title","parameterTypes":[] }, 
+    {"name":"url","parameterTypes":[] }
   ]}
 ,
 {
   ]}
 ,
 {
index ca6e305ceb8df3b6c0b7ac460b975b0e57535e18..7c15131e39d44a4ca28aee86b97e7bfaee03a8dc 100644 (file)
@@ -1,18 +1,16 @@
 package org.asamk.signal.manager;
 
 import org.asamk.signal.manager.api.InvalidDeviceLinkException;
 package org.asamk.signal.manager;
 
 import org.asamk.signal.manager.api.InvalidDeviceLinkException;
+import org.asamk.signal.manager.util.Utils;
 import org.whispersystems.libsignal.InvalidKeyException;
 import org.whispersystems.libsignal.ecc.Curve;
 import org.whispersystems.libsignal.ecc.ECPublicKey;
 
 import java.net.URI;
 import java.net.URISyntaxException;
 import org.whispersystems.libsignal.InvalidKeyException;
 import org.whispersystems.libsignal.ecc.Curve;
 import org.whispersystems.libsignal.ecc.ECPublicKey;
 
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.net.URLDecoder;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.util.Base64;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.util.Base64;
-import java.util.HashMap;
-import java.util.Map;
 
 import static org.whispersystems.signalservice.internal.util.Util.isEmpty;
 
 
 import static org.whispersystems.signalservice.internal.util.Util.isEmpty;
 
@@ -24,7 +22,7 @@ public record DeviceLinkInfo(String deviceIdentifier, ECPublicKey deviceKey) {
             throw new RuntimeException("Invalid device link uri");
         }
 
             throw new RuntimeException("Invalid device link uri");
         }
 
-        var query = getQueryMap(rawQuery);
+        var query = Utils.getQueryMap(rawQuery);
         var deviceIdentifier = query.get("uuid");
         var publicKeyEncoded = query.get("pub_key");
 
         var deviceIdentifier = query.get("uuid");
         var publicKeyEncoded = query.get("pub_key");
 
@@ -48,18 +46,6 @@ public record DeviceLinkInfo(String deviceIdentifier, ECPublicKey deviceKey) {
         return new DeviceLinkInfo(deviceIdentifier, deviceKey);
     }
 
         return new DeviceLinkInfo(deviceIdentifier, deviceKey);
     }
 
-    private static Map<String, String> getQueryMap(String query) {
-        var params = query.split("&");
-        var map = new HashMap<String, String>();
-        for (var param : params) {
-            final var paramParts = param.split("=");
-            var name = URLDecoder.decode(paramParts[0], StandardCharsets.UTF_8);
-            var value = URLDecoder.decode(paramParts[1], StandardCharsets.UTF_8);
-            map.put(name, value);
-        }
-        return map;
-    }
-
     public URI createDeviceLinkUri() {
         final var deviceKeyString = Base64.getEncoder().encodeToString(deviceKey.serialize()).replace("=", "");
         try {
     public URI createDeviceLinkUri() {
         final var deviceKeyString = Base64.getEncoder().encodeToString(deviceKey.serialize()).replace("=", "");
         try {
index 7e39909f5f57c13dc25b805ce32816de03231c80..b33116f41c1ae299586b49bc4d6f072752100aac 100644 (file)
@@ -14,6 +14,7 @@ import org.asamk.signal.manager.api.RecipientIdentifier;
 import org.asamk.signal.manager.api.SendGroupMessageResults;
 import org.asamk.signal.manager.api.SendMessageResults;
 import org.asamk.signal.manager.api.StickerPack;
 import org.asamk.signal.manager.api.SendGroupMessageResults;
 import org.asamk.signal.manager.api.SendMessageResults;
 import org.asamk.signal.manager.api.StickerPack;
+import org.asamk.signal.manager.api.StickerPackUrl;
 import org.asamk.signal.manager.api.TypingAction;
 import org.asamk.signal.manager.api.UnregisteredRecipientException;
 import org.asamk.signal.manager.api.UpdateGroup;
 import org.asamk.signal.manager.api.TypingAction;
 import org.asamk.signal.manager.api.UnregisteredRecipientException;
 import org.asamk.signal.manager.api.UpdateGroup;
@@ -220,7 +221,7 @@ public interface Manager extends Closeable {
      * @param path Path can be a path to a manifest.json file or to a zip file that contains a manifest.json file
      * @return if successful, returns the URL to install the sticker pack in the signal app
      */
      * @param path Path can be a path to a manifest.json file or to a zip file that contains a manifest.json file
      * @return if successful, returns the URL to install the sticker pack in the signal app
      */
-    URI uploadStickerPack(File path) throws IOException, StickerPackInvalidException;
+    StickerPackUrl uploadStickerPack(File path) throws IOException, StickerPackInvalidException;
 
     List<StickerPack> getStickerPacks();
 
 
     List<StickerPack> getStickerPacks();
 
index fbcf1b48bf4108b06c100e6a02787c8940989f92..a19caa7a105ce80eaaeee576d1ffa4efe4581d90 100644 (file)
@@ -31,6 +31,7 @@ import org.asamk.signal.manager.api.SendMessageResult;
 import org.asamk.signal.manager.api.SendMessageResults;
 import org.asamk.signal.manager.api.StickerPack;
 import org.asamk.signal.manager.api.StickerPackId;
 import org.asamk.signal.manager.api.SendMessageResults;
 import org.asamk.signal.manager.api.StickerPack;
 import org.asamk.signal.manager.api.StickerPackId;
+import org.asamk.signal.manager.api.StickerPackUrl;
 import org.asamk.signal.manager.api.TypingAction;
 import org.asamk.signal.manager.api.UnregisteredRecipientException;
 import org.asamk.signal.manager.api.UpdateGroup;
 import org.asamk.signal.manager.api.TypingAction;
 import org.asamk.signal.manager.api.UnregisteredRecipientException;
 import org.asamk.signal.manager.api.UpdateGroup;
@@ -70,9 +71,6 @@ import org.whispersystems.signalservice.internal.util.Util;
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
 import java.io.File;
 import java.io.IOException;
 import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -658,7 +656,7 @@ public class ManagerImpl implements Manager {
     }
 
     @Override
     }
 
     @Override
-    public URI uploadStickerPack(File path) throws IOException, StickerPackInvalidException {
+    public StickerPackUrl uploadStickerPack(File path) throws IOException, StickerPackInvalidException {
         var manifest = StickerUtils.getSignalServiceStickerManifestUpload(path);
 
         var messageSender = dependencies.getMessageSender();
         var manifest = StickerUtils.getSignalServiceStickerManifestUpload(path);
 
         var messageSender = dependencies.getMessageSender();
@@ -670,17 +668,7 @@ public class ManagerImpl implements Manager {
         var sticker = new Sticker(packId, packKey);
         account.getStickerStore().updateSticker(sticker);
 
         var sticker = new Sticker(packId, packKey);
         account.getStickerStore().updateSticker(sticker);
 
-        try {
-            return new URI("https",
-                    "signal.art",
-                    "/addstickers/",
-                    "pack_id="
-                            + URLEncoder.encode(Hex.toStringCondensed(packId.serialize()), StandardCharsets.UTF_8)
-                            + "&pack_key="
-                            + URLEncoder.encode(Hex.toStringCondensed(packKey), StandardCharsets.UTF_8));
-        } catch (URISyntaxException e) {
-            throw new AssertionError(e);
-        }
+        return new StickerPackUrl(packId, packKey);
     }
 
     @Override
     }
 
     @Override
@@ -691,7 +679,7 @@ public class ManagerImpl implements Manager {
                 try {
                     final var manifest = stickerPackStore.retrieveManifest(pack.getPackId());
                     return new StickerPack(pack.getPackId(),
                 try {
                     final var manifest = stickerPackStore.retrieveManifest(pack.getPackId());
                     return new StickerPack(pack.getPackId(),
-                            pack.getPackKey(),
+                            new StickerPackUrl(pack.getPackId(), pack.getPackKey()),
                             pack.isInstalled(),
                             manifest.title(),
                             manifest.author(),
                             pack.isInstalled(),
                             manifest.title(),
                             manifest.author(),
index e051a961cfa53d8a9edb4aff02fd7214d94e2de5..f6d092d917413518a22519903db44fac86cbe287 100644 (file)
@@ -5,7 +5,7 @@ import java.util.Optional;
 
 public record StickerPack(
         StickerPackId packId,
 
 public record StickerPack(
         StickerPackId packId,
-        byte[] packKey,
+        StickerPackUrl url,
         boolean installed,
         String title,
         String author,
         boolean installed,
         String title,
         String author,
@@ -14,7 +14,7 @@ public record StickerPack(
 ) {
 
     public StickerPack(final StickerPackId packId, final byte[] packKey, final boolean installed) {
 ) {
 
     public StickerPack(final StickerPackId packId, final byte[] packKey, final boolean installed) {
-        this(packId, packKey, installed, "", "", Optional.empty(), List.of());
+        this(packId, new StickerPackUrl(packId, packKey), installed, "", "", Optional.empty(), List.of());
     }
 
     public record Sticker(int id, String emoji, String contentType) {}
     }
 
     public record Sticker(int id, String emoji, String contentType) {}
diff --git a/lib/src/main/java/org/asamk/signal/manager/api/StickerPackUrl.java b/lib/src/main/java/org/asamk/signal/manager/api/StickerPackUrl.java
new file mode 100644 (file)
index 0000000..d018ac3
--- /dev/null
@@ -0,0 +1,88 @@
+package org.asamk.signal.manager.api;
+
+import org.asamk.signal.manager.util.Utils;
+import org.whispersystems.signalservice.internal.util.Hex;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
+import static org.whispersystems.signalservice.internal.util.Util.isEmpty;
+
+public final class StickerPackUrl {
+
+    private final StickerPackId packId;
+    private final byte[] packKey;
+
+    /**
+     * @throws InvalidStickerPackLinkException If url cannot be parsed.
+     */
+    public static StickerPackUrl fromUri(URI uri) throws InvalidStickerPackLinkException {
+        final var rawQuery = uri.getRawFragment();
+        if (isEmpty(rawQuery)) {
+            throw new RuntimeException("Invalid sticker pack uri");
+        }
+
+        var query = Utils.getQueryMap(rawQuery);
+        var packIdString = query.get("pack_id");
+        var packKeyString = query.get("pack_key");
+
+        if (isEmpty(packIdString) || isEmpty(packKeyString)) {
+            throw new InvalidStickerPackLinkException("Incomplete sticker pack uri");
+        }
+
+        StickerPackId packId;
+        try {
+            packId = StickerPackId.deserialize(Hex.fromStringCondensed(packIdString));
+        } catch (IOException e) {
+            throw new InvalidStickerPackLinkException("Invalid sticker pack", e);
+        }
+        final byte[] packKey;
+        try {
+            packKey = Hex.fromStringCondensed(packKeyString);
+        } catch (IOException e) {
+            throw new InvalidStickerPackLinkException("Invalid sticker pack uri", e);
+        }
+        return new StickerPackUrl(packId, packKey);
+    }
+
+    public StickerPackUrl(final StickerPackId packId, final byte[] packKey) {
+        this.packId = packId;
+        this.packKey = packKey;
+    }
+
+    public URI getUrl() {
+        try {
+            return new URI("https",
+                    "signal.art",
+                    "/addstickers/",
+                    "pack_id="
+                            + URLEncoder.encode(Hex.toStringCondensed(packId.serialize()), StandardCharsets.UTF_8)
+                            + "&pack_key="
+                            + URLEncoder.encode(Hex.toStringCondensed(packKey), StandardCharsets.UTF_8));
+        } catch (URISyntaxException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    public StickerPackId getPackId() {
+        return packId;
+    }
+
+    public byte[] getPackKey() {
+        return packKey;
+    }
+
+    public final static class InvalidStickerPackLinkException extends Exception {
+
+        public InvalidStickerPackLinkException(String message) {
+            super(message);
+        }
+
+        public InvalidStickerPackLinkException(final String message, final Throwable cause) {
+            super(message, cause);
+        }
+    }
+}
index 05de2c862de5e1abcf277cdf875341c56715b3fa..c255eb436989ad44a1f5e48880c182a09b8b0b65 100644 (file)
@@ -14,8 +14,12 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URLConnection;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URLConnection;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Files;
+import java.util.HashMap;
 import java.util.Locale;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Spliterator;
 import java.util.Spliterators;
 import java.util.function.BiFunction;
 import java.util.Spliterator;
 import java.util.Spliterators;
 import java.util.function.BiFunction;
@@ -106,4 +110,16 @@ public class Utils {
             }
         }, leftStream.isParallel() || rightStream.isParallel());
     }
             }
         }, leftStream.isParallel() || rightStream.isParallel());
     }
+
+    public static Map<String, String> getQueryMap(String query) {
+        var params = query.split("&");
+        var map = new HashMap<String, String>();
+        for (var param : params) {
+            final var paramParts = param.split("=");
+            var name = URLDecoder.decode(paramParts[0], StandardCharsets.UTF_8);
+            var value = URLDecoder.decode(paramParts[1], StandardCharsets.UTF_8);
+            map.put(name, value);
+        }
+        return map;
+    }
 }
 }
index fa61e7533ff229a98cd7babb63814afe91b921ec..53f3f3527c5afcfa56a87ab22775f45673ca59d4 100644 (file)
@@ -35,21 +35,29 @@ public class ListStickerPacksCommand implements JsonRpcLocalCommand {
             jsonWriter.write(jsonStickerPacks);
         } else if (outputWriter instanceof PlainTextWriter plainTextWriter) {
             for (final var sticker : stickerPacks) {
             jsonWriter.write(jsonStickerPacks);
         } else if (outputWriter instanceof PlainTextWriter plainTextWriter) {
             for (final var sticker : stickerPacks) {
-                plainTextWriter.println("Pack {}: “{}” by “{}” has {} stickers",
+                plainTextWriter.println("Pack {}: “{}” by “{}” has {} stickers. {}",
                         Hex.toStringCondensed(sticker.packId().serialize()),
                         sticker.title(),
                         sticker.author(),
                         Hex.toStringCondensed(sticker.packId().serialize()),
                         sticker.title(),
                         sticker.author(),
-                        sticker.stickers().size());
+                        sticker.stickers().size(),
+                        sticker.url().getUrl());
             }
         }
     }
 
     private record JsonStickerPack(
             }
         }
     }
 
     private record JsonStickerPack(
-            String packId, boolean installed, String title, String author, JsonSticker cover, List<JsonSticker> stickers
+            String packId,
+            String url,
+            boolean installed,
+            String title,
+            String author,
+            JsonSticker cover,
+            List<JsonSticker> stickers
     ) {
 
         JsonStickerPack(StickerPack stickerPack) {
             this(Hex.toStringCondensed(stickerPack.packId().serialize()),
     ) {
 
         JsonStickerPack(StickerPack stickerPack) {
             this(Hex.toStringCondensed(stickerPack.packId().serialize()),
+                    stickerPack.url().getUrl().toString(),
                     stickerPack.installed(),
                     stickerPack.title(),
                     stickerPack.author(),
                     stickerPack.installed(),
                     stickerPack.title(),
                     stickerPack.author(),
index 0fc75aeef4890dd4003bf56de27dbbd3c3f0434c..b70d9e0d9cb3994f1c974d840c5517791a122ee7 100644 (file)
@@ -43,10 +43,10 @@ public class UploadStickerPackCommand implements JsonRpcLocalCommand {
         try {
             var url = m.uploadStickerPack(path);
             if (outputWriter instanceof PlainTextWriter writer) {
         try {
             var url = m.uploadStickerPack(path);
             if (outputWriter instanceof PlainTextWriter writer) {
-                writer.println("{}", url);
+                writer.println("{}", url.getUrl());
             } else {
                 final var writer = (JsonWriter) outputWriter;
             } else {
                 final var writer = (JsonWriter) outputWriter;
-                writer.write(Map.of("url", url));
+                writer.write(Map.of("url", url.getUrl()));
             }
         } catch (IOException e) {
             throw new IOErrorException("Upload error (maybe image size too large):" + e.getMessage(), e);
             }
         } catch (IOException e) {
             throw new IOErrorException("Upload error (maybe image size too large):" + e.getMessage(), e);
index 345a385aa7f0a93948c78b2e5072fb1b026329d1..3e3af300a19f64e2a2ee3da249193f890099aa5f 100644 (file)
@@ -19,6 +19,7 @@ import org.asamk.signal.manager.api.RecipientIdentifier;
 import org.asamk.signal.manager.api.SendGroupMessageResults;
 import org.asamk.signal.manager.api.SendMessageResults;
 import org.asamk.signal.manager.api.StickerPack;
 import org.asamk.signal.manager.api.SendGroupMessageResults;
 import org.asamk.signal.manager.api.SendMessageResults;
 import org.asamk.signal.manager.api.StickerPack;
+import org.asamk.signal.manager.api.StickerPackUrl;
 import org.asamk.signal.manager.api.TypingAction;
 import org.asamk.signal.manager.api.UpdateGroup;
 import org.asamk.signal.manager.groups.GroupId;
 import org.asamk.signal.manager.api.TypingAction;
 import org.asamk.signal.manager.api.UpdateGroup;
 import org.asamk.signal.manager.groups.GroupId;
@@ -436,10 +437,10 @@ public class DbusManagerImpl implements Manager {
     }
 
     @Override
     }
 
     @Override
-    public URI uploadStickerPack(final File path) throws IOException, StickerPackInvalidException {
+    public StickerPackUrl uploadStickerPack(final File path) throws IOException, StickerPackInvalidException {
         try {
         try {
-            return new URI(signal.uploadStickerPack(path.getPath()));
-        } catch (URISyntaxException e) {
+            return StickerPackUrl.fromUri(new URI(signal.uploadStickerPack(path.getPath())));
+        } catch (URISyntaxException | StickerPackUrl.InvalidStickerPackLinkException e) {
             throw new AssertionError(e);
         }
     }
             throw new AssertionError(e);
         }
     }