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