mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 02:20:39 +00:00
Add sticker pack url to list output
This commit is contained in:
parent
99eef05084
commit
8a5f98dac6
10 changed files with 133 additions and 44 deletions
|
@ -444,7 +444,8 @@
|
|||
{"name":"installed","parameterTypes":[] },
|
||||
{"name":"packId","parameterTypes":[] },
|
||||
{"name":"stickers","parameterTypes":[] },
|
||||
{"name":"title","parameterTypes":[] }
|
||||
{"name":"title","parameterTypes":[] },
|
||||
{"name":"url","parameterTypes":[] }
|
||||
]}
|
||||
,
|
||||
{
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
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 java.net.URLDecoder;
|
||||
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;
|
||||
|
||||
|
@ -24,7 +22,7 @@ public record DeviceLinkInfo(String deviceIdentifier, ECPublicKey deviceKey) {
|
|||
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");
|
||||
|
||||
|
@ -48,18 +46,6 @@ public record DeviceLinkInfo(String deviceIdentifier, ECPublicKey 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 {
|
||||
|
|
|
@ -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.StickerPackUrl;
|
||||
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
|
||||
*/
|
||||
URI uploadStickerPack(File path) throws IOException, StickerPackInvalidException;
|
||||
StickerPackUrl uploadStickerPack(File path) throws IOException, StickerPackInvalidException;
|
||||
|
||||
List<StickerPack> getStickerPacks();
|
||||
|
||||
|
|
|
@ -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.StickerPackUrl;
|
||||
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.net.URISyntaxException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -658,7 +656,7 @@ public class ManagerImpl implements Manager {
|
|||
}
|
||||
|
||||
@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();
|
||||
|
@ -670,17 +668,7 @@ public class ManagerImpl implements Manager {
|
|||
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
|
||||
|
@ -691,7 +679,7 @@ public class ManagerImpl implements Manager {
|
|||
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(),
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.Optional;
|
|||
|
||||
public record StickerPack(
|
||||
StickerPackId packId,
|
||||
byte[] packKey,
|
||||
StickerPackUrl url,
|
||||
boolean installed,
|
||||
String title,
|
||||
String author,
|
||||
|
@ -14,7 +14,7 @@ public record StickerPack(
|
|||
) {
|
||||
|
||||
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) {}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,8 +14,12 @@ import java.io.FileInputStream;
|
|||
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.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.function.BiFunction;
|
||||
|
@ -106,4 +110,16 @@ public class Utils {
|
|||
}
|
||||
}, 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,21 +35,29 @@ public class ListStickerPacksCommand implements JsonRpcLocalCommand {
|
|||
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(),
|
||||
sticker.stickers().size());
|
||||
sticker.stickers().size(),
|
||||
sticker.url().getUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()),
|
||||
stickerPack.url().getUrl().toString(),
|
||||
stickerPack.installed(),
|
||||
stickerPack.title(),
|
||||
stickerPack.author(),
|
||||
|
|
|
@ -43,10 +43,10 @@ public class UploadStickerPackCommand implements JsonRpcLocalCommand {
|
|||
try {
|
||||
var url = m.uploadStickerPack(path);
|
||||
if (outputWriter instanceof PlainTextWriter writer) {
|
||||
writer.println("{}", url);
|
||||
writer.println("{}", url.getUrl());
|
||||
} 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);
|
||||
|
|
|
@ -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.StickerPackUrl;
|
||||
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
|
||||
public URI uploadStickerPack(final File path) throws IOException, StickerPackInvalidException {
|
||||
public StickerPackUrl uploadStickerPack(final File path) throws IOException, StickerPackInvalidException {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue