[#922] Refactored file accessing

- All plugin files moved to /assets/ inside the jar
- InputStreams, lines and flat string now accessed through Resource
  interface obtained from PlanFiles
- Removed FileUtil
- Removed old methods from PlanFiles that returned something that is now
  accessed via Resource interface.
- Implemented a PlanFiles class for Sponge that uses Sponge
  Asset API for fetching items in the jar.
This commit is contained in:
Rsl1122 2019-04-03 19:24:19 +03:00
parent f1b42e9a58
commit 1335ba299f
206 changed files with 1173 additions and 976 deletions

View File

@ -32,7 +32,6 @@ import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.ExportSettings;
import com.djrapitops.plan.system.settings.theme.Theme;
import com.djrapitops.plan.system.settings.theme.ThemeVal;
import com.djrapitops.plan.utilities.file.FileUtil;
import com.djrapitops.plan.utilities.html.pages.InspectPage;
import com.djrapitops.plan.utilities.html.pages.PageFactory;
import com.djrapitops.plugin.api.Check;
@ -217,12 +216,13 @@ public class HtmlExport extends SpecificExport {
copyFromJar(resources);
try {
String demo = files.readFromResourceFlat("web/js/demo.js")
String demo = files.getCustomizableResourceOrDefault("web/js/demo.js")
.asString()
.replace("${defaultTheme}", theme.getValue(ThemeVal.THEME_DEFAULT));
List<String> lines = Arrays.asList(demo.split("\n"));
File outputFolder = new File(getFolder(), "js");
Verify.isTrue(outputFolder.exists() && outputFolder.isDirectory() || outputFolder.mkdirs(),
() -> new FileNotFoundException("Output folder could not be created at" + outputFolder.getAbsolutePath()));
() -> new FileNotFoundException("Output folder could not be created at " + outputFolder.getAbsolutePath()));
export(new File(outputFolder, "demo.js"), lines);
} catch (IOException e) {
errorHandler.log(L.WARN, this.getClass(), e);
@ -258,19 +258,21 @@ public class HtmlExport extends SpecificExport {
}
private void copyFromJar(String resource) throws IOException {
String possibleFile = resource.replace("web/", "").replace("/", File.separator);
List<String> lines = FileUtil.lines(plugin, new File(plugin.getDataFolder(), possibleFile), resource);
String outputFile = possibleFile.replace("web/", "");
File to = new File(getFolder(), outputFile);
List<String> lines = files.getCustomizableResourceOrDefault(resource).asLines();
File to = new File(getFolder(), resource.replace("web/", "").replace("/", File.separator));
File locationFolder = to.getParentFile();
Verify.isTrue(locationFolder.exists() && locationFolder.isDirectory() || locationFolder.mkdirs(),
() -> new FileNotFoundException("Output folder could not be created at" + locationFolder.getAbsolutePath()));
if (to.exists()) {
Files.delete(to.toPath());
if (!to.createNewFile()) {
return;
}
}
export(to, lines);
}
}

View File

@ -0,0 +1,81 @@
/*
* 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.system.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* {@link Resource} implementation for a {@link File}.
*
* @author Rsl1122
*/
public class FileResource implements Resource {
private final String resourceName;
private final File file;
public FileResource(String resourceName, File file) {
this.resourceName = resourceName;
this.file = file;
}
public static List<String> lines(File file) throws IOException {
List<String> lines = new ArrayList<>();
if (file != null && file.exists()) {
try (Stream<String> linesStream = Files.lines(file.toPath(), StandardCharsets.UTF_8)) {
lines = linesStream.collect(Collectors.toList());
}
}
return lines;
}
@Override
public String getResourceName() {
return resourceName;
}
@Override
public InputStream asInputStream() throws IOException {
return new FileInputStream(file);
}
@Override
public List<String> asLines() throws IOException {
return lines(file);
}
@Override
public String asString() throws IOException {
StringBuilder flat = new StringBuilder();
try (Scanner scanner = new Scanner(file, "UTF-8")) {
while (scanner.hasNextLine()) {
flat.append(scanner.nextLine()).append("\r\n");
}
}
return flat.toString();
}
}

View File

@ -0,0 +1,88 @@
/*
* 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.system.file;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* {@link Resource} implementation for something that is read via InputStream.
*
* @author Rsl1122
*/
public class JarResource implements Resource {
private final String resourceName;
private final StreamSupplier streamSupplier;
public JarResource(String resourceName, StreamSupplier streamSupplier) {
this.resourceName = resourceName;
this.streamSupplier = streamSupplier;
}
@Override
public InputStream asInputStream() throws IOException {
InputStream stream = streamSupplier.get();
if (stream == null) {
throw new FileNotFoundException("a Resource was not found inside the jar (" + resourceName + "), " +
"Plan does not support /reload or updates using " +
"Plugin Managers, restart the server and see if the error persists.");
}
return stream;
}
@Override
public List<String> asLines() throws IOException {
List<String> lines = new ArrayList<>();
try (
InputStream inputStream = asInputStream();
Scanner scanner = new Scanner(inputStream, "UTF-8")
) {
while (scanner.hasNextLine()) {
lines.add(scanner.nextLine());
}
}
return lines;
}
@Override
public String asString() throws IOException {
StringBuilder flat = new StringBuilder();
try (
InputStream inputStream = asInputStream();
Scanner scanner = new Scanner(inputStream, "UTF-8")
) {
while (scanner.hasNextLine()) {
flat.append(scanner.nextLine()).append("\r\n");
}
}
return flat.toString();
}
@Override
public String getResourceName() {
return resourceName;
}
interface StreamSupplier {
InputStream get() throws IOException;
}
}

View File

@ -19,15 +19,15 @@ package com.djrapitops.plan.system.file;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.system.SubSystem;
import com.djrapitops.plan.utilities.file.FileUtil;
import com.djrapitops.plugin.utilities.Verify;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Optional;
/**
* Abstracts File methods of Plugin classes so that they can be tested without Mocks.
@ -37,7 +37,7 @@ import java.util.List;
@Singleton
public class PlanFiles implements SubSystem {
private final PlanPlugin plugin;
protected final PlanPlugin plugin;
private final File dataFolder;
private final File configFile;
@ -68,7 +68,7 @@ public class PlanFiles implements SubSystem {
}
public File getFileFromPluginFolder(String name) {
return new File(dataFolder, name);
return new File(dataFolder, name.replace("/", File.separator));
}
@Override
@ -89,53 +89,53 @@ public class PlanFiles implements SubSystem {
}
/**
* Read a file from jar as lines.
* Get a file in the jar as a {@link Resource}.
*
* @param fileName Name of the file.
* @return lines of the file
* @throws IOException If the resource can not be read.
* @param resourceName Path to the file inside jar/assets/ folder.
* @return a {@link Resource} for accessing the resource.
*/
public List<String> readFromResource(String fileName) throws IOException {
return FileUtil.lines(plugin, fileName);
}
public InputStream readStreamFromResource(String fileName) throws IOException {
return plugin.getResource(fileName);
public Resource getResourceFromJar(String resourceName) {
return new JarResource("assets/" + resourceName, () -> plugin.getResource("assets/" + resourceName));
}
/**
* Read a file from jar as a flat String.
* Get a file from plugin folder as a {@link Resource}.
*
* @param fileName Name of the file
* @return Flattened lines with {@code \r\n} line separators.
* @throws IOException If the resource can not be read.
* @param resourceName Path to the file inside the plugin folder.
* @return a {@link Resource} for accessing the resource.
*/
public String readFromResourceFlat(String fileName) throws IOException {
return flatten(readFromResource(fileName));
public Resource getResourceFromPluginFolder(String resourceName) {
return new FileResource(resourceName, getFileFromPluginFolder(resourceName));
}
/**
* Read a file from jar or /plugins/Plan/ folder.
* Get a customizable resource from the plugin files or from the jar if one doesn't exist.
*
* @param fileName Name of the file
* @return Flattened lines with {@code \r\n} line separators.
* @throws IOException If the resource can not be read.
* @param resourceName Path to the file inside the plugin folder.
* @return a {@link Resource} for accessing the resource, either from the plugin folder or jar.
*/
public String readCustomizableResourceFlat(String fileName) throws IOException {
return flatten(FileUtil.lines(
plugin, new File(plugin.getDataFolder(), fileName.replace("/", File.separator)), fileName
));
public Resource getCustomizableResourceOrDefault(String resourceName) {
return attemptToFind(resourceName).map(file -> (Resource) new FileResource(resourceName, file)).orElse(getResourceFromJar(resourceName));
}
public InputStream readCustomizableResource(String fileName) {
return FileUtil.stream(plugin, new File(plugin.getDataFolder(), fileName.replace("/", File.separator)), fileName);
}
private Optional<File> attemptToFind(String resourceName) {
if (dataFolder.exists() && dataFolder.isDirectory()) {
ArrayDeque<File> que = new ArrayDeque<>();
que.add(dataFolder);
private String flatten(List<String> lines) {
StringBuilder flat = new StringBuilder();
for (String line : lines) {
flat.append(line).append("\r\n");
while (!que.isEmpty()) {
File file = que.pop();
if (file.isFile() && resourceName.equals(file.getName())) {
return Optional.of(file);
}
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
que.addAll(Arrays.asList(files));
}
}
}
}
return flat.toString();
return Optional.empty();
}
}

View File

@ -0,0 +1,61 @@
/*
* 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.system.file;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* Interface for accessing plugin resources in jar or plugin files.
*
* @author Rsl1122
*/
public interface Resource {
/**
* Get the name of this Resource.
*
* @return Relative file path given to {@link PlanFiles}.
*/
String getResourceName();
/**
* Get the resource as an InputStream.
*
* @return InputStream of the resource, not closed automatically.
* @throws IOException If the resource is unavailable.
*/
InputStream asInputStream() throws IOException;
/**
* Get the resource as lines.
*
* @return Lines of the resource file.
* @throws IOException If the resource is unavailable.
*/
List<String> asLines() throws IOException;
/**
* Get the resource as a String with each line separated by CRLF newline characters {@code \r\n}.
*
* @return Flat string with each line separated by {@code \r\n}.
* @throws IOException If the resource is unavailable.
*/
String asString() throws IOException;
}

View File

@ -45,7 +45,7 @@ public class ServerInfoFile extends Config {
}
public void prepare() throws IOException {
try (ConfigReader reader = new ConfigReader(files.readStreamFromResource("DefaultServerInfoFile.yml"))) {
try (ConfigReader reader = new ConfigReader(files.getResourceFromJar("DefaultServerInfoFile.yml").asInputStream())) {
copyMissing(reader.read());
}
save();

View File

@ -16,7 +16,8 @@
*/
package com.djrapitops.plan.system.locale;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.system.file.FileResource;
import com.djrapitops.plan.system.file.PlanFiles;
import com.djrapitops.plan.system.locale.lang.*;
import java.io.File;
@ -36,16 +37,16 @@ import java.util.stream.Collectors;
*/
public class Locale extends HashMap<Lang, Message> {
public static Locale forLangCodeString(PlanPlugin plugin, String code) throws IOException {
return forLangCode(LangCode.fromString(code), plugin);
public static Locale forLangCodeString(PlanFiles files, String code) throws IOException {
return forLangCode(LangCode.fromString(code), files);
}
public static Locale forLangCode(LangCode code, PlanPlugin plugin) throws IOException {
return new LocaleFileReader(plugin, code.getFileName()).load();
public static Locale forLangCode(LangCode code, PlanFiles files) throws IOException {
return new LocaleFileReader(files.getResourceFromJar("locale/" + code.getFileName())).load();
}
public static Locale fromFile(File file) throws IOException {
return new LocaleFileReader(file).load();
return new LocaleFileReader(new FileResource(file.getName(), file)).load();
}
@Override

View File

@ -16,11 +16,9 @@
*/
package com.djrapitops.plan.system.locale;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.system.file.Resource;
import com.djrapitops.plan.system.locale.lang.Lang;
import com.djrapitops.plan.utilities.file.FileUtil;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@ -34,12 +32,8 @@ public class LocaleFileReader {
private List<String> lines;
public LocaleFileReader(File from) throws IOException {
lines = FileUtil.lines(from);
}
public LocaleFileReader(PlanPlugin planPlugin, String fileName) throws IOException {
lines = FileUtil.lines(planPlugin, "locale/" + fileName);
public LocaleFileReader(Resource resource) throws IOException {
lines = resource.asLines();
}
public Locale load() {

View File

@ -132,7 +132,7 @@ public class LocaleSystem implements SubSystem {
try {
String setting = config.get(PluginSettings.LOCALE);
if (!"default".equalsIgnoreCase(setting)) {
return Optional.of(Locale.forLangCodeString(plugin, setting));
return Optional.of(Locale.forLangCodeString(files, setting));
}
} catch (IOException e) {
logger.warn("Failed to read locale from jar: " + config.get(PluginSettings.LOCALE) + ", " + e.toString());

View File

@ -76,7 +76,7 @@ public class BukkitConfigSystem extends ConfigSystem {
@Override
protected void copyDefaults() throws IOException {
configUpdater.applyConfigUpdate(config);
try (ConfigReader reader = new ConfigReader(files.readStreamFromResource("config.yml"))) {
try (ConfigReader reader = new ConfigReader(files.getResourceFromJar("config.yml").asInputStream())) {
config.copyMissing(reader.read());
}
}

View File

@ -73,7 +73,7 @@ public class ProxyConfigSystem extends ConfigSystem {
@Override
protected void copyDefaults() throws IOException {
configUpdater.applyConfigUpdate(config);
try (ConfigReader reader = new ConfigReader(files.readStreamFromResource("bungeeconfig.yml"))) {
try (ConfigReader reader = new ConfigReader(files.getResourceFromJar("bungeeconfig.yml").asInputStream())) {
config.copyMissing(reader.read());
}
}

View File

@ -54,7 +54,7 @@ public class ThemeConfig extends Config {
String fileName = config.get(DisplaySettings.THEME);
String fileLocation = getFileLocation(fileName);
try (ConfigReader reader = new ConfigReader(files.readStreamFromResource(fileLocation))) {
try (ConfigReader reader = new ConfigReader(files.getResourceFromJar(fileLocation).asInputStream())) {
return reader.read();
} catch (IOException e) {
logger.error("Could not find theme " + fileLocation + ". Attempting to use default.");

View File

@ -49,7 +49,7 @@ public class ByteResponse extends Response {
exchange.sendResponseHeaders(getCode(), 0);
try (OutputStream out = exchange.getResponseBody();
InputStream bis = files.readCustomizableResource(fileName)) {
InputStream bis = files.getCustomizableResourceOrDefault(fileName).asInputStream()) {
byte[] buffer = new byte[2048];
int count;
while ((count = bis.read(buffer)) != -1) {

View File

@ -32,7 +32,7 @@ public class FileResponse extends Response {
public FileResponse(String fileName, PlanFiles files) throws IOException {
super.setHeader("HTTP/1.1 200 OK");
super.setContent(files.readCustomizableResourceFlat(fileName));
super.setContent(files.getCustomizableResourceOrDefault(fileName).asString());
}
public static String format(String fileName) {

View File

@ -40,7 +40,7 @@ public class ErrorResponse extends PageResponse {
public ErrorResponse(VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException {
this.versionCheckSystem = versionCheckSystem;
setContent(files.readCustomizableResourceFlat("web/error.html"));
setContent(files.getCustomizableResourceOrDefault("web/error.html").asString());
}
public ErrorResponse(String message) {

View File

@ -1,134 +0,0 @@
/*
* 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.file;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.logging.L;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class FileUtil {
private FileUtil() {
throw new IllegalStateException("Utility class");
}
public static List<String> lines(PlanPlugin plugin, File savedFile, String defaults) throws IOException {
if (savedFile.exists()) {
return lines(savedFile);
} else {
String fileName = savedFile.getName();
File found = attemptToFind(fileName, new File(plugin.getDataFolder(), "web"));
if (found != null) {
return lines(found);
}
}
return lines(plugin, defaults);
}
public static InputStream stream(PlanPlugin plugin, File savedFile, String defaults) {
try {
if (savedFile.exists()) {
return stream(savedFile);
} else {
String fileName = savedFile.getName();
File found = attemptToFind(fileName, new File(plugin.getDataFolder(), "web"));
if (found != null) {
return stream(found);
}
}
} catch (FileNotFoundException ignore) {
// File was not found, use jar version
}
return stream(plugin, defaults);
}
private static InputStream stream(PlanPlugin plugin, String resource) {
return plugin.getResource(resource);
}
private static InputStream stream(File savedFile) throws FileNotFoundException {
return new FileInputStream(savedFile);
}
/**
* Breadth-First search through the file tree to find the file.
*
* @param fileName Name of the searched file
* @param dataFolder Folder to look from
* @return File if found or null
*/
private static File attemptToFind(String fileName, File dataFolder) {
if (dataFolder.exists() && dataFolder.isDirectory()) {
ArrayDeque<File> que = new ArrayDeque<>();
que.add(dataFolder);
while (!que.isEmpty()) {
File file = que.pop();
if (file.isFile() && fileName.equals(file.getName())) {
return file;
}
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
que.addAll(Arrays.asList(files));
}
}
}
}
return null;
}
public static List<String> lines(PlanPlugin plugin, String resource) throws IOException {
List<String> lines = new ArrayList<>();
Scanner scanner = null;
try (InputStream inputStream = plugin.getResource(resource)) {
scanner = new Scanner(inputStream, "UTF-8");
while (scanner.hasNextLine()) {
lines.add(scanner.nextLine());
}
} catch (NullPointerException e) {
plugin.getPluginLogger().log(L.INFO_COLOR, "§ea Resource was not found inside the jar (" + resource + "), Plan does not support /reload or updates using " +
"Plugin Managers, restart the server and see if the error persists.");
throw new FileNotFoundException("File not found inside jar: " + resource);
} finally {
MiscUtils.close(scanner);
}
return lines;
}
public static List<String> lines(File file) throws IOException {
return lines(file, StandardCharsets.UTF_8);
}
public static List<String> lines(File file, Charset charset) throws IOException {
List<String> lines = new ArrayList<>();
if (file != null && file.exists()) {
try (Stream<String> linesStream = Files.lines(file.toPath(), charset)) {
lines = linesStream.collect(Collectors.toList());
}
}
return lines;
}
}

View File

@ -95,7 +95,7 @@ public class AnalysisPage implements Page {
performanceNumbers(placeholderReplacer);
try {
return placeholderReplacer.apply(files.readCustomizableResourceFlat("web/server.html"));
return placeholderReplacer.apply(files.getCustomizableResourceOrDefault("web/server.html").asString());
} catch (IOException e) {
throw new ParseException(e);
} finally {

View File

@ -21,13 +21,13 @@ import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.data.store.objects.DateHolder;
import com.djrapitops.plan.db.Database;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.file.FileResource;
import com.djrapitops.plan.system.info.connection.ConnectionLog;
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.info.server.properties.ServerProperties;
import com.djrapitops.plan.system.webserver.cache.ResponseCache;
import com.djrapitops.plan.utilities.file.FileUtil;
import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.formatting.Formatters;
import com.djrapitops.plan.utilities.html.Html;
@ -282,7 +282,7 @@ public class DebugPage implements Page {
.flatMap(FolderTimeStampFileLogger::getCurrentFile)
.map(file -> {
try {
return FileUtil.lines(file);
return FileResource.lines(file);
} catch (IOException e) {
errorHandler.log(L.WARN, this.getClass(), e);
return new ArrayList<String>();

View File

@ -271,7 +271,7 @@ public class InspectPage implements Page {
InspectPagePluginsContent pluginsTab = (InspectPagePluginsContent) ResponseCache.loadResponse(PageId.PLAYER_PLUGINS_TAB.of(playerUUID), InspectPagePluginsContent::new);
pluginsTab.addTab(new InspectPagePluginsContent(pluginTabs.getNav(), pluginTabs.getTab()));
return replacer.apply(files.readCustomizableResourceFlat("web/player.html"));
return replacer.apply(files.getCustomizableResourceOrDefault("web/player.html").asString());
}
private void sessionsAndPlaytime(PlaceholderReplacer replacer, SessionsMutator sessionsMutator, SessionsMutator daySessionsMutator, SessionsMutator weekSessionsMutator, SessionsMutator monthSessionsMutator) {

View File

@ -92,7 +92,7 @@ public class NetworkPage implements Page {
placeholderReplacer.put("navPluginsTabs", nav);
placeholderReplacer.put("tabsPlugins", tabs);
return placeholderReplacer.apply(files.readCustomizableResourceFlat("web/network.html"));
return placeholderReplacer.apply(files.getCustomizableResourceOrDefault("web/network.html").asString());
} catch (Exception e) {
throw new ParseException(e);
}

View File

@ -86,7 +86,7 @@ public class PlayersPage implements Page {
placeholderReplacer.put("playersTable", tables.playerTableForPlayersPage(playerContainers).parseHtml());
timings.end("Pages", "Players page players table parsing");
return placeholderReplacer.apply(files.readCustomizableResourceFlat("web/players.html"));
return placeholderReplacer.apply(files.getCustomizableResourceOrDefault("web/players.html").asString());
} catch (Exception e) {
throw new ParseException(e);
}

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -374,7 +374,7 @@
svgHourText.addEventListener('click', this._onSelectHour.bind(this));
}
svgClockElement.appendChild(svgHourCircle)
svgClockElement.appendChild(svgHourCircle);
svgClockElement.appendChild(svgHourText)
}
@ -404,7 +404,7 @@
svgHourText.addEventListener('click', this._onSelectHour.bind(this));
}
svgClockElement.appendChild(svgHourCircle)
svgClockElement.appendChild(svgHourCircle);
svgClockElement.appendChild(svgHourText)
}
@ -505,7 +505,7 @@
var svgClockFace = this.createSVGElement("circle", {r: '192', fill: '#eee', stroke: '#bdbdbd', 'stroke-width': 2});
var svgClockCenter = this.createSVGElement("circle", {r: '15', fill: '#757575'});
svgGElement.appendChild(svgClockFace)
svgGElement.appendChild(svgClockFace);
if (isHour)
{
@ -523,9 +523,9 @@
svgGElement.appendChild(svgMinuteHand);
}
svgGElement.appendChild(svgClockCenter)
svgGElement.appendChild(svgClockCenter);
svgElement.appendChild(svgGElement)
svgElement.appendChild(svgGElement);
this.$dtpElement.find("#dtp-svg-clock").empty();
this.$dtpElement.find("#dtp-svg-clock")[0].appendChild(svgElement);

View File

@ -77,7 +77,7 @@
this.animations = {
start: 'webkitAnimationStart oanimationstart MSAnimationStart animationstart',
end: 'webkitAnimationEnd oanimationend MSAnimationEnd animationend'
}
};
if (typeof this.settings.offset == 'number') {
this.settings.offset = {
@ -87,9 +87,8 @@
}
this.init();
};
$.extend(Notify.prototype, {
}
$.extend(Notify.prototype, {
init: function () {
var self = this;
@ -145,8 +144,8 @@
break;
default:
this.$ele.find('[data-notify="' + command +'"]').html(commands[command]);
};
}
}
}
var posX = this.$ele.outerHeight() + parseInt(self.settings.spacing) + parseInt(self.settings.offset.y);
self.reposition(posX);
},
@ -264,7 +263,7 @@
this.$ele.find('[data-notify="dismiss"]').on('click', function() {
self.close();
})
});
this.$ele.mouseover(function(e) {
$(this).data('data-hover', "true");

Some files were not shown because too many files have changed in this diff Show More