package controllers; import javax.inject.Inject; import javax.inject.Singleton; import models.Proposal; import models.RegisteredUser; import play.data.Form; import play.libs.F.Callback; import play.libs.F.Callback0; import play.libs.F.Function; import play.libs.F.Promise; import play.libs.F.Tuple; import play.libs.OAuth.RequestToken; import play.mvc.Controller; import play.mvc.Result; import play.mvc.WebSocket; import actors.messages.CloseConnectionEvent; import actors.messages.NewConnectionEvent; import actors.messages.NewProposalEvent; import actors.messages.UserRegistrationEvent; import akka.actor.ActorRef; import com.fasterxml.jackson.databind.JsonNode; import external.services.OAuthService; @Singleton public class Application extends Controller { private final Form<Proposal> proposalForm = Form.form(Proposal.class); private final ActorRef ref; private final OAuthService oauthService; @Inject public Application(ActorRef ref, OAuthService oauthService) { this.ref = ref; this.oauthService = oauthService; } public Result register() { String callbackUrl = routes.Application.registerCallback().absoluteURL(request()); Tuple<String, RequestToken> t = oauthService.retrieveRequestToken(callbackUrl); flash("request_token", t._2.token); flash("request_secret", t._2.secret); return redirect(t._1); } public Result registerCallback() { RequestToken token = new RequestToken(flash("request_token"), flash("request_secret")); String authVerifier = request().getQueryString("oauth_verifier"); Promise<JsonNode> userProfile = oauthService.registeredUserProfile(token, authVerifier); userProfile.onRedeem(new Callback<JsonNode>(){ @Override public void invoke(JsonNode twitterJson) throws Throwable { RegisteredUser user = RegisteredUser.fromJson(twitterJson); user.save(); ref.tell(new UserRegistrationEvent(user), ActorRef.noSender()); } }); return redirect(routes.Application.index()); } public WebSocket<JsonNode> buzz() { return new WebSocket<JsonNode>() { @Override public void onReady(play.mvc.WebSocket.In<JsonNode> in, play.mvc.WebSocket.Out<JsonNode> out) { //use the out channel to push the data back to the client final String uuid = java.util.UUID.randomUUID().toString(); ref.tell(new NewConnectionEvent(uuid, out), ActorRef.noSender()); in.onClose(new Callback0() { @Override public void invoke() throws Throwable { ref.tell(new CloseConnectionEvent(uuid), ActorRef.noSender()); } }); } }; } public Promise<Result> index() { Promise<Proposal> keynote = Proposal.findKeynote(); Promise<Result> result = keynote.map(new Function<Proposal, Result>() { @Override public Result apply(Proposal keynote) throws Throwable { return ok(views.html.index.render(keynote)); } }); return result; } public Result newProposal() { return ok(views.html.newProposal.render(proposalForm)); } public Promise<Result> submitProposal() { Form<Proposal> submittedForm = proposalForm.bindFromRequest(); if(submittedForm.hasErrors()) { return Promise.<Result>pure(ok(views.html.newProposal.render(submittedForm))); } else { final Proposal proposal = submittedForm.get(); Promise<Result> r = proposal.asyncSave().map(new Function<Void, Result>(){ @Override public Result apply(Void arg0) throws Throwable { flash ("message", "Thanks for submitting a proposal"); ref.tell(new NewProposalEvent(proposal), ActorRef.noSender()); return redirect(routes.Application.index()); } }); return r; } } }