diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitTaskSystem.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitTaskSystem.java index 2c1962414..59fe57daa 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitTaskSystem.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitTaskSystem.java @@ -16,7 +16,6 @@ */ package com.djrapitops.plan; -import com.djrapitops.plan.delivery.upkeep.PeriodicServerExportTask; import com.djrapitops.plan.delivery.webserver.cache.JSONCache; import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask; 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.settings.config.PlanConfig; 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.upkeep.ConfigStoreTask; import com.djrapitops.plan.storage.upkeep.DBCleanTask; @@ -52,7 +50,6 @@ public class BukkitTaskSystem extends TaskSystem { private final PlanConfig config; private final ShutdownHook shutdownHook; private final JSONCache.CleanTask jsonCacheCleanTask; - private final PeriodicServerExportTask periodicServerExportTask; private final LogsFolderCleanTask logsFolderCleanTask; private final BukkitPingCounter pingCounter; private final ConfigStoreTask configStoreTask; @@ -75,9 +72,7 @@ public class BukkitTaskSystem extends TaskSystem { LogsFolderCleanTask logsFolderCleanTask, ConfigStoreTask configStoreTask, DBCleanTask dbCleanTask, - JSONCache.CleanTask jsonCacheCleanTask, - - PeriodicServerExportTask periodicServerExportTask + JSONCache.CleanTask jsonCacheCleanTask ) { super(runnableFactory); this.plugin = plugin; @@ -92,8 +87,6 @@ public class BukkitTaskSystem extends TaskSystem { this.logsFolderCleanTask = logsFolderCleanTask; this.configStoreTask = configStoreTask; this.dbCleanTask = dbCleanTask; - - this.periodicServerExportTask = periodicServerExportTask; } @Override @@ -117,10 +110,6 @@ public class BukkitTaskSystem extends TaskSystem { ); long minute = TimeAmount.toTicks(1, TimeUnit.MINUTES); 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() { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/Exporter.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/Exporter.java index 468ec5bdd..549f7037e 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/Exporter.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/Exporter.java @@ -16,20 +16,22 @@ */ package com.djrapitops.plan.delivery.export; +import com.djrapitops.plan.exceptions.ExportException; import com.djrapitops.plan.exceptions.ParseException; import com.djrapitops.plan.exceptions.connection.NotFoundException; import com.djrapitops.plan.identification.Server; import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.ExportSettings; 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.Singleton; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; /** * Handles export for different pages. @@ -42,33 +44,54 @@ public class Exporter { private final PlanFiles files; private final PlanConfig config; private final ServerPageExporter serverPageExporter; - private final ErrorHandler errorHandler; + private final NetworkPageExporter networkPageExporter; + + private final Set failedServers; @Inject public Exporter( PlanFiles files, PlanConfig config, ServerPageExporter serverPageExporter, - ErrorHandler errorHandler + NetworkPageExporter networkPageExporter ) { this.files = files; this.config = config; 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)); return exportDirectory.isAbsolute() ? 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 { - 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) { - 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); } } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/HtmlExport.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/HtmlExport.java index 0c03931ad..37b8c0032 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/HtmlExport.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/HtmlExport.java @@ -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.PageFactory; 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.database.DBOpException; import com.djrapitops.plan.gathering.domain.BaseUser; @@ -97,7 +98,11 @@ public class HtmlExport extends SpecificExport { // if (serverInfo.getServer().isNotProxy() && hasProxy) { // return; // } - exporter.exportServerPage(server); + try { + exporter.exportServerPage(server); + } catch (ExportException e) { + errorHandler.log(L.WARN, this.getClass(), e); + } } public void exportPlayerPage(UUID playerUUID) { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/NetworkPageExporter.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/NetworkPageExporter.java new file mode 100644 index 000000000..ef1079762 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/NetworkPageExporter.java @@ -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 . + */ +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, "../"); + } + +} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ServerPageExporter.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ServerPageExporter.java index 12227d64a..80badb5d2 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ServerPageExporter.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/export/ServerPageExporter.java @@ -16,8 +16,8 @@ */ 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.ServerPage; import com.djrapitops.plan.delivery.webserver.RequestTarget; import com.djrapitops.plan.delivery.webserver.pages.json.RootJSONHandler; 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.identification.Server; 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.Resource; import org.apache.commons.lang3.StringUtils; @@ -49,6 +51,8 @@ public class ServerPageExporter extends FileExporter { private final PlanFiles files; private final PageFactory pageFactory; private final RootJSONHandler jsonHandler; + private final Locale locale; + private final Theme theme; private final ServerInfo serverInfo; private final ExportPaths exportPaths; @@ -58,11 +62,15 @@ public class ServerPageExporter extends FileExporter { PlanFiles files, PageFactory pageFactory, RootJSONHandler jsonHandler, + Locale locale, + Theme theme, ServerInfo serverInfo // To know if current server is a Proxy ) { this.files = files; this.pageFactory = pageFactory; this.jsonHandler = jsonHandler; + this.locale = locale; + this.theme = theme; this.serverInfo = serverInfo; exportPaths = new ExportPaths(); @@ -80,31 +88,39 @@ public class ServerPageExporter extends FileExporter { .resolve(serverInfo.getServer().isProxy() ? "server/" + server.getName() : "server") .resolve("index.html"); - ServerPage serverPage = pageFactory.serverPage(serverUUID); - export(to, exportPaths.resolveExportPaths(serverPage.toHtml())); + Page page = pageFactory.serverPage(serverUUID); + export(to, exportPaths.resolveExportPaths(locale.replaceMatchingLanguage(page.toHtml()))); } private void exportJSON(Path toDirectory, Server server) throws IOException, NotFoundException { String serverName = server.getName(); - exportJSON(toDirectory, "serverOverview?server=" + serverName); - exportJSON(toDirectory, "onlineOverview?server=" + serverName); - exportJSON(toDirectory, "sessionsOverview?server=" + serverName); - exportJSON(toDirectory, "playerVersus?server=" + serverName); - exportJSON(toDirectory, "playerbaseOverview?server=" + serverName); - exportJSON(toDirectory, "performanceOverview?server=" + serverName); - exportJSON(toDirectory, "graph?type=performance&server=" + serverName); - exportJSON(toDirectory, "graph?type=aggregatedPing&server=" + serverName); - exportJSON(toDirectory, "graph?type=worldPie&server=" + serverName); - exportJSON(toDirectory, "graph?type=activity&server=" + serverName); - exportJSON(toDirectory, "graph?type=geolocation&server=" + serverName); - exportJSON(toDirectory, "graph?type=uniqueAndNew&server=" + serverName); - exportJSON(toDirectory, "graph?type=serverCalendar&server=" + serverName); - exportJSON(toDirectory, "graph?type=punchCard&server=" + serverName); - exportJSON(toDirectory, "players?server=" + serverName); - exportJSON(toDirectory, "kills?server=" + serverName); - exportJSON(toDirectory, "pingTable?server=" + serverName); - exportJSON(toDirectory, "sessions?server=" + serverName); + exportJSON(toDirectory, + "serverOverview?server=" + serverName, + "onlineOverview?server=" + serverName, + "sessionsOverview?server=" + serverName, + "playerVersus?server=" + serverName, + "playerbaseOverview?server=" + serverName, + "performanceOverview?server=" + serverName, + "graph?type=performance&server=" + serverName, + "graph?type=aggregatedPing&server=" + serverName, + "graph?type=worldPie&server=" + serverName, + "graph?type=activity&server=" + serverName, + "graph?type=geolocation&server=" + serverName, + "graph?type=uniqueAndNew&server=" + serverName, + "graph?type=serverCalendar&server=" + serverName, + "graph?type=punchCard&server=" + serverName, + "players?server=" + serverName, + "kills?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 { @@ -133,43 +149,51 @@ public class ServerPageExporter extends FileExporter { } 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"); - // Plugins - exportResource(toDirectory, "vendor/jquery/jquery.min.js"); - exportResource(toDirectory, "vendor/bootstrap/js/bootstrap.bundle.min.js"); - exportResource(toDirectory, "vendor/jquery-easing/jquery.easing.min.js"); - exportResource(toDirectory, "vendor/datatables/jquery.dataTables.min.js"); - exportResource(toDirectory, "vendor/datatables/dataTables.bootstrap4.min.js"); - exportResource(toDirectory, "vendor/highcharts/highstock.js"); - exportResource(toDirectory, "vendor/highcharts/map.js"); - exportResource(toDirectory, "vendor/highcharts/world.js"); - exportResource(toDirectory, "vendor/highcharts/drilldown.js"); - exportResource(toDirectory, "vendor/highcharts/highcharts-more.js"); - exportResource(toDirectory, "vendor/highcharts/no-data-to-display.js"); - exportResource(toDirectory, "vendor/fullcalendar/fullcalendar.min.css"); - exportResource(toDirectory, "vendor/momentjs/moment.js"); - exportResource(toDirectory, "vendor/fullcalendar/fullcalendar.min.js"); + // Style + 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", + "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 - exportResource(toDirectory, "js/sb-admin-2.js"); - exportResource(toDirectory, "js/xmlhttprequests.js"); - 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 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); - export(to, resource.asLines()); + + if (resourceName.endsWith(".css")) { + export(to, theme.replaceThemeColors(resource.asString())); + } else { + export(to, resource.asLines()); + } exportPaths.put(resourceName, toRelativePathFromRoot(resourceName)); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/upkeep/PeriodicServerExportTask.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/upkeep/ExportTask.java similarity index 65% rename from Plan/common/src/main/java/com/djrapitops/plan/delivery/upkeep/PeriodicServerExportTask.java rename to Plan/common/src/main/java/com/djrapitops/plan/delivery/upkeep/ExportTask.java index c236eaaa6..b1ec42cbb 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/upkeep/PeriodicServerExportTask.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/upkeep/ExportTask.java @@ -16,29 +16,29 @@ */ 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.console.PluginLogger; import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.task.AbsRunnable; -import javax.inject.Inject; -import javax.inject.Singleton; +public class ExportTask extends AbsRunnable { -@Singleton -public class PeriodicServerExportTask extends AbsRunnable { - - private final HtmlExport htmlExport; + private final Exporter exporter; + private final ThrowingConsumer exportAction; private final PluginLogger logger; private final ErrorHandler errorHandler; - @Inject - public PeriodicServerExportTask( - HtmlExport htmlExport, + public ExportTask( + Exporter exporter, + ThrowingConsumer exportAction, PluginLogger logger, ErrorHandler errorHandler ) { - this.htmlExport = htmlExport; + this.exporter = exporter; + this.exportAction = exportAction; this.logger = logger; this.errorHandler = errorHandler; } @@ -46,11 +46,11 @@ public class PeriodicServerExportTask extends AbsRunnable { @Override public void run() { try { - htmlExport.exportAvailableServerPages(); - } catch (IllegalStateException ignore) { - /* Plugin was reloading */ + exportAction.accept(exporter); + } catch (ExportException e) { + errorHandler.log(L.WARN, this.getClass(), 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); cancel(); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/exceptions/ExportException.java b/Plan/common/src/main/java/com/djrapitops/plan/exceptions/ExportException.java new file mode 100644 index 000000000..a37a8f8b4 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/exceptions/ExportException.java @@ -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 . + */ +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); + } +} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/ThrowingConsumer.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/ThrowingConsumer.java new file mode 100644 index 000000000..4d515c3d5 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/java/ThrowingConsumer.java @@ -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 . + */ +package com.djrapitops.plan.utilities.java; + +/** + * Functional interface that performs an operation that might throw an exception. + *

+ * Follows naming scheme of Java 8 functional interfaces. + * + * @author Rsl1122 + */ +public interface ThrowingConsumer { + + void accept(T consume) throws K; + +} \ No newline at end of file diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/SpongeTaskSystem.java b/Plan/sponge/src/main/java/com/djrapitops/plan/SpongeTaskSystem.java index d34c2a7ef..4897c9b3d 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/SpongeTaskSystem.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/SpongeTaskSystem.java @@ -16,7 +16,6 @@ */ package com.djrapitops.plan; -import com.djrapitops.plan.delivery.upkeep.PeriodicServerExportTask; import com.djrapitops.plan.delivery.webserver.cache.JSONCache; import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask; 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.settings.config.PlanConfig; 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.upkeep.ConfigStoreTask; import com.djrapitops.plan.storage.upkeep.DBCleanTask; @@ -46,7 +44,6 @@ public class SpongeTaskSystem extends TaskSystem { private final ShutdownHook shutdownHook; private final SpongeTPSCounter tpsCounter; private final JSONCache.CleanTask jsonCacheCleanTask; - private final PeriodicServerExportTask periodicServerExportTask; private final SpongePingCounter pingCounter; private final LogsFolderCleanTask logsFolderCleanTask; private final ConfigStoreTask configStoreTask; @@ -67,9 +64,7 @@ public class SpongeTaskSystem extends TaskSystem { LogsFolderCleanTask logsFolderCleanTask, ConfigStoreTask configStoreTask, DBCleanTask dbCleanTask, - JSONCache.CleanTask jsonCacheCleanTask, - - PeriodicServerExportTask periodicServerExportTask + JSONCache.CleanTask jsonCacheCleanTask ) { super(runnableFactory); this.plugin = plugin; @@ -85,7 +80,6 @@ public class SpongeTaskSystem extends TaskSystem { this.dbCleanTask = dbCleanTask; this.jsonCacheCleanTask = jsonCacheCleanTask; - this.periodicServerExportTask = periodicServerExportTask; } @Override @@ -109,10 +103,6 @@ public class SpongeTaskSystem extends TaskSystem { ); long minute = TimeAmount.toTicks(1, TimeUnit.MINUTES); 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() {