mirror of
https://github.com/TotalFreedomMC/TF-PlotSquared.git
synced 2024-05-29 00:11:26 +00:00
223 lines
8 KiB
Java
223 lines
8 KiB
Java
/*
|
|
* _____ _ _ _____ _
|
|
* | __ \| | | | / ____| | |
|
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
* | |
|
|
* |_|
|
|
* PlotSquared plot management system for Minecraft
|
|
* Copyright (C) 2020 IntellectualSites
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package com.plotsquared.core.util.net;
|
|
|
|
import com.google.common.base.Charsets;
|
|
import com.plotsquared.core.PlotSquared;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.InputStreamReader;
|
|
import java.io.OutputStream;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.URL;
|
|
import java.net.URLConnection;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.Iterator;
|
|
import java.util.Locale;
|
|
|
|
/**
|
|
* Single class paster for the Incendo paste service
|
|
*/
|
|
@SuppressWarnings({"unused", "WeakerAccess"})
|
|
public final class IncendoPaster {
|
|
|
|
/**
|
|
* Upload service URL
|
|
*/
|
|
public static final String UPLOAD_PATH = "https://athion.net/ISPaster/paste/upload";
|
|
/**
|
|
* Valid paste applications
|
|
*/
|
|
public static final Collection<String> VALID_APPLICATIONS =
|
|
Arrays.asList("plotsquared", "fastasyncworldedit", "incendopermissions", "kvantum");
|
|
|
|
private final Collection<PasteFile> files = new ArrayList<>();
|
|
private final String pasteApplication;
|
|
|
|
/**
|
|
* Construct a new paster
|
|
*
|
|
* @param pasteApplication The application that is sending the paste
|
|
*/
|
|
public IncendoPaster(final String pasteApplication) {
|
|
if (pasteApplication == null || pasteApplication.isEmpty()) {
|
|
throw new IllegalArgumentException("paste application cannot be null, nor empty");
|
|
}
|
|
if (!VALID_APPLICATIONS.contains(pasteApplication.toLowerCase(Locale.ENGLISH))) {
|
|
throw new IllegalArgumentException(
|
|
String.format("Unknown application name: %s", pasteApplication));
|
|
}
|
|
this.pasteApplication = pasteApplication;
|
|
}
|
|
|
|
/**
|
|
* Get an immutable collection containing all the files that have been added to this paster
|
|
*
|
|
* @return Unmodifiable collection
|
|
*/
|
|
public final Collection<PasteFile> getFiles() {
|
|
return Collections.unmodifiableCollection(this.files);
|
|
}
|
|
|
|
/**
|
|
* Add a file to the paster
|
|
*
|
|
* @param file File to paste
|
|
*/
|
|
public void addFile(final PasteFile file) {
|
|
if (file == null) {
|
|
throw new IllegalArgumentException("File cannot be null");
|
|
}
|
|
// Check to see that no duplicate files are submitted
|
|
for (final PasteFile pasteFile : this.files) {
|
|
if (pasteFile.fileName.equalsIgnoreCase(file.getFileName())) {
|
|
throw new IllegalArgumentException(
|
|
String.format("Found duplicate file with name %s", file.getFileName()));
|
|
}
|
|
}
|
|
this.files.add(file);
|
|
}
|
|
|
|
/**
|
|
* Create a JSON string from the submitted information
|
|
*
|
|
* @return compiled JSON string
|
|
*/
|
|
private String toJsonString() {
|
|
final StringBuilder builder = new StringBuilder("{\n");
|
|
builder.append("\"paste_application\": \"").append(this.pasteApplication)
|
|
.append("\",\n\"files\": \"");
|
|
Iterator<PasteFile> fileIterator = this.files.iterator();
|
|
while (fileIterator.hasNext()) {
|
|
final PasteFile file = fileIterator.next();
|
|
builder.append(file.getFileName());
|
|
if (fileIterator.hasNext()) {
|
|
builder.append(",");
|
|
}
|
|
}
|
|
builder.append("\",\n");
|
|
fileIterator = this.files.iterator();
|
|
while (fileIterator.hasNext()) {
|
|
final PasteFile file = fileIterator.next();
|
|
builder.append("\"file-").append(file.getFileName()).append("\": \"")
|
|
.append(file.getContent().replaceAll("\"", "\\\\\"")).append("\"");
|
|
if (fileIterator.hasNext()) {
|
|
builder.append(",\n");
|
|
}
|
|
}
|
|
builder.append("\n}");
|
|
return builder.toString();
|
|
}
|
|
|
|
/**
|
|
* Upload the paste and return the status message
|
|
*
|
|
* @return Status message
|
|
* @throws Throwable any and all exceptions
|
|
*/
|
|
public final String upload() throws Throwable {
|
|
final URL url = new URL(UPLOAD_PATH);
|
|
final URLConnection connection = url.openConnection();
|
|
final HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
|
|
httpURLConnection.setRequestMethod("POST");
|
|
httpURLConnection.setDoOutput(true);
|
|
final byte[] content = toJsonString().getBytes(Charsets.UTF_8);
|
|
httpURLConnection.setFixedLengthStreamingMode(content.length);
|
|
httpURLConnection.setRequestProperty("Content-Type", "application/json");
|
|
httpURLConnection.setRequestProperty("Accept", "*/*");
|
|
httpURLConnection.connect();
|
|
try (final OutputStream stream = httpURLConnection.getOutputStream()) {
|
|
stream.write(content);
|
|
}
|
|
if (!httpURLConnection.getResponseMessage().contains("OK")) {
|
|
if (httpURLConnection.getResponseCode() == 413) {
|
|
final long size = content.length;
|
|
PlotSquared.debug(String.format("Paste Too Big > Size: %dMB", size / 1_000_000));
|
|
}
|
|
throw new IllegalStateException(String
|
|
.format("Server returned status: %d %s", httpURLConnection.getResponseCode(),
|
|
httpURLConnection.getResponseMessage()));
|
|
}
|
|
final StringBuilder input = new StringBuilder();
|
|
try (final BufferedReader inputStream = new BufferedReader(
|
|
new InputStreamReader(httpURLConnection.getInputStream()))) {
|
|
String line;
|
|
while ((line = inputStream.readLine()) != null) {
|
|
input.append(line).append("\n");
|
|
}
|
|
}
|
|
return input.toString();
|
|
}
|
|
|
|
/**
|
|
* Simple class that represents a paste file
|
|
*/
|
|
public static class PasteFile {
|
|
|
|
private final String fileName;
|
|
private final String content;
|
|
|
|
/**
|
|
* Construct a new paste file
|
|
*
|
|
* @param fileName File name, cannot be empty, nor null
|
|
* @param content File content, cannot be empty, nor null
|
|
*/
|
|
public PasteFile(final String fileName, final String content) {
|
|
if (fileName == null || fileName.isEmpty()) {
|
|
throw new IllegalArgumentException("file name cannot be null, nor empty");
|
|
}
|
|
if (content == null || content.isEmpty()) {
|
|
throw new IllegalArgumentException("content cannot be null, nor empty");
|
|
}
|
|
this.fileName = fileName;
|
|
this.content = content;
|
|
}
|
|
|
|
/**
|
|
* Get the file name
|
|
*
|
|
* @return File name
|
|
*/
|
|
public String getFileName() {
|
|
return this.fileName;
|
|
}
|
|
|
|
/**
|
|
* Get the file content as a single string
|
|
*
|
|
* @return File content
|
|
*/
|
|
public String getContent() {
|
|
return this.content;
|
|
}
|
|
}
|
|
|
|
}
|