From 64d3704f8ecfa7bd12f7f8a286e3d5cc6fbc77a7 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Sat, 2 Dec 2017 13:32:08 +0200 Subject: [PATCH] Server Html Export #317 --- .../plan/utilities/analysis/Analysis.java | 6 +- .../utilities/analysis/ExportUtility.java | 122 ---------- .../plan/utilities/file/FileUtil.java | 4 +- .../utilities/file/export/HtmlExport.java | 217 ++++++++++++++++++ .../web/js/charts/pluginsTabExpand.js | 17 -- .../web/js/charts/sessionDistributionChart.js | 29 --- .../web/js/charts/sessionTabExpand.js | 17 -- Plan/src/main/resources/web/player.html | 32 +-- 8 files changed, 239 insertions(+), 205 deletions(-) delete mode 100644 Plan/src/main/java/com/djrapitops/plan/utilities/analysis/ExportUtility.java create mode 100644 Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java delete mode 100644 Plan/src/main/resources/web/js/charts/pluginsTabExpand.js delete mode 100644 Plan/src/main/resources/web/js/charts/sessionDistributionChart.js delete mode 100644 Plan/src/main/resources/web/js/charts/sessionTabExpand.js diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java index 368c1ca94..d6c0b4931 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/Analysis.java @@ -21,6 +21,7 @@ import main.java.com.djrapitops.plan.systems.info.BukkitInformationManager; import main.java.com.djrapitops.plan.systems.info.InformationManager; import main.java.com.djrapitops.plan.systems.webserver.response.ErrorResponse; import main.java.com.djrapitops.plan.systems.webserver.response.InternalErrorResponse; +import main.java.com.djrapitops.plan.utilities.file.export.HtmlExport; import java.util.*; @@ -137,8 +138,9 @@ public class Analysis { analysisData.parsePluginsSection(analyzeAdditionalPluginData(profile.getUuids())); ((BukkitInformationManager) infoManager).cacheAnalysisData(analysisData); - // TODO Export -// ExportUtility.export(analysisData, rawData); + if (Settings.ANALYSIS_EXPORT.isTrue()) { + RunnableFactory.createNew(new HtmlExport(plugin)).runTaskAsynchronously(); + } } catch (Exception e) { Log.toLog(this.getClass().getName(), e); ((BukkitInformationManager) plugin.getInfoManager()).cacheAnalysisHtml(new InternalErrorResponse(e, "Analysis").getContent()); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/ExportUtility.java b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/ExportUtility.java deleted file mode 100644 index 64a018a35..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/ExportUtility.java +++ /dev/null @@ -1,122 +0,0 @@ -package main.java.com.djrapitops.plan.utilities.analysis; - -import com.djrapitops.plugin.api.utility.log.Log; -import main.java.com.djrapitops.plan.Plan; -import main.java.com.djrapitops.plan.data.AnalysisData; -import main.java.com.djrapitops.plan.data.container.UserInfo; -import main.java.com.djrapitops.plan.settings.Settings; - -import java.io.File; -import java.nio.file.Paths; -import java.util.List; - -/** - * @author Rsl1122 - * @since 3.4.0 - */ -public class ExportUtility { - - /** - * Constructor used to hide the public constructor - */ - private ExportUtility() { - throw new IllegalStateException("Utility class"); - } - - public static File getFolder() { - String path = Settings.ANALYSIS_EXPORT_PATH.toString(); - - Log.logDebug("Export", "Path: " + path); - boolean isAbsolute = Paths.get(path).isAbsolute(); - Log.logDebug("Export", "Absolute: " + (isAbsolute ? "Yes" : "No")); - if (isAbsolute) { - File folder = new File(path); - if (!folder.exists() || !folder.isDirectory()) { - folder.mkdirs(); - } - return folder; - } - File dataFolder = Plan.getInstance().getDataFolder(); - File folder = new File(dataFolder, path); - folder.mkdirs(); - return folder; - } - - public static void export(AnalysisData analysisData, List playerNames) { - if (!Settings.ANALYSIS_EXPORT.isTrue()) { - return; - } - -// Benchmark.start("Export","Exporting Html pages"); -// try { -// File folder = getFolder(); -// Log.logDebug("Export", "Folder: " + folder.getAbsolutePath()); -// -// writePlayersPageHtml(playerNames, new File(folder, "players")); -// writeAnalysisHtml(analysisData, new File(folder, "server")); -// -// File playersFolder = getPlayersFolder(folder); -// Log.logDebug("Export", "Player html files."); -// Log.logDebug("Export", "Player Page Folder: " + playersFolder.getAbsolutePath()); -// -// String playerHtml = FileUtil.getStringFromResource("player.html"); -// -// Benchmark.start("Exporting Player pages"); -// playerNames.forEach(userData -> writeInspectHtml(userData, playersFolder, playerHtml)); -// Benchmark.stop("Export", "Exporting Player pages"); -// } catch (IOException ex) { -// Log.toLog("ExportUtils.export", ex); -// } finally { -// Benchmark.stop("Export", "Exporting Html pages"); -// Log.logDebug("Export"); -// } - } - - public static File getPlayersFolder(File folder) { - File playersFolder = new File(folder, "player"); - playersFolder.mkdirs(); - return playersFolder; - } - - public static void writeInspectHtml(UserInfo userInfo, File playersFolder, String playerHtml) { - if (!Settings.ANALYSIS_EXPORT.isTrue()) { - return; - } - - String name = userInfo.getName(); - - if (name.endsWith(".")) { - name = name.replace(".", "%2E"); - } - - if (name.endsWith(" ")) { - name = name.replace(" ", "%20"); - } - -// try { -// String inspectHtml = HtmlUtils.replacePlaceholders(playerHtml, -// PlaceholderUtils.getInspectReplaceRules(userInfo)); - -// File playerFolder = new File(playersFolder, name); -// playerFolder.mkdirs(); -// -// File inspectHtmlFile = new File(playerFolder, "index.html"); -// Files.write(inspectHtmlFile.toPath(), Collections.singletonList(inspectHtml)); -// } catch (IOException e) { -// Log.toLog("Export.writeInspectHtml: " + name, e); -// } - } - - public static void writeAnalysisHtml(AnalysisData analysisData, File serverFolder) { - if (!Settings.ANALYSIS_EXPORT.isTrue()) { - return; - } - serverFolder.mkdirs(); -// String analysisHtml = HtmlUtils.replacePlaceholders(FileUtil.getStringFromResource("server.html"), -// PlaceholderUtils.getAnalysisReplaceRules(analysisData)) -// .replace(HtmlUtils.getInspectUrl(""), "../player/"); -// File analysisHtmlFile = new File(serverFolder, "index.html"); -// Log.logDebug("Export", "Analysis Page File: " + analysisHtmlFile.getAbsolutePath()); -// Files.write(analysisHtmlFile.toPath(), Collections.singletonList(analysisHtml)); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/file/FileUtil.java b/Plan/src/main/java/com/djrapitops/plan/utilities/file/FileUtil.java index 87f4f87e8..ee577ce75 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/file/FileUtil.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/file/FileUtil.java @@ -35,7 +35,7 @@ public class FileUtil { return lines(savedFile); } else { String fileName = savedFile.getName(); - File found = attemptToFind(fileName, plugin.getDataFolder()); + File found = attemptToFind(fileName, new File(plugin.getDataFolder(), "web")); if (found != null) { return lines(found); } @@ -51,7 +51,7 @@ public class FileUtil { * @return File if found or null */ private static File attemptToFind(String fileName, File dataFolder) { - if (dataFolder.isDirectory()) { + if (dataFolder.exists() && dataFolder.isDirectory()) { ArrayDeque que = new ArrayDeque<>(); que.add(dataFolder); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java new file mode 100644 index 000000000..01768026e --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java @@ -0,0 +1,217 @@ +/* + * Licence is provided in the jar as license.yml also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml + */ +package main.java.com.djrapitops.plan.utilities.file.export; + +import com.djrapitops.plugin.api.Check; +import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.task.AbsRunnable; +import main.java.com.djrapitops.plan.Plan; +import main.java.com.djrapitops.plan.api.IPlan; +import main.java.com.djrapitops.plan.settings.Settings; +import main.java.com.djrapitops.plan.systems.webserver.PageCache; +import main.java.com.djrapitops.plan.systems.webserver.response.Response; +import main.java.com.djrapitops.plan.utilities.MiscUtils; +import main.java.com.djrapitops.plan.utilities.file.FileUtil; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * Class responsible for Html Export task. + * + * @author Rsl1122 + */ +public class HtmlExport extends AbsRunnable { + + private final IPlan plugin; + private final boolean usingBungee; + private final boolean exportSpecificPage; + + private String specificPage; + + private final File outputFolder; + + public HtmlExport(IPlan plugin) { + super("HtmlExportTask"); + usingBungee = Check.isBungeeAvailable(); + this.plugin = plugin; + + outputFolder = getFolder(); + exportSpecificPage = false; + } + + public HtmlExport(IPlan plugin, String specificPage) { + super("HtmlExportTask"); + usingBungee = Check.isBungeeAvailable(); + this.plugin = plugin; + + outputFolder = getFolder(); + exportSpecificPage = true; + this.specificPage = specificPage; + } + + @Override + public void run() { + try { + boolean usingAnotherWebServer = plugin.getInfoManager().isUsingAnotherWebServer(); + if (usingAnotherWebServer) { + return; + } + + exportCss(); + exportJs(); + exportPlugins(); + + exportAvailableServerPages(); + } catch (IOException | SQLException e) { + Log.toLog(this.getClass().getName(), e); + } finally { + this.cancel(); + } + } + + private void exportAvailableServerPages() throws SQLException, IOException { + Map serverNames = plugin.getDB().getServerTable().getServerNames(); + + for (Map.Entry entry : serverNames.entrySet()) { + UUID serverUUID = entry.getKey(); + + Response response = PageCache.loadPage("analysisPage:" + serverUUID); + if (response == null) { + continue; + } + + String html = response.getContent() + .replace("href=\"plugins/", "href=\"../plugins/") + .replace("href=\"css/", "href=\"../css/") + .replace("src=\"plugins/", "src=\"../plugins/") + .replace("src=\"js/", "src=\"../js/"); + + File htmlLocation = null; + if (usingBungee && serverUUID.equals(MiscUtils.getIPlan().getServerUuid())) { + htmlLocation = new File(outputFolder, "network"); + } else { + String serverName = entry.getValue(); + File serverFolder = getServerFolder(); + htmlLocation = new File(serverFolder, serverName.replace(" ", "%20")); + html = html.replace("../", "../../"); + } + htmlLocation.mkdirs(); + File exportFile = new File(htmlLocation, "index.html"); + + List lines = Arrays.asList(html.split("\n")); + + export(exportFile, lines); + } + } + + private void exportCss() { + String[] resources = new String[]{ + "web/css/main.css", + "web/css/materialize.css", + "web/css/style.css", + "web/css/themes/all-themes.css" + }; + copyFromJar(resources); + } + + private void exportJs() { + String[] resources = new String[]{ + "web/js/admin.js", + "web/js/demo.js", + "web/js/helpers.js", + "web/js/script.js", + "web/js/charts/activityPie.js", + "web/js/charts/activityStackGraph.js", + "web/js/charts/performanceGraph.js", + "web/js/charts/playerGraph.js", + "web/js/charts/playerGraphNoNav.js", + "web/js/charts/resourceGraph.js", + "web/js/charts/tpsGraph.js", + "web/js/charts/worldGraph.js", + "web/js/charts/worldMap.js", + "web/js/charts/punchCard.js", + "web/js/charts/serverPie.js", + "web/js/charts/worldPie.js", + "web/js/charts/healthGauge.js" + }; + copyFromJar(resources); + } + + private void exportPlugins() { + String[] resources = new String[]{ + "web/plugins/bootstrap/css/bootstrap.css", + "web/plugins/node-waves/waves.css", + "web/plugins/node-waves/waves.js", + "web/plugins/animate-css/animate.css", + "web/plugins/jquery-slimscroll/jquery.slimscroll.js", + "web/plugins/jquery/jquery.min.js", + "web/plugins/bootstrap/js/bootstrap.js", + "web/plugins/jquery-datatable/skin/bootstrap/js/dataTables.bootstrap.js", + "web/plugins/jquery-datatable/jquery.dataTables.js" + }; + copyFromJar(resources); + } + + public File getFolder() { + String path = Settings.ANALYSIS_EXPORT_PATH.toString(); + + Log.logDebug("Export", "Path: " + path); + boolean isAbsolute = Paths.get(path).isAbsolute(); + Log.logDebug("Export", "Absolute: " + (isAbsolute ? "Yes" : "No")); + if (isAbsolute) { + File folder = new File(path); + if (!folder.exists() || !folder.isDirectory()) { + folder.mkdirs(); + } + return folder; + } + File dataFolder = Plan.getInstance().getDataFolder(); + File folder = new File(dataFolder, path); + folder.mkdirs(); + return folder; + } + + private void copyFromJar(String[] resources) { + for (String resource : resources) { + try { + copyFromJar(resource); + } catch (IOException e) { + Log.toLog(this.getClass().getName(), e); + } + } + } + + private void copyFromJar(String resource) throws IOException { + String possibleFile = resource.replace("web/", "").replace("/", File.separator); + List lines = FileUtil.lines(plugin, new File(plugin.getDataFolder(), possibleFile), resource); + String outputFile = possibleFile.replace("web/", ""); + File to = new File(outputFolder, outputFile); + to.mkdirs(); + if (to.exists()) { + to.delete(); + to.createNewFile(); + } + export(to, lines); + } + + private void export(File to, List lines) throws IOException { + Files.write(to.toPath(), lines, Charset.forName("UTF-8")); + } + + public File getServerFolder() { + File server = new File(outputFolder, "server"); + server.mkdirs(); + return server; + } +} \ No newline at end of file diff --git a/Plan/src/main/resources/web/js/charts/pluginsTabExpand.js b/Plan/src/main/resources/web/js/charts/pluginsTabExpand.js deleted file mode 100644 index 16f6f2de2..000000000 --- a/Plan/src/main/resources/web/js/charts/pluginsTabExpand.js +++ /dev/null @@ -1,17 +0,0 @@ -$(".plugins-header").click(function () { - $header = $(this); - $content = $header.next(); - $(this).parent().siblings().children().next().slideUp(500); - - $header.html(function(i, origText) { - $(".plugins-header").html(function(i, origText) { - return origText.replace("fa-chevron-up", "fa-chevron-down") - }); - if (origText.includes("fa-chevron-down")) { - return origText.replace("fa-chevron-down", "fa-chevron-up") - } else { - return origText.replace("fa-chevron-up", "fa-chevron-down") - } - }); - $content.slideToggle(500); -}); \ No newline at end of file diff --git a/Plan/src/main/resources/web/js/charts/sessionDistributionChart.js b/Plan/src/main/resources/web/js/charts/sessionDistributionChart.js deleted file mode 100644 index 123943962..000000000 --- a/Plan/src/main/resources/web/js/charts/sessionDistributionChart.js +++ /dev/null @@ -1,29 +0,0 @@ -function sessionDistributionChart(id, sessionLengthSeries) { - Highcharts.chart(id, { - chart: { - type: 'column' - }, - xAxis: { - type: 'category', - labels: { - rotation: -45 - } - }, - yAxis: { - min: 0, - title: { - text: 'Sessions' - } - }, - legend: { - enabled: false - }, - plotOptions: { - series: { - groupPadding: 0 - }, - pointPadding: 0 - }, - series: [sessionLengthSeries] - }); -} \ No newline at end of file diff --git a/Plan/src/main/resources/web/js/charts/sessionTabExpand.js b/Plan/src/main/resources/web/js/charts/sessionTabExpand.js deleted file mode 100644 index 66dbdad3f..000000000 --- a/Plan/src/main/resources/web/js/charts/sessionTabExpand.js +++ /dev/null @@ -1,17 +0,0 @@ -$(".session-header").click(function () { - $header = $(this); - $content = $header.next(); - $(this).parent().siblings().children().next().slideUp(500); - - $header.html(function(i, origText) { - $(".session-header").html(function(i, origText) { - return origText.replace("fa-chevron-up", "fa-chevron-down") - }); - if (origText.includes("fa-chevron-down")) { - return origText.replace("fa-chevron-down", "fa-chevron-up") - } else { - return origText.replace("fa-chevron-up", "fa-chevron-down") - } - }); - $content.slideToggle(500); -}); \ No newline at end of file diff --git a/Plan/src/main/resources/web/player.html b/Plan/src/main/resources/web/player.html index 056f7866f..83f93ad9c 100644 --- a/Plan/src/main/resources/web/player.html +++ b/Plan/src/main/resources/web/player.html @@ -15,22 +15,22 @@ - + - + - + - + - + - + @@ -552,20 +552,20 @@ - + - + - + - + - - + + @@ -578,12 +578,12 @@ - + - - - + + +