mirror of
https://github.com/AsamK/signal-cli
synced 2025-09-02 12:30:39 +00:00
Added base64 encoded attachment support
This commit is contained in:
parent
63e94a9fb4
commit
ed8793f354
4 changed files with 47 additions and 7 deletions
|
@ -51,7 +51,7 @@ public class AttachmentHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public SignalServiceAttachmentPointer uploadAttachment(String attachment) throws IOException, AttachmentInvalidException {
|
public SignalServiceAttachmentPointer uploadAttachment(String attachment) throws IOException, AttachmentInvalidException {
|
||||||
var attachmentStream = AttachmentUtils.createAttachmentStream(new File(attachment));
|
var attachmentStream = AttachmentUtils.createAttachmentStream(attachment);
|
||||||
return uploadAttachment(attachmentStream);
|
return uploadAttachment(attachmentStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import org.whispersystems.signalservice.api.util.StreamDetails;
|
||||||
import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec;
|
import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -19,17 +20,21 @@ public class AttachmentUtils {
|
||||||
}
|
}
|
||||||
final var signalServiceAttachments = new ArrayList<SignalServiceAttachmentStream>(attachments.size());
|
final var signalServiceAttachments = new ArrayList<SignalServiceAttachmentStream>(attachments.size());
|
||||||
for (var attachment : attachments) {
|
for (var attachment : attachments) {
|
||||||
signalServiceAttachments.add(createAttachmentStream(new File(attachment)));
|
signalServiceAttachments.add(createAttachmentStream(attachment));
|
||||||
}
|
}
|
||||||
return signalServiceAttachments;
|
return signalServiceAttachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SignalServiceAttachmentStream createAttachmentStream(File attachmentFile) throws AttachmentInvalidException {
|
public static SignalServiceAttachmentStream createAttachmentStream(String attachment) throws AttachmentInvalidException {
|
||||||
try {
|
try {
|
||||||
final var streamDetails = Utils.createStreamDetailsFromFile(attachmentFile);
|
final var streamDetails = Utils.createStreamDetails(attachment);
|
||||||
return createAttachmentStream(streamDetails, Optional.of(attachmentFile.getName()));
|
final var name = streamDetails.getStream() instanceof FileInputStream
|
||||||
|
? new File(attachment).getName()
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return createAttachmentStream(streamDetails, Optional.ofNullable(name));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new AttachmentInvalidException(attachmentFile.toString(), e);
|
throw new AttachmentInvalidException(attachment, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||||
import org.whispersystems.signalservice.api.util.StreamDetails;
|
import org.whispersystems.signalservice.api.util.StreamDetails;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -17,6 +18,7 @@ import java.net.URLConnection;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -44,6 +46,29 @@ public class Utils {
|
||||||
return mime;
|
return mime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isBase64DataString(String[] parts) {
|
||||||
|
return parts.length == 2
|
||||||
|
&& parts[0].startsWith("data:")
|
||||||
|
&& parts[0].contains("/")
|
||||||
|
&& parts[1].startsWith("base64,");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isBase64DataString(String value) {
|
||||||
|
return isBase64DataString(value.split(";", 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StreamDetails createStreamDetailsFromBase64(String base64) {
|
||||||
|
final String[] parts = base64.split(";", 2);
|
||||||
|
if (!isBase64DataString(parts)) {
|
||||||
|
throw new IllegalArgumentException("The given argument is not a valid base64 string.");
|
||||||
|
}
|
||||||
|
|
||||||
|
parts[0] = parts[0].substring(5);
|
||||||
|
byte[] bytes = Base64.getDecoder().decode(parts[1].substring(7).getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
return new StreamDetails(new ByteArrayInputStream(bytes), parts[0], bytes.length);
|
||||||
|
}
|
||||||
|
|
||||||
public static StreamDetails createStreamDetailsFromFile(File file) throws IOException {
|
public static StreamDetails createStreamDetailsFromFile(File file) throws IOException {
|
||||||
InputStream stream = new FileInputStream(file);
|
InputStream stream = new FileInputStream(file);
|
||||||
final var size = file.length();
|
final var size = file.length();
|
||||||
|
@ -51,6 +76,14 @@ public class Utils {
|
||||||
return new StreamDetails(stream, mime, size);
|
return new StreamDetails(stream, mime, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static StreamDetails createStreamDetails(String value) throws IOException {
|
||||||
|
if (isBase64DataString(value)) {
|
||||||
|
return createStreamDetailsFromBase64(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return createStreamDetailsFromFile(new File(value));
|
||||||
|
}
|
||||||
|
|
||||||
public static Fingerprint computeSafetyNumber(
|
public static Fingerprint computeSafetyNumber(
|
||||||
boolean isUuidCapable,
|
boolean isUuidCapable,
|
||||||
SignalServiceAddress ownAddress,
|
SignalServiceAddress ownAddress,
|
||||||
|
|
|
@ -55,7 +55,9 @@ public class SendCommand implements JsonRpcLocalCommand {
|
||||||
mut.addArgument("--message-from-stdin")
|
mut.addArgument("--message-from-stdin")
|
||||||
.action(Arguments.storeTrue())
|
.action(Arguments.storeTrue())
|
||||||
.help("Read the message from standard input.");
|
.help("Read the message from standard input.");
|
||||||
subparser.addArgument("-a", "--attachment").nargs("*").help("Add file as attachment");
|
subparser.addArgument("-a", "--attachment").nargs("*").help("Add file as attachment."
|
||||||
|
+ "Base64 encoded attachments can be added and must follow the format "
|
||||||
|
+ "data:<MIME-TYPE>;base64,<BASE64 ENCODED DATA>.");
|
||||||
subparser.addArgument("-e", "--end-session", "--endsession")
|
subparser.addArgument("-e", "--end-session", "--endsession")
|
||||||
.help("Clear session state and send end session message.")
|
.help("Clear session state and send end session message.")
|
||||||
.action(Arguments.storeTrue());
|
.action(Arguments.storeTrue());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue