Export of /network page

This commit is contained in:
Rsl1122 2019-09-01 16:21:19 +03:00
parent c1c2da8517
commit d1123525ac
9 changed files with 393 additions and 98 deletions

View File

@ -16,7 +16,6 @@
*/ */
package com.djrapitops.plan; package com.djrapitops.plan;
import com.djrapitops.plan.delivery.upkeep.PeriodicServerExportTask;
import com.djrapitops.plan.delivery.webserver.cache.JSONCache; import com.djrapitops.plan.delivery.webserver.cache.JSONCache;
import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask; import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask;
import com.djrapitops.plan.gathering.ShutdownHook; import com.djrapitops.plan.gathering.ShutdownHook;
@ -25,7 +24,6 @@ import com.djrapitops.plan.gathering.timed.BukkitTPSCounter;
import com.djrapitops.plan.gathering.timed.PaperTPSCounter; import com.djrapitops.plan.gathering.timed.PaperTPSCounter;
import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.DataGatheringSettings; import com.djrapitops.plan.settings.config.paths.DataGatheringSettings;
import com.djrapitops.plan.settings.config.paths.ExportSettings;
import com.djrapitops.plan.settings.config.paths.TimeSettings; import com.djrapitops.plan.settings.config.paths.TimeSettings;
import com.djrapitops.plan.settings.upkeep.ConfigStoreTask; import com.djrapitops.plan.settings.upkeep.ConfigStoreTask;
import com.djrapitops.plan.storage.upkeep.DBCleanTask; import com.djrapitops.plan.storage.upkeep.DBCleanTask;
@ -52,7 +50,6 @@ public class BukkitTaskSystem extends TaskSystem {
private final PlanConfig config; private final PlanConfig config;
private final ShutdownHook shutdownHook; private final ShutdownHook shutdownHook;
private final JSONCache.CleanTask jsonCacheCleanTask; private final JSONCache.CleanTask jsonCacheCleanTask;
private final PeriodicServerExportTask periodicServerExportTask;
private final LogsFolderCleanTask logsFolderCleanTask; private final LogsFolderCleanTask logsFolderCleanTask;
private final BukkitPingCounter pingCounter; private final BukkitPingCounter pingCounter;
private final ConfigStoreTask configStoreTask; private final ConfigStoreTask configStoreTask;
@ -75,9 +72,7 @@ public class BukkitTaskSystem extends TaskSystem {
LogsFolderCleanTask logsFolderCleanTask, LogsFolderCleanTask logsFolderCleanTask,
ConfigStoreTask configStoreTask, ConfigStoreTask configStoreTask,
DBCleanTask dbCleanTask, DBCleanTask dbCleanTask,
JSONCache.CleanTask jsonCacheCleanTask, JSONCache.CleanTask jsonCacheCleanTask
PeriodicServerExportTask periodicServerExportTask
) { ) {
super(runnableFactory); super(runnableFactory);
this.plugin = plugin; this.plugin = plugin;
@ -92,8 +87,6 @@ public class BukkitTaskSystem extends TaskSystem {
this.logsFolderCleanTask = logsFolderCleanTask; this.logsFolderCleanTask = logsFolderCleanTask;
this.configStoreTask = configStoreTask; this.configStoreTask = configStoreTask;
this.dbCleanTask = dbCleanTask; this.dbCleanTask = dbCleanTask;
this.periodicServerExportTask = periodicServerExportTask;
} }
@Override @Override
@ -117,10 +110,6 @@ public class BukkitTaskSystem extends TaskSystem {
); );
long minute = TimeAmount.toTicks(1, TimeUnit.MINUTES); long minute = TimeAmount.toTicks(1, TimeUnit.MINUTES);
registerTask(jsonCacheCleanTask).runTaskTimerAsynchronously(minute, minute); registerTask(jsonCacheCleanTask).runTaskTimerAsynchronously(minute, minute);
if (config.get(ExportSettings.SERVER_PAGE)) {
registerTask(periodicServerExportTask).runTaskTimerAsynchronously(TimeAmount.toTicks(30L, TimeUnit.SECONDS), TimeAmount.toTicks(20L, TimeUnit.MINUTES));
}
} }
private void registerTPSCounter() { private void registerTPSCounter() {

View File

@ -16,20 +16,22 @@
*/ */
package com.djrapitops.plan.delivery.export; package com.djrapitops.plan.delivery.export;
import com.djrapitops.plan.exceptions.ExportException;
import com.djrapitops.plan.exceptions.ParseException; import com.djrapitops.plan.exceptions.ParseException;
import com.djrapitops.plan.exceptions.connection.NotFoundException; import com.djrapitops.plan.exceptions.connection.NotFoundException;
import com.djrapitops.plan.identification.Server; import com.djrapitops.plan.identification.Server;
import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.ExportSettings; import com.djrapitops.plan.settings.config.paths.ExportSettings;
import com.djrapitops.plan.storage.file.PlanFiles; import com.djrapitops.plan.storage.file.PlanFiles;
import com.djrapitops.plugin.logging.L;
import com.djrapitops.plugin.logging.error.ErrorHandler;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/** /**
* Handles export for different pages. * Handles export for different pages.
@ -42,33 +44,54 @@ public class Exporter {
private final PlanFiles files; private final PlanFiles files;
private final PlanConfig config; private final PlanConfig config;
private final ServerPageExporter serverPageExporter; private final ServerPageExporter serverPageExporter;
private final ErrorHandler errorHandler; private final NetworkPageExporter networkPageExporter;
private final Set<UUID> failedServers;
@Inject @Inject
public Exporter( public Exporter(
PlanFiles files, PlanFiles files,
PlanConfig config, PlanConfig config,
ServerPageExporter serverPageExporter, ServerPageExporter serverPageExporter,
ErrorHandler errorHandler NetworkPageExporter networkPageExporter
) { ) {
this.files = files; this.files = files;
this.config = config; this.config = config;
this.serverPageExporter = serverPageExporter; this.serverPageExporter = serverPageExporter;
this.errorHandler = errorHandler; this.networkPageExporter = networkPageExporter;
failedServers = new HashSet<>();
} }
public Path getPageExportDirectory() { private Path getPageExportDirectory() {
Path exportDirectory = Paths.get(config.get(ExportSettings.HTML_EXPORT_PATH)); Path exportDirectory = Paths.get(config.get(ExportSettings.HTML_EXPORT_PATH));
return exportDirectory.isAbsolute() return exportDirectory.isAbsolute()
? exportDirectory ? exportDirectory
: files.getDataDirectory().resolve(exportDirectory); : files.getDataDirectory().resolve(exportDirectory);
} }
public void exportServerPage(Server server) { /**
* Export a page of a server.
*
* @param server Server which page is going to be exported
* @return false if the page was not exported due to previous failure.
* @throws ExportException If the export failed
*/
public boolean exportServerPage(Server server) throws ExportException {
UUID serverUUID = server.getUuid();
if (failedServers.contains(serverUUID)) return false;
try { try {
serverPageExporter.export(getPageExportDirectory(), server); Path toDirectory = getPageExportDirectory();
if (server.isProxy()) {
networkPageExporter.export(toDirectory, server);
} else {
serverPageExporter.export(toDirectory, server);
}
return true;
} catch (IOException | NotFoundException | ParseException e) { } catch (IOException | NotFoundException | ParseException e) {
errorHandler.log(L.WARN, this.getClass(), e); failedServers.add(serverUUID);
throw new ExportException("Failed to export server: " + server.getIdentifiableName() + " (Attempts disabled until next reload), " + e.getMessage(), e);
} }
} }
} }

View File

@ -20,6 +20,7 @@ import com.djrapitops.plan.delivery.rendering.json.JSONFactory;
import com.djrapitops.plan.delivery.rendering.pages.NetworkPage; import com.djrapitops.plan.delivery.rendering.pages.NetworkPage;
import com.djrapitops.plan.delivery.rendering.pages.PageFactory; import com.djrapitops.plan.delivery.rendering.pages.PageFactory;
import com.djrapitops.plan.delivery.rendering.pages.PlayerPage; import com.djrapitops.plan.delivery.rendering.pages.PlayerPage;
import com.djrapitops.plan.exceptions.ExportException;
import com.djrapitops.plan.exceptions.ParseException; import com.djrapitops.plan.exceptions.ParseException;
import com.djrapitops.plan.exceptions.database.DBOpException; import com.djrapitops.plan.exceptions.database.DBOpException;
import com.djrapitops.plan.gathering.domain.BaseUser; import com.djrapitops.plan.gathering.domain.BaseUser;
@ -97,7 +98,11 @@ public class HtmlExport extends SpecificExport {
// if (serverInfo.getServer().isNotProxy() && hasProxy) { // if (serverInfo.getServer().isNotProxy() && hasProxy) {
// return; // return;
// } // }
exporter.exportServerPage(server); try {
exporter.exportServerPage(server);
} catch (ExportException e) {
errorHandler.log(L.WARN, this.getClass(), e);
}
} }
public void exportPlayerPage(UUID playerUUID) { public void exportPlayerPage(UUID playerUUID) {

View File

@ -0,0 +1,201 @@
/*
* 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.rendering.pages.Page;
import com.djrapitops.plan.delivery.rendering.pages.PageFactory;
import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.pages.json.RootJSONHandler;
import com.djrapitops.plan.delivery.webserver.response.Response;
import com.djrapitops.plan.delivery.webserver.response.errors.ErrorResponse;
import com.djrapitops.plan.exceptions.ParseException;
import com.djrapitops.plan.exceptions.connection.NotFoundException;
import com.djrapitops.plan.exceptions.connection.WebException;
import com.djrapitops.plan.identification.Server;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.theme.Theme;
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.net.URI;
import java.nio.file.Path;
/**
* Handles exporting of /network page html, data and resources.
*
* @author Rsl1122
*/
@Singleton
public class NetworkPageExporter extends FileExporter {
private final PlanFiles files;
private final PageFactory pageFactory;
private final RootJSONHandler jsonHandler;
private final Locale locale;
private final Theme theme;
private final ExportPaths exportPaths;
@Inject
public NetworkPageExporter(
PlanFiles files,
PageFactory pageFactory,
RootJSONHandler jsonHandler,
Locale locale,
Theme theme
) {
this.files = files;
this.pageFactory = pageFactory;
this.jsonHandler = jsonHandler;
this.locale = locale;
this.theme = theme;
exportPaths = new ExportPaths();
}
public void export(Path toDirectory, Server server) throws IOException, NotFoundException, ParseException {
exportRequiredResources(toDirectory);
exportJSON(toDirectory, server);
exportHtml(toDirectory);
}
private void exportHtml(Path toDirectory) throws IOException, ParseException {
Path to = toDirectory
.resolve("network")
.resolve("index.html");
Page page = pageFactory.networkPage();
export(to, exportPaths.resolveExportPaths(locale.replaceMatchingLanguage(page.toHtml())));
}
private void exportJSON(Path toDirectory, Server server) throws IOException, NotFoundException {
String serverUUID = server.getUuid().toString();
exportJSON(toDirectory,
"network/overview",
"network/servers",
"network/sessionsOverview",
"network/playerbaseOverview",
"graph?type=playersOnline&server=" + serverUUID,
"graph?type=uniqueAndNew",
"graph?type=serverPie",
"graph?type=activity",
"graph?type=geolocation",
"graph?type=uniqueAndNew",
"network/pingTable",
"sessions"
);
}
private void exportJSON(Path toDirectory, String... resources) throws NotFoundException, IOException {
for (String resource : resources) {
exportJSON(toDirectory, resource);
}
}
private void exportJSON(Path toDirectory, String resource) throws NotFoundException, IOException {
Response found = getJSONResponse(resource);
if (found instanceof ErrorResponse) {
throw new NotFoundException(resource + " was not properly exported: " + found.getContent());
}
String jsonResourceName = toFileName(toJSONResourceName(resource)) + ".json";
export(toDirectory.resolve("data").resolve(jsonResourceName), found.getContent());
exportPaths.put("../v1/" + resource, toRelativePathFromRoot("data/" + jsonResourceName));
}
private String toJSONResourceName(String resource) {
return StringUtils.replaceEach(resource, new String[]{"?", "&", "type=", "server="}, new String[]{"-", "_", "", ""});
}
private Response getJSONResponse(String resource) {
try {
return jsonHandler.getResponse(null, new RequestTarget(URI.create(resource)));
} catch (WebException e) {
// The rest of the exceptions should not be thrown
throw new IllegalStateException("Unexpected exception thrown: " + e.toString(), e);
}
}
private void exportRequiredResources(Path toDirectory) throws IOException {
exportImage(toDirectory, "img/Flaticon_circle.png");
exportResources(toDirectory,
"css/sb-admin-2.css",
"css/style.css",
"vendor/jquery/jquery.min.js",
"vendor/bootstrap/js/bootstrap.bundle.min.js",
"vendor/jquery-easing/jquery.easing.min.js",
"vendor/datatables/jquery.dataTables.min.js",
"vendor/datatables/dataTables.bootstrap4.min.js",
"vendor/highcharts/highstock.js",
"vendor/highcharts/map.js",
"vendor/highcharts/world.js",
"vendor/highcharts/drilldown.js",
"vendor/highcharts/highcharts-more.js",
"vendor/highcharts/no-data-to-display.js",
"js/sb-admin-2.js",
"js/xmlhttprequests.js",
"js/color-selector.js",
"js/sessionAccordion.js",
"js/pingTable.js",
"js/graphs.js",
"js/network-values.js"
);
}
private void exportResources(Path toDirectory, String... resourceNames) throws IOException {
for (String resourceName : resourceNames) {
exportResource(toDirectory, resourceName);
}
}
private void exportResource(Path toDirectory, String resourceName) throws IOException {
Resource resource = files.getCustomizableResourceOrDefault("web/" + resourceName);
Path to = toDirectory.resolve(resourceName);
if (resourceName.endsWith(".css")) {
export(to, theme.replaceThemeColors(resource.asString()));
} else {
export(to, resource.asLines());
}
exportPaths.put(resourceName, toRelativePathFromRoot(resourceName));
}
private void exportImage(Path toDirectory, String resourceName) throws IOException {
Resource resource = files.getCustomizableResourceOrDefault("web/" + resourceName);
Path to = toDirectory.resolve(resourceName);
export(to, resource);
exportPaths.put(resourceName, toRelativePathFromRoot(resourceName));
}
private String toRelativePathFromRoot(String resourceName) {
// Network html is exported at /network//index.html or /server/index.html
return "../" + toNonRelativePath(resourceName);
}
private String toNonRelativePath(String resourceName) {
return StringUtils.remove(resourceName, "../");
}
}

View File

@ -16,8 +16,8 @@
*/ */
package com.djrapitops.plan.delivery.export; package com.djrapitops.plan.delivery.export;
import com.djrapitops.plan.delivery.rendering.pages.Page;
import com.djrapitops.plan.delivery.rendering.pages.PageFactory; import com.djrapitops.plan.delivery.rendering.pages.PageFactory;
import com.djrapitops.plan.delivery.rendering.pages.ServerPage;
import com.djrapitops.plan.delivery.webserver.RequestTarget; import com.djrapitops.plan.delivery.webserver.RequestTarget;
import com.djrapitops.plan.delivery.webserver.pages.json.RootJSONHandler; import com.djrapitops.plan.delivery.webserver.pages.json.RootJSONHandler;
import com.djrapitops.plan.delivery.webserver.response.Response; import com.djrapitops.plan.delivery.webserver.response.Response;
@ -27,6 +27,8 @@ import com.djrapitops.plan.exceptions.connection.NotFoundException;
import com.djrapitops.plan.exceptions.connection.WebException; import com.djrapitops.plan.exceptions.connection.WebException;
import com.djrapitops.plan.identification.Server; import com.djrapitops.plan.identification.Server;
import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.identification.ServerInfo;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.storage.file.PlanFiles; import com.djrapitops.plan.storage.file.PlanFiles;
import com.djrapitops.plan.storage.file.Resource; import com.djrapitops.plan.storage.file.Resource;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -49,6 +51,8 @@ public class ServerPageExporter extends FileExporter {
private final PlanFiles files; private final PlanFiles files;
private final PageFactory pageFactory; private final PageFactory pageFactory;
private final RootJSONHandler jsonHandler; private final RootJSONHandler jsonHandler;
private final Locale locale;
private final Theme theme;
private final ServerInfo serverInfo; private final ServerInfo serverInfo;
private final ExportPaths exportPaths; private final ExportPaths exportPaths;
@ -58,11 +62,15 @@ public class ServerPageExporter extends FileExporter {
PlanFiles files, PlanFiles files,
PageFactory pageFactory, PageFactory pageFactory,
RootJSONHandler jsonHandler, RootJSONHandler jsonHandler,
Locale locale,
Theme theme,
ServerInfo serverInfo // To know if current server is a Proxy ServerInfo serverInfo // To know if current server is a Proxy
) { ) {
this.files = files; this.files = files;
this.pageFactory = pageFactory; this.pageFactory = pageFactory;
this.jsonHandler = jsonHandler; this.jsonHandler = jsonHandler;
this.locale = locale;
this.theme = theme;
this.serverInfo = serverInfo; this.serverInfo = serverInfo;
exportPaths = new ExportPaths(); exportPaths = new ExportPaths();
@ -80,31 +88,39 @@ public class ServerPageExporter extends FileExporter {
.resolve(serverInfo.getServer().isProxy() ? "server/" + server.getName() : "server") .resolve(serverInfo.getServer().isProxy() ? "server/" + server.getName() : "server")
.resolve("index.html"); .resolve("index.html");
ServerPage serverPage = pageFactory.serverPage(serverUUID); Page page = pageFactory.serverPage(serverUUID);
export(to, exportPaths.resolveExportPaths(serverPage.toHtml())); export(to, exportPaths.resolveExportPaths(locale.replaceMatchingLanguage(page.toHtml())));
} }
private void exportJSON(Path toDirectory, Server server) throws IOException, NotFoundException { private void exportJSON(Path toDirectory, Server server) throws IOException, NotFoundException {
String serverName = server.getName(); String serverName = server.getName();
exportJSON(toDirectory, "serverOverview?server=" + serverName); exportJSON(toDirectory,
exportJSON(toDirectory, "onlineOverview?server=" + serverName); "serverOverview?server=" + serverName,
exportJSON(toDirectory, "sessionsOverview?server=" + serverName); "onlineOverview?server=" + serverName,
exportJSON(toDirectory, "playerVersus?server=" + serverName); "sessionsOverview?server=" + serverName,
exportJSON(toDirectory, "playerbaseOverview?server=" + serverName); "playerVersus?server=" + serverName,
exportJSON(toDirectory, "performanceOverview?server=" + serverName); "playerbaseOverview?server=" + serverName,
exportJSON(toDirectory, "graph?type=performance&server=" + serverName); "performanceOverview?server=" + serverName,
exportJSON(toDirectory, "graph?type=aggregatedPing&server=" + serverName); "graph?type=performance&server=" + serverName,
exportJSON(toDirectory, "graph?type=worldPie&server=" + serverName); "graph?type=aggregatedPing&server=" + serverName,
exportJSON(toDirectory, "graph?type=activity&server=" + serverName); "graph?type=worldPie&server=" + serverName,
exportJSON(toDirectory, "graph?type=geolocation&server=" + serverName); "graph?type=activity&server=" + serverName,
exportJSON(toDirectory, "graph?type=uniqueAndNew&server=" + serverName); "graph?type=geolocation&server=" + serverName,
exportJSON(toDirectory, "graph?type=serverCalendar&server=" + serverName); "graph?type=uniqueAndNew&server=" + serverName,
exportJSON(toDirectory, "graph?type=punchCard&server=" + serverName); "graph?type=serverCalendar&server=" + serverName,
exportJSON(toDirectory, "players?server=" + serverName); "graph?type=punchCard&server=" + serverName,
exportJSON(toDirectory, "kills?server=" + serverName); "players?server=" + serverName,
exportJSON(toDirectory, "pingTable?server=" + serverName); "kills?server=" + serverName,
exportJSON(toDirectory, "sessions?server=" + serverName); "pingTable?server=" + serverName,
"sessions?server=" + serverName
);
}
private void exportJSON(Path toDirectory, String... resources) throws NotFoundException, IOException {
for (String resource : resources) {
exportJSON(toDirectory, resource);
}
} }
private void exportJSON(Path toDirectory, String resource) throws NotFoundException, IOException { private void exportJSON(Path toDirectory, String resource) throws NotFoundException, IOException {
@ -133,43 +149,51 @@ public class ServerPageExporter extends FileExporter {
} }
private void exportRequiredResources(Path toDirectory) throws IOException { private void exportRequiredResources(Path toDirectory) throws IOException {
// Style
exportResource(toDirectory, "css/sb-admin-2.css");
exportResource(toDirectory, "css/style.css");
exportImage(toDirectory, "img/Flaticon_circle.png"); exportImage(toDirectory, "img/Flaticon_circle.png");
// Plugins // Style
exportResource(toDirectory, "vendor/jquery/jquery.min.js"); exportResources(toDirectory,
exportResource(toDirectory, "vendor/bootstrap/js/bootstrap.bundle.min.js"); "css/sb-admin-2.css",
exportResource(toDirectory, "vendor/jquery-easing/jquery.easing.min.js"); "css/style.css",
exportResource(toDirectory, "vendor/datatables/jquery.dataTables.min.js"); "vendor/jquery/jquery.min.js",
exportResource(toDirectory, "vendor/datatables/dataTables.bootstrap4.min.js"); "vendor/bootstrap/js/bootstrap.bundle.min.js",
exportResource(toDirectory, "vendor/highcharts/highstock.js"); "vendor/jquery-easing/jquery.easing.min.js",
exportResource(toDirectory, "vendor/highcharts/map.js"); "vendor/datatables/jquery.dataTables.min.js",
exportResource(toDirectory, "vendor/highcharts/world.js"); "vendor/datatables/dataTables.bootstrap4.min.js",
exportResource(toDirectory, "vendor/highcharts/drilldown.js"); "vendor/highcharts/highstock.js",
exportResource(toDirectory, "vendor/highcharts/highcharts-more.js"); "vendor/highcharts/map.js",
exportResource(toDirectory, "vendor/highcharts/no-data-to-display.js"); "vendor/highcharts/world.js",
exportResource(toDirectory, "vendor/fullcalendar/fullcalendar.min.css"); "vendor/highcharts/drilldown.js",
exportResource(toDirectory, "vendor/momentjs/moment.js"); "vendor/highcharts/highcharts-more.js",
exportResource(toDirectory, "vendor/fullcalendar/fullcalendar.min.js"); "vendor/highcharts/no-data-to-display.js",
"vendor/fullcalendar/fullcalendar.min.css",
"vendor/momentjs/moment.js",
"vendor/fullcalendar/fullcalendar.min.js",
"js/sb-admin-2.js",
"js/xmlhttprequests.js",
"js/color-selector.js",
"js/sessionAccordion.js",
"js/pingTable.js",
"js/graphs.js",
"js/server-values.js"
);
}
// Page level plugins private void exportResources(Path toDirectory, String... resourceNames) throws IOException {
exportResource(toDirectory, "js/sb-admin-2.js"); for (String resourceName : resourceNames) {
exportResource(toDirectory, "js/xmlhttprequests.js"); exportResource(toDirectory, resourceName);
exportResource(toDirectory, "js/color-selector.js"); }
// Page level scripts
exportResource(toDirectory, "js/sessionAccordion.js");
exportResource(toDirectory, "js/pingTable.js");
exportResource(toDirectory, "js/graphs.js");
exportResource(toDirectory, "js/server-values.js");
} }
private void exportResource(Path toDirectory, String resourceName) throws IOException { private void exportResource(Path toDirectory, String resourceName) throws IOException {
Resource resource = files.getCustomizableResourceOrDefault("web/" + resourceName); Resource resource = files.getCustomizableResourceOrDefault("web/" + resourceName);
Path to = toDirectory.resolve(resourceName); Path to = toDirectory.resolve(resourceName);
export(to, resource.asLines());
if (resourceName.endsWith(".css")) {
export(to, theme.replaceThemeColors(resource.asString()));
} else {
export(to, resource.asLines());
}
exportPaths.put(resourceName, toRelativePathFromRoot(resourceName)); exportPaths.put(resourceName, toRelativePathFromRoot(resourceName));
} }

View File

@ -16,29 +16,29 @@
*/ */
package com.djrapitops.plan.delivery.upkeep; package com.djrapitops.plan.delivery.upkeep;
import com.djrapitops.plan.delivery.export.HtmlExport; import com.djrapitops.plan.delivery.export.Exporter;
import com.djrapitops.plan.exceptions.ExportException;
import com.djrapitops.plan.utilities.java.ThrowingConsumer;
import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.L;
import com.djrapitops.plugin.logging.console.PluginLogger; import com.djrapitops.plugin.logging.console.PluginLogger;
import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.logging.error.ErrorHandler;
import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.AbsRunnable;
import javax.inject.Inject; public class ExportTask extends AbsRunnable {
import javax.inject.Singleton;
@Singleton private final Exporter exporter;
public class PeriodicServerExportTask extends AbsRunnable { private final ThrowingConsumer<Exporter, ExportException> exportAction;
private final HtmlExport htmlExport;
private final PluginLogger logger; private final PluginLogger logger;
private final ErrorHandler errorHandler; private final ErrorHandler errorHandler;
@Inject public ExportTask(
public PeriodicServerExportTask( Exporter exporter,
HtmlExport htmlExport, ThrowingConsumer<Exporter, ExportException> exportAction,
PluginLogger logger, PluginLogger logger,
ErrorHandler errorHandler ErrorHandler errorHandler
) { ) {
this.htmlExport = htmlExport; this.exporter = exporter;
this.exportAction = exportAction;
this.logger = logger; this.logger = logger;
this.errorHandler = errorHandler; this.errorHandler = errorHandler;
} }
@ -46,11 +46,11 @@ public class PeriodicServerExportTask extends AbsRunnable {
@Override @Override
public void run() { public void run() {
try { try {
htmlExport.exportAvailableServerPages(); exportAction.accept(exporter);
} catch (IllegalStateException ignore) { } catch (ExportException e) {
/* Plugin was reloading */ errorHandler.log(L.WARN, this.getClass(), e);
} catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) { } catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) {
logger.error("Periodic Analysis Task Disabled due to error, reload Plan to re-enable."); logger.error("Export Task Disabled due to error, reload Plan to re-enable.");
errorHandler.log(L.ERROR, this.getClass(), e); errorHandler.log(L.ERROR, this.getClass(), e);
cancel(); cancel();
} }

View File

@ -0,0 +1,33 @@
/*
* 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.exceptions;
/**
* Exception thrown by {@link com.djrapitops.plan.delivery.export.Exporter} if something goes wrong with export.
*
* @author Rsl1122
*/
public class ExportException extends Exception {
public ExportException(String message) {
super(message);
}
public ExportException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,30 @@
/*
* 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.utilities.java;
/**
* Functional interface that performs an operation that might throw an exception.
* <p>
* Follows naming scheme of Java 8 functional interfaces.
*
* @author Rsl1122
*/
public interface ThrowingConsumer<T, K extends Throwable> {
void accept(T consume) throws K;
}

View File

@ -16,7 +16,6 @@
*/ */
package com.djrapitops.plan; package com.djrapitops.plan;
import com.djrapitops.plan.delivery.upkeep.PeriodicServerExportTask;
import com.djrapitops.plan.delivery.webserver.cache.JSONCache; import com.djrapitops.plan.delivery.webserver.cache.JSONCache;
import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask; import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask;
import com.djrapitops.plan.gathering.ShutdownHook; import com.djrapitops.plan.gathering.ShutdownHook;
@ -24,7 +23,6 @@ import com.djrapitops.plan.gathering.timed.SpongePingCounter;
import com.djrapitops.plan.gathering.timed.SpongeTPSCounter; import com.djrapitops.plan.gathering.timed.SpongeTPSCounter;
import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.DataGatheringSettings; import com.djrapitops.plan.settings.config.paths.DataGatheringSettings;
import com.djrapitops.plan.settings.config.paths.ExportSettings;
import com.djrapitops.plan.settings.config.paths.TimeSettings; import com.djrapitops.plan.settings.config.paths.TimeSettings;
import com.djrapitops.plan.settings.upkeep.ConfigStoreTask; import com.djrapitops.plan.settings.upkeep.ConfigStoreTask;
import com.djrapitops.plan.storage.upkeep.DBCleanTask; import com.djrapitops.plan.storage.upkeep.DBCleanTask;
@ -46,7 +44,6 @@ public class SpongeTaskSystem extends TaskSystem {
private final ShutdownHook shutdownHook; private final ShutdownHook shutdownHook;
private final SpongeTPSCounter tpsCounter; private final SpongeTPSCounter tpsCounter;
private final JSONCache.CleanTask jsonCacheCleanTask; private final JSONCache.CleanTask jsonCacheCleanTask;
private final PeriodicServerExportTask periodicServerExportTask;
private final SpongePingCounter pingCounter; private final SpongePingCounter pingCounter;
private final LogsFolderCleanTask logsFolderCleanTask; private final LogsFolderCleanTask logsFolderCleanTask;
private final ConfigStoreTask configStoreTask; private final ConfigStoreTask configStoreTask;
@ -67,9 +64,7 @@ public class SpongeTaskSystem extends TaskSystem {
LogsFolderCleanTask logsFolderCleanTask, LogsFolderCleanTask logsFolderCleanTask,
ConfigStoreTask configStoreTask, ConfigStoreTask configStoreTask,
DBCleanTask dbCleanTask, DBCleanTask dbCleanTask,
JSONCache.CleanTask jsonCacheCleanTask, JSONCache.CleanTask jsonCacheCleanTask
PeriodicServerExportTask periodicServerExportTask
) { ) {
super(runnableFactory); super(runnableFactory);
this.plugin = plugin; this.plugin = plugin;
@ -85,7 +80,6 @@ public class SpongeTaskSystem extends TaskSystem {
this.dbCleanTask = dbCleanTask; this.dbCleanTask = dbCleanTask;
this.jsonCacheCleanTask = jsonCacheCleanTask; this.jsonCacheCleanTask = jsonCacheCleanTask;
this.periodicServerExportTask = periodicServerExportTask;
} }
@Override @Override
@ -109,10 +103,6 @@ public class SpongeTaskSystem extends TaskSystem {
); );
long minute = TimeAmount.toTicks(1, TimeUnit.MINUTES); long minute = TimeAmount.toTicks(1, TimeUnit.MINUTES);
registerTask(jsonCacheCleanTask).runTaskTimerAsynchronously(minute, minute); registerTask(jsonCacheCleanTask).runTaskTimerAsynchronously(minute, minute);
if (config.get(ExportSettings.SERVER_PAGE)) {
registerTask(periodicServerExportTask).runTaskTimerAsynchronously(TimeAmount.toTicks(30L, TimeUnit.SECONDS), TimeAmount.toTicks(20L, TimeUnit.MINUTES));
}
} }
private void registerTPSCounter() { private void registerTPSCounter() {