Merge pull request #2288 from Multiverse/webpaste

Rework Webpaste Package
This commit is contained in:
Jeremy Wood 2020-07-28 20:50:08 -04:00 committed by GitHub
commit 242f05fc77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 597 additions and 371 deletions

41
pom.xml
View File

@ -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,14 +102,35 @@
<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>
</execution>
</executions>
<configuration> <configuration>
<file>target/classes/plugin.yml</file> <basedir>${project.build.directory}/classes</basedir>
<includes>
<include>plugin.yml</include>
</includes>
<replacements> <replacements>
<replacement> <replacement>
<token>maven-version-number</token> <token>maven-version-number</token>
@ -105,6 +138,8 @@
</replacement> </replacement>
</replacements> </replacements>
</configuration> </configuration>
</execution>
</executions>
</plugin> </plugin>
<!-- Jar Plugin --> <!-- Jar Plugin -->
<plugin> <plugin>

View File

@ -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;
@ -24,9 +25,12 @@ import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.permissions.PermissionDefault; import org.bukkit.permissions.PermissionDefault;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.StringUtil;
import java.io.*; import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -35,94 +39,89 @@ 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);
this.setName("Multiverse Version"); this.setName("Multiverse Version");
this.setCommandUsage("/mv version " + ChatColor.GOLD + "-[bh] [--include-plugin-list]"); this.setCommandUsage("/mv version " + ChatColor.GOLD + "-[bhp] [--include-plugin-list]");
this.setArgRange(0, 2); this.setArgRange(0, 2);
this.addKey("mv version"); this.addKey("mv version");
this.addKey("mvv"); this.addKey("mvv");
this.addKey("mvversion"); this.addKey("mvversion");
this.setPermission("multiverse.core.version", this.setPermission("multiverse.core.version",
"Dumps version info to the console, optionally to pastie.org with -p or pastebin.com with a -b.", PermissionDefault.TRUE); "Dumps version info to the console, optionally to pastebin.com with -b, to hastebin.com using -h, or to paste.gg with -p.", PermissionDefault.TRUE);
} }
private String getLegacyString() { private String getLegacyString() {
StringBuilder legacyFile = new StringBuilder(); return "[Multiverse-Core] Multiverse-Core Version: " + this.plugin.getDescription().getVersion() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] Multiverse-Core Version: ").append(this.plugin.getDescription().getVersion()).append('\n'); "[Multiverse-Core] Bukkit Version: " + this.plugin.getServer().getVersion() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] Bukkit Version: ").append(this.plugin.getServer().getVersion()).append('\n'); "[Multiverse-Core] Loaded Worlds: " + this.plugin.getMVWorldManager().getMVWorlds() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] Loaded Worlds: ").append(this.plugin.getMVWorldManager().getMVWorlds()).append('\n'); "[Multiverse-Core] Multiverse Plugins Loaded: " + this.plugin.getPluginCount() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] Multiverse Plugins Loaded: ").append(this.plugin.getPluginCount()).append('\n'); "[Multiverse-Core] Economy being used: " + plugin.getEconomist().getEconomyName() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] Economy being used: ").append(plugin.getEconomist().getEconomyName()).append('\n'); "[Multiverse-Core] Permissions Plugin: " + this.plugin.getMVPerms().getType() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] Permissions Plugin: ").append(this.plugin.getMVPerms().getType()).append('\n'); "[Multiverse-Core] Dumping Config Values: (version " + this.plugin.getMVConfig().getVersion() + ")" + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] Dumping Config Values: (version ") "[Multiverse-Core] messagecooldown: " + plugin.getMessaging().getCooldown() + System.lineSeparator() +
.append(this.plugin.getMVConfig().getVersion()).append(")").append('\n'); "[Multiverse-Core] teleportcooldown: " + plugin.getMVConfig().getTeleportCooldown() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] messagecooldown: ").append(plugin.getMessaging().getCooldown()).append('\n'); "[Multiverse-Core] worldnameprefix: " + plugin.getMVConfig().getPrefixChat() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] teleportcooldown: ").append(plugin.getMVConfig().getTeleportCooldown()).append('\n'); "[Multiverse-Core] worldnameprefixFormat: " + plugin.getMVConfig().getPrefixChatFormat() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] worldnameprefix: ").append(plugin.getMVConfig().getPrefixChat()).append('\n'); "[Multiverse-Core] enforceaccess: " + plugin.getMVConfig().getEnforceAccess() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] worldnameprefixFormat: ").append(plugin.getMVConfig().getPrefixChatFormat()).append('\n'); "[Multiverse-Core] displaypermerrors: " + plugin.getMVConfig().getDisplayPermErrors() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] enforceaccess: ").append(plugin.getMVConfig().getEnforceAccess()).append('\n'); "[Multiverse-Core] teleportintercept: " + plugin.getMVConfig().getTeleportIntercept() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] displaypermerrors: ").append(plugin.getMVConfig().getDisplayPermErrors()).append('\n'); "[Multiverse-Core] firstspawnoverride: " + plugin.getMVConfig().getFirstSpawnOverride() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] teleportintercept: ").append(plugin.getMVConfig().getTeleportIntercept()).append('\n'); "[Multiverse-Core] firstspawnworld: " + plugin.getMVConfig().getFirstSpawnWorld() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] firstspawnoverride: ").append(plugin.getMVConfig().getFirstSpawnOverride()).append('\n'); "[Multiverse-Core] debug: " + plugin.getMVConfig().getGlobalDebug() + System.lineSeparator() +
legacyFile.append("[Multiverse-Core] firstspawnworld: ").append(plugin.getMVConfig().getFirstSpawnWorld()).append('\n'); "[Multiverse-Core] Special Code: FRN002" + System.lineSeparator();
legacyFile.append("[Multiverse-Core] debug: ").append(plugin.getMVConfig().getGlobalDebug()).append('\n');
legacyFile.append("[Multiverse-Core] Special Code: FRN002").append('\n');
return legacyFile.toString();
} }
private String getMarkdownString() { private String getMarkdownString() {
StringBuilder markdownString = new StringBuilder(); return "# Multiverse-Core" + System.lineSeparator() +
markdownString.append("# Multiverse-Core\n"); "## Overview" + System.lineSeparator() +
markdownString.append("## Overview\n"); "| Name | Value |" + System.lineSeparator() +
markdownString.append("| Name | Value |\n"); "| --- | --- |" + System.lineSeparator() +
markdownString.append("| --- | --- |\n"); "| Multiverse-Core Version | `" + this.plugin.getDescription().getVersion() + "` |" + System.lineSeparator() +
markdownString.append("| Multiverse-Core Version | `").append(this.plugin.getDescription().getVersion()).append("` |\n"); "| Bukkit Version | `" + this.plugin.getServer().getVersion() + "` |" + System.lineSeparator() +
markdownString.append("| Bukkit Version | `").append(this.plugin.getServer().getVersion()).append("` |\n"); "| Loaded Worlds | `" + this.plugin.getMVWorldManager().getMVWorlds() + "` |" + System.lineSeparator() +
//markdownString.append("| Loaded Worlds | `").append(this.plugin.getMVWorldManager().getMVWorlds()).append("` |\n"); "| Multiverse Plugins Loaded | `" + this.plugin.getPluginCount() + "` |" + System.lineSeparator() +
markdownString.append("| Multiverse Plugins Loaded | `").append(this.plugin.getPluginCount()).append("` |\n"); "| Economy being used | `" + plugin.getEconomist().getEconomyName() + "` |" + System.lineSeparator() +
markdownString.append("| Economy being used | `").append(plugin.getEconomist().getEconomyName()).append("` |\n"); "| Permissions Plugin | `" + this.plugin.getMVPerms().getType() + "` |" + System.lineSeparator() +
markdownString.append("| Permissions Plugin | `").append(this.plugin.getMVPerms().getType()).append("` |\n"); "## Parsed Config" + System.lineSeparator() +
markdownString.append("## Parsed Config\n"); "These are what Multiverse thought the in-memory values of the config were." + System.lineSeparator() + System.lineSeparator() +
markdownString.append("These are what Multiverse thought the in-memory values of the config were.\n\n"); "| Config Key | Value |" + System.lineSeparator() +
markdownString.append("| Config Key | Value |\n"); "| --- | --- |" + System.lineSeparator() +
markdownString.append("| --- | --- |\n"); "| version | `" + this.plugin.getMVConfig().getVersion() + "` |" + System.lineSeparator() +
markdownString.append("| version | `").append(this.plugin.getMVConfig().getVersion()).append("` |\n"); "| messagecooldown | `" + plugin.getMessaging().getCooldown() + "` |" + System.lineSeparator() +
markdownString.append("| messagecooldown | `").append(plugin.getMessaging().getCooldown()).append("` |\n"); "| teleportcooldown | `" + plugin.getMVConfig().getTeleportCooldown() + "` |" + System.lineSeparator() +
markdownString.append("| teleportcooldown | `").append(plugin.getMVConfig().getTeleportCooldown()).append("` |\n"); "| worldnameprefix | `" + plugin.getMVConfig().getPrefixChat() + "` |" + System.lineSeparator() +
markdownString.append("| worldnameprefix | `").append(plugin.getMVConfig().getPrefixChat()).append("` |\n"); "| worldnameprefixFormat | `" + plugin.getMVConfig().getPrefixChatFormat() + "` |" + System.lineSeparator() +
markdownString.append("| worldnameprefixFormat | `").append(plugin.getMVConfig().getPrefixChatFormat()).append("` |\n"); "| enforceaccess | `" + plugin.getMVConfig().getEnforceAccess() + "` |" + System.lineSeparator() +
markdownString.append("| enforceaccess | `").append(plugin.getMVConfig().getEnforceAccess()).append("` |\n"); "| displaypermerrors | `" + plugin.getMVConfig().getDisplayPermErrors() + "` |" + System.lineSeparator() +
markdownString.append("| displaypermerrors | `").append(plugin.getMVConfig().getDisplayPermErrors()).append("` |\n"); "| teleportintercept | `" + plugin.getMVConfig().getTeleportIntercept() + "` |" + System.lineSeparator() +
markdownString.append("| teleportintercept | `").append(plugin.getMVConfig().getTeleportIntercept()).append("` |\n"); "| firstspawnoverride | `" + plugin.getMVConfig().getFirstSpawnOverride() + "` |" + System.lineSeparator() +
markdownString.append("| firstspawnoverride | `").append(plugin.getMVConfig().getFirstSpawnOverride()).append("` |\n"); "| firstspawnworld | `" + plugin.getMVConfig().getFirstSpawnWorld() + "` |" + System.lineSeparator() +
markdownString.append("| firstspawnworld | `").append(plugin.getMVConfig().getFirstSpawnWorld()).append("` |\n"); "| debug | `" + plugin.getMVConfig().getGlobalDebug() + "` |" + System.lineSeparator();
markdownString.append("| debug | `").append(plugin.getMVConfig().getGlobalDebug()).append("` |\n");
return markdownString.toString();
} }
private String readFile(final String filename) { private String readFile(final String filename) {
String result; StringBuilder result;
try { try {
FileReader reader = new FileReader(filename); FileReader reader = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(reader); BufferedReader bufferedReader = new BufferedReader(reader);
String line; String line;
result = ""; result = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) { while ((line = bufferedReader.readLine()) != null) {
result += line + '\n'; result.append(line).append(System.lineSeparator());
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Logging.severe("Unable to find %s. Here's the traceback: %s", filename, e.getMessage()); Logging.severe("Unable to find %s. Here's the traceback: %s", filename, e.getMessage());
e.printStackTrace(); e.printStackTrace();
result = String.format("ERROR: Could not load: %s", filename); result = new StringBuilder(String.format("ERROR: Could not load: %s", filename));
} catch (IOException e) { } catch (IOException e) {
Logging.severe("Something bad happend when reading %s. Here's the traceback: %s", filename, e.getMessage()); Logging.severe("Something bad happend when reading %s. Here's the traceback: %s", filename, e.getMessage());
e.printStackTrace(); e.printStackTrace();
result = String.format("ERROR: Could not load: %s", filename); result = new StringBuilder(String.format("ERROR: Could not load: %s", filename));
} }
return result; return result.toString();
} }
private Map<String, String> getVersionFiles() { private Map<String, String> getVersionFiles() {
@ -135,7 +134,7 @@ public class VersionCommand extends MultiverseCommand {
File configFile = new File(this.plugin.getDataFolder(), "config.yml"); File configFile = new File(this.plugin.getDataFolder(), "config.yml");
files.put(configFile.getName(), this.readFile(configFile.getAbsolutePath())); files.put(configFile.getName(), this.readFile(configFile.getAbsolutePath()));
// Add the config.yml // Add the worlds.yml
File worldConfig = new File(this.plugin.getDataFolder(), "worlds.yml"); File worldConfig = new File(this.plugin.getDataFolder(), "worlds.yml");
files.put(worldConfig.getName(), this.readFile(worldConfig.getAbsolutePath())); files.put(worldConfig.getName(), this.readFile(worldConfig.getAbsolutePath()));
return files; return files;
@ -149,19 +148,20 @@ public class VersionCommand extends MultiverseCommand {
} }
MVVersionEvent versionEvent = new MVVersionEvent(this.getLegacyString(), this.getVersionFiles()); MVVersionEvent versionEvent = new MVVersionEvent(this.getLegacyString(), this.getVersionFiles());
final Map<String, String> files = this.getVersionFiles();
this.plugin.getServer().getPluginManager().callEvent(versionEvent); this.plugin.getServer().getPluginManager().callEvent(versionEvent);
String versionInfo = versionEvent.getVersionInfo(); String versionInfo = versionEvent.getVersionInfo();
Map<String, String> files = versionEvent.getDetailedVersionInfo();
if (CommandHandler.hasFlag("--include-plugin-list", args)) { if (CommandHandler.hasFlag("--include-plugin-list", args)) {
versionInfo = versionInfo + "\nPlugins: " + getPluginList(); versionInfo = versionInfo + System.lineSeparator() + "Plugins: " + getPluginList();
files.put("plugins.txt", "Plugins: " + getPluginList());
} }
final String data = versionInfo; final String data = versionInfo;
// log to console // log to console
String[] lines = data.split("\n"); String[] lines = data.split(System.lineSeparator());
for (String line : lines) { for (String line : lines) {
if (!line.isEmpty()) { if (!line.isEmpty()) {
Logging.info(line); Logging.info(line);
@ -176,9 +176,15 @@ 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)) {
// private post to github
pasteUrl = postToService(PasteServiceType.GITHUB, true, data, files);
} else if (CommandHandler.hasFlag("-h", args)) { } else if (CommandHandler.hasFlag("-h", args)) {
// private post to pastebin // private post to hastebin
pasteUrl = postToService(PasteServiceType.HASTEBIN, true, data, files); pasteUrl = postToService(PasteServiceType.HASTEBIN, true, data, files);
} else if (CommandHandler.hasFlag("-p", args)) {
// private post to paste.gg
pasteUrl = postToService(PasteServiceType.PASTEGG, true, data, files);
} else { } else {
return; return;
} }
@ -204,20 +210,25 @@ 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) {
System.out.print(e); e.printStackTrace();
return "Error posting to service"; return "Error posting to service.";
} catch (NullPointerException e) {
e.printStackTrace();
return "That service isn't supported yet.";
} }
} }

View File

@ -66,4 +66,13 @@ public class MVVersionEvent extends Event {
public void appendVersionInfo(String moreVersionInfo) { public void appendVersionInfo(String moreVersionInfo) {
this.versionInfoBuilder.append(moreVersionInfo); this.versionInfoBuilder.append(moreVersionInfo);
} }
/**
* Adds a file to to the detailed version-info currently saved in this event.
* @param filename The name of the file.
* @param text The file's content.
*/
public void putDetailedVersionInfo(String filename, String text) {
this.detailedVersionInfo.put(filename, text);
}
} }

View File

@ -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}. * A {@link URLShortener} using {@code bit.ly}. Requires an access token.
*/ */
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 BitlyURLShortener() {
private static final String USERNAME = "multiverse2"; super(BITLY_POST_REQUEST, ACCESS_TOKEN);
private static final String API_KEY = "R_9dbff4862a3bc0c4218a7d78cc10d0e0"; if (ACCESS_TOKEN.endsWith("access-token")) throw new UnsupportedOperationException();
}
public BitlyURLShortener() { /**
super(String.format(GENERIC_BITLY_REQUEST_FORMAT, API_KEY, USERNAME, "%s")); * {@inheritDoc}
*/
@Override
String encodeData(String data) {
JSONObject json = new JSONObject();
json.put("domain", "j.mp");
json.put("long_url", data);
return json.toJSONString();
}
/**
* {@inheritDoc}
*/
@Override
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("http://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;
} }
} }
} }

View File

@ -0,0 +1,88 @@
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.util.HashMap;
import java.util.Map;
/**
* Pastes to {@code gist.github.com}. Requires an access token with the {@code gist} scope.
*/
class GitHubPasteService extends PasteService {
private final boolean isPrivate;
// this access token must have the "gist" scope
private static final String ACCESS_TOKEN = "token github-access-token";
private static final String GITHUB_POST_REQUEST = "https://api.github.com/gists";
GitHubPasteService(boolean isPrivate) {
super(GITHUB_POST_REQUEST, ACCESS_TOKEN);
this.isPrivate = isPrivate;
if (ACCESS_TOKEN.endsWith("access-token")) throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*/
@Override
String encodeData(String data) {
Map<String, String> mapData = new HashMap<String, String>();
mapData.put("multiverse.txt", data);
return this.encodeData(mapData);
}
/**
* {@inheritDoc}
*/
@Override
String encodeData(Map<String, String> files) {
JSONObject root = new JSONObject();
root.put("description", "Multiverse-Core Debug Info");
root.put("public", !this.isPrivate);
JSONObject fileList = new JSONObject();
for (Map.Entry<String, String> entry : files.entrySet()) {
JSONObject fileObject = new JSONObject();
fileObject.put("content", entry.getValue());
fileList.put(entry.getKey(), fileObject);
}
root.put("files", fileList);
return root.toJSONString();
}
/**
* {@inheritDoc}
*/
@Override
public String postData(String data) throws PasteFailedException {
try {
String stringJSON = this.exec(encodeData(data), ContentType.JSON);
return (String) ((JSONObject) new JSONParser().parse(stringJSON)).get("html_url");
} catch (IOException | ParseException e) {
throw new PasteFailedException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public String postData(Map<String, String> data) throws PasteFailedException {
try {
String stringJSON = this.exec(encodeData(data), ContentType.JSON);
return (String) ((JSONObject) new JSONParser().parse(stringJSON)).get("html_url");
} catch (IOException | ParseException e) {
throw new PasteFailedException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean supportsMultiFile() {
return true;
}
}

View File

@ -1,99 +0,0 @@
package com.onarandombox.MultiverseCore.utils.webpaste;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import java.io.BufferedReader;
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.util.HashMap;
import java.util.Map;
public class GithubPasteService implements PasteService {
private final boolean isPrivate;
public GithubPasteService(boolean isPrivate) {
this.isPrivate = isPrivate;
}
@Override
public String encodeData(String data) {
Map<String, String> mapData = new HashMap<String, String>();
mapData.put("multiverse.txt", data);
return this.encodeData(mapData);
}
@Override
public String encodeData(Map<String, String> files) {
JsonObject root = new JsonObject();
root.add("description", new JsonPrimitive("Multiverse-Core Debug Info"));
root.add("public", new JsonPrimitive(!this.isPrivate));
JsonObject fileList = new JsonObject();
for (Map.Entry<String, String> entry : files.entrySet())
{
JsonObject fileObject = new JsonObject();
fileObject.add("content", new JsonPrimitive(entry.getValue()));
fileList.add(entry.getKey(), fileObject);
}
root.add("files", fileList);
return root.toString();
}
@Override
public URL getPostURL() {
try {
return new URL("https://api.github.com/gists");
//return new URL("http://jsonplaceholder.typicode.com/posts");
} catch (MalformedURLException e) {
return null; // should never hit here
}
}
@Override
public String postData(String encodedData, URL url) throws PasteFailedException {
OutputStreamWriter wr = null;
BufferedReader rd = null;
try {
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(encodedData);
wr.flush();
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
String pastieUrl = "";
//Pattern pastiePattern = this.getURLMatchingPattern();
StringBuilder responseString = new StringBuilder();
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);
} finally {
if (wr != null) {
try {
wr.close();
} catch (IOException ignore) { }
}
if (rd != null) {
try {
rd.close();
} catch (IOException ignore) { }
}
}
}
@Override
public boolean supportsMultiFile() {
return true;
}
}

View File

@ -1,79 +1,67 @@
package com.onarandombox.MultiverseCore.utils.webpaste; package com.onarandombox.MultiverseCore.utils.webpaste;
import com.google.gson.JsonElement; import org.json.simple.JSONObject;
import com.google.gson.JsonParser; 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.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";
HastebinPasteService() {
super(HASTEBIN_POST_REQUEST, null);
}
/**
* {@inheritDoc}
*/
@Override @Override
public String encodeData(String data) { String encodeData(String data) {
return data; return data;
} }
/**
* {@inheritDoc}
*/
@Override @Override
public String encodeData(Map<String, String> data) { String encodeData(Map<String, String> data) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/**
* {@inheritDoc}
*/
@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) {
}
}
@Override
public String postData(String encodedData, URL url) throws PasteFailedException {
OutputStreamWriter wr = null;
BufferedReader rd = null;
try {
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
wr = new OutputStreamWriter(conn.getOutputStream());
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
wr.write(encodedData);
wr.flush();
String line;
StringBuilder responseString = new StringBuilder();
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) { }
}
} }
} }
/**
* {@inheritDoc}
*/
@Override
public String postData(Map<String, String> data) throws PasteFailedException {
try {
String stringJSON = this.exec(encodeData(data), ContentType.PLAINTEXT);
return "https://hastebin.com/" + ((JSONObject) new JSONParser().parse(stringJSON)).get("key");
} catch (IOException | ParseException e) {
throw new PasteFailedException(e);
}
}
/**
* {@inheritDoc}
*/
@Override @Override
public boolean supportsMultiFile() { public boolean supportsMultiFile() {
return false; return false;

View File

@ -1,50 +1,120 @@
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.util.Map;
/** /**
* HTTP API-client. * HTTP API-client.
*/ */
public abstract class HttpAPIClient { 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.
*/
enum ContentType {
JSON,
PLAINTEXT,
URLENCODED
} }
HttpAPIClient(String url, String accessToken) {
this.url = url;
this.accessToken = accessToken;
}
/**
* Returns the HTTP Content-Type header that corresponds with each ContentType.
* @param type The type of data.
* @return The HTTP Content-Type header that corresponds with the type of data.
*/
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.
*/
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.
*/
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 { 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())); 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('\n'); 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();
} }
} }

View File

@ -1,7 +1,7 @@
package com.onarandombox.MultiverseCore.utils.webpaste; package com.onarandombox.MultiverseCore.utils.webpaste;
/** /**
* Thrown when pasting failed. * Thrown when pasting fails.
*/ */
public class PasteFailedException extends Exception { public class PasteFailedException extends Exception {
public PasteFailedException() { public PasteFailedException() {

View File

@ -0,0 +1,90 @@
package com.onarandombox.MultiverseCore.utils.webpaste;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* Pastes to {@code paste.gg}.
*/
class PasteGGPasteService extends PasteService {
private final boolean isPrivate;
private static final String PASTEGG_POST_REQUEST = "https://api.paste.gg/v1/pastes";
PasteGGPasteService(boolean isPrivate) {
super(PASTEGG_POST_REQUEST, null);
this.isPrivate = isPrivate;
}
/**
* {@inheritDoc}
*/
@Override
String encodeData(String data) {
Map<String, String> mapData = new HashMap<String, String>();
mapData.put("multiverse.txt", data);
return this.encodeData(mapData);
}
/**
* {@inheritDoc}
*/
@Override
String encodeData(Map<String, String> files) {
JSONObject root = new JSONObject();
root.put("name", "Multiverse-Core Debug Info");
root.put("visibility", this.isPrivate ? "unlisted" : "public");
JSONArray fileList = new JSONArray();
for (Map.Entry<String, String> entry : files.entrySet()) {
JSONObject fileObject = new JSONObject();
JSONObject contentObject = new JSONObject();
fileObject.put("name", entry.getKey());
fileObject.put("content", contentObject);
contentObject.put("format", "text");
contentObject.put("value", entry.getValue());
fileList.add(fileObject);
}
root.put("files", fileList);
return root.toJSONString();
}
/**
* {@inheritDoc}
*/
@Override
public String postData(String data) throws PasteFailedException {
try {
String stringJSON = this.exec(encodeData(data), ContentType.JSON);
return (String) ((JSONObject) ((JSONObject) new JSONParser().parse(stringJSON)).get("result")).get("id");
} catch (IOException | ParseException e) {
throw new PasteFailedException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public String postData(Map<String, String> data) throws PasteFailedException {
try {
String stringJSON = this.exec(encodeData(data), ContentType.JSON);
return "https://paste.gg/" + ((JSONObject) ((JSONObject) new JSONParser().parse(stringJSON)).get("result")).get("id");
} catch (IOException | ParseException e) {
throw new PasteFailedException(e);
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean supportsMultiFile() {
return true;
}
}

View File

@ -1,63 +1,48 @@
package com.onarandombox.MultiverseCore.utils.webpaste; package com.onarandombox.MultiverseCore.utils.webpaste;
import java.net.URL;
import java.util.Map; import java.util.Map;
/** /**
* An interface to a web-based text-pasting service. Classes implementing this * An interface to a web-based text-pasting service. Classes extending this
* interface should implement its methods to send data to an online text-sharing * should implement its methods to send data to an online text-sharing service,
* service, such as pastebin.com. Conventionally, a paste is accomplished by (given * such as pastebin.com. Given some PasteService instance ps, a paste is accomplished by:
* some PasteService instance ps):
* *
* {@code ps.postData(ps.encodeData(someString), ps.getPostURL());} * {@code ps.postData(someString);}
* *
* Services that provide a distinction between "public" and "private" pastes * Services that provide a distinction between "public" and "private" pastes
* should implement a custom constructor that specifies which kind the PasteService * should implement a 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 {
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 String to post to the web.
* @return A URL-encoded string.
*/
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 Map to post to the web.
* @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.
* *
* Newer services like gist support multi-file which allows us to upload configs * Newer services like GitHub's Gist support multi-file pastes,
* in addition to the standard logs. * which allows us to upload configs in addition to the standard logs.
* *
* @return True if this service supports multiple file upload. * @return True if this service supports multiple file upload.
*/ */
boolean supportsMultiFile(); public abstract boolean supportsMultiFile();
} }

View File

@ -14,12 +14,14 @@ public class PasteServiceFactory {
*/ */
public static PasteService getService(PasteServiceType type, boolean isPrivate) { public static PasteService getService(PasteServiceType type, boolean isPrivate) {
switch(type) { switch(type) {
case PASTEGG:
return new PasteGGPasteService(isPrivate);
case PASTEBIN: case PASTEBIN:
return new PastebinPasteService(isPrivate); return new PastebinPasteService(isPrivate);
case HASTEBIN: case HASTEBIN:
return new HastebinPasteService(); return new HastebinPasteService();
case GITHUB: case GITHUB:
return new GithubPasteService(isPrivate); return new GitHubPasteService(isPrivate);
default: default:
return null; return null;
} }

View File

@ -7,6 +7,10 @@ package com.onarandombox.MultiverseCore.utils.webpaste;
* @see PasteServiceFactory * @see PasteServiceFactory
*/ */
public enum PasteServiceType { public enum PasteServiceType {
/**
* @see PasteGGPasteService
*/
PASTEGG,
/** /**
* @see PastebinPasteService * @see PastebinPasteService
*/ */
@ -16,7 +20,7 @@ public enum PasteServiceType {
*/ */
HASTEBIN, HASTEBIN,
/** /**
* @see GithubPasteService * @see GitHubPasteService
*/ */
GITHUB GITHUB
} }

View File

@ -1,24 +1,19 @@
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.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 static final String PASTEBIN_POST_REQUEST = "https://pastebin.com/api/api_post.php";
private boolean isPrivate; PastebinPasteService(boolean isPrivate) {
super(PASTEBIN_POST_REQUEST, null);
public PastebinPasteService(boolean isPrivate) {
this.isPrivate = isPrivate; this.isPrivate = isPrivate;
} }
@ -26,73 +21,54 @@ public class PastebinPasteService implements PasteService {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public URL getPostURL() { String encodeData(String data) {
try { try {
return new URL("http://pastebin.com/api/api_post.php"); return URLEncoder.encode("api_dev_key", "UTF-8") + "=" + URLEncoder.encode("d61d68d31e8e0392b59b50b277411c71", "UTF-8") +
} catch (MalformedURLException e) { "&" + URLEncoder.encode("api_option", "UTF-8") + "=" + URLEncoder.encode("paste", "UTF-8") +
return null; // should never hit here "&" + 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_format", "UTF-8") + "=" + URLEncoder.encode("yaml", "UTF-8") +
"&" + URLEncoder.encode("api_paste_name", "UTF-8") + "=" + URLEncoder.encode("Multiverse-Core Debug Info", "UTF-8");
/**
* {@inheritDoc}
*/
@Override
public String encodeData(String data) {
try {
String encData = URLEncoder.encode("api_dev_key", "UTF-8") + "=" + URLEncoder.encode("d61d68d31e8e0392b59b50b277411c71", "UTF-8");
encData += "&" + URLEncoder.encode("api_option", "UTF-8") + "=" + URLEncoder.encode("paste", "UTF-8");
encData += "&" + URLEncoder.encode("api_paste_code", "UTF-8") + "=" + URLEncoder.encode(data, "UTF-8");
encData += "&" + URLEncoder.encode("api_paste_private", "UTF-8") + "=" + URLEncoder.encode(this.isPrivate ? "1" : "0", "UTF-8");
encData += "&" + URLEncoder.encode("api_paste_format", "UTF-8") + "=" + URLEncoder.encode("yaml", "UTF-8");
return encData;
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
return ""; // should never hit here return ""; // should never hit here
} }
} }
/**
* {@inheritDoc}
*/
@Override @Override
public String encodeData(Map<String, String> data) { String encodeData(Map<String, String> data) {
return null; throw new UnsupportedOperationException();
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public String postData(String encodedData, URL url) throws PasteFailedException { public String postData(String data) throws PasteFailedException {
OutputStreamWriter wr = null;
BufferedReader rd = null;
try { try {
URLConnection conn = url.openConnection(); return this.exec(encodeData(data), ContentType.URLENCODED);
conn.setDoOutput(true); } catch (IOException e) {
wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(encodedData);
wr.flush();
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
String pastebinUrl = "";
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) { }
}
} }
} }
/**
* {@inheritDoc}
*/
@Override
public String postData(Map<String, String> data) throws PasteFailedException {
try {
return this.exec(encodeData(data), ContentType.URLENCODED);
} catch (IOException e) {
throw new PasteFailedException(e);
}
}
/**
* {@inheritDoc}
*/
@Override @Override
public boolean supportsMultiFile() { public boolean supportsMultiFile() {
return false; return false;

View File

@ -1,13 +1,23 @@
package com.onarandombox.MultiverseCore.utils.webpaste; package com.onarandombox.MultiverseCore.utils.webpaste;
/** /**
* URL-Shortener. * An interface to a web-based URL Shortener. Classes extending this should
* implement its methods to shorten links using the service. Given some
* URLShortener instance us, a URL is shortened by:
*
* {@code us.shorten(longUrl);}
*
* An example of this, is the BitlyURLShortener.
*/ */
public interface URLShortener { public abstract class URLShortener extends HttpAPIClient {
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);
} }

View File

@ -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;
}
}

View File

@ -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
}