diff --git a/LICENCE b/LICENCE
new file mode 100644
index 0000000..07270af
--- /dev/null
+++ b/LICENCE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 brmlab
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..2ec1af7
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,13 @@
+version: '2'
+
+services:
+ wekanmailer:
+ image: malanius/wekan-mailer:latest
+ container_name: wekan-mailer
+ restart: always
+ environment:
+ - WEKAN_URL=http://localhost:3000
+ - WEKAN_USER=someuser
+ - WEKAN_PASSWORD=somepass
+ - WEKAN_TARGET_BOARD=someId
+ - WEKAN_TARGET_LIST=someListId
diff --git a/pom.xml b/pom.xml
index eb00fef..01690d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,6 +29,21 @@
spring-boot-starter-test
test
+
+
+ org.projectlombok
+ lombok
+ 1.18.2
+ provided
+
+
+
+ com.github.stefanbirkner
+ system-rules
+ 1.18.0
+ test
+
+
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..3274675
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,36 @@
+# Wekan mailer
+
+## About
+
+This is small application which provides email to board function for wekan.
+It is supposed to run in docker compose alongside [wekan+mongodb](https://github.com/wekan/wekan-mongodb), but may be used separately as it is Java based.
+**The application is currently WIP, use at your own risk!**
+
+## Functions
+
+- read emails from single SMTP server account
+- create card from received email on single wekan board in target list
+
+*Note: These are just starting functions, other may or may not be added later.*
+
+## Configuration
+
+The configuration is passed to the wekan-mailer trough environment variables simmilar to the approach in wekan+mongodb is compose used.
+
+### Wekan
+
+Required env vars are:
+
+- `WEKAN_URL`=http://localhost:3000
+- `WEKAN_USER`=someuser
+- `WEKAN_PASSWORD`=somepass
+- `WEKAN_TARGET_BOARD`=someId
+- `WEKAN_TARGET_LIST`=someListId
+
+```env
+WEKAN_URL=http://localhost:3000
+WEKAN_USER=someuser
+WEKAN_PASSWORD=somepass
+WEKAN_TARGET_BOARD=someId
+WEKAN_TARGET_LIST=someListId
+```
diff --git a/src/main/java/cz/brmlab/wekan/mailer/Application.java b/src/main/java/cz/brmlab/wekan/mailer/Application.java
deleted file mode 100644
index d4505bc..0000000
--- a/src/main/java/cz/brmlab/wekan/mailer/Application.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package cz.brmlab.wekan.mailer;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@SpringBootApplication
-@RestController
-public class Application {
-
- @RequestMapping("/")
- public String home() {
- return "Hello Docker World";
- }
-
- public static void main(String[] args) {
- SpringApplication.run(Application.class, args);
- System.out.println("Hello Docker World");
- }
-
-}
diff --git a/src/main/java/cz/brmlab/wm/Application.java b/src/main/java/cz/brmlab/wm/Application.java
new file mode 100644
index 0000000..04623d1
--- /dev/null
+++ b/src/main/java/cz/brmlab/wm/Application.java
@@ -0,0 +1,30 @@
+package cz.brmlab.wm;
+
+import cz.brmlab.wm.utils.Exceptions.BrmException;
+import cz.brmlab.wm.wekan.WekanConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application implements CommandLineRunner {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Application.class);
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+
+ @Override
+ public void run(String... args) {
+ try {
+ WekanConfiguration wekanConfiguration = new WekanConfiguration();
+
+ } catch (BrmException ex) {
+ System.exit(ex.getExitCode().getCode());
+ }
+ }
+}
diff --git a/src/main/java/cz/brmlab/wm/utils/Exceptions/BrmException.java b/src/main/java/cz/brmlab/wm/utils/Exceptions/BrmException.java
new file mode 100644
index 0000000..7dfa703
--- /dev/null
+++ b/src/main/java/cz/brmlab/wm/utils/Exceptions/BrmException.java
@@ -0,0 +1,9 @@
+package cz.brmlab.wm.utils.Exceptions;
+
+import lombok.Data;
+
+@Data
+public class BrmException extends Exception {
+ private final String message;
+ private final ExitCode exitCode;
+}
diff --git a/src/main/java/cz/brmlab/wm/utils/Exceptions/ExitCode.java b/src/main/java/cz/brmlab/wm/utils/Exceptions/ExitCode.java
new file mode 100644
index 0000000..fe95534
--- /dev/null
+++ b/src/main/java/cz/brmlab/wm/utils/Exceptions/ExitCode.java
@@ -0,0 +1,20 @@
+package cz.brmlab.wm.utils.Exceptions;
+
+import lombok.Getter;
+
+public enum ExitCode {
+
+ CONFIGURATION_MISSING(10, "Missing configuration property: ");
+
+ @Getter
+ private String reason;
+ @Getter
+ private int code;
+
+ ExitCode(int code, String reason) {
+ this.code = code;
+ this.reason = reason;
+ }
+
+
+}
diff --git a/src/main/java/cz/brmlab/wm/wekan/WekanConfiguration.java b/src/main/java/cz/brmlab/wm/wekan/WekanConfiguration.java
new file mode 100644
index 0000000..9d69546
--- /dev/null
+++ b/src/main/java/cz/brmlab/wm/wekan/WekanConfiguration.java
@@ -0,0 +1,74 @@
+package cz.brmlab.wm.wekan;
+
+import cz.brmlab.wm.utils.Exceptions.BrmException;
+import cz.brmlab.wm.utils.Exceptions.ExitCode;
+import lombok.Getter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class WekanConfiguration {
+
+ /**
+ * Class logger
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(WekanConfiguration.class);
+
+ //ENV variables for wekan
+ private static final String WEKAN_URL = "WEKAN_URL";
+ private static final String WEKAN_USER = "WEKAN_USER";
+ private static final String WEKAN_PASSWORD = "WEKAN_PASSWORD";
+ private static final String WEKAN_TARGET_BOARD = "WEKAN_TARGET_BOARD";
+ private static final String WEKAN_TARGET_LIST = "WEKAN_TARGET_LIST";
+
+ //List of wekan ENV vars
+ private static final List properties = new ArrayList<>(Arrays.asList(WEKAN_URL, WEKAN_USER, WEKAN_PASSWORD, WEKAN_TARGET_BOARD, WEKAN_TARGET_LIST));
+
+ /**
+ * Configuration for wekan. Taken from the container ENV variables.
+ *
+ * @throws BrmException if some of the properties is missing in ENV variables.
+ */
+ public WekanConfiguration() throws BrmException {
+ LOG.trace("{}() - start.", this.getClass().getSimpleName());
+
+ for (String prop : properties) {
+ checkProp(prop);
+ }
+ this.wekanUrl = System.getenv(WEKAN_URL);
+ this.wekanUser = System.getenv(WEKAN_USER);
+ this.wekanPassword = System.getenv(WEKAN_PASSWORD);
+ this.wekanBoard = System.getenv(WEKAN_TARGET_BOARD);
+ this.wekanList = System.getenv(WEKAN_TARGET_LIST);
+
+ LOG.info("Wekan config loaded successfully.");
+ }
+
+ @Getter
+ private String wekanUrl;
+
+ @Getter
+ private String wekanUser;
+
+ @Getter
+ private String wekanPassword;
+
+ @Getter
+ private String wekanBoard;
+
+ @Getter
+ private String wekanList;
+
+ private void checkProp(String prop) throws BrmException {
+ LOG.trace("checkProp({}) - start.", prop);
+
+ if (System.getenv(prop) == null) {
+ String message = ExitCode.CONFIGURATION_MISSING.getReason() + prop;
+ LOG.error(message, ExitCode.CONFIGURATION_MISSING);
+ throw new BrmException(message, ExitCode.CONFIGURATION_MISSING);
+ }
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644
index 0000000..03bc25b
--- /dev/null
+++ b/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+spring.main.web-application-type=none
+
+logging.level.root=INFO
+logging.level.cz.brmlab=TRACE
diff --git a/src/test/java/cz/brmlab/wm/wekan/WekanConfigurationTest.java b/src/test/java/cz/brmlab/wm/wekan/WekanConfigurationTest.java
new file mode 100644
index 0000000..2211dc9
--- /dev/null
+++ b/src/test/java/cz/brmlab/wm/wekan/WekanConfigurationTest.java
@@ -0,0 +1,92 @@
+package cz.brmlab.wm.wekan;
+
+import cz.brmlab.wm.utils.Exceptions.BrmException;
+import cz.brmlab.wm.utils.Exceptions.ExitCode;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.EnvironmentVariables;
+
+import static org.junit.Assert.*;
+
+public class WekanConfigurationTest {
+
+ @Rule
+ public final EnvironmentVariables environmentVariables
+ = new EnvironmentVariables();
+
+ private static final String WEKAN_URL = "WEKAN_URL";
+ private static final String WEKAN_URL_VALUE = "wekan.test.url";
+
+ private static final String WEKAN_USER = "WEKAN_USER";
+ private static final String WEKAN_USER_VALUE = "someuser";
+
+ private static final String WEKAN_PASSWORD = "WEKAN_PASSWORD";
+ private static final String WEKAN_PASSWORD_VALUE = "somepass";
+
+ private static final String WEKAN_TARGET_BOARD = "WEKAN_TARGET_BOARD";
+ private static final String WEKAN_TARGET_BOARD_VALUE = "someboardif";
+
+ private static final String WEKAN_TARGET_LIST = "WEKAN_TARGET_LIST";
+ private static final String WEKAN_TARGET_LIST_VALUE = "somelistid";
+
+
+ @After
+ public void cleanEnvVars() {
+ environmentVariables.clear(WEKAN_URL, WEKAN_USER, WEKAN_PASSWORD, WEKAN_TARGET_BOARD, WEKAN_TARGET_LIST);
+ }
+
+ @Test
+ public void configurationOk() {
+ environmentVariables.set(WEKAN_URL, WEKAN_URL_VALUE);
+ environmentVariables.set(WEKAN_USER, WEKAN_USER_VALUE);
+ environmentVariables.set(WEKAN_PASSWORD, WEKAN_PASSWORD_VALUE);
+ environmentVariables.set(WEKAN_TARGET_BOARD, WEKAN_TARGET_BOARD_VALUE);
+ environmentVariables.set(WEKAN_TARGET_LIST, WEKAN_TARGET_LIST_VALUE);
+
+
+ WekanConfiguration configuration = null;
+ try {
+ configuration = new WekanConfiguration();
+ } catch (BrmException e) {
+ fail("OK configuration should not throw an error!");
+ }
+ assertEquals(WEKAN_URL_VALUE, configuration.getWekanUrl());
+ assertEquals(WEKAN_USER_VALUE, configuration.getWekanUser());
+ assertEquals(WEKAN_PASSWORD_VALUE, configuration.getWekanPassword());
+ assertEquals(WEKAN_TARGET_BOARD_VALUE, configuration.getWekanBoard());
+ assertEquals(WEKAN_TARGET_LIST_VALUE, configuration.getWekanList());
+ }
+
+ @Test
+ public void allConfigurationMissing() {
+ WekanConfiguration configuration = null;
+ try {
+ configuration = new WekanConfiguration();
+ fail("Missing whole configuration should not throw an error!");
+ } catch (BrmException ignored) {
+
+ }
+ assertNull(null, configuration);
+ }
+
+ @Test
+ public void missingOneProp() {
+
+ environmentVariables.set(WEKAN_URL, WEKAN_URL_VALUE);
+ environmentVariables.set(WEKAN_USER, WEKAN_USER_VALUE);
+ //environmentVariables.set(WEKAN_PASSWORD, WEKAN_PASSWORD_VALUE);
+ environmentVariables.set(WEKAN_TARGET_BOARD, WEKAN_TARGET_BOARD_VALUE);
+ environmentVariables.set(WEKAN_TARGET_LIST, WEKAN_TARGET_LIST_VALUE);
+
+ WekanConfiguration configuration = null;
+ try {
+ configuration = new WekanConfiguration();
+ fail("Missing one property in configuration should not throw an error!");
+ } catch (BrmException ex) {
+ assertEquals(ExitCode.CONFIGURATION_MISSING.getReason() + WEKAN_PASSWORD, ex.getMessage());
+ }
+ assertNull(null, configuration);
+ }
+}
+