Implement listStickerPacks command

This commit is contained in:
AsamK 2022-01-03 16:11:03 +01:00
parent 404063a080
commit e70463d7b8
10 changed files with 167 additions and 3 deletions

View file

@ -433,6 +433,31 @@
"allDeclaredMethods":true, "allDeclaredMethods":true,
"allDeclaredConstructors":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", "name":"org.asamk.signal.commands.RegisterCommand$RegistrationParams",
"allDeclaredFields":true, "allDeclaredFields":true,
@ -743,6 +768,7 @@
"queryAllDeclaredMethods":true, "queryAllDeclaredMethods":true,
"queryAllDeclaredConstructors":true, "queryAllDeclaredConstructors":true,
"methods":[ "methods":[
{"name":"<init>","parameterTypes":["java.lang.Integer","java.lang.String","java.lang.String","java.lang.String"] },
{"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] }, {"name":"<init>","parameterTypes":["java.lang.String","java.lang.String","java.lang.String"] },
{"name":"contentType","parameterTypes":[] }, {"name":"contentType","parameterTypes":[] },
{"name":"emoji","parameterTypes":[] }, {"name":"emoji","parameterTypes":[] },

View file

@ -1,8 +1,15 @@
package org.asamk.signal.manager; package org.asamk.signal.manager;
import org.asamk.signal.manager.api.StickerPack;
import java.util.List; import java.util.List;
public record JsonStickerPack(String title, String author, JsonSticker cover, List<JsonSticker> stickers) { public record JsonStickerPack(String title, String author, JsonSticker cover, List<JsonSticker> 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);
}
}
} }

View file

@ -13,6 +13,7 @@ import org.asamk.signal.manager.api.Pair;
import org.asamk.signal.manager.api.RecipientIdentifier; import org.asamk.signal.manager.api.RecipientIdentifier;
import org.asamk.signal.manager.api.SendGroupMessageResults; import org.asamk.signal.manager.api.SendGroupMessageResults;
import org.asamk.signal.manager.api.SendMessageResults; 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.TypingAction;
import org.asamk.signal.manager.api.UnregisteredRecipientException; import org.asamk.signal.manager.api.UnregisteredRecipientException;
import org.asamk.signal.manager.api.UpdateGroup; import org.asamk.signal.manager.api.UpdateGroup;
@ -221,6 +222,8 @@ public interface Manager extends Closeable {
*/ */
URI uploadStickerPack(File path) throws IOException, StickerPackInvalidException; URI uploadStickerPack(File path) throws IOException, StickerPackInvalidException;
List<StickerPack> getStickerPacks();
void requestAllSyncData() throws IOException; void requestAllSyncData() throws IOException;
/** /**

View file

@ -29,6 +29,7 @@ import org.asamk.signal.manager.api.RecipientIdentifier;
import org.asamk.signal.manager.api.SendGroupMessageResults; import org.asamk.signal.manager.api.SendGroupMessageResults;
import org.asamk.signal.manager.api.SendMessageResult; import org.asamk.signal.manager.api.SendMessageResult;
import org.asamk.signal.manager.api.SendMessageResults; 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.TypingAction;
import org.asamk.signal.manager.api.UnregisteredRecipientException; import org.asamk.signal.manager.api.UnregisteredRecipientException;
import org.asamk.signal.manager.api.UpdateGroup; import org.asamk.signal.manager.api.UpdateGroup;
@ -682,6 +683,29 @@ public class ManagerImpl implements Manager {
} }
} }
@Override
public List<StickerPack> 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 @Override
public void requestAllSyncData() throws IOException { public void requestAllSyncData() throws IOException {
context.getSyncHelper().requestAllSyncData(); context.getSyncHelper().requestAllSyncData();

View file

@ -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<Sticker> cover,
List<Sticker> 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) {}
}

View file

@ -54,13 +54,15 @@ public class RetrieveStickerPackJob implements Job {
final var jsonManifest = new JsonStickerPack(manifest.getTitle().orNull(), final var jsonManifest = new JsonStickerPack(manifest.getTitle().orNull(),
manifest.getAuthor().orNull(), manifest.getAuthor().orNull(),
manifest.getCover() manifest.getCover()
.transform(c -> new JsonStickerPack.JsonSticker(c.getEmoji(), .transform(c -> new JsonStickerPack.JsonSticker(c.getId(),
c.getEmoji(),
String.valueOf(c.getId()), String.valueOf(c.getId()),
c.getContentType())) c.getContentType()))
.orNull(), .orNull(),
manifest.getStickers() manifest.getStickers()
.stream() .stream()
.map(c -> new JsonStickerPack.JsonSticker(c.getEmoji(), .map(c -> new JsonStickerPack.JsonSticker(c.getId(),
c.getEmoji(),
String.valueOf(c.getId()), String.valueOf(c.getId()),
c.getContentType())) c.getContentType()))
.toList()); .toList());

View file

@ -1,6 +1,7 @@
package org.asamk.signal.manager.storage.stickers; package org.asamk.signal.manager.storage.stickers;
import java.util.Base64; import java.util.Base64;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -41,6 +42,10 @@ public class StickerStore {
return new StickerStore(stickers, saver); return new StickerStore(stickers, saver);
} }
public Collection<Sticker> getStickerPacks() {
return stickers.values();
}
public Sticker getStickerPack(StickerPackId packId) { public Sticker getStickerPack(StickerPackId packId) {
synchronized (stickers) { synchronized (stickers) {
return stickers.get(packId); return stickers.get(packId);

View file

@ -23,6 +23,7 @@ public class Commands {
addCommand(new ListDevicesCommand()); addCommand(new ListDevicesCommand());
addCommand(new ListGroupsCommand()); addCommand(new ListGroupsCommand());
addCommand(new ListIdentitiesCommand()); addCommand(new ListIdentitiesCommand());
addCommand(new ListStickerPacksCommand());
addCommand(new QuitGroupCommand()); addCommand(new QuitGroupCommand());
addCommand(new ReceiveCommand()); addCommand(new ReceiveCommand());
addCommand(new RegisterCommand()); addCommand(new RegisterCommand());

View file

@ -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<JsonSticker> 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());
}
}
}
}

View file

@ -18,6 +18,7 @@ import org.asamk.signal.manager.api.Pair;
import org.asamk.signal.manager.api.RecipientIdentifier; import org.asamk.signal.manager.api.RecipientIdentifier;
import org.asamk.signal.manager.api.SendGroupMessageResults; import org.asamk.signal.manager.api.SendGroupMessageResults;
import org.asamk.signal.manager.api.SendMessageResults; 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.TypingAction;
import org.asamk.signal.manager.api.UpdateGroup; import org.asamk.signal.manager.api.UpdateGroup;
import org.asamk.signal.manager.groups.GroupId; import org.asamk.signal.manager.groups.GroupId;
@ -443,6 +444,11 @@ public class DbusManagerImpl implements Manager {
} }
} }
@Override
public List<StickerPack> getStickerPacks() {
throw new UnsupportedOperationException();
}
@Override @Override
public void requestAllSyncData() throws IOException { public void requestAllSyncData() throws IOException {
signal.sendSyncRequest(); signal.sendSyncRequest();