Commit 5f5f1b12 authored by Dave McCormick's avatar Dave McCormick
Browse files

massive tidy up

parent f8c7d75b
package actors;
import com.fasterxml.jackson.databind.node.ObjectNode;
import play.libs.Json;
import twitter4j.*;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.UntypedActor;
import twitter4j.conf.ConfigurationBuilder;
import model.GibberishHub;
/*
Consumer Key (API Key) MkpBoVPy3REAIdsPNSZpC7u0I
Consumer Secret (API Secret) 3cNybn6qSJPpw2AnizXGitOclFV3ZolFXidWBWLpOnafRw7uL8
Access Token 315679785-SVT1kCKoow1eCTgTWLzPrh6BPaKA5OiPOfIlmAxt
Access Token Secret TYTg0PLDbU7isjXxm3uPIeu2xdYg3rXGaEGUdJuBkvCg2
*/
/**
* A rather trivial Actor that just plays FizzBuzz
*/
public class FizzBuzzActor extends UntypedActor {
int nextNum = 0;
/**
* The marshall. We'll also send them the messages
*/
ActorRef marshallActor;
/**
*
*/
public static Props props = Props.create(FizzBuzzActor.class);
TwitterStream twitterStream;
StatusListener listener;
public FizzBuzzActor() {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey("MkpBoVPy3REAIdsPNSZpC7u0I")
.setOAuthConsumerSecret("3cNybn6qSJPpw2AnizXGitOclFV3ZolFXidWBWLpOnafRw7uL8")
.setOAuthAccessToken("315679785-SVT1kCKoow1eCTgTWLzPrh6BPaKA5OiPOfIlmAxt")
.setOAuthAccessTokenSecret("TYTg0PLDbU7isjXxm3uPIeu2xdYg3rXGaEGUdJuBkvCg2");
twitterStream = new TwitterStreamFactory(cb.build()).getInstance();
listener = new StatusListener() {
@Override
public void onStatus(Status status) {
GeoLocation loc = status.getGeoLocation();
if (loc == null){
return;
}
//System.out.println("Got a tweet");
ObjectNode n = Json.newObject();
//n.put("msg", "@" + status.getUser().getScreenName() + "said " + status.getText() + " - " + loc);
n.put("lat", loc.getLatitude());
n.put("lng", loc.getLongitude());
reply(n);
}
@Override
public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {
System.out.println("Got a status deletion notice id:" + statusDeletionNotice.getStatusId());
}
@Override
public void onTrackLimitationNotice(int numberOfLimitedStatuses) {
System.out.println("Got track limitation notice:" + numberOfLimitedStatuses);
}
@Override
public void onScrubGeo(long userId, long upToStatusId) {
System.out.println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId);
}
@Override
public void onStallWarning(StallWarning warning) {
System.out.println("Got stall warning:" + warning);
}
@Override
public void onException(Exception ex) {
ex.printStackTrace();
}
};
}
@Override
public void onReceive(Object message) throws TwitterException {
System.out.println("Received a call");
if (message.equals("Marshall")) {
/*
* We're given the marshall's ActorRef by a message saying "Marshall". The Marshall will appear
* to be the sender (even though it's actually been sent by Setup)
*/
marshallActor = getSender();
} else if (message.equals("Heatmap")){
System.out.println("Got heatmap call...");
getStreamForHeatmap();
}
}
void reply(ObjectNode tweetDetails) {
GibberishHub.getInstance().send(tweetDetails);
//marshallActor.tell(trendName, getSelf());
// Put this Actor to sleep for 250ms before it checks its next message
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
// do nothing
}
}
void getStreamForHeatmap(){
FilterQuery fq = new FilterQuery();
double[][] boundingBox= {{-180, -90}, {180, 90}}; /// whole world;
FilterQuery filtro = new FilterQuery();
filtro.locations(boundingBox);
twitterStream.addListener(listener);
twitterStream.filter(filtro);
}
}
package actors;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.actor.UntypedActor;
import javax.inject.Inject;
/**
* You might or might not want this actor in the end. In this example, its role is to be the central point of
* contact between your web app and the actor system that might be receiving outside events.
*/
public class MarshallActor extends UntypedActor {
StringBuilder messages = new StringBuilder();
public static Props props = Props.create(MarshallActor.class);
public MarshallActor() {
}
@Override
public void onReceive(Object message) {
if (message.equals("Report!")) {
getSender().tell(messages.toString(), getSelf());
}
else if (message.equals("ActorReadyAgain"))
{
getSender().tell("Heatmap",getSelf());
} else {
messages.append(message);
messages.append("\n");
}
}
}
......@@ -15,23 +15,9 @@ import javax.inject.Singleton;
@Singleton
public class Setup {
/**
* This is a reference to an Actor
*/
public final ActorRef marshallActor;
@Inject
public Setup(ActorSystem system) {
marshallActor = system.actorOf(MarshallActor.props);
System.out.println("Booting up..");
ActorRef fb1 = system.actorOf(FizzBuzzActor.props, "Player1");
System.out.println("Built actor Player1");
fb1.tell("Marshall", marshallActor);
System.out.println("Told actor about marshall");
fb1.tell("Heatmap", marshallActor);
System.out.println("Told actor about heatmap");
ActorRef fb1 = system.actorOf(TwitterStreamActor.props, "TwitterStream");
fb1.tell("ConnectToStream", ActorRef.noSender());
}
}
\ No newline at end of file
......@@ -4,7 +4,9 @@ import actors.Setup;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import play.mvc.Controller;
import play.mvc.LegacyWebSocket;
import play.mvc.Result;
import play.mvc.WebSocket;
import scala.compat.java8.FutureConverters;
import play.libs.ws.*;
......@@ -25,32 +27,19 @@ public class Application extends Controller {
}
/**
* Play framework suppors asynchronous controller methods -- that is, methods that instead of returning a Result
* return a CompletionStage, which will produce a Result some time in the future
* Our WebSockets endpoint. We'll assume we're sending String messages for now
*/
public CompletionStage<Result> index() {
/*
* This code might look a little complex.
*
* ask sends a message to an ActorRef, and then returns a Future that will eventually contain the response.
* But Future is a Scala class, so FutureConverters.toJava converts it into a CompletionStage, which is Java's equivalent.
* thenApply is a method on CompletionStage that means "when you get the result, do this with it, and return a new CompletionStage"
*/
public LegacyWebSocket<String> socket(String topic) {
/*
Play framework provides an Actor for client automatically. That's the <code>out</code> argument below.
return FutureConverters.toJava(ask(actorSetup.marshallActor, "Report!", 1000))
.thenApply(response -> {
String responseString = response.toString();
return ok(views.html.application.index.render(responseString));
});
}
We need to tell Play what kind of actor we want on the server side. We do that with a "Props" object, because
Play will ask Akka to create the actor for us.
/**
* This controller method uses Play's Web Service client to make another HTTP call, and do something with the
* response
*/
public CompletionStage<Result> whatDidGitLabSay() {
return wsClient.url("http://www.une.edu.au").get().thenApply(r -> ok(r.getStatusText()));
We want a TweetWebSocketActor, and we want to pass the client actor and the topic as constructor arguments.
TweetWebSocketActor.props(topic, out) will produce a Props object saying that.
*/
return WebSocket.withActor((out) -> TweetWebSocketActor.props(topic, out));
}
}
package controllers;
/**
* Created by davidmccormick on 21/08/16.
*/
import akka.actor.*;
import model.GibberishHub;
import model.GibberishListener;
public class GibberishWebSocketActor extends UntypedActor {
/**
* We don't create the actor ourselves. Instead, Play will ask Akka to make it for us. We have to give Akka a
* "Props" object that tells Akka what kind of actor to create, and what constructor arguments to pass to it.
* This method produces that Props object.
*/
public static Props props(String topic, ActorRef out) {
// Create a Props object that says:
// - I want a GibberishWebSocketActor,
// - and pass (topic, out) as the arguments to its constructor
return Props.create(GibberishWebSocketActor.class, topic, out);
}
/** The Actor for the client (browser) */
private final ActorRef out;
/** The topic string we have subscribed to */
private final String topic;
/** A listener that we will register with our GibberishHub */
private final GibberishListener listener;
/**
* This constructor is called by Akka to create our actor (we don't call it ourselves).
*/
public GibberishWebSocketActor(String topic, ActorRef out) {
this.topic = topic;
this.out = out;
/*
Our GibberishListener, written as a Java 8 Lambda.
Whenever we receive a gibberish, if it matches our topic, convert it to a JSON string, and send it to the client.
*/
this.listener = (g) -> {
String message = g.toString();
out.tell(message, self());
};
// Register this actor to hear gibberish
GibberishHub.getInstance().addListener(listener);
}
/**
* This is called whenever the browser sends a message to the serverover the websocket
*/
public void onReceive(Object message) throws Exception {
// The client isn't going to send us messages down the websocket in this example, so this doesn't matter
if (message instanceof String) {
out.tell("I received your message: " + message, self());
}
}
/**
* This is called by Play after the WebSocket has closed
*/
public void postStop() throws Exception {
// De-register our listener
GibberishHub.getInstance().removeListener(this.listener);
}
}
package controllers;
/**
* Created by davidmccormick on 21/08/16.
*/
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import model.Gibberish;
import model.GibberishHub;
import play.libs.Json;
import play.mvc.Controller;
import play.mvc.LegacyWebSocket;
import play.mvc.Result;
import play.mvc.WebSocket;
public class JsonExample extends Controller {
public static ObjectNode toJson(Gibberish g) {
ObjectNode n = Json.newObject();
n.put("msg", g.getSubject());
n.put("lat", g.getAdverb());
n.put("lng", g.getVerb());
n.put("adjective", g.getAdjective());
n.put("object", g.getObj());
return n;
}
public Result getGibberish(int n) {
ObjectNode[] arr = new ObjectNode[n];
ArrayNode an = Json.newArray();
for (int i = 0; i < n; i++) {
Gibberish g = new Gibberish();
an.add(toJson(g));
// Send the gibberish to the GibberishHub
//GibberishHub.getInstance().send(g);
}
return ok(an);
}
public static Result postGibberish() {
JsonNode json = request().body().asJson();
if(json == null) {
return badRequest("Expecting Json data");
} else {
Gibberish g = new Gibberish();
g.setSubject(json.findPath("subject").textValue());
g.setAdverb(json.findPath("adverb").textValue());
g.setVerb(json.findPath("verb").textValue());
g.setAdjective(json.findPath("adjective").textValue());
g.setObj(json.findPath("object").textValue());
System.out.println(g);
return ok("printed it");
}
}
/**
* Our WebSockets endpoint. We'll assume we're sending String messages for now
*/
public LegacyWebSocket<String> socket(String topic) {
/*
Play framework provides an Actor for client automatically. That's the <code>out</code> argument below.
We need to tell Play what kind of actor we want on the server side. We do that with a "Props" object, because
Play will ask Akka to create the actor for us.
We want a GibberishWebSocketActor, and we want to pass the client actor and the topic as constructor arguments.
GibberishWebSocketActor.props(topic, out) will produce a Props object saying that.
*/
return WebSocket.<String>withActor((out) -> GibberishWebSocketActor.props(topic, out));
}
}
\ No newline at end of file
package model;
import org.mindrot.jbcrypt.BCrypt;
/**
* A little demo code to show how BCrypt is used to hash passwords
*/
public class BCryptExample {
// Eek, not threadsafe.
static String last;
public static String encrypt(String s) {
last = BCrypt.hashpw(s, BCrypt.gensalt());
return last;
}
public static boolean matchesLastEncrypted(String pw) {
return BCrypt.checkpw(pw, last);
}
}
package model;
public class Captcha {
/**
* URLs of photos the user should select
*/
public static String[] yesPhotos = {
"http://assets.dogtime.com/breed/profile/image/4d3771f10106195669001f8c/beagle.jpg",
"https://gdkennel.files.wordpress.com/2013/09/010.jpg",
"http://www.perros2.com/wp-content/uploads/2012/06/ddd.jpg",
"http://dogobedienceadvice.com/images/beagle_training.jpg",
"http://www.swish-swash.co.uk/images/beagle/beagles.jpg"
};
/**
* URLs of photos the user should not select
*/
public static String[] noPhotos = {
"http://www.pets4homes.co.uk/images/articles/1265/large/ten-reasons-why-dogs-make-better-pets-than-cats-52bc3172b4816.jpg",
"http://www.adweek.com/files/imagecache/node-blog/sa_article/dog_image_0.jpg",
"http://7-themes.com/data_images/out/36/6891162-dogs.jpg",
"http://www.boxer-dog.org/sites/default/files/imagecache/500_width/ruby2.jpg",
"http://www.imagepuppy.com/resized/762ce6cb8241c08d73ec9304b42f6d5f.jpg"
};
/**
* How many photos there are in total
*/
public static int numPhotos() {
return yesPhotos.length + noPhotos.length;
}
/**
* The index of a random photo
*/
public static int randomPhotoIdx() {
return (int)(Math.random() * numPhotos());
}
/**
* Get a photo with the specified index
*/
public static String getPhoto(int idx) {
if (idx < 0 || idx >= numPhotos()) {
throw new IllegalArgumentException("index out of range");
}
if (idx < yesPhotos.length) {
return yesPhotos[idx];
} else {
return noPhotos[idx - yesPhotos.length];
}
}
/**
* Whether a photo selected by the user was in the "yes" set
*/
public static boolean isCorrect(int idx) {
return idx >= 0 && idx < yesPhotos.length;
}
}
package model;
/**
* Created by davidmccormick on 21/08/16.
*/
/**
* A nonsense class, just for sending something to the client
*/
public class Gibberish {
static final String[] SUBJECTS = {
"Algernon", "Bertie", "Cecily", "Dahlia", "Edwin"
};
static final String[] ADVERBS = {
"quickly", "slowly", "hesitatingly", "grudgingly", "naughtily"
};
static final String[] VERBS = {
"ate", "juggled", "bounced", "dropped", "hid"
};
static final String[] ADJECTIVES = {
"yellow", "polkadot", "small", "smelly", "tasty", "plastic"
};
static final String[] OBJS = {
"toy ducks", "mice", "bananas", "tissues", "shoes"
};
public String getSubject() {
return subject;
}
public String getAdverb() {
return adverb;
}
public String getVerb() {
return verb;
}
public String getAdjective() {
return adjective;
}
public String getObj() {
return obj;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setAdverb(String adverb) {
this.adverb = adverb;
}
public void setVerb(String verb) {
this.verb = verb;
}
public void setAdjective(String adjective) {
this.adjective = adjective;
}
public void setObj(String obj) {
this.obj = obj;
}
String subject;
String adverb;
String verb;
String adjective;
String obj;
public String allocate(String[] candidates) {
return candidates[(int)(Math.random() * candidates.length)];
}
public Gibberish() {
this.subject = allocate(SUBJECTS);
this.adverb = allocate(ADVERBS);
this.verb = allocate(VERBS);
this.adjective = allocate(ADJECTIVES);
this.obj = allocate(OBJS);
}
@Override
public String toString() {
return subject + " " + adverb + " " + verb + " " + adjective + " " + obj + ".";
}
}
\ No newline at end of file
package model;
/**
* Created by davidmccormick on 21/08/16.
*/
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* This is a simple publish-subscribe list. It maintains a list of listeners, and whenever it receives a call to