1 package org
.asamk
.signal
.manager
;
3 import org
.asamk
.signal
.manager
.groups
.GroupId
;
4 import org
.asamk
.signal
.manager
.util
.IOUtils
;
5 import org
.asamk
.signal
.manager
.util
.Utils
;
6 import org
.whispersystems
.signalservice
.api
.push
.SignalServiceAddress
;
7 import org
.whispersystems
.signalservice
.api
.util
.StreamDetails
;
10 import java
.io
.FileOutputStream
;
11 import java
.io
.IOException
;
12 import java
.io
.OutputStream
;
13 import java
.nio
.file
.Files
;
15 public class AvatarStore
{
17 private final File avatarsPath
;
19 public AvatarStore(final File avatarsPath
) {
20 this.avatarsPath
= avatarsPath
;
23 public StreamDetails
retrieveContactAvatar(SignalServiceAddress address
) throws IOException
{
24 return retrieveAvatar(getContactAvatarFile(address
));
27 public StreamDetails
retrieveProfileAvatar(SignalServiceAddress address
) throws IOException
{
28 return retrieveAvatar(getProfileAvatarFile(address
));
31 public StreamDetails
retrieveGroupAvatar(GroupId groupId
) throws IOException
{
32 final var groupAvatarFile
= getGroupAvatarFile(groupId
);
33 return retrieveAvatar(groupAvatarFile
);
36 public void storeContactAvatar(SignalServiceAddress address
, AvatarStorer storer
) throws IOException
{
37 storeAvatar(getContactAvatarFile(address
), storer
);
40 public void storeProfileAvatar(SignalServiceAddress address
, AvatarStorer storer
) throws IOException
{
41 storeAvatar(getProfileAvatarFile(address
), storer
);
44 public void storeGroupAvatar(GroupId groupId
, AvatarStorer storer
) throws IOException
{
45 storeAvatar(getGroupAvatarFile(groupId
), storer
);
48 public void deleteProfileAvatar(SignalServiceAddress address
) throws IOException
{
49 deleteAvatar(getProfileAvatarFile(address
));
52 public void deleteGroupAvatar(GroupId groupId
) throws IOException
{
53 deleteAvatar(getGroupAvatarFile(groupId
));
56 private StreamDetails
retrieveAvatar(final File avatarFile
) throws IOException
{
57 if (!avatarFile
.exists()) {
60 return Utils
.createStreamDetailsFromFile(avatarFile
);
63 private void storeAvatar(final File avatarFile
, final AvatarStorer storer
) throws IOException
{
65 try (OutputStream output
= new FileOutputStream(avatarFile
)) {
70 private void deleteAvatar(final File avatarFile
) throws IOException
{
71 if (avatarFile
.exists()) {
72 Files
.delete(avatarFile
.toPath());
76 private File
getGroupAvatarFile(GroupId groupId
) {
77 return new File(avatarsPath
, "group-" + groupId
.toBase64().replace("/", "_"));
80 private File
getContactAvatarFile(SignalServiceAddress address
) {
81 return new File(avatarsPath
, "contact-" + getLegacyIdentifier(address
));
84 private String
getLegacyIdentifier(final SignalServiceAddress address
) {
85 return address
.getNumber().or(() -> address
.getUuid().toString());
88 private File
getProfileAvatarFile(SignalServiceAddress address
) {
89 return new File(avatarsPath
, "profile-" + getLegacyIdentifier(address
));
92 private void createAvatarsDir() throws IOException
{
93 IOUtils
.createPrivateDirectories(avatarsPath
);
97 public interface AvatarStorer
{
99 void store(OutputStream outputStream
) throws IOException
;