From: AsamK Date: Mon, 3 Jan 2022 15:11:03 +0000 (+0100) Subject: Implement listStickerPacks command X-Git-Tag: v0.10.1~9 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/e70463d7b8a9ea921028dc2a0cf77f90998f6831?ds=sidebyside Implement listStickerPacks command --- diff --git a/graalvm-config-dir/reflect-config.json b/graalvm-config-dir/reflect-config.json index 2e5295cc..7adb67ea 100644 --- a/graalvm-config-dir/reflect-config.json +++ b/graalvm-config-dir/reflect-config.json @@ -433,6 +433,31 @@ "allDeclaredMethods":true, "allDeclaredConstructors":true} , +{ + "name":"org.asamk.signal.commands.ListStickerPacksCommand$JsonStickerPack", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[ + {"name":"author","parameterTypes":[] }, + {"name":"cover","parameterTypes":[] }, + {"name":"installed","parameterTypes":[] }, + {"name":"packId","parameterTypes":[] }, + {"name":"stickers","parameterTypes":[] }, + {"name":"title","parameterTypes":[] } + ]} +, +{ + "name":"org.asamk.signal.commands.ListStickerPacksCommand$JsonStickerPack$JsonSticker", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[ + {"name":"contentType","parameterTypes":[] }, + {"name":"emoji","parameterTypes":[] }, + {"name":"id","parameterTypes":[] } + ]} +, { "name":"org.asamk.signal.commands.RegisterCommand$RegistrationParams", "allDeclaredFields":true, @@ -743,6 +768,7 @@ "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true, "methods":[ + {"name":"","parameterTypes":["java.lang.Integer","java.lang.String","java.lang.String","java.lang.String"] }, {"name":"","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }, {"name":"contentType","parameterTypes":[] }, {"name":"emoji","parameterTypes":[] }, diff --git a/lib/src/main/java/org/asamk/signal/manager/JsonStickerPack.java b/lib/src/main/java/org/asamk/signal/manager/JsonStickerPack.java index 89114426..75e65bcb 100644 --- a/lib/src/main/java/org/asamk/signal/manager/JsonStickerPack.java +++ b/lib/src/main/java/org/asamk/signal/manager/JsonStickerPack.java @@ -1,8 +1,15 @@ package org.asamk.signal.manager; +import org.asamk.signal.manager.api.StickerPack; + import java.util.List; public record JsonStickerPack(String title, String author, JsonSticker cover, List stickers) { - public record JsonSticker(String emoji, String file, String contentType) {} + public record JsonSticker(Integer id, String emoji, String file, String contentType) { + + public StickerPack.Sticker toApi() { + return new StickerPack.Sticker(id == null ? Integer.parseInt(file) : id, emoji, contentType); + } + } } diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index a60afc8c..7e39909f 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -13,6 +13,7 @@ import org.asamk.signal.manager.api.Pair; 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.TypingAction; import org.asamk.signal.manager.api.UnregisteredRecipientException; import org.asamk.signal.manager.api.UpdateGroup; @@ -221,6 +222,8 @@ public interface Manager extends Closeable { */ URI uploadStickerPack(File path) throws IOException, StickerPackInvalidException; + List getStickerPacks(); + void requestAllSyncData() throws IOException; /** diff --git a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java index 708b0226..fdb28929 100644 --- a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java @@ -29,6 +29,7 @@ import org.asamk.signal.manager.api.RecipientIdentifier; import org.asamk.signal.manager.api.SendGroupMessageResults; 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.TypingAction; import org.asamk.signal.manager.api.UnregisteredRecipientException; import org.asamk.signal.manager.api.UpdateGroup; @@ -682,6 +683,29 @@ public class ManagerImpl implements Manager { } } + @Override + public List getStickerPacks() { + final var stickerPackStore = context.getStickerPackStore(); + return account.getStickerStore().getStickerPacks().stream().map(pack -> { + if (stickerPackStore.existsStickerPack(pack.getPackId())) { + try { + final var manifest = stickerPackStore.retrieveManifest(pack.getPackId()); + return new StickerPack(pack.getPackId(), + pack.getPackKey(), + pack.isInstalled(), + manifest.title(), + manifest.author(), + java.util.Optional.ofNullable(manifest.cover() == null ? null : manifest.cover().toApi()), + manifest.stickers().stream().map(JsonStickerPack.JsonSticker::toApi).toList()); + } catch (Exception e) { + logger.warn("Failed to read local sticker pack manifest: {}", e.getMessage(), e); + } + } + + return new StickerPack(pack.getPackId(), pack.getPackKey(), pack.isInstalled()); + }).toList(); + } + @Override public void requestAllSyncData() throws IOException { context.getSyncHelper().requestAllSyncData(); diff --git a/lib/src/main/java/org/asamk/signal/manager/api/StickerPack.java b/lib/src/main/java/org/asamk/signal/manager/api/StickerPack.java new file mode 100644 index 00000000..45d86c8e --- /dev/null +++ b/lib/src/main/java/org/asamk/signal/manager/api/StickerPack.java @@ -0,0 +1,23 @@ +package org.asamk.signal.manager.api; + +import org.asamk.signal.manager.storage.stickers.StickerPackId; + +import java.util.List; +import java.util.Optional; + +public record StickerPack( + StickerPackId packId, + byte[] packKey, + boolean installed, + String title, + String author, + Optional cover, + List stickers +) { + + public StickerPack(final StickerPackId packId, final byte[] packKey, final boolean installed) { + this(packId, packKey, installed, "", "", Optional.empty(), List.of()); + } + + public record Sticker(int id, String emoji, String contentType) {} +} diff --git a/lib/src/main/java/org/asamk/signal/manager/jobs/RetrieveStickerPackJob.java b/lib/src/main/java/org/asamk/signal/manager/jobs/RetrieveStickerPackJob.java index 0e45eecb..4a3ac306 100644 --- a/lib/src/main/java/org/asamk/signal/manager/jobs/RetrieveStickerPackJob.java +++ b/lib/src/main/java/org/asamk/signal/manager/jobs/RetrieveStickerPackJob.java @@ -54,13 +54,15 @@ public class RetrieveStickerPackJob implements Job { final var jsonManifest = new JsonStickerPack(manifest.getTitle().orNull(), manifest.getAuthor().orNull(), manifest.getCover() - .transform(c -> new JsonStickerPack.JsonSticker(c.getEmoji(), + .transform(c -> new JsonStickerPack.JsonSticker(c.getId(), + c.getEmoji(), String.valueOf(c.getId()), c.getContentType())) .orNull(), manifest.getStickers() .stream() - .map(c -> new JsonStickerPack.JsonSticker(c.getEmoji(), + .map(c -> new JsonStickerPack.JsonSticker(c.getId(), + c.getEmoji(), String.valueOf(c.getId()), c.getContentType())) .toList()); diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/stickers/StickerStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/stickers/StickerStore.java index 1a67c15a..b1de3fec 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/stickers/StickerStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/stickers/StickerStore.java @@ -1,6 +1,7 @@ package org.asamk.signal.manager.storage.stickers; import java.util.Base64; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -41,6 +42,10 @@ public class StickerStore { return new StickerStore(stickers, saver); } + public Collection getStickerPacks() { + return stickers.values(); + } + public Sticker getStickerPack(StickerPackId packId) { synchronized (stickers) { return stickers.get(packId); diff --git a/src/main/java/org/asamk/signal/commands/Commands.java b/src/main/java/org/asamk/signal/commands/Commands.java index d13d50ac..aee9a7ba 100644 --- a/src/main/java/org/asamk/signal/commands/Commands.java +++ b/src/main/java/org/asamk/signal/commands/Commands.java @@ -23,6 +23,7 @@ public class Commands { addCommand(new ListDevicesCommand()); addCommand(new ListGroupsCommand()); addCommand(new ListIdentitiesCommand()); + addCommand(new ListStickerPacksCommand()); addCommand(new QuitGroupCommand()); addCommand(new ReceiveCommand()); addCommand(new RegisterCommand()); diff --git a/src/main/java/org/asamk/signal/commands/ListStickerPacksCommand.java b/src/main/java/org/asamk/signal/commands/ListStickerPacksCommand.java new file mode 100644 index 00000000..fa61e753 --- /dev/null +++ b/src/main/java/org/asamk/signal/commands/ListStickerPacksCommand.java @@ -0,0 +1,67 @@ +package org.asamk.signal.commands; + +import net.sourceforge.argparse4j.inf.Namespace; +import net.sourceforge.argparse4j.inf.Subparser; + +import org.asamk.signal.commands.exceptions.CommandException; +import org.asamk.signal.manager.Manager; +import org.asamk.signal.manager.api.StickerPack; +import org.asamk.signal.output.JsonWriter; +import org.asamk.signal.output.OutputWriter; +import org.asamk.signal.output.PlainTextWriter; +import org.asamk.signal.util.Hex; + +import java.util.List; + +public class ListStickerPacksCommand implements JsonRpcLocalCommand { + + @Override + public String getName() { + return "listStickerPacks"; + } + + @Override + public void attachToSubparser(final Subparser subparser) { + subparser.help("Show a list of known sticker packs."); + } + + @Override + public void handleCommand( + final Namespace ns, final Manager c, final OutputWriter outputWriter + ) throws CommandException { + final var stickerPacks = c.getStickerPacks(); + if (outputWriter instanceof JsonWriter jsonWriter) { + final var jsonStickerPacks = stickerPacks.stream().map(JsonStickerPack::new).toList(); + jsonWriter.write(jsonStickerPacks); + } else if (outputWriter instanceof PlainTextWriter plainTextWriter) { + for (final var sticker : stickerPacks) { + plainTextWriter.println("Pack {}: “{}” by “{}” has {} stickers", + Hex.toStringCondensed(sticker.packId().serialize()), + sticker.title(), + sticker.author(), + sticker.stickers().size()); + } + } + } + + private record JsonStickerPack( + String packId, boolean installed, String title, String author, JsonSticker cover, List stickers + ) { + + JsonStickerPack(StickerPack stickerPack) { + this(Hex.toStringCondensed(stickerPack.packId().serialize()), + stickerPack.installed(), + stickerPack.title(), + stickerPack.author(), + stickerPack.cover().map(JsonSticker::new).orElse(null), + stickerPack.stickers().stream().map(JsonSticker::new).toList()); + } + + private record JsonSticker(int id, String emoji, String contentType) { + + JsonSticker(StickerPack.Sticker sticker) { + this(sticker.id(), sticker.emoji(), sticker.contentType()); + } + } + } +} diff --git a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java index 7faf87e8..345a385a 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java @@ -18,6 +18,7 @@ import org.asamk.signal.manager.api.Pair; 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.TypingAction; import org.asamk.signal.manager.api.UpdateGroup; import org.asamk.signal.manager.groups.GroupId; @@ -443,6 +444,11 @@ public class DbusManagerImpl implements Manager { } } + @Override + public List getStickerPacks() { + throw new UnsupportedOperationException(); + } + @Override public void requestAllSyncData() throws IOException { signal.sendSyncRequest();