Browse code

port from jb3

devnewton authored on 08/06/2017 16:25:35
Showing 17 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,25 @@
1
+FROM openjdk:8
2
+
3
+# Update apt
4
+RUN apt-get update
5
+
6
+# Install maven
7
+RUN apt-get install -y maven
8
+
9
+# Set correct java version
10
+RUN update-java-alternatives -s java-1.8.0-openjdk-amd64
11
+
12
+WORKDIR /code
13
+
14
+# Prepare by downloading dependencies
15
+ADD pom.xml /code/pom.xml
16
+RUN ["mvn", "dependency:resolve"]
17
+RUN ["mvn", "verify"]
18
+
19
+# Adding source, compile and package into a fat jar
20
+ADD src /code/src
21
+RUN ["mvn", "package"]
22
+
23
+EXPOSE 27017
24
+EXPOSE 8080
25
+ENTRYPOINT java -jar target/sara-1.0-SNAPSHOT.jar
0 26
\ No newline at end of file
1 27
new file mode 100644
... ...
@@ -0,0 +1,3 @@
1
+# sara
2
+
3
+Sara is a java bot with web based IA.
0 4
\ No newline at end of file
1 5
new file mode 100644
... ...
@@ -0,0 +1,103 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
+    <modelVersion>4.0.0</modelVersion>
4
+    <parent>
5
+        <groupId>org.springframework.boot</groupId>
6
+        <artifactId>spring-boot-starter-parent</artifactId>
7
+        <version>1.5.1.RELEASE</version>
8
+    </parent>
9
+    <artifactId>sara</artifactId>
10
+    <groupId>im.bci</groupId>
11
+    <name>sara</name>
12
+    <description>Java highly scalable tribune</description>
13
+    <version>1.1-SNAPSHOT</version>
14
+    <url>http://devnewton.bci.im</url>
15
+    <properties>
16
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
18
+    </properties>
19
+    <dependencies>
20
+        <dependency>
21
+            <groupId>org.springframework.boot</groupId>
22
+            <artifactId>spring-boot-starter</artifactId>
23
+        </dependency>
24
+        <dependency>
25
+            <groupId>org.springframework.boot</groupId>
26
+            <artifactId>spring-boot-starter-web</artifactId>
27
+        </dependency>
28
+        <dependency>
29
+            <groupId>org.apache.commons</groupId>
30
+            <artifactId>commons-lang3</artifactId>
31
+            <version>3.5</version>
32
+        </dependency>
33
+        <dependency>
34
+            <groupId>org.jsoup</groupId>
35
+            <artifactId>jsoup</artifactId>
36
+            <version>1.10.2</version>
37
+        </dependency>
38
+    </dependencies>
39
+    <build>
40
+        <resources>
41
+            <resource>
42
+                <directory>src/main/resources</directory>
43
+                <filtering>false</filtering>
44
+                <includes>
45
+                    <include>**/*.html</include>
46
+                    <include>**/*.properties</include>
47
+                    <include>**/*.js</include>
48
+                    <include>**/*.tag</include>
49
+                    <include>**/*.css</include>
50
+                    <include>**/*.png</include>
51
+                    <include>**/*.svg</include>
52
+                </includes>
53
+            </resource>
54
+        </resources>
55
+        <plugins>
56
+            <plugin>
57
+                <groupId>org.springframework.boot</groupId>
58
+                <artifactId>spring-boot-maven-plugin</artifactId>
59
+                <configuration>
60
+                    <mainClass>im.bci.sara.SaraApplication</mainClass>
61
+                </configuration>
62
+            </plugin>
63
+            <plugin>
64
+                <artifactId>maven-compiler-plugin</artifactId>
65
+                <configuration>
66
+                    <source>1.8</source>
67
+                    <target>1.8</target>
68
+                </configuration>
69
+            </plugin>
70
+            <plugin>
71
+                <groupId>org.apache.maven.plugins</groupId>
72
+                <artifactId>maven-release-plugin</artifactId>
73
+                <version>2.5.3</version>
74
+            </plugin>
75
+            <!-- <plugin>
76
+                <groupId>ro.isdc.wro4j</groupId>
77
+                <artifactId>wro4j-maven-plugin</artifactId>
78
+                <version>1.8.0</version>
79
+                <executions>
80
+                    <execution>
81
+                        <id>generate-resources</id>
82
+                        <phase>generate-resources</phase>
83
+                        <configuration>
84
+                            <cssDestinationFolder>${project.build.directory}/classes/static/wro</cssDestinationFolder>
85
+                            <jsDestinationFolder>${project.build.directory}/classes/static/wro</jsDestinationFolder>
86
+                            <contextFolder>${basedir}/src/main/resources/static</contextFolder>
87
+                            <wroFile>${basedir}/src/main/resources/wro/wro.xml</wroFile>
88
+                            <extraConfigFile>${basedir}/src/main/resources/wro/wro.properties</extraConfigFile>
89
+                            <ignoreMissingResources>false</ignoreMissingResources>
90
+                        </configuration>
91
+                        <goals>
92
+                            <goal>run</goal>
93
+                        </goals>
94
+                    </execution>
95
+                </executions>
96
+            </plugin> -->
97
+        </plugins>
98
+    </build>
99
+    <scm>
100
+        <developerConnection>scm:git:https://github.com/devnewton/sara</developerConnection>
101
+        <tag>HEAD</tag>
102
+    </scm>
103
+</project>
0 104
new file mode 100644
... ...
@@ -0,0 +1,38 @@
1
+package im.bci.sara;
2
+
3
+import java.util.regex.Pattern;
4
+import org.apache.commons.lang3.StringUtils;
5
+import org.apache.commons.logging.LogFactory;
6
+import org.jsoup.Jsoup;
7
+import org.jsoup.nodes.Document;
8
+import org.springframework.stereotype.Component;
9
+
10
+/**
11
+ *
12
+ * @author devnewton
13
+ */
14
+@Component
15
+public class AvenirEnCommun implements SaraAction {
16
+
17
+    private static final Pattern PHI = Pattern.compile("\\b(jlm|jean\\sluc|((m[ée]l([ea]n|u))|holo)ch?(on|e)|avenir\\sen\\scommun|phi|france\\sinsoumise?|φ)\\b", Pattern.CASE_INSENSITIVE);
18
+
19
+    @Override
20
+    public MatchLevel match(Post post) {
21
+        return PHI.matcher(post.getMessage()).find() ? MatchLevel.MUST : MatchLevel.NO;
22
+    }
23
+
24
+    @Override
25
+    public String reply(Post post) {
26
+        try {
27
+            Document doc = Jsoup.connect("https://laec.fr/hasard").get();
28
+            String sujet = doc.select("#contenu .subject-foreword").text();
29
+            if (StringUtils.isNotBlank(sujet)) {
30
+                return sujet;
31
+            }
32
+        } catch (Exception ex) {
33
+            LogFactory.getLog(this.getClass()).error("avenir en commun error", ex);
34
+        }
35
+        return null;
36
+    }
37
+
38
+}
0 39
new file mode 100644
... ...
@@ -0,0 +1,37 @@
1
+package im.bci.sara;
2
+
3
+import java.util.regex.Pattern;
4
+import org.apache.commons.logging.LogFactory;
5
+import org.jsoup.Jsoup;
6
+import org.jsoup.nodes.Document;
7
+import org.jsoup.nodes.Document.OutputSettings;
8
+import org.jsoup.safety.Whitelist;
9
+import org.springframework.stereotype.Component;
10
+
11
+@Component
12
+public class Blague implements SaraAction {
13
+
14
+    private static final int MAX_BLAGUE_LINES = 42;
15
+
16
+    private static final Pattern BLAGUE = Pattern.compile("\\b(blague?s?|humours?|rires?)\\b", Pattern.CASE_INSENSITIVE);
17
+
18
+    @Override
19
+    public MatchLevel match(Post post) {
20
+        return BLAGUE.matcher(post.getMessage()).find() ? MatchLevel.MUST : MatchLevel.NO;
21
+    }
22
+
23
+    @Override
24
+    public String reply(Post post) {
25
+        try {
26
+            Document doc = Jsoup.connect("http://www.blague.org/").get();
27
+            doc.select("#humour h1").remove();
28
+            String blague = Jsoup.clean(doc.select("#humour").first().html(), "", Whitelist.none(),
29
+                    new OutputSettings().prettyPrint(false));
30
+            return blague;
31
+        } catch (Exception ex) {
32
+            LogFactory.getLog(this.getClass()).error("blague error", ex);
33
+        }
34
+        return null;
35
+    }
36
+
37
+}
0 38
new file mode 100644
... ...
@@ -0,0 +1,42 @@
1
+package im.bci.sara;
2
+
3
+import java.io.IOException;
4
+import java.util.regex.Pattern;
5
+import org.apache.commons.lang3.StringUtils;
6
+import org.apache.commons.logging.LogFactory;
7
+import org.jsoup.Jsoup;
8
+import org.jsoup.nodes.Document;
9
+import org.springframework.stereotype.Component;
10
+import org.springframework.web.util.UriComponentsBuilder;
11
+
12
+/**
13
+ *
14
+ * @author devnewton
15
+ */
16
+@Component
17
+public class Boobpedia implements SaraAction {
18
+
19
+    private static final Pattern BOOB = Pattern.compile("\\b(boob?s?|seins?|nichons?|poitrines?)\\b", Pattern.CASE_INSENSITIVE);
20
+
21
+    @Override
22
+    public MatchLevel match(Post post) {
23
+        return BOOB.matcher(post.getMessage()).find() ? MatchLevel.MUST : MatchLevel.NO;
24
+    }
25
+
26
+    @Override
27
+    public String reply(Post post) {
28
+        try {
29
+            Document doc = Jsoup.connect("http://www.boobpedia.com/boobs/Special:Random").timeout(30000).get();
30
+            String boobText = doc.select("#mw-content-text > p:nth-child(2)").text();
31
+            String boobImageSrc = doc.select(".image > img:nth-child(1)").attr("src");
32
+            String boobURI = UriComponentsBuilder.fromUriString("http://www.boobpedia.com").path(boobImageSrc).build().encode().toString();
33
+            if (StringUtils.isNoneBlank(boobText) && StringUtils.isNoneBlank(boobURI)) {
34
+                return boobText + " " + boobURI;
35
+            }
36
+        } catch (IOException ex) {
37
+            LogFactory.getLog(this.getClass()).error("boobpedia error", ex);
38
+        }
39
+        return null;
40
+    }
41
+
42
+}
0 43
new file mode 100644
... ...
@@ -0,0 +1,58 @@
1
+package im.bci.sara;
2
+
3
+import java.io.IOException;
4
+import java.util.Random;
5
+import java.util.regex.Matcher;
6
+import java.util.regex.Pattern;
7
+
8
+import org.apache.commons.lang3.StringUtils;
9
+import org.apache.commons.logging.LogFactory;
10
+import org.jsoup.Connection;
11
+import org.jsoup.Jsoup;
12
+import org.jsoup.nodes.Document;
13
+import org.jsoup.nodes.Element;
14
+import org.jsoup.safety.Whitelist;
15
+import org.jsoup.select.Elements;
16
+import org.springframework.stereotype.Component;
17
+
18
+@Component
19
+public class Define implements SaraAction {
20
+
21
+    private static final Pattern DEFINE_PATTERN = Pattern.compile("^.*(define|what('s|\\sis))\\s*(?<word>.*)$");
22
+    
23
+    private final Random random = new Random();
24
+
25
+    @Override
26
+    public MatchLevel match(Post post) {
27
+        return DEFINE_PATTERN.matcher(post.getMessage()).find() ? MatchLevel.MUST : MatchLevel.CAN;
28
+    }
29
+
30
+    @Override
31
+    public String reply(Post post) {
32
+        try {
33
+            Matcher matcher = DEFINE_PATTERN.matcher(post.getMessage());
34
+            if (matcher.matches()) {
35
+                return postDefinition(matcher.group("word"), post);
36
+            }
37
+        } catch (Exception ex) {
38
+            LogFactory.getLog(this.getClass()).error("define error", ex);
39
+        }
40
+        return null;
41
+    }
42
+
43
+    private String postDefinition(String word, Post post) throws IOException {
44
+        Connection connection = Jsoup.connect("https://www.urbandictionary.com/define.php");
45
+        if(StringUtils.isNotBlank(word)) {
46
+            connection.data("term", word);
47
+        }
48
+        Document doc = connection.get();
49
+        Elements definitions = doc.select(".def-panel");
50
+        if(definitions.isEmpty()) {
51
+            return null;
52
+        }
53
+        Element definition = definitions.get(random.nextInt(definitions.size()));
54
+        String text = definition.select(".word").text() + " " + definition.select(".meaning").text();
55
+        String cleanedText = Jsoup.clean(text, Whitelist.none().addTags("a").addAttributes("a", "href"));
56
+        return cleanedText;
57
+    }
58
+}
0 59
new file mode 100644
... ...
@@ -0,0 +1,39 @@
1
+package im.bci.sara;
2
+
3
+import java.io.IOException;
4
+import java.util.regex.Pattern;
5
+import org.apache.commons.lang3.StringUtils;
6
+import org.apache.commons.logging.LogFactory;
7
+import org.jsoup.Jsoup;
8
+import org.jsoup.nodes.Document;
9
+import org.springframework.stereotype.Component;
10
+
11
+/**
12
+ *
13
+ * @author devnewton
14
+ */
15
+@Component
16
+public class JourneeMondiale implements SaraAction {
17
+
18
+    private static final Pattern JOURNEE = Pattern.compile("\\b(journées?|jours?|aujourd)\\b", Pattern.CASE_INSENSITIVE);
19
+
20
+    @Override
21
+    public MatchLevel match(Post post) {
22
+        return JOURNEE.matcher(post.getMessage()).find() ? MatchLevel.MUST : MatchLevel.CAN;
23
+    }
24
+
25
+    @Override
26
+    public String reply(Post post) {
27
+        try {
28
+            Document doc = Jsoup.connect("http://www.journee-mondiale.com/").get();
29
+            String journee = doc.select("#journeesDuJour > article:nth-child(1) > a:nth-child(1) > h2:nth-child(2)").text();
30
+            if (StringUtils.isNotBlank(journee)) {
31
+                return "Aujourd'hui, c'est la " + journee + ". Hihi!";
32
+            }
33
+        } catch (IOException ex) {
34
+            LogFactory.getLog(this.getClass()).error("journee mondiale error", ex);
35
+        }
36
+        return null;
37
+    }
38
+
39
+}
0 40
new file mode 100644
... ...
@@ -0,0 +1,82 @@
1
+package im.bci.sara;
2
+
3
+import java.io.IOException;
4
+import java.util.regex.Matcher;
5
+import java.util.regex.Pattern;
6
+
7
+import org.apache.commons.lang3.StringUtils;
8
+import org.apache.commons.logging.LogFactory;
9
+import org.jsoup.Jsoup;
10
+import org.jsoup.nodes.Document;
11
+import org.jsoup.safety.Whitelist;
12
+import org.springframework.beans.factory.annotation.Value;
13
+import org.springframework.stereotype.Component;
14
+
15
+@Component
16
+public class Meteo implements SaraAction {
17
+
18
+    private static final String NAME = "meteo";
19
+
20
+    private static final Pattern METEO_PATTERN = Pattern.compile("^.*m[eé]t[eé]o\\s*à?\\s*(?<lieu>.*)$");
21
+
22
+    @Value("${sara.meteo.openweathermap.api.key:}")
23
+    private String openWeatherMapApiKey;
24
+
25
+    @Override
26
+    public MatchLevel match(Post post) {
27
+        return METEO_PATTERN.matcher(post.getMessage()).find() ? MatchLevel.MUST : MatchLevel.NO;
28
+    }
29
+
30
+    @Override
31
+    public String reply(Post post) {
32
+        try {
33
+            Matcher matcher = METEO_PATTERN.matcher(post.getMessage());
34
+            if (matcher.matches()) {
35
+                return postMeteo(matcher.group("lieu"), post);
36
+            }
37
+        } catch (Exception ex) {
38
+            LogFactory.getLog(this.getClass()).error("meteo error", ex);
39
+        }
40
+        return null;
41
+    }
42
+
43
+    private String postMeteo(String lieu, Post post) throws IOException {
44
+        if (StringUtils.isBlank(lieu)) {
45
+            lieu = "Nice";
46
+        }
47
+        String meteo = meteoFrance(lieu);
48
+        if (StringUtils.isBlank(meteo)) {
49
+            meteo = openWeatherMap(lieu);
50
+        }
51
+        if (StringUtils.isNotBlank(meteo)) {
52
+            return meteo;
53
+        } else {
54
+            return null;
55
+        }
56
+    }
57
+
58
+    private String openWeatherMap(String lieu) throws IOException {
59
+        try {
60
+            if (StringUtils.isNotBlank(openWeatherMapApiKey)) {
61
+                Document doc = Jsoup.connect("http://api.openweathermap.org/data/2.5/weather").data("q", lieu)
62
+                        .data("mode", "html").data("lang", "fr").data("appid", openWeatherMapApiKey).get();
63
+                return Jsoup.clean(doc.html(), Whitelist.none().addTags("a").addAttributes("a", "href"));
64
+            }
65
+            return null;
66
+        } catch (Exception e) {
67
+            return null;
68
+        }
69
+    }
70
+
71
+    private String meteoFrance(String lieu) throws IOException {
72
+        try {
73
+            Document doc = Jsoup.connect("http://www.meteofrance.com/recherche/resultats").data("facet", "previsions")
74
+                    .data("query", lieu).post();
75
+            String meteo = doc.select(".day-data").first().text();
76
+            return meteo;
77
+        } catch (Exception e) {
78
+            return null;
79
+        }
80
+    }
81
+
82
+}
0 83
new file mode 100644
... ...
@@ -0,0 +1,36 @@
1
+package im.bci.sara;
2
+
3
+import java.util.regex.Pattern;
4
+import org.apache.commons.lang3.StringUtils;
5
+import org.apache.commons.logging.LogFactory;
6
+import org.jsoup.Jsoup;
7
+import org.jsoup.nodes.Document;
8
+import org.jsoup.nodes.Element;
9
+import org.springframework.stereotype.Component;
10
+
11
+@Component
12
+public class Moinsbete implements SaraAction {
13
+
14
+    private static final Pattern JOURNEE = Pattern.compile("\\b(moins\\s*b[eê]tes?)\\b", Pattern.CASE_INSENSITIVE);
15
+
16
+    @Override
17
+    public MatchLevel match(Post post) {
18
+        return JOURNEE.matcher(post.getMessage()).find() ? MatchLevel.MUST : MatchLevel.CAN;
19
+    }
20
+
21
+    @Override
22
+    public String reply(Post post) {
23
+        try {
24
+            Document doc = Jsoup.connect("http://secouchermoinsbete.fr/random").get();
25
+            Element anecdote = doc.select(".anecdote-content-wrapper .summary a").first();
26
+            anecdote.select(".read-more").remove();
27
+            if (StringUtils.isNotBlank(anecdote.text())) {
28
+                return anecdote.text();
29
+            }
30
+        } catch (Exception ex) {
31
+            LogFactory.getLog(this.getClass()).error("moinsbete error", ex);
32
+        }
33
+        return null;
34
+    }
35
+
36
+}
0 37
new file mode 100644
... ...
@@ -0,0 +1,42 @@
1
+package im.bci.sara;
2
+
3
+public class Post {
4
+
5
+    public String getInfo() {
6
+        return info;
7
+    }
8
+
9
+    public void setInfo(String info) {
10
+        this.info = info;
11
+    }
12
+
13
+    public String getMessage() {
14
+        return message;
15
+    }
16
+
17
+    public void setMessage(String message) {
18
+        this.message = message;
19
+    }
20
+
21
+    public String getTime() {
22
+        return time;
23
+    }
24
+
25
+    public void setTime(String time) {
26
+        this.time = time;
27
+    }
28
+
29
+    public long getId() {
30
+        return id;
31
+    }
32
+
33
+    public void setId(long id) {
34
+        this.id = id;
35
+    }
36
+
37
+    private String info;
38
+    private String message;
39
+    private String time;
40
+    private long id;
41
+
42
+}
0 43
new file mode 100644
... ...
@@ -0,0 +1,62 @@
1
+package im.bci.sara;
2
+
3
+import java.util.ArrayList;
4
+import java.util.Collections;
5
+import java.util.List;
6
+import org.apache.commons.logging.LogFactory;
7
+
8
+import org.springframework.beans.factory.annotation.Autowired;
9
+import org.springframework.stereotype.Component;
10
+
11
+@Component
12
+public class Sara {
13
+
14
+    public static final String NAME = "sara";
15
+
16
+    @Autowired
17
+    private SaraAction[] actions;
18
+
19
+    public String reply(final Post post) {
20
+        try {
21
+            if (isBotCall(post)) {
22
+                List<SaraAction> musts = new ArrayList<>();
23
+                List<SaraAction> cans = new ArrayList<>();
24
+                for (SaraAction action : actions) {
25
+                    switch (action.match(post)) {
26
+                        case MUST:
27
+                            musts.add(action);
28
+                        case CAN:
29
+                            cans.add(action);
30
+                            break;
31
+                        case NO:
32
+                            break;
33
+                    }
34
+
35
+                }
36
+                Collections.shuffle(musts);
37
+                for (SaraAction action : musts) {
38
+                    String reply = action.reply(post);
39
+                    if (null != reply) {
40
+                        return reply;
41
+                    }
42
+                }
43
+                Collections.shuffle(cans);
44
+                for (SaraAction action : cans) {
45
+                    String reply = action.reply(post);
46
+                    if (null != reply) {
47
+                        return reply;
48
+                    }
49
+                }
50
+            }
51
+        } catch (Exception ex) {
52
+            LogFactory.getLog(this.getClass()).error(NAME + " bot error", ex);
53
+        }
54
+        return null;
55
+    }
56
+
57
+    private boolean isBotCall(Post post) {
58
+        String message = post.getMessage();
59
+        return message.contains("/" + NAME) || message.contains(NAME + "<");
60
+    }
61
+
62
+}
0 63
new file mode 100644
... ...
@@ -0,0 +1,18 @@
1
+package im.bci.sara;
2
+
3
+import org.springframework.web.util.UriComponentsBuilder;
4
+
5
+/**
6
+ *
7
+ * @author devnewton
8
+ */
9
+public interface SaraAction {
10
+    
11
+    public enum MatchLevel {
12
+        NO,
13
+        CAN,
14
+        MUST        
15
+    }
16
+    MatchLevel match(Post post);
17
+    String reply(Post post);
18
+}
0 19
new file mode 100644
... ...
@@ -0,0 +1,30 @@
1
+package im.bci.sara;
2
+
3
+import java.util.concurrent.Executor;
4
+import org.springframework.beans.BeansException;
5
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
6
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
7
+import org.springframework.boot.CommandLineRunner;
8
+import org.springframework.boot.SpringApplication;
9
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
10
+import org.springframework.context.annotation.Bean;
11
+import org.springframework.context.annotation.ComponentScan;
12
+import org.springframework.context.annotation.Configuration;
13
+import org.springframework.context.support.SimpleThreadScope;
14
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
15
+import org.springframework.stereotype.Component;
16
+
17
+@Configuration
18
+@EnableAutoConfiguration
19
+@ComponentScan
20
+public class SaraApplication implements CommandLineRunner {
21
+
22
+    @Override
23
+    public void run(String... args) throws Exception {
24
+        System.out.println("Sara? Non c'est à côté!");
25
+    }
26
+
27
+    public static void main(String[] args) throws Exception {
28
+        SpringApplication.run(SaraApplication.class, args);
29
+    }
30
+}
0 31
new file mode 100644
... ...
@@ -0,0 +1,31 @@
1
+package im.bci.sara;
2
+
3
+import org.apache.commons.lang3.StringUtils;
4
+import org.springframework.beans.factory.annotation.Autowired;
5
+import org.springframework.stereotype.Controller;
6
+import org.springframework.web.bind.annotation.RequestMapping;
7
+import org.springframework.web.bind.annotation.RequestMethod;
8
+import org.springframework.web.bind.annotation.ResponseBody;
9
+import org.springframework.web.bind.annotation.RestController;
10
+
11
+/**
12
+ *
13
+ * @author devnewton
14
+ */
15
+@RestController
16
+@RequestMapping("/")
17
+public class SaraController {
18
+
19
+    @Autowired
20
+    private Sara sara;
21
+
22
+    @ResponseBody
23
+    @RequestMapping(path = "")
24
+    public String onPost(Post post) {
25
+        if(null != post && StringUtils.isNotBlank(post.getMessage())) {
26
+            return sara.reply(post);
27
+        }
28
+        return "";
29
+    }
30
+
31
+}
0 32
new file mode 100644
... ...
@@ -0,0 +1,8 @@
1
+spring.http.encoding.charset=UTF-8
2
+spring.http.encoding.enabled=true
3
+spring.http.encoding.force=true
4
+
5
+server.tomcat.uri-encoding=UTF-8
6
+
7
+logging.level.root=WARN
8
+logging.level.org.springframework.web=WARN
0 9
\ No newline at end of file
1 10
new file mode 100644
2 11
Binary files /dev/null and b/src/main/resources/static/favicon.png differ