mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2024-11-22 18:47:20 +01:00
rework webpaste package
This commit is contained in:
parent
b9267a3dfc
commit
4f41b7aa6e
53
pom.xml
53
pom.xml
@ -9,6 +9,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.build.number>UNKNOWN</project.build.number>
|
<project.build.number>UNKNOWN</project.build.number>
|
||||||
|
<project.bitly-access-token>bitly-access-token</project.bitly-access-token>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
@ -69,6 +70,17 @@
|
|||||||
<project.build.number>${env.BUILD_NUMBER}</project.build.number>
|
<project.build.number>${env.BUILD_NUMBER}</project.build.number>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>bitly</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>env.BITLY_ACCESS_TOKEN</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<properties>
|
||||||
|
<project.bitly-access-token>${env.BITLY_ACCESS_TOKEN}</project.bitly-access-token>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -90,21 +102,44 @@
|
|||||||
<version>1.4.1</version>
|
<version>1.4.1</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
<id>replace-bitly-access-token</id>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>replace</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<basedir>${project.build.sourceDirectory}</basedir>
|
||||||
|
<includes>
|
||||||
|
<include>com/onarandombox/MultiverseCore/utils/webpaste/BitlyURLShortener.java</include>
|
||||||
|
</includes>
|
||||||
|
<replacements>
|
||||||
|
<replacement>
|
||||||
|
<token>bitly-access-token</token>
|
||||||
|
<value>${project.bitly-access-token}</value>
|
||||||
|
</replacement>
|
||||||
|
</replacements>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>replace-maven-version-number</id>
|
||||||
<phase>prepare-package</phase>
|
<phase>prepare-package</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>replace</goal>
|
<goal>replace</goal>
|
||||||
</goals>
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<basedir>${project.build.directory}/classes</basedir>
|
||||||
|
<includes>
|
||||||
|
<include>plugin.yml</include>
|
||||||
|
</includes>
|
||||||
|
<replacements>
|
||||||
|
<replacement>
|
||||||
|
<token>maven-version-number</token>
|
||||||
|
<value>${project.version}-b${project.build.number}</value>
|
||||||
|
</replacement>
|
||||||
|
</replacements>
|
||||||
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
<configuration>
|
|
||||||
<file>target/classes/plugin.yml</file>
|
|
||||||
<replacements>
|
|
||||||
<replacement>
|
|
||||||
<token>maven-version-number</token>
|
|
||||||
<value>${project.version}-b${project.build.number}</value>
|
|
||||||
</replacement>
|
|
||||||
</replacements>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- Jar Plugin -->
|
<!-- Jar Plugin -->
|
||||||
<plugin>
|
<plugin>
|
||||||
|
@ -10,12 +10,13 @@ package com.onarandombox.MultiverseCore.commands;
|
|||||||
import com.dumptruckman.minecraft.util.Logging;
|
import com.dumptruckman.minecraft.util.Logging;
|
||||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||||
import com.onarandombox.MultiverseCore.event.MVVersionEvent;
|
import com.onarandombox.MultiverseCore.event.MVVersionEvent;
|
||||||
import com.onarandombox.MultiverseCore.utils.webpaste.BitlyURLShortener;
|
|
||||||
import com.onarandombox.MultiverseCore.utils.webpaste.PasteFailedException;
|
import com.onarandombox.MultiverseCore.utils.webpaste.PasteFailedException;
|
||||||
import com.onarandombox.MultiverseCore.utils.webpaste.PasteService;
|
import com.onarandombox.MultiverseCore.utils.webpaste.PasteService;
|
||||||
import com.onarandombox.MultiverseCore.utils.webpaste.PasteServiceFactory;
|
import com.onarandombox.MultiverseCore.utils.webpaste.PasteServiceFactory;
|
||||||
import com.onarandombox.MultiverseCore.utils.webpaste.PasteServiceType;
|
import com.onarandombox.MultiverseCore.utils.webpaste.PasteServiceType;
|
||||||
import com.onarandombox.MultiverseCore.utils.webpaste.URLShortener;
|
import com.onarandombox.MultiverseCore.utils.webpaste.URLShortener;
|
||||||
|
import com.onarandombox.MultiverseCore.utils.webpaste.URLShortenerFactory;
|
||||||
|
import com.onarandombox.MultiverseCore.utils.webpaste.URLShortenerType;
|
||||||
import com.pneumaticraft.commandhandler.CommandHandler;
|
import com.pneumaticraft.commandhandler.CommandHandler;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -38,7 +39,7 @@ import java.util.Map;
|
|||||||
* Dumps version info to the console.
|
* Dumps version info to the console.
|
||||||
*/
|
*/
|
||||||
public class VersionCommand extends MultiverseCommand {
|
public class VersionCommand extends MultiverseCommand {
|
||||||
private static final URLShortener SHORTENER = new BitlyURLShortener();
|
private static final URLShortener SHORTENER = URLShortenerFactory.getService(URLShortenerType.BITLY);
|
||||||
|
|
||||||
public VersionCommand(MultiverseCore plugin) {
|
public VersionCommand(MultiverseCore plugin) {
|
||||||
super(plugin);
|
super(plugin);
|
||||||
@ -174,15 +175,10 @@ public class VersionCommand extends MultiverseCommand {
|
|||||||
if (CommandHandler.hasFlag("-b", args)) {
|
if (CommandHandler.hasFlag("-b", args)) {
|
||||||
// private post to pastebin
|
// private post to pastebin
|
||||||
pasteUrl = postToService(PasteServiceType.PASTEBIN, true, data, files);
|
pasteUrl = postToService(PasteServiceType.PASTEBIN, true, data, files);
|
||||||
}
|
} else if (CommandHandler.hasFlag("-g", args)) {
|
||||||
|
|
||||||
// pasting to GitHub now requires an account, so we've disabled it
|
|
||||||
/* else if (CommandHandler.hasFlag("-g", args)) {
|
|
||||||
// private post to github
|
// private post to github
|
||||||
pasteUrl = postToService(PasteServiceType.GITHUB, true, data, files);
|
pasteUrl = postToService(PasteServiceType.GITHUB, true, data, files);
|
||||||
} */
|
} else if (CommandHandler.hasFlag("-h", args)) {
|
||||||
|
|
||||||
else if (CommandHandler.hasFlag("-h", args)) {
|
|
||||||
// private post to hastebin
|
// private post to hastebin
|
||||||
pasteUrl = postToService(PasteServiceType.HASTEBIN, true, data, files);
|
pasteUrl = postToService(PasteServiceType.HASTEBIN, true, data, files);
|
||||||
} else {
|
} else {
|
||||||
@ -210,17 +206,19 @@ public class VersionCommand extends MultiverseCommand {
|
|||||||
* @param pasteFiles Map of filenames/contents of debug info.
|
* @param pasteFiles Map of filenames/contents of debug info.
|
||||||
* @return URL of visible paste
|
* @return URL of visible paste
|
||||||
*/
|
*/
|
||||||
private static String postToService(PasteServiceType type, boolean isPrivate, String pasteData,
|
private static String postToService(PasteServiceType type, boolean isPrivate, String pasteData, Map<String, String> pasteFiles) {
|
||||||
Map<String, String> pasteFiles) {
|
|
||||||
PasteService ps = PasteServiceFactory.getService(type, isPrivate);
|
PasteService ps = PasteServiceFactory.getService(type, isPrivate);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String result;
|
String result;
|
||||||
if (ps.supportsMultiFile()) {
|
if (ps.supportsMultiFile()) {
|
||||||
result = ps.postData(ps.encodeData(pasteFiles), ps.getPostURL());
|
result = ps.postData(pasteFiles);
|
||||||
} else {
|
} else {
|
||||||
result = ps.postData(ps.encodeData(pasteData), ps.getPostURL());
|
result = ps.postData(pasteData);
|
||||||
}
|
}
|
||||||
return SHORTENER.shorten(result);
|
|
||||||
|
if (SHORTENER != null) return SHORTENER.shorten(result);
|
||||||
|
return result;
|
||||||
} catch (PasteFailedException e) {
|
} catch (PasteFailedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return "Error posting to service.";
|
return "Error posting to service.";
|
||||||
|
@ -1,19 +1,41 @@
|
|||||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||||
|
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
import org.json.simple.parser.JSONParser;
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link URLShortener} using {@code bit.ly}.
|
* An {@link URLShortener} using {@code bit.ly}.
|
||||||
*/
|
*/
|
||||||
public class BitlyURLShortener extends HttpAPIClient implements URLShortener {
|
class BitlyURLShortener extends URLShortener {
|
||||||
private static final String GENERIC_BITLY_REQUEST_FORMAT = "https://api-ssl.bitly.com/v3/shorten?format=txt&apiKey=%s&login=%s&longUrl=%s";
|
private static final String ACCESS_TOKEN = "Bearer bitly-access-token";
|
||||||
|
private static final String BITLY_POST_REQUEST = "https://api-ssl.bitly.com/v4/shorten";
|
||||||
// I think it's no problem that these are public
|
|
||||||
private static final String USERNAME = "multiverse2";
|
|
||||||
private static final String API_KEY = "R_9dbff4862a3bc0c4218a7d78cc10d0e0";
|
|
||||||
|
|
||||||
public BitlyURLShortener() {
|
public BitlyURLShortener() {
|
||||||
super(String.format(GENERIC_BITLY_REQUEST_FORMAT, API_KEY, USERNAME, "%s"));
|
super(BITLY_POST_REQUEST, ACCESS_TOKEN);
|
||||||
|
if (ACCESS_TOKEN.endsWith("access-token")) throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String encodeData(String data) {
|
||||||
|
JSONObject json = new JSONObject();
|
||||||
|
json.put("domain", "j.mp");
|
||||||
|
json.put("long_url", data);
|
||||||
|
return json.toJSONString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String encodeData(Map<String, String> data) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,13 +44,11 @@ public class BitlyURLShortener extends HttpAPIClient implements URLShortener {
|
|||||||
@Override
|
@Override
|
||||||
public String shorten(String longUrl) {
|
public String shorten(String longUrl) {
|
||||||
try {
|
try {
|
||||||
String result = this.exec(longUrl);
|
String stringJSON = this.exec(encodeData(longUrl), ContentType.JSON);
|
||||||
if (!result.startsWith("https://j.mp/")) // ... then it's failed :/
|
return (String) ((JSONObject) new JSONParser().parse(stringJSON)).get("link");
|
||||||
throw new IOException(result);
|
} catch (IOException | ParseException e) {
|
||||||
return result;
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return longUrl; // sorry ...
|
return longUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,23 @@
|
|||||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import org.json.simple.JSONObject;
|
||||||
import com.google.gson.JsonParser;
|
import org.json.simple.parser.JSONParser;
|
||||||
import com.google.gson.JsonPrimitive;
|
import org.json.simple.parser.ParseException;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class GitHubPasteService implements PasteService {
|
public class GitHubPasteService extends PasteService {
|
||||||
|
|
||||||
private final boolean isPrivate;
|
private final boolean isPrivate;
|
||||||
|
// this access token must have the "gist" OAuth scope
|
||||||
|
private static final String ACCESS_TOKEN = "token github-access-token";
|
||||||
|
private static final String GITHUB_POST_REQUEST = "https://api.github.com/gists";
|
||||||
|
|
||||||
public GitHubPasteService(boolean isPrivate) {
|
public GitHubPasteService(boolean isPrivate) {
|
||||||
|
super(GITHUB_POST_REQUEST, ACCESS_TOKEN);
|
||||||
this.isPrivate = isPrivate;
|
this.isPrivate = isPrivate;
|
||||||
|
if (ACCESS_TOKEN.endsWith("access-token")) throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -32,68 +29,37 @@ public class GitHubPasteService implements PasteService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String encodeData(Map<String, String> files) {
|
public String encodeData(Map<String, String> files) {
|
||||||
JsonObject root = new JsonObject();
|
JSONObject root = new JSONObject();
|
||||||
root.add("description", new JsonPrimitive("Multiverse-Core Debug Info"));
|
root.put("description", "Multiverse-Core Debug Info");
|
||||||
root.add("public", new JsonPrimitive(!this.isPrivate));
|
root.put("public", !this.isPrivate);
|
||||||
JsonObject fileList = new JsonObject();
|
JSONObject fileList = new JSONObject();
|
||||||
for (Map.Entry<String, String> entry : files.entrySet())
|
for (Map.Entry<String, String> entry : files.entrySet()) {
|
||||||
{
|
JSONObject fileObject = new JSONObject();
|
||||||
JsonObject fileObject = new JsonObject();
|
fileObject.put("content", entry.getValue());
|
||||||
fileObject.add("content", new JsonPrimitive(entry.getValue()));
|
fileList.put(entry.getKey(), fileObject);
|
||||||
fileList.add(entry.getKey(), fileObject);
|
|
||||||
}
|
}
|
||||||
root.add("files", fileList);
|
|
||||||
return root.toString();
|
root.put("files", fileList);
|
||||||
|
return root.toJSONString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URL getPostURL() {
|
public String postData(String data) throws PasteFailedException {
|
||||||
try {
|
try {
|
||||||
return new URL("https://api.github.com/gists");
|
String stringJSON = this.exec(encodeData(data), ContentType.JSON);
|
||||||
|
return (String) ((JSONObject) new JSONParser().parse(stringJSON)).get("html_url");
|
||||||
// the following can be used for testing purposes
|
} catch (IOException | ParseException e) {
|
||||||
// return new URL("http://jsonplaceholder.typicode.com/posts");
|
throw new PasteFailedException(e);
|
||||||
} catch (MalformedURLException e) {
|
}
|
||||||
return null; // should never hit here
|
}
|
||||||
}
|
|
||||||
}
|
@Override
|
||||||
|
public String postData(Map<String, String> data) throws PasteFailedException {
|
||||||
@Override
|
try {
|
||||||
public String postData(String encodedData, URL url) throws PasteFailedException {
|
String stringJSON = this.exec(encodeData(data), ContentType.JSON);
|
||||||
OutputStreamWriter wr = null;
|
return (String) ((JSONObject) new JSONParser().parse(stringJSON)).get("html_url");
|
||||||
BufferedReader rd = null;
|
} catch (IOException | ParseException e) {
|
||||||
try {
|
|
||||||
URLConnection conn = url.openConnection();
|
|
||||||
conn.setDoOutput(true);
|
|
||||||
|
|
||||||
// this isn't required, but is technically correct
|
|
||||||
conn.addRequestProperty("Content-Type", "application/json; charset=utf-8");
|
|
||||||
|
|
||||||
wr = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
|
|
||||||
wr.write(encodedData);
|
|
||||||
wr.flush();
|
|
||||||
|
|
||||||
String line;
|
|
||||||
StringBuilder responseString = new StringBuilder();
|
|
||||||
// this has to be initialized AFTER the data has been flushed!
|
|
||||||
rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
|
|
||||||
while ((line = rd.readLine()) != null) {
|
|
||||||
responseString.append(line);
|
|
||||||
}
|
|
||||||
return new JsonParser().parse(responseString.toString()).getAsJsonObject().get("html_url").getAsString();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new PasteFailedException(e);
|
throw new PasteFailedException(e);
|
||||||
} finally {
|
|
||||||
if (wr != null) {
|
|
||||||
try {
|
|
||||||
wr.close();
|
|
||||||
} catch (IOException ignore) { }
|
|
||||||
}
|
|
||||||
if (rd != null) {
|
|
||||||
try {
|
|
||||||
rd.close();
|
|
||||||
} catch (IOException ignore) { }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,81 +1,55 @@
|
|||||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||||
|
|
||||||
import com.google.gson.JsonParser;
|
import org.json.simple.JSONObject;
|
||||||
|
import org.json.simple.parser.JSONParser;
|
||||||
|
import org.json.simple.parser.ParseException;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pastes to {@code hastebin.com}.
|
* Pastes to {@code hastebin.com}.
|
||||||
*/
|
*/
|
||||||
public class HastebinPasteService implements PasteService {
|
class HastebinPasteService extends PasteService {
|
||||||
|
private static final String HASTEBIN_POST_REQUEST = "https://hastebin.com/documents";
|
||||||
|
|
||||||
|
public HastebinPasteService() {
|
||||||
|
super(HASTEBIN_POST_REQUEST, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String encodeData(String data) {
|
public String encodeData(String data) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String encodeData(Map<String, String> data) {
|
public String encodeData(Map<String, String> data) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URL getPostURL() {
|
public String postData(String data) throws PasteFailedException {
|
||||||
try {
|
try {
|
||||||
return new URL("https://hastebin.com/documents");
|
String stringJSON = this.exec(encodeData(data), ContentType.PLAINTEXT);
|
||||||
} catch (MalformedURLException e) {
|
return "https://hastebin.com/" + ((JSONObject) new JSONParser().parse(stringJSON)).get("key");
|
||||||
return null; // should never hit here
|
} catch (IOException | ParseException e) {
|
||||||
|
throw new PasteFailedException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String postData(String encodedData, URL url) throws PasteFailedException {
|
public String postData(Map<String, String> data) throws PasteFailedException {
|
||||||
OutputStreamWriter wr = null;
|
|
||||||
BufferedReader rd = null;
|
|
||||||
try {
|
try {
|
||||||
URLConnection conn = url.openConnection();
|
String stringJSON = this.exec(encodeData(data), ContentType.PLAINTEXT);
|
||||||
conn.setDoOutput(true);
|
return "https://hastebin.com/" + ((JSONObject) new JSONParser().parse(stringJSON)).get("key");
|
||||||
|
} catch (IOException | ParseException e) {
|
||||||
// hastebin needs a user-agent
|
|
||||||
conn.addRequestProperty("User-Agent", "placeholder");
|
|
||||||
// this isn't required, but is technically correct
|
|
||||||
conn.addRequestProperty("Content-Type", "text/plain; charset=utf-8");
|
|
||||||
|
|
||||||
wr = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8.newEncoder());
|
|
||||||
wr.write(encodedData);
|
|
||||||
wr.flush();
|
|
||||||
|
|
||||||
String line;
|
|
||||||
StringBuilder responseString = new StringBuilder();
|
|
||||||
// this has to be initialized AFTER the data has been flushed!
|
|
||||||
rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
|
|
||||||
while ((line = rd.readLine()) != null) {
|
|
||||||
responseString.append(line);
|
|
||||||
}
|
|
||||||
String key = new JsonParser().parse(responseString.toString()).getAsJsonObject().get("key").getAsString();
|
|
||||||
|
|
||||||
return "https://hastebin.com/" + key;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new PasteFailedException(e);
|
throw new PasteFailedException(e);
|
||||||
} finally {
|
|
||||||
if (wr != null) {
|
|
||||||
try {
|
|
||||||
wr.close();
|
|
||||||
} catch (IOException ignore) { }
|
|
||||||
}
|
|
||||||
if (rd != null) {
|
|
||||||
try {
|
|
||||||
rd.close();
|
|
||||||
} catch (IOException ignore) { }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,51 +1,115 @@
|
|||||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTTP API-client.
|
* HTTP API-client.
|
||||||
*/
|
*/
|
||||||
public abstract class HttpAPIClient {
|
public abstract class HttpAPIClient {
|
||||||
/**
|
/**
|
||||||
* The URL for this API-request.
|
* The URL for this API-request, and if necessary, the access token.
|
||||||
|
* If an access token is not necessary, it should be set to null.
|
||||||
*/
|
*/
|
||||||
protected final String urlFormat;
|
private final String url;
|
||||||
|
private final String accessToken;
|
||||||
|
|
||||||
public HttpAPIClient(String urlFormat) {
|
/**
|
||||||
this.urlFormat = urlFormat;
|
* Types of data that can be sent.
|
||||||
|
*/
|
||||||
|
protected enum ContentType {
|
||||||
|
JSON,
|
||||||
|
PLAINTEXT,
|
||||||
|
URLENCODED
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpAPIClient(String url, String accessToken) {
|
||||||
|
this.url = url;
|
||||||
|
this.accessToken = accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getContentHeader(ContentType type) {
|
||||||
|
switch (type) {
|
||||||
|
case JSON:
|
||||||
|
return "application/json; charset=utf-8";
|
||||||
|
case PLAINTEXT:
|
||||||
|
return "text/plain; charset=utf-8";
|
||||||
|
case URLENCODED:
|
||||||
|
return "application/x-www-form-urlencoded; charset=utf-8";
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unexpected value: " + type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode the given String data into a format suitable for transmission in an HTTP request.
|
||||||
|
*
|
||||||
|
* @param data The raw data to encode.
|
||||||
|
* @return A URL-encoded string.
|
||||||
|
*/
|
||||||
|
protected abstract String encodeData(String data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode the given Map data into a format suitable for transmission in an HTTP request.
|
||||||
|
*
|
||||||
|
* @param data The raw data to encode.
|
||||||
|
* @return A URL-encoded string.
|
||||||
|
*/
|
||||||
|
protected abstract String encodeData(Map<String, String> data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes this API-Request.
|
* Executes this API-Request.
|
||||||
* @param args Format-args.
|
* @param payload The data that will be sent.
|
||||||
|
* @param type The type of data that will be sent.
|
||||||
* @return The result (as text).
|
* @return The result (as text).
|
||||||
* @throws IOException When the I/O-operation failed.
|
* @throws IOException When the I/O-operation failed.
|
||||||
*/
|
*/
|
||||||
protected final String exec(Object... args) throws IOException {
|
protected final String exec(String payload, ContentType type) throws IOException {
|
||||||
|
BufferedReader rd = null;
|
||||||
|
OutputStreamWriter wr = null;
|
||||||
|
|
||||||
URLConnection conn = new URL(String.format(this.urlFormat, args)).openConnection();
|
|
||||||
conn.connect();
|
|
||||||
StringBuilder ret = new StringBuilder();
|
|
||||||
BufferedReader reader = null;
|
|
||||||
try {
|
try {
|
||||||
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
|
HttpsURLConnection conn = (HttpsURLConnection) new URL(this.url).openConnection();
|
||||||
while (!reader.ready()); // wait until reader is ready, may not be necessary, SUPPRESS CHECKSTYLE: EmptyStatement
|
conn.setRequestMethod("POST");
|
||||||
|
conn.setDoOutput(true);
|
||||||
|
|
||||||
while (reader.ready()) {
|
// we can receive anything!
|
||||||
ret.append(reader.readLine()).append(System.lineSeparator());
|
conn.addRequestProperty("Accept", "*/*");
|
||||||
}
|
// set a dummy User-Agent
|
||||||
|
conn.addRequestProperty("User-Agent", "placeholder");
|
||||||
|
// this isn't required, but is technically correct
|
||||||
|
conn.addRequestProperty("Content-Type", getContentHeader(type));
|
||||||
|
// only some API requests require an access token
|
||||||
|
if (this.accessToken != null) conn.addRequestProperty("Authorization", this.accessToken);
|
||||||
|
|
||||||
|
wr = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8.newEncoder());
|
||||||
|
wr.write(payload);
|
||||||
|
wr.flush();
|
||||||
|
|
||||||
|
String line;
|
||||||
|
StringBuilder responseString = new StringBuilder();
|
||||||
|
// this has to be initialized AFTER the data has been flushed!
|
||||||
|
rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
while ((line = rd.readLine()) != null) responseString.append(line);
|
||||||
|
return responseString.toString();
|
||||||
} finally {
|
} finally {
|
||||||
if (reader != null) {
|
if (wr != null) {
|
||||||
try {
|
try {
|
||||||
reader.close();
|
wr.close();
|
||||||
|
} catch (IOException ignore) { }
|
||||||
|
}
|
||||||
|
if (rd != null) {
|
||||||
|
try {
|
||||||
|
rd.close();
|
||||||
} catch (IOException ignore) { }
|
} catch (IOException ignore) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,41 +14,30 @@ import java.util.Map;
|
|||||||
* should implement a custom constructor that specifies which kind the PasteService
|
* should implement a custom constructor that specifies which kind the PasteService
|
||||||
* instance is submitting; an example of this is the PastebinPasteService class.
|
* instance is submitting; an example of this is the PastebinPasteService class.
|
||||||
*/
|
*/
|
||||||
public interface PasteService {
|
public abstract class PasteService extends HttpAPIClient {
|
||||||
|
public PasteService(String url, String accessToken) {
|
||||||
|
super(url, accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode the given String data into a format suitable for transmission in an HTTP request.
|
* Post data to the Web.
|
||||||
*
|
*
|
||||||
* @param data The raw data to encode.
|
* @param data A URL-encoded String containing the full request to post to
|
||||||
* @return A URL-encoded string.
|
* the given URL. Can be the result of calling #encodeData().
|
||||||
*/
|
|
||||||
String encodeData(String data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encode the given Map data into a format suitable for transmission in an HTTP request.
|
|
||||||
*
|
|
||||||
* @param data The raw data to encode.
|
|
||||||
* @return A URL-encoded string.
|
|
||||||
*/
|
|
||||||
String encodeData(Map<String, String> data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the URL to which this paste service sends new pastes.
|
|
||||||
*
|
|
||||||
* @return The URL that will be accessed to complete the paste.
|
|
||||||
*/
|
|
||||||
URL getPostURL();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Post encoded data to the Web.
|
|
||||||
*
|
|
||||||
* @param encodedData A URL-encoded String containing the full request to post to
|
|
||||||
* the given URL. Can be the result of calling #encodeData().
|
|
||||||
* @param url The URL to which to paste. Can be the result of calling #getPostURL().
|
|
||||||
* @throws PasteFailedException When pasting/posting the data failed.
|
* @throws PasteFailedException When pasting/posting the data failed.
|
||||||
* @return The URL at which the new paste is visible.
|
* @return The URL at which the new paste is visible.
|
||||||
*/
|
*/
|
||||||
String postData(String encodedData, URL url) throws PasteFailedException;
|
public abstract String postData(String data) throws PasteFailedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post data to the Web.
|
||||||
|
*
|
||||||
|
* @param data A URL-encoded Map containing the full request to post to
|
||||||
|
* the given URL. Can be the result of calling #encodeData().
|
||||||
|
* @throws PasteFailedException When pasting/posting the data failed.
|
||||||
|
* @return The URL at which the new paste is visible.
|
||||||
|
*/
|
||||||
|
public abstract String postData(Map<String, String> data) throws PasteFailedException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does this service support uploading multiple files.
|
* Does this service support uploading multiple files.
|
||||||
@ -59,5 +47,5 @@ public interface PasteService {
|
|||||||
*
|
*
|
||||||
* @return True if this service supports multiple file upload.
|
* @return True if this service supports multiple file upload.
|
||||||
*/
|
*/
|
||||||
boolean supportsMultiFile();
|
public abstract boolean supportsMultiFile();
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,22 @@
|
|||||||
package com.onarandombox.MultiverseCore.utils.webpaste;
|
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pastes to {@code pastebin.com}.
|
* Pastes to {@code pastebin.com}.
|
||||||
*/
|
*/
|
||||||
public class PastebinPasteService implements PasteService {
|
class PastebinPasteService extends PasteService {
|
||||||
|
private final boolean isPrivate;
|
||||||
private boolean isPrivate;
|
private static final String PASTEBIN_POST_REQUEST = "https://pastebin.com/api/api_post.php";
|
||||||
|
|
||||||
public PastebinPasteService(boolean isPrivate) {
|
public PastebinPasteService(boolean isPrivate) {
|
||||||
|
super(PASTEBIN_POST_REQUEST, null);
|
||||||
this.isPrivate = isPrivate;
|
this.isPrivate = isPrivate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public URL getPostURL() {
|
|
||||||
try {
|
|
||||||
return new URL("http://pastebin.com/api/api_post.php");
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
return null; // should never hit here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@ -42,59 +24,45 @@ public class PastebinPasteService implements PasteService {
|
|||||||
public String encodeData(String data) {
|
public String encodeData(String data) {
|
||||||
try {
|
try {
|
||||||
return URLEncoder.encode("api_dev_key", "UTF-8") + "=" + URLEncoder.encode("d61d68d31e8e0392b59b50b277411c71", "UTF-8") +
|
return URLEncoder.encode("api_dev_key", "UTF-8") + "=" + URLEncoder.encode("d61d68d31e8e0392b59b50b277411c71", "UTF-8") +
|
||||||
"&" + URLEncoder.encode("api_option", "UTF-8") + "=" + URLEncoder.encode("paste", "UTF-8") +
|
"&" + URLEncoder.encode("api_option", "UTF-8") + "=" + URLEncoder.encode("paste", "UTF-8") +
|
||||||
"&" + URLEncoder.encode("api_paste_code", "UTF-8") + "=" + URLEncoder.encode(data, "UTF-8") +
|
"&" + URLEncoder.encode("api_paste_code", "UTF-8") + "=" + URLEncoder.encode(data, "UTF-8") +
|
||||||
"&" + URLEncoder.encode("api_paste_private", "UTF-8") + "=" + URLEncoder.encode(this.isPrivate ? "1" : "0", "UTF-8") +
|
"&" + URLEncoder.encode("api_paste_private", "UTF-8") + "=" + URLEncoder.encode(this.isPrivate ? "1" : "0", "UTF-8") +
|
||||||
"&" + URLEncoder.encode("api_paste_format", "UTF-8") + "=" + URLEncoder.encode("yaml", "UTF-8");
|
"&" + URLEncoder.encode("api_paste_format", "UTF-8") + "=" + URLEncoder.encode("yaml", "UTF-8") +
|
||||||
|
"&" + URLEncoder.encode("api_paste_name", "UTF-8") + "=" + URLEncoder.encode("Multiverse-Core Debug Info", "UTF-8");
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
return ""; // should never hit here
|
return ""; // should never hit here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String encodeData(Map<String, String> data) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String postData(String encodedData, URL url) throws PasteFailedException {
|
public String encodeData(Map<String, String> data) {
|
||||||
OutputStreamWriter wr = null;
|
throw new UnsupportedOperationException();
|
||||||
BufferedReader rd = null;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String postData(String data) throws PasteFailedException {
|
||||||
try {
|
try {
|
||||||
URLConnection conn = url.openConnection();
|
return this.exec(encodeData(data), ContentType.URLENCODED);
|
||||||
conn.setDoOutput(true);
|
} catch (IOException e) {
|
||||||
|
throw new PasteFailedException(e);
|
||||||
// this isn't required, but is technically correct
|
}
|
||||||
conn.addRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
|
}
|
||||||
|
|
||||||
wr = new OutputStreamWriter(conn.getOutputStream(), StandardCharsets.UTF_8);
|
/**
|
||||||
wr.write(encodedData);
|
* {@inheritDoc}
|
||||||
wr.flush();
|
*/
|
||||||
|
@Override
|
||||||
String line;
|
public String postData(Map<String, String> data) throws PasteFailedException {
|
||||||
String pastebinUrl = "";
|
try {
|
||||||
// this has to be initialized AFTER the data has been flushed!
|
return this.exec(encodeData(data), ContentType.URLENCODED);
|
||||||
rd = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
|
} catch (IOException e) {
|
||||||
while ((line = rd.readLine()) != null) {
|
|
||||||
pastebinUrl = line;
|
|
||||||
}
|
|
||||||
return pastebinUrl;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new PasteFailedException(e);
|
throw new PasteFailedException(e);
|
||||||
} finally {
|
|
||||||
if (wr != null) {
|
|
||||||
try {
|
|
||||||
wr.close();
|
|
||||||
} catch (IOException ignore) { }
|
|
||||||
}
|
|
||||||
if (rd != null) {
|
|
||||||
try {
|
|
||||||
rd.close();
|
|
||||||
} catch (IOException ignore) { }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,11 +3,15 @@ package com.onarandombox.MultiverseCore.utils.webpaste;
|
|||||||
/**
|
/**
|
||||||
* URL-Shortener.
|
* URL-Shortener.
|
||||||
*/
|
*/
|
||||||
public interface URLShortener {
|
public abstract class URLShortener extends HttpAPIClient {
|
||||||
|
public URLShortener(String url, String accessToken) {
|
||||||
|
super(url, accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shorten an URL.
|
* Shorten a URL.
|
||||||
* @param longUrl The long form.
|
* @param longUrl The long form.
|
||||||
* @return The shortened URL.
|
* @return The shortened URL.
|
||||||
*/
|
*/
|
||||||
String shorten(String longUrl);
|
public abstract String shorten(String longUrl);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to construct {@link URLShortener}s.
|
||||||
|
*/
|
||||||
|
public class URLShortenerFactory {
|
||||||
|
private URLShortenerFactory() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link URLShortener}.
|
||||||
|
* @param type The {@link URLShortenerType}.
|
||||||
|
* @return The newly created {@link URLShortener}.
|
||||||
|
*/
|
||||||
|
public static URLShortener getService(URLShortenerType type) {
|
||||||
|
if (type == URLShortenerType.BITLY) {
|
||||||
|
try {
|
||||||
|
return new BitlyURLShortener();
|
||||||
|
} catch (UnsupportedOperationException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.onarandombox.MultiverseCore.utils.webpaste;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An enum containing all known {@link URLShortener}s.
|
||||||
|
*
|
||||||
|
* @see URLShortener
|
||||||
|
* @see URLShortenerFactory
|
||||||
|
*/
|
||||||
|
public enum URLShortenerType {
|
||||||
|
/**
|
||||||
|
* @see BitlyURLShortener
|
||||||
|
*/
|
||||||
|
BITLY
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user