That fuck shit the fascists are using
1package org.tm.archive.migrations;
2
3import androidx.annotation.NonNull;
4import androidx.annotation.Nullable;
5
6import org.signal.core.util.StreamUtil;
7import org.signal.core.util.logging.Log;
8import org.tm.archive.groups.GroupId;
9import org.tm.archive.jobmanager.Job;
10import org.tm.archive.phonenumbers.NumberUtil;
11import org.tm.archive.profiles.AvatarHelper;
12import org.tm.archive.recipients.Recipient;
13
14import java.io.ByteArrayInputStream;
15import java.io.File;
16import java.io.FileInputStream;
17import java.io.IOException;
18import java.util.regex.Pattern;
19
20/**
21 * Previously, we used a recipient's address as the filename for their avatar. We want to use
22 * recipientId's instead in preparation for UUIDs.
23 */
24public class AvatarMigrationJob extends MigrationJob {
25
26 public static final String KEY = "AvatarMigrationJob";
27
28 private static final String TAG = Log.tag(AvatarMigrationJob.class);
29
30 private static final Pattern NUMBER_PATTERN = Pattern.compile("^[0-9\\-+]+$");
31
32 AvatarMigrationJob() {
33 this(new Parameters.Builder().build());
34 }
35
36 private AvatarMigrationJob(@NonNull Parameters parameters) {
37 super(parameters);
38 }
39
40 @Override
41 public boolean isUiBlocking() {
42 return true;
43 }
44
45 @Override
46 public @NonNull String getFactoryKey() {
47 return KEY;
48 }
49
50 @Override
51 public void performMigration() {
52 File oldDirectory = new File(context.getFilesDir(), "avatars");
53 File[] files = oldDirectory.listFiles();
54
55 if (files == null) {
56 Log.w(TAG, "Unable to read directory, and therefore unable to migrate any avatars.");
57 return;
58 }
59
60 Log.i(TAG, "Preparing to move " + files.length + " avatars.");
61
62 for (File file : files) {
63 try {
64 if (isValidFileName(file.getName())) {
65 Recipient recipient = Recipient.external(context, file.getName());
66 byte[] data = StreamUtil.readFully(new FileInputStream(file));
67
68 AvatarHelper.setAvatar(context, recipient.getId(), new ByteArrayInputStream(data));
69 } else {
70 Log.w(TAG, "Invalid file name! Can't migrate this file. It'll just get deleted.");
71 }
72 } catch (IOException e) {
73 Log.w(TAG, "Failed to copy avatar file. Skipping it.", e);
74 } finally {
75 file.delete();
76 }
77 }
78 }
79
80 @Override
81 boolean shouldRetry(@NonNull Exception e) {
82 return false;
83 }
84
85 private static boolean isValidFileName(@NonNull String name) {
86 return NUMBER_PATTERN.matcher(name).matches() || GroupId.isEncodedGroup(name) || NumberUtil.isValidEmail(name);
87 }
88
89 public static class Factory implements Job.Factory<AvatarMigrationJob> {
90 @Override
91 public @NonNull AvatarMigrationJob create(@NonNull Parameters parameters, @Nullable byte[] serializedData) {
92 return new AvatarMigrationJob(parameters);
93 }
94 }
95}