package controllers;
import com.atlassian.plugin.remotable.play.Ap3;
import com.atlassian.plugin.remotable.play.CheckValidOAuthRequest;
import com.atlassian.plugin.remotable.play.controllers.Ap3Controller;
import com.atlassian.plugin.remotable.play.util.Environment;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import models.Paste;
import org.apache.commons.lang.StringUtils;
import org.leberrigaud.pastebin.utils.Api;
import org.leberrigaud.pastebin.utils.Hash;
import org.leberrigaud.pastebin.utils.Languages;
import org.leberrigaud.pastebin.utils.PastebinUrl;
import play.Logger;
import play.libs.F;
import play.libs.WS;
import play.mvc.Result;
import utils.WsUtils;
import views.html.index;
import views.html.pastebinBadRequest;
import views.html.pastebinMacro;
import views.xml.descriptor;
import static com.atlassian.fugue.Option.option;
import static play.mvc.Results.async;
import static play.mvc.Results.badRequest;
import static play.mvc.Results.ok;
public final class Pastebin extends Ap3Controller
{
public static Result index()
{
return Ap3Controller.index(
new Supplier<Result>()
{
@Override
public Result get()
{
return ok(index.render());
}
},
new Supplier<Result>()
{
@Override
public Result get()
{
return ok(descriptor.render("1.0-SNAPSHOT", Ap3.baseUrl.get()));
}
}
);
}
@CheckValidOAuthRequest
public static Result renderMacro(String id, final String body, String lang)
{
if (StringUtils.isBlank(id) && StringUtils.isNotBlank(body))
{
final String actualLang = Languages.forRequestParameter(lang);
final String sha1 = Hash.of(body, actualLang);
Logger.debug("Got some code, sha1 is " + sha1);
final Paste paste = Paste.findByHash(sha1);
if (paste != null)
{
Logger.info("Found id " + paste.key + " for code with sha1 " + sha1);
return ok(pastebinMacro.render(paste.key, body));
}
Logger.debug("Need to generate an id for code with sha1 " + sha1);
return Api.post(body, actualLang, new Api.Call<Result>()
{
public Result call(String url, ImmutableMap<String, String> parameters)
{
return async(WsUtils.post(url, parameters)
.map(new F.Function<WS.Response, Result>()
{
public Result apply(WS.Response response) throws Throwable
{
final String responseBody = response.getBody();
if (PastebinUrl.isUrl(responseBody))
{
final String pasteId = PastebinUrl.id(responseBody);
final Paste p = new Paste();
p.key = pasteId;
p.hash = sha1;
Paste.create(p);
Logger.info("Created id " + pasteId + " for code with sha1 " + sha1);
return ok(pastebinMacro.render(pasteId, body));
}
else
{
Logger.warn("Got an error trying to generate id for sha1 " + sha1);
return badRequest(pastebinBadRequest.render(responseBody, body));
}
}
})
.recover(new F.Function<Throwable, Result>()
{
@Override
public Result apply(Throwable throwable) throws Throwable
{
Logger.warn("Got an error trying access PasteBin service: " + sha1, throwable);
return badRequest(pastebinBadRequest.render(throwable.getMessage(), body));
}
}));
}
}, Suppliers.ofInstance(option(Environment.getEnv("PASTEBIN_USER_KEY"))));
}
else if (StringUtils.isNotBlank(id))
{
Logger.info("Got id " + id + " from the macro.");
return ok(pastebinMacro.render(PastebinUrl.id(id), ""));
}
else
{
Logger.info("Got neither an id nor a code body from the macro.");
return badRequest(pastebinBadRequest.render("Please fill either the ID or the body, not both!", body));
}
}
}