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

@ -519,10 +519,10 @@ public class ManagerImpl implements Manager {
final var stickerId = sticker.stickerId();
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");
}
final var manifest = context.getStickerPackStore().retrieveManifest(packId);
final var manifest = context.getStickerHelper().getOrRetrieveStickerPack(packId, stickerPack.getPackKey());
if (manifest.stickers().size() <= stickerId) {
throw new InvalidStickerException("Sticker id not part of this pack");
}

View file

@ -33,6 +33,7 @@ public class Context {
private ReceiveHelper receiveHelper;
private RecipientHelper recipientHelper;
private SendHelper sendHelper;
private StickerHelper stickerHelper;
private StorageHelper storageHelper;
private SyncHelper syncHelper;
private UnidentifiedAccessHelper unidentifiedAccessHelper;
@ -129,6 +130,10 @@ public class Context {
return getOrCreate(() -> sendHelper, () -> sendHelper = new SendHelper(this));
}
public StickerHelper getStickerHelper() {
return getOrCreate(() -> stickerHelper, () -> stickerHelper = new StickerHelper(this));
}
public StorageHelper getStorageHelper() {
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;
import org.asamk.signal.manager.JsonStickerPack;
import org.asamk.signal.manager.api.StickerPackId;
import org.asamk.signal.manager.helper.Context;
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 RetrieveStickerPackJob implements Job {
@ -30,43 +27,8 @@ public class RetrieveStickerPackJob implements Job {
logger.debug("Sticker pack {} already downloaded.", Hex.toStringCondensed(packId.serialize()));
return;
}
logger.debug("Retrieving sticker pack {}.", Hex.toStringCondensed(packId.serialize()));
try {
final var manifest = context.getDependencies()
.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);
context.getStickerHelper().retrieveStickerPack(packId, packKey);
} catch (IOException e) {
logger.warn("Failed to retrieve sticker pack {}: {}",
Hex.toStringCondensed(packId.serialize()),