Skip to content

Commit

Permalink
add config file
Browse files Browse the repository at this point in the history
  • Loading branch information
kevodwyer committed Sep 3, 2021
1 parent 9e9177c commit 08102d1
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 15 deletions.
62 changes: 50 additions & 12 deletions src/peergos/email/EmailBridge.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import peergos.shared.user.UserContext;
import peergos.shared.util.Futures;

import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -78,11 +80,37 @@ private static Map<String, Map<String, String>> readEmailAccountFile(Path emailA
return accounts;
}

public void start(Path emailAccountsFilePath) {
private static Properties readConfigFile(Path emailBridgeConfigFilePath) {
Properties props = new Properties();
if (! emailBridgeConfigFilePath.toFile().exists())
return props;
try (FileReader fr = new FileReader(emailBridgeConfigFilePath.toFile())){
props.load(fr);
List<String> fields = Arrays.asList("sendIntervalSeconds", "receiveInitialDelaySeconds", "receiveIntervalSeconds", "maxNumberOfUnreadEmails");
for(String field : fields) {
if (!props.containsKey(field)) {
System.err.println("Field:" + field + " not found");
throw new IllegalStateException("Email-Bridge config file invalid");
}
try {
Integer.parseInt(props.getProperty(field));
} catch (NumberFormatException ioe) {
System.err.println("Field:" + field + " value not valid");
throw new IllegalStateException("Email-Bridge config file value for " + field + " is invalid");
}
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
return props;
}

public void start(Path configFilePath, Path emailAccountsFilePath) {
Properties config = readConfigFile(configFilePath);

SendTask send = new SendTask(emailAccountsFilePath);
SendTask send = new SendTask(config, emailAccountsFilePath);
//send.run();
ReceiveTask receive = new ReceiveTask(emailAccountsFilePath);
ReceiveTask receive = new ReceiveTask(config, emailAccountsFilePath);
//receive.run();

Function<Void, Void> shutdownRequest = s -> {
Expand All @@ -97,8 +125,9 @@ public void start(Path emailAccountsFilePath) {
}));

ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
executor.scheduleAtFixedRate(send, 0L, 30, TimeUnit.SECONDS);
executor.scheduleAtFixedRate(receive, 30L, 30, TimeUnit.SECONDS);
executor.scheduleAtFixedRate(send, 0L, Integer.parseInt(config.getProperty("sendIntervalSeconds")), TimeUnit.SECONDS);
executor.scheduleAtFixedRate(receive, Integer.parseInt(config.getProperty("receiveInitialDelaySeconds")),
Integer.parseInt(config.getProperty("receiveIntervalSeconds")), TimeUnit.SECONDS);
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {
Expand All @@ -108,10 +137,19 @@ public void start(Path emailAccountsFilePath) {
}

abstract class Task implements Runnable {
protected final Path pathToAccountsFile;
protected final Properties config;

protected volatile CompletableFuture<Boolean> shutdownFuture = Futures.incomplete();
protected volatile boolean shutdownRequested = false;
protected volatile boolean running = false;

public Task(Properties config, Path pathToAccountsFile) {
this.config = config;
this.pathToAccountsFile = pathToAccountsFile;
}
public abstract void run();

public CompletableFuture<Boolean> requestShutdown() {
shutdownRequested = true;
if (!running) {
Expand All @@ -122,9 +160,8 @@ public CompletableFuture<Boolean> requestShutdown() {
}

class SendTask extends Task {
private final Path pathToAccountsFile;
public SendTask(Path pathToAccountsFile) {
this.pathToAccountsFile = pathToAccountsFile;
public SendTask(Properties config, Path pathToAccountsFile) {
super(config, pathToAccountsFile);
}
@Override
public void run() {
Expand All @@ -134,6 +171,7 @@ public void run() {
}
running = true;
sender.refresh();

Map<String, Map<String, String>> accounts = readEmailAccountFile(pathToAccountsFile);
System.out.println(LocalDateTime.now() + " Running Task SendTask. Accounts: " + accounts.size());
int delayMs = defaultDelayOnFailureMs;
Expand All @@ -160,11 +198,10 @@ public void run() {
}
}
class ReceiveTask extends Task {
private final Path pathToAccountsFile;
private final Random random = new Random();

public ReceiveTask(Path pathToAccountsFile) {
this.pathToAccountsFile = pathToAccountsFile;
public ReceiveTask(Properties config, Path pathToAccountsFile) {
super(config, pathToAccountsFile);
}
@Override
public void run() {
Expand All @@ -183,8 +220,9 @@ public void run() {
Supplier<String> messageIdSupplier = () -> "<" + Math.abs(random.nextInt(Integer.MAX_VALUE - 1))
+ "." + Math.abs(random.nextInt(Integer.MAX_VALUE - 1)) + "@" + domain + ">";
Map<String, String> props = entry.getValue();
int maxNumberOfUnreadEmails = Integer.parseInt(config.getProperty("maxNumberOfUnreadEmails"));
boolean ok = retriever.retrieveEmailsFromServer(props.get("username"), props.get("emailAddress"),
messageIdSupplier, props.get("imapUsername"), props.get("imapPassword"));
messageIdSupplier, props.get("imapUsername"), props.get("imapPassword"), maxNumberOfUnreadEmails);
if (ok) {
delayMs = defaultDelayOnFailureMs;
} else {
Expand Down
12 changes: 11 additions & 1 deletion src/peergos/email/EmailRetriever.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import peergos.shared.email.Attachment;
import peergos.shared.email.EmailMessage;
import peergos.shared.user.UserContext;
import peergos.shared.user.fs.FileWrapper;
import peergos.shared.util.Pair;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

public class EmailRetriever extends EmailTask {
private final IMAPClient imapClient;
Expand All @@ -21,12 +23,20 @@ public EmailRetriever(IMAPClient imapClient, UserContext context) {
}

public boolean retrieveEmailsFromServer(String peergosUsername, String emailAddress, Supplier<String> messageIdSupplier,
String imapUserame, String imapPassword) {
String imapUserame, String imapPassword, int maxNumberOfUnreadEmails) {

EmailBridgeClient bridge = buildEmailBridgeClient(context, peergosUsername, emailAddress);
if (bridge == null) {
return true;// user not setup yet
}
String inboxPath = peergosUsername + "/.apps/email/data/default/pending/inbox";
FileWrapper directory = context.getByPath(inboxPath).join().get();
Set<FileWrapper> unreadEmails = directory.getChildren(context.crypto.hasher, context.network).join()
.stream().filter(f -> !f.isDirectory()).collect(Collectors.toSet());
if (unreadEmails.size() > maxNumberOfUnreadEmails) {
System.err.println("Skipping user: " + peergosUsername + " due to excess unread emails");
return true;
}
Function<MimeMessage, Boolean> upload = (msg) -> {
Pair<EmailMessage, List<RawAttachment>> emailPackage = EmailConverter.parseMail(msg, messageIdSupplier);
List<Attachment> attachments = new ArrayList<>();
Expand Down
15 changes: 14 additions & 1 deletion src/peergos/email/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public class Main {
public static final Path DEFAULT_PEERGOS_DIR_PATH =
Paths.get(System.getProperty("user.home"), ".email-bridge");
private static final String EMAIL_ACCOUNTS_CONFIG_FILENAME = "accounts.json";
private static final String EMAIL_BRIDGE_CONFIG_FILENAME = "config.txt";
private static final Path emailAccountsFilePath = DEFAULT_PEERGOS_DIR_PATH.resolve(EMAIL_ACCOUNTS_CONFIG_FILENAME);
private static final Path configFilePath = DEFAULT_PEERGOS_DIR_PATH.resolve(EMAIL_BRIDGE_CONFIG_FILENAME);

public static Command<Boolean> EMAIL_BRIDGE = new Command<>("Run EmailBridge",
"Run EmailBridge",
Expand Down Expand Up @@ -52,9 +54,20 @@ public class Main {
java -jar EmailBridge.jar -username blah -password qwerty -peergos-url http://localhost:8000 -is-public-server false -smtp-host smtpHost -smtp-port 1 -imap-host imapHost -imap-port 1
example accounts.json contents:
[{ "username": "test", "emailAddress": "", "smtpUsername": "", "smtpPassword": "", "imapUsername": "", "imapPassword": ""}]
example config.txt contents:
sendIntervalSeconds: 30
receiveInitialDelaySeconds: 30
receiveIntervalSeconds: 30
maxNumberOfUnreadEmails: 100
*/
public static void main(String[] args) {
System.out.println("starting EmailBridge");
if (! configFilePath.toFile().exists()) {
System.err.println("Email-Bridge config file does not exist. expected path:" + configFilePath);
System.exit(1);
} else {
System.out.println("Using Email-Bridge config file at path:" + configFilePath);
}
if (! emailAccountsFilePath.toFile().exists()) {
System.err.println("Email account file does not exist. expected path:" + emailAccountsFilePath);
System.exit(1);
Expand All @@ -63,7 +76,7 @@ public static void main(String[] args) {
}
EMAIL_BRIDGE.main(Args.parse(args));
if (emailBridge != null) {
emailBridge.start(emailAccountsFilePath);
emailBridge.start(configFilePath, emailAccountsFilePath);
}
}
}
3 changes: 2 additions & 1 deletion src/peergos/email/tests/MockTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ public void retrieveEmails(String username, String password, Function<MimeMessag
uploadFunc.apply(mimeMessage);
}
}, emailBridgeContext);
retriever.retrieveEmailsFromServer(userContext.username, emailAddress, messageIdSupplier, "imapUsername", "imapPwd");
retriever.retrieveEmailsFromServer(userContext.username, emailAddress, messageIdSupplier,
"imapUsername", "imapPwd", 100);

App emailApp = App.init(userContext, "email").join();
EmailClient client = EmailClient.load(emailApp, crypto).join();
Expand Down

0 comments on commit 08102d1

Please sign in to comment.