From ffe2e33fc8eb64fed58e02f6aff343c5a8c5e488 Mon Sep 17 00:00:00 2001 From: Ed Lewis Date: Tue, 11 Apr 2017 00:07:20 +0100 Subject: [PATCH 1/7] Fix bing searching --- .../modules/bingsearch/BingSearch.java | 166 +++++++++++------- 1 file changed, 102 insertions(+), 64 deletions(-) diff --git a/src/main/java/org/marissabot/marissa/modules/bingsearch/BingSearch.java b/src/main/java/org/marissabot/marissa/modules/bingsearch/BingSearch.java index 892c91b..9f2a6dd 100644 --- a/src/main/java/org/marissabot/marissa/modules/bingsearch/BingSearch.java +++ b/src/main/java/org/marissabot/marissa/modules/bingsearch/BingSearch.java @@ -1,13 +1,9 @@ package org.marissabot.marissa.modules.bingsearch; import org.apache.commons.io.IOUtils; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.codehaus.jackson.JsonNode; @@ -16,106 +12,148 @@ import org.slf4j.LoggerFactory; import java.io.IOException; +import java.io.InputStream; +import java.net.URI; import java.net.URISyntaxException; -import java.util.ArrayList; +import java.net.URL; +import java.net.URLConnection; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; public class BingSearch { private static final String appid; - private static final String host = "http://api.datamarket.azure.com/Bing/Search/"; static { appid = Persist.load("bingsearch", "appid"); } - private BingSearch() {} + private BingSearch() { + } public static List search(String query) throws IOException { - if (query==null||query.isEmpty()) + if (query == null || query.isEmpty()) throw new IllegalArgumentException("cannot search for nothing"); - String jsonResults = fetch(query, "Web"); + URI uri; - ObjectMapper o = new ObjectMapper(); - JsonNode n = o.readTree(jsonResults); - List res = n.get("d").get("results").findValuesAsText("Url"); - LoggerFactory.getLogger(BingSearch.class).info(String.join("\n", res)); + try { + uri = new URIBuilder() + .setScheme("https") + .setHost("api.cognitive.microsoft.com") + .setPath("/bing/v5.0/search") + .addParameter("q", query) + .addParameter("mkt", "en-GB") + .addParameter("count", "5") + .build(); + } catch (URISyntaxException e) { + throw new IllegalStateException("Couldn't build URI for search", e); + } - return res; - } + LoggerFactory.getLogger(BingSearch.class).info("[GET] " + uri.toString()); - public static List imageSearch(String query) throws IOException { - if (query==null||query.isEmpty()) - throw new IllegalArgumentException("cannot image search for nothing"); + HttpGet get = new HttpGet(uri); - String jsonResults = fetch(query, "Image"); + get.addHeader("Ocp-Apim-Subscription-Key", appid); + + CloseableHttpClient httpClient = HttpClientBuilder.create().build(); + CloseableHttpResponse r = httpClient.execute(get); + String searchResults = IOUtils.toString(r.getEntity().getContent()); ObjectMapper o = new ObjectMapper(); - JsonNode n = o.readTree(jsonResults); - List res = n.get("d").get("results").findValuesAsText("MediaUrl"); + JsonNode n = o.readTree(searchResults); + + List res = n.get("webPages").get("value").findValuesAsText("url"); + LoggerFactory.getLogger(BingSearch.class).info(String.join("\n", res)); - return res; + return mapRedirects(res); } - public static List animatedSearch(String query) throws IOException { - if (query==null||query.isEmpty()) - throw new IllegalArgumentException("cannot animated search for nothing"); + public static List imageSearch(String query) throws IOException { + if (query == null || query.isEmpty()) + throw new IllegalArgumentException("cannot image search with nothing"); - String jsonResults = fetch(query + " .gif", "Image"); - ObjectMapper o = new ObjectMapper(); - JsonNode n = o.readTree(jsonResults); - JsonNode results = n.get("d").get("results"); - - List res = new ArrayList<>(); - for (JsonNode result : results) { - if ("image/animatedgif".equals(result.findValue("ContentType").asText())) - { - res.add( result.findValue("MediaUrl").asText() ); - } + URI uri; + try { + uri = new URIBuilder() + .setScheme("https") + .setHost("api.cognitive.microsoft.com") + .setPath("/bing/v5.0/images/search") + .addParameter("q", query) + .addParameter("mkt", "en-GB") + .addParameter("count", "5") + .build(); + } catch (URISyntaxException e) { + throw new IllegalStateException("couldn't build image search URI", e); } - LoggerFactory.getLogger(BingSearch.class).info(String.join("\n", res)); - return res; + return mapRedirects(fetch(uri)); } - private static String fetch(String query, String source) throws IOException { - - CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); - credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("", appid)); - - CloseableHttpClient httpClient = HttpClientBuilder.create() - .setDefaultCredentialsProvider(credentialsProvider) - .build(); - - URIBuilder uriBuilder; - - try { - uriBuilder = new URIBuilder(host + source); - uriBuilder.addParameter("Query", "'"+query+"'"); - uriBuilder.addParameter("$format", "json"); - } catch (URISyntaxException e) { - throw new IllegalStateException("cannot generate search url", e); - } + public static List animatedSearch(String query) throws IOException { + if (query == null || query.isEmpty()) + throw new IllegalArgumentException("cannot animated search with nothing"); - HttpGet g; + URI uri; try { - g = new HttpGet(uriBuilder.build()); + uri = new URIBuilder() + .setScheme("https") + .setHost("api.cognitive.microsoft.com") + .setPath("/bing/v5.0/images/search") + .addParameter("q", query) + .addParameter("mkt", "en-GB") + .addParameter("imageType", "animatedGif") + .addParameter("count", "5") + .build(); } catch (URISyntaxException e) { - throw new IllegalArgumentException("cannot build request for query"); + throw new IllegalStateException("couldn't build animated search URI", e); } - LoggerFactory.getLogger(BingSearch.class).info("[GET] " + g.getURI()); + return mapRedirects(fetch(uri)); + } - CloseableHttpResponse r = httpClient.execute(g); + private static List fetch(URI uri) throws IOException { + LoggerFactory.getLogger(BingSearch.class).info("[GET] " + uri.toString()); + + HttpGet get = new HttpGet(uri); + + get.addHeader("Ocp-Apim-Subscription-Key", appid); + + CloseableHttpClient httpClient = HttpClientBuilder.create().build(); + CloseableHttpResponse r = httpClient.execute(get); String searchResults = IOUtils.toString(r.getEntity().getContent()); - LoggerFactory.getLogger(BingSearch.class).info("Content:\n" + searchResults); + ObjectMapper o = new ObjectMapper(); + JsonNode n = o.readTree(searchResults); + + List res = n.get("value").findValuesAsText("contentUrl"); - httpClient.close(); + LoggerFactory.getLogger(BingSearch.class).info(String.join("\n", res)); + + return res; + } - return searchResults; + private static List mapRedirects(List uris) { + return uris.parallelStream() + .map((url) -> { + try { + URLConnection con = new URL(url).openConnection(); + con.setReadTimeout(700); // give up early + LoggerFactory.getLogger(BingSearch.class).info("Following redirects for '" + url + "'"); + con.connect(); + InputStream is = con.getInputStream(); + LoggerFactory.getLogger(BingSearch.class).info("Redirected URL is '" + con.getURL() + "'"); + is.close(); + return Optional.of(con.getURL().toString()); + } catch (Exception e) { + return Optional.empty(); + } + }) + .filter(Optional::isPresent) + .map(url -> (String) url.get()) // oh java + .collect(Collectors.toList()); } } From 50c04d23bee11f371833d83249ff8918b87ed9a8 Mon Sep 17 00:00:00 2001 From: Ed Lewis Date: Tue, 11 Apr 2017 00:15:23 +0100 Subject: [PATCH 2/7] Split giphy into own 'giphy' command for animations - set animate to use bing by default. Randomize image choices --- .../java/org/marissabot/marissa/Main.java | 8 ++- .../marissabot/marissa/modules/Animate.java | 30 ++++------- .../marissa/modules/GiphySearch.java | 51 +++++++++++++++++++ .../marissabot/marissa/modules/Search.java | 8 ++- 4 files changed, 70 insertions(+), 27 deletions(-) create mode 100644 src/main/java/org/marissabot/marissa/modules/GiphySearch.java diff --git a/src/main/java/org/marissabot/marissa/Main.java b/src/main/java/org/marissabot/marissa/Main.java index 6e4314b..d04822d 100644 --- a/src/main/java/org/marissabot/marissa/Main.java +++ b/src/main/java/org/marissabot/marissa/Main.java @@ -5,12 +5,9 @@ import java.util.Arrays; import org.marissabot.libmarissa.*; import org.marissabot.marissa.lib.Persist; -import org.marissabot.marissa.modules.Animate; -import org.marissabot.marissa.modules.Search; +import org.marissabot.marissa.modules.*; import org.marissabot.marissa.modules.define.Define; import org.marissabot.marissa.modules.scripting.ScriptEngine; -import org.marissabot.marissa.modules.MiscUtils; -import org.marissabot.marissa.modules.Score; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rocks.xmpp.core.XmppException; @@ -37,6 +34,7 @@ public static void main(String[] args) throws XmppException, SuspendExecution, I router.on("(search|image)\\s+.*", Search::search); router.on("animate\\s+.*", Animate::search); + router.on("giphy\\s+.*", GiphySearch::search); router.on("[-+]\\d+", Score::scoreChange); router.on("score", Score::scores); @@ -50,7 +48,7 @@ public static void main(String[] args) throws XmppException, SuspendExecution, I username, password, nickname, - Arrays.asList(new String[]{joinRoom}) + Arrays.asList(joinRoom) ); Runtime.getRuntime().addShutdownHook( diff --git a/src/main/java/org/marissabot/marissa/modules/Animate.java b/src/main/java/org/marissabot/marissa/modules/Animate.java index 8570701..c929706 100644 --- a/src/main/java/org/marissabot/marissa/modules/Animate.java +++ b/src/main/java/org/marissabot/marissa/modules/Animate.java @@ -3,52 +3,40 @@ import org.marissabot.libmarissa.Response; import org.marissabot.libmarissa.model.Context; import org.marissabot.marissa.modules.bingsearch.BingSearch; -import org.marissabot.marissa.modules.giphy.GiphySearch; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.List; import java.util.Optional; +import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Animate { - public static void search(Context context, String trigger, Response response) { + public static void search(Context c, String trigger, Response response) { Optional qry = getSearchQuery(trigger); if (qry.isPresent()) { List results; + try { - results = GiphySearch.search(qry.get()); + results = BingSearch.animatedSearch(qry.get()); } catch (IOException e) { - response.send("Oops. Some kind of IO error. Rate limited?"); - LoggerFactory.getLogger(Animate.class).error("IO Error on giphy", e); + response.send("Oops. Some kind of IO error?"); + LoggerFactory.getLogger(Animate.class).error("IO Error on bing animated", e); return; } - if (results.isEmpty()) - { - // lets check bing too - LoggerFactory.getLogger(Animate.class).info("giphy gave nothing, falling through to bing"); - - try { - results = BingSearch.animatedSearch(qry.get()); - } catch (IOException e) { - response.send("Oops. Some kind of IO error?"); - LoggerFactory.getLogger(Animate.class).error("IO Error on bing animated", e); - return; - } - } - if (results.isEmpty()) { response.send("Sorry.. no results"); } else { // pick a random // this is actually pretty annoying as they're sorted by relevance - //int choice = new Random(System.nanoTime()).nextInt(results.size()); - response.send(results.get(0)); + int choice = new Random(System.nanoTime()).nextInt(results.size()); + response.send(results.get(choice)); } + } else { response.send("Sorry I don't really understand"); } diff --git a/src/main/java/org/marissabot/marissa/modules/GiphySearch.java b/src/main/java/org/marissabot/marissa/modules/GiphySearch.java new file mode 100644 index 0000000..c23c6a7 --- /dev/null +++ b/src/main/java/org/marissabot/marissa/modules/GiphySearch.java @@ -0,0 +1,51 @@ +package org.marissabot.marissa.modules; + +import org.marissabot.libmarissa.Response; +import org.marissabot.libmarissa.model.Context; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class GiphySearch { + + public static void search(Context context, String trigger, Response response) { + Optional qry = getSearchQuery(trigger); + + if (qry.isPresent()) { + List results; + try { + results = org.marissabot.marissa.modules.giphy.GiphySearch.search(qry.get()); + } catch (IOException e) { + response.send("Oops. Some kind of IO error. Rate limited?"); + LoggerFactory.getLogger(Animate.class).error("IO Error on giphy", e); + return; + } + + if (results.isEmpty()) { + response.send("Sorry.. no results"); + } else { + int choice = new Random(System.nanoTime()).nextInt(results.size()); + response.send(results.get(choice)); + } + } else { + response.send("Sorry I don't really understand"); + } + } + + protected static Optional getSearchQuery(String trigger) { + + Pattern p = Pattern.compile(".*giphy\\s+(me\\s+)?(.*)", Pattern.CASE_INSENSITIVE); + Matcher m = p.matcher(trigger); + + if (m.matches()) { + return Optional.of(m.group(2).trim()); + } else { + return Optional.empty(); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/marissabot/marissa/modules/Search.java b/src/main/java/org/marissabot/marissa/modules/Search.java index c323cf8..5560e6a 100644 --- a/src/main/java/org/marissabot/marissa/modules/Search.java +++ b/src/main/java/org/marissabot/marissa/modules/Search.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.util.List; import java.util.Optional; +import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -63,7 +64,12 @@ public static void search(Context context, String trigger, Response response){ if (results.size() == 0) { response.send("No results :("); } else { - response.send(results.get(0)); + if (searchQuery.getType().equals(SearchQuery.Type.Image)) { + int choice = new Random(System.nanoTime()).nextInt(results.size()); + response.send(results.get(choice)); + } else { + response.send(results.get(0)); + } } } else { From fee4d07b45fb56003ec84e3d6a6e6d2b121ff0ae Mon Sep 17 00:00:00 2001 From: Ed Lewis Date: Tue, 11 Apr 2017 00:16:19 +0100 Subject: [PATCH 3/7] Set time command output to be UTC iso8601 --- .../org/marissabot/marissa/modules/MiscUtils.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/marissabot/marissa/modules/MiscUtils.java b/src/main/java/org/marissabot/marissa/modules/MiscUtils.java index af5b4c0..a1034ef 100644 --- a/src/main/java/org/marissabot/marissa/modules/MiscUtils.java +++ b/src/main/java/org/marissabot/marissa/modules/MiscUtils.java @@ -1,8 +1,13 @@ package org.marissabot.marissa.modules; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.Date; import java.util.Random; +import java.util.TimeZone; + import org.marissabot.libmarissa.Response; import org.marissabot.libmarissa.model.Context; import org.slf4j.LoggerFactory; @@ -14,7 +19,11 @@ private MiscUtils() {} public static void tellTheTime(Context context, String trigger, Response response) { - response.send(LocalDateTime.now().format(DateTimeFormatter.ofPattern("EEE dd MMM yyyy -- HH:mm.ss"))); + TimeZone tz = TimeZone.getTimeZone("UTC"); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); + df.setTimeZone(tz); + String nowAsISO = df.format(new Date()); + response.send(nowAsISO); // utc iso860 - don't be a heathen } public static void selfie(Context context, String trigger, Response response) From 1c81f45538ffa970d34d04cbbb6ab5ab1b7c6d62 Mon Sep 17 00:00:00 2001 From: Ed Lewis Date: Tue, 11 Apr 2017 00:17:00 +0100 Subject: [PATCH 4/7] Dynamically generate selfies using bing if possible --- .../marissabot/marissa/modules/MiscUtils.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/marissabot/marissa/modules/MiscUtils.java b/src/main/java/org/marissabot/marissa/modules/MiscUtils.java index a1034ef..603eb39 100644 --- a/src/main/java/org/marissabot/marissa/modules/MiscUtils.java +++ b/src/main/java/org/marissabot/marissa/modules/MiscUtils.java @@ -10,6 +10,7 @@ import org.marissabot.libmarissa.Response; import org.marissabot.libmarissa.model.Context; +import org.marissabot.marissa.modules.bingsearch.BingSearch; import org.slf4j.LoggerFactory; @@ -28,21 +29,26 @@ public static void tellTheTime(Context context, String trigger, Response respons public static void selfie(Context context, String trigger, Response response) { - String[] selfies = { - "http://aib.edu.au/blog/wp-content/uploads/2014/05/222977-marissa-mayer.jpg", - "http://i.huffpost.com/gen/882663/images/o-MARISSA-MAYER-facebook.jpg", - "http://static.businessinsider.com/image/5213c32cecad045804000016/image.jpg", - "http://static.businessinsider.com/image/5213c32cecad045804000016/image.jpg", - "http://i2.cdn.turner.com/money/dam/assets/130416164248-marissa-mayer-620xa.png", - "http://wpuploads.appadvice.com/wp-content/uploads/2013/05/marissa-mayer-yahoo-new-c-008.jpg", - "https://pbs.twimg.com/profile_images/323982494/marissa_new4.jpg", - "http://media.idownloadblog.com/wp-content/uploads/2015/01/Marissa-Mayer-Yahoo-001.jpg", - "http://women2.com/wp-content/uploads/2012/07/121128_marissa_mayer.jpg" + final String[] fallbackSelfies = { + "http://aib.edu.au/blog/wp-content/uploads/2014/05/222977-marissa-mayer.jpg", + "http://i.huffpost.com/gen/882663/images/o-MARISSA-MAYER-facebook.jpg", + "http://i2.cdn.turner.com/money/dam/assets/130416164248-marissa-mayer-620xa.png", + "http://wpuploads.appadvice.com/wp-content/uploads/2013/05/marissa-mayer-yahoo-new-c-008.jpg", + "https://pbs.twimg.com/profile_images/323982494/marissa_new4.jpg", + "http://media.idownloadblog.com/wp-content/uploads/2015/01/Marissa-Mayer-Yahoo-001.jpg", + "https://s-media-cache-ak0.pinimg.com/originals/39/87/26/398726bb39ec252e0291c2b4e9e5dd7b.jpg" }; - + + String[] selfies; + try { + selfies = BingSearch.imageSearch("marissa mayer").toArray(new String[0]); + } catch (Exception e) { + selfies = fallbackSelfies; + } + int selfieNo = new Random().nextInt(selfies.length); - - response.send(selfies[selfieNo]); + + response.send(selfies[selfieNo]); } public static void ping(Context context, String trigger, Response response) From a626a9474441d558e3efbf4de5cc72dcfd459a3c Mon Sep 17 00:00:00 2001 From: Ed Lewis Date: Tue, 11 Apr 2017 00:24:32 +0100 Subject: [PATCH 5/7] Increase randomness on selfies --- src/main/java/org/marissabot/marissa/modules/MiscUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/marissabot/marissa/modules/MiscUtils.java b/src/main/java/org/marissabot/marissa/modules/MiscUtils.java index 603eb39..0fda7fa 100644 --- a/src/main/java/org/marissabot/marissa/modules/MiscUtils.java +++ b/src/main/java/org/marissabot/marissa/modules/MiscUtils.java @@ -46,7 +46,7 @@ public static void selfie(Context context, String trigger, Response response) selfies = fallbackSelfies; } - int selfieNo = new Random().nextInt(selfies.length); + int selfieNo = new Random(System.nanoTime()).nextInt(selfies.length); response.send(selfies[selfieNo]); } From 370d378fb90d78cc84309f5b3b1fb9170ac48cda Mon Sep 17 00:00:00 2001 From: Ed Lewis Date: Tue, 11 Apr 2017 00:29:59 +0100 Subject: [PATCH 6/7] Increase max image pulls on bing --- .../marissabot/marissa/modules/bingsearch/BingSearch.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/marissabot/marissa/modules/bingsearch/BingSearch.java b/src/main/java/org/marissabot/marissa/modules/bingsearch/BingSearch.java index 9f2a6dd..eac3faa 100644 --- a/src/main/java/org/marissabot/marissa/modules/bingsearch/BingSearch.java +++ b/src/main/java/org/marissabot/marissa/modules/bingsearch/BingSearch.java @@ -24,6 +24,7 @@ public class BingSearch { private static final String appid; + private static final String MAX_RESULTS = "20"; static { appid = Persist.load("bingsearch", "appid"); @@ -45,7 +46,7 @@ public static List search(String query) throws IOException { .setPath("/bing/v5.0/search") .addParameter("q", query) .addParameter("mkt", "en-GB") - .addParameter("count", "5") + .addParameter("count", MAX_RESULTS) .build(); } catch (URISyntaxException e) { throw new IllegalStateException("Couldn't build URI for search", e); @@ -83,7 +84,7 @@ public static List imageSearch(String query) throws IOException { .setPath("/bing/v5.0/images/search") .addParameter("q", query) .addParameter("mkt", "en-GB") - .addParameter("count", "5") + .addParameter("count", MAX_RESULTS) .build(); } catch (URISyntaxException e) { throw new IllegalStateException("couldn't build image search URI", e); @@ -105,7 +106,7 @@ public static List animatedSearch(String query) throws IOException { .addParameter("q", query) .addParameter("mkt", "en-GB") .addParameter("imageType", "animatedGif") - .addParameter("count", "5") + .addParameter("count", MAX_RESULTS) .build(); } catch (URISyntaxException e) { throw new IllegalStateException("couldn't build animated search URI", e); From 7b0a46809370349abd37926638b11ac0a5cc6c0a Mon Sep 17 00:00:00 2001 From: Ed Lewis Date: Tue, 11 Apr 2017 00:49:02 +0100 Subject: [PATCH 7/7] Add selfie-strike. Fix time appearing in other commands --- .../java/org/marissabot/marissa/Main.java | 10 +++--- .../marissabot/marissa/modules/MiscUtils.java | 31 +++++++++++++------ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/marissabot/marissa/Main.java b/src/main/java/org/marissabot/marissa/Main.java index d04822d..ae84c33 100644 --- a/src/main/java/org/marissabot/marissa/Main.java +++ b/src/main/java/org/marissabot/marissa/Main.java @@ -21,21 +21,21 @@ public static void main(String[] args) throws XmppException, SuspendExecution, I String nickname = Persist.load("core", "nickname"); final String joinRoom = Persist.load("core", "joinroom"); - Router router = new Router("(?i)@?"+nickname, true); + Router router = new Router("(?i)@?"+nickname, false); - router.on(".*time.*", MiscUtils::tellTheTime); - router.on("selfie", MiscUtils::selfie); + router.on("selfie\\s+strike", MiscUtils::selfieStrike); + router.on("selfie\\s*$", MiscUtils::selfie); router.on("ping", MiscUtils::ping); router.on("echo.*", MiscUtils::echo); - //router.on(".*", ScriptEngine::dispatchToAll); - router.on("define\\s+.*", Define::defineWord); router.on("(search|image)\\s+.*", Search::search); router.on("animate\\s+.*", Animate::search); router.on("giphy\\s+.*", GiphySearch::search); + router.on(".*time.*", MiscUtils::tellTheTime); + router.on("[-+]\\d+", Score::scoreChange); router.on("score", Score::scores); router.whenContains("[-+]\\d+\\s+(?i)@?"+nickname, diff --git a/src/main/java/org/marissabot/marissa/modules/MiscUtils.java b/src/main/java/org/marissabot/marissa/modules/MiscUtils.java index 0fda7fa..f4ffd1b 100644 --- a/src/main/java/org/marissabot/marissa/modules/MiscUtils.java +++ b/src/main/java/org/marissabot/marissa/modules/MiscUtils.java @@ -4,9 +4,7 @@ import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.Date; -import java.util.Random; -import java.util.TimeZone; +import java.util.*; import org.marissabot.libmarissa.Response; import org.marissabot.libmarissa.model.Context; @@ -26,9 +24,23 @@ public static void tellTheTime(Context context, String trigger, Response respons String nowAsISO = df.format(new Date()); response.send(nowAsISO); // utc iso860 - don't be a heathen } - + + public static void selfieStrike(Context c, String trigger, Response response) { + List selfies = fetchSelfies(); + Collections.shuffle(selfies); + selfies.stream() + .limit(5) + .forEach(response::send); + } + public static void selfie(Context context, String trigger, Response response) { + List selfies = fetchSelfies(); + int selfieNo = new Random(System.nanoTime()).nextInt(selfies.size()); + response.send(selfies.get(selfieNo)); + } + + private static List fetchSelfies() { final String[] fallbackSelfies = { "http://aib.edu.au/blog/wp-content/uploads/2014/05/222977-marissa-mayer.jpg", "http://i.huffpost.com/gen/882663/images/o-MARISSA-MAYER-facebook.jpg", @@ -39,16 +51,15 @@ public static void selfie(Context context, String trigger, Response response) "https://s-media-cache-ak0.pinimg.com/originals/39/87/26/398726bb39ec252e0291c2b4e9e5dd7b.jpg" }; - String[] selfies; + List selfies; try { - selfies = BingSearch.imageSearch("marissa mayer").toArray(new String[0]); + selfies = BingSearch.imageSearch("marissa mayer"); } catch (Exception e) { - selfies = fallbackSelfies; + selfies = new ArrayList<>(); + Collections.addAll(selfies, fallbackSelfies); } - int selfieNo = new Random(System.nanoTime()).nextInt(selfies.length); - - response.send(selfies[selfieNo]); + return selfies; } public static void ping(Context context, String trigger, Response response)