From c5c3720f80fdecb62fad38b188fc9e040d282453 Mon Sep 17 00:00:00 2001 From: infra <77526490+i-infra@users.noreply.github.com> Date: Tue, 27 Apr 2021 11:50:36 -0400 Subject: [PATCH 1/3] Enables reproducible builds by disabling timestamps and enabling reproducible build order in archive outputs. (#607) Co-authored-by: infra --- build.gradle.kts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 55d95145..69e40c01 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -35,6 +35,12 @@ configurations { } } + +tasks.withType().configureEach { + isPreserveFileTimestamps = false + isReproducibleFileOrder = true +} + tasks.withType { options.encoding = "UTF-8" } From ee99815918afd4d8df741cd018bd83f6514c8b03 Mon Sep 17 00:00:00 2001 From: infra Date: Wed, 28 Apr 2021 00:54:05 -0400 Subject: [PATCH 2/3] Rebased and squashed (the ugly way) version of @technillogue's stdio. Re #396 --- .../org/asamk/signal/commands/Commands.java | 1 + .../asamk/signal/commands/StdioCommand.java | 122 ++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 src/main/java/org/asamk/signal/commands/StdioCommand.java diff --git a/src/main/java/org/asamk/signal/commands/Commands.java b/src/main/java/org/asamk/signal/commands/Commands.java index 830049a5..4a8c70f4 100644 --- a/src/main/java/org/asamk/signal/commands/Commands.java +++ b/src/main/java/org/asamk/signal/commands/Commands.java @@ -11,6 +11,7 @@ public class Commands { addCommand("addDevice", new AddDeviceCommand()); addCommand("block", new BlockCommand()); addCommand("daemon", new DaemonCommand()); + addCommand("stdio", new StdioCommand()); addCommand("getUserStatus", new GetUserStatusCommand()); addCommand("link", new LinkCommand()); addCommand("listContacts", new ListContactsCommand()); diff --git a/src/main/java/org/asamk/signal/commands/StdioCommand.java b/src/main/java/org/asamk/signal/commands/StdioCommand.java new file mode 100644 index 00000000..dcdc2287 --- /dev/null +++ b/src/main/java/org/asamk/signal/commands/StdioCommand.java @@ -0,0 +1,122 @@ +package org.asamk.signal.commands; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import net.sourceforge.argparse4j.impl.Arguments; +import net.sourceforge.argparse4j.inf.Namespace; +import net.sourceforge.argparse4j.inf.Subparser; + +import org.asamk.signal.JsonReceiveMessageHandler; +import org.asamk.signal.ReceiveMessageHandler; +import org.asamk.signal.manager.AttachmentInvalidException; +import org.asamk.signal.manager.Manager; +import org.whispersystems.signalservice.api.push.exceptions.EncapsulatedExceptions; +import org.whispersystems.signalservice.api.util.InvalidNumberException; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static org.asamk.signal.util.ErrorUtils.handleAssertionError; + +class JsonInterface { + + public String commandName; + public String recipient; + public String content; + public JsonNode details; +} + +class InputReader implements Runnable { + + private volatile boolean alive = true; + private final Manager m; + + InputReader(final Manager m) { + this.m = m; + } + + public void terminate() { + this.alive = false; + } + + @Override + public void run() { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + ObjectMapper jsonProcessor = new ObjectMapper(); + while (alive) { + try { + String in = br.readLine(); + if (in != null) { + JsonInterface command = jsonProcessor.readValue(in, JsonInterface.class); + if (command.commandName.equals("sendMessage")) { + List recipients = new ArrayList(); + recipients.add(command.recipient); + List attachments = new ArrayList<>(); + if (command.details != null && command.details.has("attachments")) { + command.details.get("attachments").forEach(attachment -> { + if (attachment.isTextual()) { + attachments.add(attachment.asText()); + } + }); + } + try { + // verbosity flag? better yet, json acknowledgement with timestamp or message id? + System.out.println("sentMessage '" + command.content + "' to " + command.recipient); + this.m.sendMessage(command.content, attachments, recipients); + } catch (AssertionError | AttachmentInvalidException | InvalidNumberException e) { + System.err.println("error in sending message"); + e.printStackTrace(System.out); + } + } /* elif (command.commandName == "sendTyping") { + getMessageSender().sendTyping(signalServiceAddress?, ....) + }*/ + } + + } catch (IOException e) { + System.err.println(e); + alive = false; + } + + } + } +} + +public class StdioCommand implements LocalCommand { + + @Override + public void attachToSubparser(final Subparser subparser) { + subparser.addArgument("--ignore-attachments") + .help("Don’t download attachments of received messages.") + .action(Arguments.storeTrue()); + subparser.addArgument("--json") // should maybe remove this + .help("Output received messages in json format, one json object per line.") + .action(Arguments.storeTrue()); + } + + @Override + public void handleCommand(final Namespace ns, final Manager m) { + boolean ignoreAttachments = ns.getBoolean("ignore_attachments"); + InputReader reader = new InputReader(m); + Thread readerThread = new Thread(reader); + readerThread.start(); + try { + m.receiveMessages(1, + TimeUnit.HOURS, + false, + ignoreAttachments, + ns.getBoolean("json") ? new JsonReceiveMessageHandler(m) : new ReceiveMessageHandler(m) + /*true*/); + } catch (IOException e) { + System.err.println("Error while receiving messages: " + e.getMessage()); + } catch (AssertionError e) { + handleAssertionError(e); + } finally { + reader.terminate(); + } + } +} From 9d3dc8f7350e1d36367ef20e53e6235daf65b475 Mon Sep 17 00:00:00 2001 From: infra Date: Wed, 28 Apr 2021 01:15:53 -0400 Subject: [PATCH 3/3] Cleanups and proper logging. --- .../asamk/signal/commands/StdioCommand.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/asamk/signal/commands/StdioCommand.java b/src/main/java/org/asamk/signal/commands/StdioCommand.java index dcdc2287..278e67fa 100644 --- a/src/main/java/org/asamk/signal/commands/StdioCommand.java +++ b/src/main/java/org/asamk/signal/commands/StdioCommand.java @@ -8,9 +8,13 @@ import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Subparser; import org.asamk.signal.JsonReceiveMessageHandler; +import org.asamk.signal.JsonWriter; +import org.asamk.signal.OutputType; import org.asamk.signal.ReceiveMessageHandler; import org.asamk.signal.manager.AttachmentInvalidException; import org.asamk.signal.manager.Manager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.whispersystems.signalservice.api.push.exceptions.EncapsulatedExceptions; import org.whispersystems.signalservice.api.util.InvalidNumberException; @@ -19,6 +23,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.concurrent.TimeUnit; import static org.asamk.signal.util.ErrorUtils.handleAssertionError; @@ -32,6 +37,7 @@ class JsonInterface { } class InputReader implements Runnable { + private final static Logger logger = LoggerFactory.getLogger(InputReader.class); private volatile boolean alive = true; private final Manager m; @@ -66,11 +72,11 @@ class InputReader implements Runnable { } try { // verbosity flag? better yet, json acknowledgement with timestamp or message id? - System.out.println("sentMessage '" + command.content + "' to " + command.recipient); this.m.sendMessage(command.content, attachments, recipients); + logger.info("sentMessage '" + command.content + "' to " + command.recipient); } catch (AssertionError | AttachmentInvalidException | InvalidNumberException e) { - System.err.println("error in sending message"); - e.printStackTrace(System.out); + logger.error("Error in sending message", e); + logger.error(e.getMessage(), e); } } /* elif (command.commandName == "sendTyping") { getMessageSender().sendTyping(signalServiceAddress?, ....) @@ -87,19 +93,26 @@ class InputReader implements Runnable { } public class StdioCommand implements LocalCommand { + private final static Logger logger = LoggerFactory.getLogger(StdioCommand.class); @Override public void attachToSubparser(final Subparser subparser) { subparser.addArgument("--ignore-attachments") .help("Don’t download attachments of received messages.") .action(Arguments.storeTrue()); - subparser.addArgument("--json") // should maybe remove this - .help("Output received messages in json format, one json object per line.") + subparser.addArgument("--json") + .help("WARNING: This parameter is now deprecated! Please use the global \"--output=json\" option instead.\n\nOutput received messages in json format, one json object per line.") .action(Arguments.storeTrue()); } + @Override + public Set getSupportedOutputTypes() { + return Set.of(OutputType.PLAIN_TEXT, OutputType.JSON); + } + @Override public void handleCommand(final Namespace ns, final Manager m) { + var inJson = ns.get("output") == OutputType.JSON || ns.getBoolean("json"); boolean ignoreAttachments = ns.getBoolean("ignore_attachments"); InputReader reader = new InputReader(m); Thread readerThread = new Thread(reader); @@ -109,7 +122,7 @@ public class StdioCommand implements LocalCommand { TimeUnit.HOURS, false, ignoreAttachments, - ns.getBoolean("json") ? new JsonReceiveMessageHandler(m) : new ReceiveMessageHandler(m) + inJson ? new JsonReceiveMessageHandler(m) : new ReceiveMessageHandler(m) /*true*/); } catch (IOException e) { System.err.println("Error while receiving messages: " + e.getMessage());