Retrieve sticker pack before sending if necessary

This commit is contained in:
AsamK 2022-01-03 17:54:53 +01:00
parent beb3adcc72
commit 99eef05084
5 changed files with 94 additions and 42 deletions

View file

@ -772,7 +772,8 @@
{"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":[] },
{"name":"file","parameterTypes":[] } {"name":"file","parameterTypes":[] },
{"name":"id","parameterTypes":[] }
]} ]}
, ,
{ {

View file

@ -519,10 +519,10 @@ public class ManagerImpl implements Manager {
final var stickerId = sticker.stickerId(); final var stickerId = sticker.stickerId();
final var stickerPack = context.getAccount().getStickerStore().getStickerPack(packId); final var stickerPack = context.getAccount().getStickerStore().getStickerPack(packId);
if (stickerPack == null || !context.getStickerPackStore().existsStickerPack(packId)) { if (stickerPack == null) {
throw new InvalidStickerException("Sticker pack not found"); throw new InvalidStickerException("Sticker pack not found");
} }
final var manifest = context.getStickerPackStore().retrieveManifest(packId); final var manifest = context.getStickerHelper().getOrRetrieveStickerPack(packId, stickerPack.getPackKey());
if (manifest.stickers().size() <= stickerId) { if (manifest.stickers().size() <= stickerId) {
throw new InvalidStickerException("Sticker id not part of this pack"); throw new InvalidStickerException("Sticker id not part of this pack");
} }

View file

@ -33,6 +33,7 @@ public class Context {
private ReceiveHelper receiveHelper; private ReceiveHelper receiveHelper;
private RecipientHelper recipientHelper; private RecipientHelper recipientHelper;
private SendHelper sendHelper; private SendHelper sendHelper;
private StickerHelper stickerHelper;
private StorageHelper storageHelper; private StorageHelper storageHelper;
private SyncHelper syncHelper; private SyncHelper syncHelper;
private UnidentifiedAccessHelper unidentifiedAccessHelper; private UnidentifiedAccessHelper unidentifiedAccessHelper;
@ -129,6 +130,10 @@ public class Context {
return getOrCreate(() -> sendHelper, () -> sendHelper = new SendHelper(this)); return getOrCreate(() -> sendHelper, () -> sendHelper = new SendHelper(this));
} }
public StickerHelper getStickerHelper() {
return getOrCreate(() -> stickerHelper, () -> stickerHelper = new StickerHelper(this));
}
public StorageHelper getStorageHelper() { public StorageHelper getStorageHelper() {
return getOrCreate(() -> storageHelper, () -> storageHelper = new StorageHelper(this)); return getOrCreate(() -> storageHelper, () -> storageHelper = new StorageHelper(this));
} }

View file

@ -0,0 +1,84 @@
package org.asamk.signal.manager.helper;
import org.asamk.signal.manager.JsonStickerPack;
import org.asamk.signal.manager.SignalDependencies;
import org.asamk.signal.manager.api.InvalidStickerException;
import org.asamk.signal.manager.api.StickerPackId;
import org.asamk.signal.manager.storage.SignalAccount;
import org.asamk.signal.manager.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.InvalidMessageException;
import org.whispersystems.signalservice.internal.util.Hex;
import java.io.IOException;
import java.util.HashSet;
public class StickerHelper {
private final static Logger logger = LoggerFactory.getLogger(StickerHelper.class);
private final Context context;
private final SignalAccount account;
private final SignalDependencies dependencies;
public StickerHelper(final Context context) {
this.account = context.getAccount();
this.dependencies = context.getDependencies();
this.context = context;
}
public JsonStickerPack getOrRetrieveStickerPack(
StickerPackId packId, byte[] packKey
) throws InvalidStickerException {
if (!context.getStickerPackStore().existsStickerPack(packId)) {
try {
retrieveStickerPack(packId, packKey);
} catch (InvalidMessageException | IOException e) {
throw new InvalidStickerException("Failed to retrieve sticker pack");
}
}
final JsonStickerPack manifest;
try {
manifest = context.getStickerPackStore().retrieveManifest(packId);
} catch (IOException e) {
throw new InvalidStickerException("Failed to load sticker pack manifest");
}
return manifest;
}
public void retrieveStickerPack(StickerPackId packId, byte[] packKey) throws InvalidMessageException, IOException {
logger.debug("Retrieving sticker pack {}.", Hex.toStringCondensed(packId.serialize()));
final var manifest = dependencies.getMessageReceiver().retrieveStickerManifest(packId.serialize(), packKey);
final var stickerIds = new HashSet<Integer>();
if (manifest.getCover().isPresent()) {
stickerIds.add(manifest.getCover().get().getId());
}
for (var sticker : manifest.getStickers()) {
stickerIds.add(sticker.getId());
}
for (var id : stickerIds) {
final var inputStream = dependencies.getMessageReceiver().retrieveSticker(packId.serialize(), packKey, id);
context.getStickerPackStore().storeSticker(packId, id, o -> IOUtils.copyStream(inputStream, o));
}
final var jsonManifest = new JsonStickerPack(manifest.getTitle().orNull(),
manifest.getAuthor().orNull(),
manifest.getCover()
.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.getId(),
c.getEmoji(),
String.valueOf(c.getId()),
c.getContentType()))
.toList());
context.getStickerPackStore().storeManifest(packId, jsonManifest);
}
}

View file

@ -1,16 +1,13 @@
package org.asamk.signal.manager.jobs; package org.asamk.signal.manager.jobs;
import org.asamk.signal.manager.JsonStickerPack;
import org.asamk.signal.manager.api.StickerPackId; import org.asamk.signal.manager.api.StickerPackId;
import org.asamk.signal.manager.helper.Context; import org.asamk.signal.manager.helper.Context;
import org.asamk.signal.manager.util.IOUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.InvalidMessageException; import org.whispersystems.libsignal.InvalidMessageException;
import org.whispersystems.signalservice.internal.util.Hex; import org.whispersystems.signalservice.internal.util.Hex;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet;
public class RetrieveStickerPackJob implements Job { public class RetrieveStickerPackJob implements Job {
@ -30,43 +27,8 @@ public class RetrieveStickerPackJob implements Job {
logger.debug("Sticker pack {} already downloaded.", Hex.toStringCondensed(packId.serialize())); logger.debug("Sticker pack {} already downloaded.", Hex.toStringCondensed(packId.serialize()));
return; return;
} }
logger.debug("Retrieving sticker pack {}.", Hex.toStringCondensed(packId.serialize()));
try { try {
final var manifest = context.getDependencies() context.getStickerHelper().retrieveStickerPack(packId, packKey);
.getMessageReceiver()
.retrieveStickerManifest(packId.serialize(), packKey);
final var stickerIds = new HashSet<Integer>();
if (manifest.getCover().isPresent()) {
stickerIds.add(manifest.getCover().get().getId());
}
for (var sticker : manifest.getStickers()) {
stickerIds.add(sticker.getId());
}
for (var id : stickerIds) {
final var inputStream = context.getDependencies()
.getMessageReceiver()
.retrieveSticker(packId.serialize(), packKey, id);
context.getStickerPackStore().storeSticker(packId, id, o -> IOUtils.copyStream(inputStream, o));
}
final var jsonManifest = new JsonStickerPack(manifest.getTitle().orNull(),
manifest.getAuthor().orNull(),
manifest.getCover()
.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.getId(),
c.getEmoji(),
String.valueOf(c.getId()),
c.getContentType()))
.toList());
context.getStickerPackStore().storeManifest(packId, jsonManifest);
} catch (IOException e) { } catch (IOException e) {
logger.warn("Failed to retrieve sticker pack {}: {}", logger.warn("Failed to retrieve sticker pack {}: {}",
Hex.toStringCondensed(packId.serialize()), Hex.toStringCondensed(packId.serialize()),