]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/util/StickerUtils.java
Update libsignal-service
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / util / StickerUtils.java
1 package org.asamk.signal.manager.util;
2
3 import com.fasterxml.jackson.databind.ObjectMapper;
4
5 import org.asamk.signal.manager.api.Pair;
6 import org.asamk.signal.manager.api.StickerPackInvalidException;
7 import org.asamk.signal.manager.storage.stickerPacks.JsonStickerPack;
8 import org.whispersystems.signalservice.api.messages.SignalServiceStickerManifestUpload;
9
10 import java.io.BufferedInputStream;
11 import java.io.File;
12 import java.io.FileInputStream;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.util.ArrayList;
16 import java.util.Optional;
17 import java.util.zip.ZipFile;
18
19 public class StickerUtils {
20
21 public static SignalServiceStickerManifestUpload getSignalServiceStickerManifestUpload(
22 final File file
23 ) throws IOException, StickerPackInvalidException {
24 ZipFile zip = null;
25 String rootPath = null;
26
27 if (file.getName().endsWith(".zip")) {
28 zip = new ZipFile(file);
29 } else if (file.getName().equals("manifest.json")) {
30 rootPath = file.getParent();
31 } else {
32 throw new StickerPackInvalidException("Could not find manifest.json");
33 }
34
35 var pack = parseStickerPack(rootPath, zip);
36
37 if (pack.stickers() == null) {
38 throw new StickerPackInvalidException("Must set a 'stickers' field.");
39 }
40
41 if (pack.stickers().isEmpty()) {
42 throw new StickerPackInvalidException("Must include stickers.");
43 }
44
45 var stickers = new ArrayList<SignalServiceStickerManifestUpload.StickerInfo>(pack.stickers().size());
46 for (var sticker : pack.stickers()) {
47 if (sticker.file() == null) {
48 throw new StickerPackInvalidException("Must set a 'file' field on each sticker.");
49 }
50
51 Pair<InputStream, Long> data;
52 try {
53 data = getInputStreamAndLength(rootPath, zip, sticker.file());
54 } catch (IOException ignored) {
55 throw new StickerPackInvalidException("Could not find find " + sticker.file());
56 }
57
58 var contentType = sticker.contentType() != null && !sticker.contentType().isEmpty()
59 ? sticker.contentType()
60 : getContentType(rootPath, zip, sticker.file());
61 var stickerInfo = new SignalServiceStickerManifestUpload.StickerInfo(data.first(),
62 data.second(),
63 Optional.ofNullable(sticker.emoji()).orElse(""),
64 contentType);
65 stickers.add(stickerInfo);
66 }
67
68 SignalServiceStickerManifestUpload.StickerInfo cover = null;
69 if (pack.cover() != null) {
70 if (pack.cover().file() == null) {
71 throw new StickerPackInvalidException("Must set a 'file' field on the cover.");
72 }
73
74 Pair<InputStream, Long> data;
75 try {
76 data = getInputStreamAndLength(rootPath, zip, pack.cover().file());
77 } catch (IOException ignored) {
78 throw new StickerPackInvalidException("Could not find find " + pack.cover().file());
79 }
80
81 var contentType = pack.cover().contentType() != null && !pack.cover().contentType().isEmpty() ? pack.cover()
82 .contentType() : getContentType(rootPath, zip, pack.cover().file());
83 cover = new SignalServiceStickerManifestUpload.StickerInfo(data.first(),
84 data.second(),
85 Optional.ofNullable(pack.cover().emoji()).orElse(""),
86 contentType);
87 }
88
89 return new SignalServiceStickerManifestUpload(pack.title(), pack.author(), cover, stickers);
90 }
91
92 private static JsonStickerPack parseStickerPack(String rootPath, ZipFile zip) throws IOException {
93 InputStream inputStream;
94 if (zip != null) {
95 inputStream = zip.getInputStream(zip.getEntry("manifest.json"));
96 } else {
97 inputStream = new FileInputStream((new File(rootPath, "manifest.json")));
98 }
99 return new ObjectMapper().readValue(inputStream, JsonStickerPack.class);
100 }
101
102 private static Pair<InputStream, Long> getInputStreamAndLength(
103 final String rootPath, final ZipFile zip, final String subfile
104 ) throws IOException {
105 if (zip != null) {
106 final var entry = zip.getEntry(subfile);
107 return new Pair<>(zip.getInputStream(entry), entry.getSize());
108 } else {
109 final var file = new File(rootPath, subfile);
110 return new Pair<>(new FileInputStream(file), file.length());
111 }
112 }
113
114 private static String getContentType(
115 final String rootPath, final ZipFile zip, final String subfile
116 ) throws IOException {
117 if (zip != null) {
118 final var entry = zip.getEntry(subfile);
119 try (InputStream bufferedStream = new BufferedInputStream(zip.getInputStream(entry))) {
120 return MimeUtils.getStreamMimeType(bufferedStream).orElse(null);
121 }
122 } else {
123 final var file = new File(rootPath, subfile);
124 return MimeUtils.getFileMimeType(file).orElse(null);
125 }
126 }
127 }