mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-03-02 11:11:21 +01:00
Wrote an Exporter to export react bundle files
This commit is contained in:
parent
76f85b8d7d
commit
362105cf98
@ -120,6 +120,8 @@ task copyYarnBuildResults {
|
||||
}
|
||||
|
||||
task determineAssetModifications {
|
||||
dependsOn yarnBundle
|
||||
inputs.files(fileTree("$rootDir/react/dashboard/build"))
|
||||
inputs.files(fileTree(dir: 'src/main/resources/assets/plan/web'))
|
||||
inputs.files(fileTree(dir: 'src/main/resources/assets/plan/locale'))
|
||||
outputs.file("build/resources/main/assets/plan/AssetVersion.yml")
|
||||
@ -139,7 +141,7 @@ task determineAssetModifications {
|
||||
// git returns UNIX time in seconds, but most things in Java use UNIX time in milliseconds
|
||||
def modified = gitModifiedAsString.isEmpty() ? System.currentTimeMillis() : Long.parseLong(gitModifiedAsString) * 1000
|
||||
def relativePath = tree.getDir().toPath().relativize(f.toPath()) // File path relative to the tree
|
||||
versionFile.text += String.format( // writing YAML as raw text probably isn't the best idea
|
||||
versionFile.text += String.format(
|
||||
"%s: %s\n", relativePath.toString().replace('.', ','), modified
|
||||
)
|
||||
}
|
||||
@ -154,7 +156,16 @@ task determineAssetModifications {
|
||||
// git returns UNIX time in seconds, but most things in Java use UNIX time in milliseconds
|
||||
def modified = gitModifiedAsString.isEmpty() ? System.currentTimeMillis() : Long.parseLong(gitModifiedAsString) * 1000
|
||||
def relativePath = tree.getDir().toPath().relativize(f.toPath()) // File path relative to the tree
|
||||
versionFile.text += String.format( // writing YAML as raw text probably isn't the best idea
|
||||
versionFile.text += String.format(
|
||||
"%s: %s\n", relativePath.toString().replace('.', ','), modified
|
||||
)
|
||||
}
|
||||
|
||||
tree = fileTree("$rootDir/react/dashboard/build")
|
||||
tree.forEach { File f ->
|
||||
def modified = System.currentTimeMillis()
|
||||
def relativePath = tree.getDir().toPath().relativize(f.toPath()) // File path relative to the tree
|
||||
versionFile.text += String.format(
|
||||
"%s: %s\n", relativePath.toString().replace('.', ','), modified
|
||||
)
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ public class Exporter extends FileExporter {
|
||||
private final NetworkPageExporter networkPageExporter;
|
||||
|
||||
private final Set<ServerUUID> failedServers;
|
||||
private final ReactExporter reactExporter;
|
||||
|
||||
@Inject
|
||||
public Exporter(
|
||||
@ -55,7 +56,8 @@ public class Exporter extends FileExporter {
|
||||
PlayerPageExporter playerPageExporter,
|
||||
PlayersPageExporter playersPageExporter,
|
||||
ServerPageExporter serverPageExporter,
|
||||
NetworkPageExporter networkPageExporter
|
||||
NetworkPageExporter networkPageExporter,
|
||||
ReactExporter reactExporter
|
||||
) {
|
||||
this.config = config;
|
||||
this.playerJSONExporter = playerJSONExporter;
|
||||
@ -63,6 +65,7 @@ public class Exporter extends FileExporter {
|
||||
this.playersPageExporter = playersPageExporter;
|
||||
this.serverPageExporter = serverPageExporter;
|
||||
this.networkPageExporter = networkPageExporter;
|
||||
this.reactExporter = reactExporter;
|
||||
|
||||
failedServers = new HashSet<>();
|
||||
}
|
||||
@ -161,4 +164,14 @@ public class Exporter extends FileExporter {
|
||||
throw new ExportException("Failed to export player: " + playerName + ", " + e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void exportReact() throws ExportException {
|
||||
Path toDirectory = config.getPageExportPath();
|
||||
|
||||
try {
|
||||
reactExporter.exportReactFiles(toDirectory);
|
||||
} catch (IOException e) {
|
||||
throw new ExportException("Failed to export react: " + e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ package com.djrapitops.plan.delivery.export;
|
||||
|
||||
import com.djrapitops.plan.delivery.rendering.html.Html;
|
||||
import com.djrapitops.plan.delivery.web.resource.WebResource;
|
||||
import com.djrapitops.plan.storage.file.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@ -60,9 +61,15 @@ abstract class FileExporter {
|
||||
export(to, Arrays.asList(StringUtils.split(content, "\r\n")));
|
||||
}
|
||||
|
||||
void export(Path to, Resource resource) throws IOException {
|
||||
export(to, resource.asWebResource());
|
||||
}
|
||||
|
||||
void export(Path to, WebResource resource) throws IOException {
|
||||
Path dir = to.getParent();
|
||||
if (!Files.isSymbolicLink(dir)) Files.createDirectories(dir);
|
||||
if (!Files.isSymbolicLink(dir) && !Files.isDirectory(dir)) {
|
||||
Files.createDirectories(dir);
|
||||
}
|
||||
|
||||
try (
|
||||
InputStream in = resource.asStream();
|
||||
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.export;
|
||||
|
||||
import com.djrapitops.plan.delivery.web.AssetVersions;
|
||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.settings.config.paths.WebserverSettings;
|
||||
import com.djrapitops.plan.storage.file.PlanFiles;
|
||||
import com.djrapitops.plan.storage.file.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Exporter in charge of exporting React related files.
|
||||
*
|
||||
* @author AuroraLS3
|
||||
*/
|
||||
@Singleton
|
||||
public class ReactExporter extends FileExporter {
|
||||
|
||||
private final PlanFiles files;
|
||||
private final PlanConfig config;
|
||||
private final AssetVersions assetVersions;
|
||||
|
||||
@Inject
|
||||
public ReactExporter(
|
||||
PlanFiles files,
|
||||
PlanConfig config,
|
||||
AssetVersions assetVersions
|
||||
) {
|
||||
this.files = files;
|
||||
this.config = config;
|
||||
this.assetVersions = assetVersions;
|
||||
}
|
||||
|
||||
public void exportReactFiles(Path toDirectory) throws IOException {
|
||||
exportAsset(toDirectory, "index.html");
|
||||
exportAsset(toDirectory, "asset-manifest.json");
|
||||
exportAsset(toDirectory, "favicon.ico");
|
||||
exportAsset(toDirectory, "logo192.png");
|
||||
exportAsset(toDirectory, "logo512.png");
|
||||
exportAsset(toDirectory, "manifest.json");
|
||||
exportAsset(toDirectory, "robots.txt");
|
||||
exportStaticBundle(toDirectory);
|
||||
}
|
||||
|
||||
private void exportStaticBundle(Path toDirectory) throws IOException {
|
||||
List<String> paths = assetVersions.getAssetPaths().stream()
|
||||
.filter(path -> path.contains("static"))
|
||||
.collect(Collectors.toList());
|
||||
for (String path : paths) {
|
||||
String resourcePath = path.replace(',', '.');
|
||||
Path to = toDirectory.resolve(resourcePath);
|
||||
Resource resource = files.getResourceFromJar("web/" + resourcePath);
|
||||
if (resourcePath.endsWith(".js")) {
|
||||
String withReplacedConstants = StringUtils.replaceEach(
|
||||
resource.asString(),
|
||||
new String[]{"PLAN_BASE_ADDRESS", "PLAN_EXPORTED_VERSION"},
|
||||
new String[]{config.get(WebserverSettings.EXTERNAL_LINK), "true"}
|
||||
);
|
||||
export(to, withReplacedConstants);
|
||||
} else {
|
||||
export(to, resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void exportAsset(Path toDirectory, String asset) throws IOException {
|
||||
export(toDirectory.resolve(asset), files.getResourceFromJar("web/" + asset));
|
||||
}
|
||||
|
||||
}
|
@ -24,6 +24,7 @@ import com.djrapitops.plan.storage.file.PlanFiles;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Singleton
|
||||
@ -61,4 +62,9 @@ public class AssetVersions {
|
||||
|
||||
return Optional.of(max);
|
||||
}
|
||||
|
||||
public List<String> getAssetPaths() throws IOException {
|
||||
if (webAssetConfig == null) prepare();
|
||||
return webAssetConfig.getConfigPaths();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.export;
|
||||
|
||||
import com.djrapitops.plan.PlanSystem;
|
||||
import com.djrapitops.plan.exceptions.ExportException;
|
||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||
import extension.FullSystemExtension;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@ExtendWith(FullSystemExtension.class)
|
||||
class ReactExporterTest {
|
||||
|
||||
@BeforeAll
|
||||
static void enableSystem(PlanSystem system) {
|
||||
system.enable();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void disableSystem(PlanSystem system) {
|
||||
system.disable();
|
||||
}
|
||||
|
||||
@Test
|
||||
void allReactFilesAreExported(PlanConfig config, Exporter exporter) throws ExportException, IOException {
|
||||
Path exportPath = config.getPageExportPath();
|
||||
exporter.exportReact();
|
||||
|
||||
Path reactBuildPath = Path.of(new File("").getAbsolutePath())
|
||||
.resolve("../react/dashboard/build");
|
||||
|
||||
List<Path> filesToExport = Files.list(reactBuildPath)
|
||||
.map(path -> path.relativize(reactBuildPath))
|
||||
.collect(Collectors.toList());
|
||||
List<Path> filesExported = Files.list(exportPath)
|
||||
.map(path -> path.relativize(exportPath))
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(filesToExport, filesExported);
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
package extension;
|
||||
|
||||
import com.djrapitops.plan.PlanSystem;
|
||||
import com.djrapitops.plan.delivery.export.Exporter;
|
||||
import com.djrapitops.plan.identification.ServerUUID;
|
||||
import com.djrapitops.plan.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.settings.config.paths.WebserverSettings;
|
||||
@ -80,7 +81,8 @@ public class FullSystemExtension implements ParameterResolver, BeforeAllCallback
|
||||
PlanConfig.class.equals(type) ||
|
||||
ServerUUID.class.equals(type) ||
|
||||
PlanPluginComponent.class.equals(type) ||
|
||||
Database.class.equals(type);
|
||||
Database.class.equals(type) ||
|
||||
Exporter.class.equals(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -105,6 +107,9 @@ public class FullSystemExtension implements ParameterResolver, BeforeAllCallback
|
||||
if (Database.class.equals(type)) {
|
||||
return planSystem.getDatabaseSystem().getDatabase();
|
||||
}
|
||||
if (Exporter.class.equals(type)) {
|
||||
return planSystem.getExportSystem().getExporter();
|
||||
}
|
||||
throw new ParameterResolutionException("Unsupported parameter type " + type.getName());
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
import axios from "axios";
|
||||
|
||||
const toBeReplaced = "PLAN_BASE_ADDRESS";
|
||||
const javaReplaced = {
|
||||
isStatic: "PLAN_EXPORTED_VERSION",
|
||||
address: "PLAN_BASE_ADDRESS"
|
||||
}
|
||||
|
||||
const isCurrentAddress = (address) => {
|
||||
const is = window.location.href.startsWith(address);
|
||||
@ -8,7 +11,8 @@ const isCurrentAddress = (address) => {
|
||||
return is;
|
||||
}
|
||||
|
||||
export const baseAddress = "PLAN_BASE_ADDRESS" === toBeReplaced || !isCurrentAddress(toBeReplaced) ? "" : toBeReplaced;
|
||||
export const baseAddress = "PLAN_BASE" + "_ADDRESS" === javaReplaced.address || !isCurrentAddress(javaReplaced.address) ? "" : javaReplaced.address;
|
||||
export const staticSite = "PLAN_EXPORTED" + "_VERSION" !== javaReplaced.isStatic;
|
||||
|
||||
export const doSomeGetRequest = async (url, statusOptions) => {
|
||||
return doSomeRequest(url, statusOptions, async () => axios.get(url));
|
||||
|
Loading…
Reference in New Issue
Block a user