Skip to content

Commit

Permalink
React html customization / public_html folder (#2862)
Browse files Browse the repository at this point in the history
* Add public_html folder, configuration and access methods to it
* Make Frontend BETA static resource resolution prefer public_html
* Add resolver for getting any file in public_html from webserver
* Test customized bundle loading from public_html
* Update gradle wrapper to 7.6
* Wrote scripts to React build or run dev server through gradle
* Disable cyclomatic-complexity check on PublicHtmlResolver
* Throw bad request exception on IllegalPathException
* Throw bad request exception on bad chars in URI query
  • Loading branch information
AuroraLS3 authored Feb 5, 2023
1 parent 413e087 commit 09279cb
Show file tree
Hide file tree
Showing 29 changed files with 682 additions and 279 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public final class MimeType {
public static final String HTML = "text/html";
public static final String CSS = "text/css";
public static final String JSON = "application/json";
public static final String JS = "application/javascript";
public static final String JS = "text/javascript";
public static final String IMAGE = "image/gif";
public static final String FAVICON = "image/x-icon";
public static final String FONT_TTF = "application/x-font-ttf";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.djrapitops.plan.delivery.web.resolver.request;

import com.djrapitops.plan.delivery.web.resolver.exception.BadRequestException;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
Expand Down Expand Up @@ -82,6 +83,8 @@ private void parseAndPutKeyEmptyValue(Map<String, String> parameters, String s)
);
} catch (UnsupportedEncodingException e) {
// If UTF-8 is unsupported, we have bigger problems
} catch (IllegalArgumentException badCharacter) {
throw new BadRequestException("URI Query contained bad character");
}
}

Expand Down
8 changes: 8 additions & 0 deletions Plan/common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ task yarnBundle(type: YarnTask) {
args = ['run', 'build']
}

task yarnStart(type: YarnTask) {
logging.captureStandardOutput LogLevel.INFO
inputs.file("$rootDir/react/dashboard/package.json")

dependsOn yarn_install
args = ['run', 'start']
}

task copyYarnBuildResults {
inputs.files(fileTree("$rootDir/react/dashboard/build"))
outputs.dir("$rootDir/common/build/resources/main/assets/plan/web")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.djrapitops.plan.delivery.formatting.Formatters;
import com.djrapitops.plan.delivery.rendering.json.graphs.Graphs;
import com.djrapitops.plan.storage.file.PublicHtmlFiles;
import dagger.Lazy;

import javax.inject.Inject;
Expand All @@ -28,14 +29,16 @@ public class DeliveryUtilities {

private final Lazy<Formatters> formatters;
private final Lazy<Graphs> graphs;
private final Lazy<PublicHtmlFiles> publicHtmlFiles;

@Inject
public DeliveryUtilities(
Lazy<Formatters> formatters,
Lazy<Graphs> graphs
) {
Lazy<Graphs> graphs,
Lazy<PublicHtmlFiles> publicHtmlFiles) {
this.formatters = formatters;
this.graphs = graphs;
this.publicHtmlFiles = publicHtmlFiles;
}

public Formatters getFormatters() {
Expand All @@ -46,4 +49,7 @@ public Graphs getGraphs() {
return graphs.get();
}

public PublicHtmlFiles getPublicHtmlFiles() {
return publicHtmlFiles.get();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries;
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
import com.djrapitops.plan.storage.file.PlanFiles;
import com.djrapitops.plan.storage.file.PublicHtmlFiles;
import com.djrapitops.plan.utilities.dev.Untrusted;
import com.djrapitops.plan.version.VersionChecker;
import dagger.Lazy;
Expand All @@ -59,6 +60,7 @@ public class PageFactory {

private final Lazy<VersionChecker> versionChecker;
private final Lazy<PlanFiles> files;
private final Lazy<PublicHtmlFiles> publicHtmlFiles;
private final Lazy<PlanConfig> config;
private final Lazy<Theme> theme;
private final Lazy<DBSystem> dbSystem;
Expand All @@ -73,7 +75,7 @@ public class PageFactory {
public PageFactory(
Lazy<VersionChecker> versionChecker,
Lazy<PlanFiles> files,
Lazy<PlanConfig> config,
Lazy<PublicHtmlFiles> publicHtmlFiles, Lazy<PlanConfig> config,
Lazy<Theme> theme,
Lazy<DBSystem> dbSystem,
Lazy<ServerInfo> serverInfo,
Expand All @@ -85,6 +87,7 @@ public PageFactory(
) {
this.versionChecker = versionChecker;
this.files = files;
this.publicHtmlFiles = publicHtmlFiles;
this.config = config;
this.theme = theme;
this.dbSystem = dbSystem;
Expand All @@ -106,7 +109,8 @@ public Page playersPage() throws IOException {
}

public Page reactPage() throws IOException {
return new ReactPage(getBasePath(), getResource("index.html"));
// TODO use ResourceService to apply snippets to the React index.html
return new ReactPage(getBasePath(), getPublicHtmlOrJarResource("index.html"));
}

private String getBasePath() {
Expand Down Expand Up @@ -244,16 +248,26 @@ public String getResourceAsString(String name) throws IOException {
return getResource(name).asString();
}

public WebResource getResource(String name) throws IOException {
public WebResource getResource(String resourceName) throws IOException {
try {
return ResourceService.getInstance().getResource("Plan", name,
() -> files.get().getResourceFromJar("web/" + name).asWebResource()
return ResourceService.getInstance().getResource("Plan", resourceName,
() -> files.get().getResourceFromJar("web/" + resourceName).asWebResource()
);
} catch (UncheckedIOException readFail) {
throw readFail.getCause();
}
}

public WebResource getPublicHtmlOrJarResource(String resourceName) throws IOException {
try {
return publicHtmlFiles.get().findPublicHtmlResource(resourceName)
.orElseGet(() -> files.get().getResourceFromJar("web/" + resourceName))
.asWebResource();
} catch (UncheckedIOException readFail) {
throw readFail.getCause();
}
}

public Page loginPage() throws IOException {
if (config.get().isTrue(PluginSettings.FRONTEND_BETA)) {
return reactPage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
package com.djrapitops.plan.delivery.web;

import com.djrapitops.plan.delivery.web.resolver.Resolver;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.PluginSettings;
import com.djrapitops.plan.utilities.dev.Untrusted;
import net.playeranalytics.plugin.server.PluginLogger;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
* ResolverService Implementation.
Expand All @@ -33,11 +37,16 @@
@Singleton
public class ResolverSvc implements ResolverService {

private final PlanConfig config;
private final PluginLogger logger;

private final List<Container> basicResolvers;
private final List<Container> regexResolvers;

@Inject
public ResolverSvc() {
public ResolverSvc(PlanConfig config, PluginLogger logger) {
this.config = config;
this.logger = logger;
basicResolvers = new ArrayList<>();
regexResolvers = new ArrayList<>();
}
Expand Down Expand Up @@ -78,6 +87,12 @@ public List<Resolver> getResolvers(@Untrusted String target) {
for (Container container : regexResolvers) {
if (container.matcher.test(target)) resolvers.add(container.resolver);
}
if (config.isTrue(PluginSettings.DEV_MODE)) {
logger.info("Match Resolvers " + target + " - " + resolvers.stream()
.map(Object::getClass)
.map(Class::getSimpleName)
.collect(Collectors.toList()));
}
return resolvers;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import com.djrapitops.plan.settings.config.ResourceSettings;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.lang.PluginLang;
import com.djrapitops.plan.storage.file.PlanFiles;
import com.djrapitops.plan.storage.file.PublicHtmlFiles;
import com.djrapitops.plan.storage.file.Resource;
import com.djrapitops.plan.utilities.dev.Untrusted;
import com.djrapitops.plan.utilities.logging.ErrorContext;
Expand Down Expand Up @@ -50,21 +50,21 @@
public class ResourceSvc implements ResourceService {

public final Set<Snippet> snippets;
private final PlanFiles files;
private final PublicHtmlFiles publicHtmlFiles;
private final ResourceSettings resourceSettings;
private final Locale locale;
private final PluginLogger logger;
private final ErrorLogger errorLogger;

@Inject
public ResourceSvc(
PlanFiles files,
PublicHtmlFiles publicHtmlFiles,
PlanConfig config,
Locale locale,
PluginLogger logger,
ErrorLogger errorLogger
) {
this.files = files;
this.publicHtmlFiles = publicHtmlFiles;
this.resourceSettings = config.getResourceSettings();
this.locale = locale;
this.logger = logger;
Expand Down Expand Up @@ -155,7 +155,7 @@ public WebResource getTheResource(String pluginName, @Untrusted String fileName,
}

public WebResource getOrWriteCustomized(@Untrusted String fileName, Supplier<WebResource> source) throws IOException {
Optional<Resource> customizedResource = files.getCustomizableResource(fileName);
Optional<Resource> customizedResource = publicHtmlFiles.findCustomizedResource(fileName);
if (customizedResource.isPresent()) {
return readCustomized(customizedResource.get());
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,19 @@
import javax.inject.Singleton;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
* Task in charge of checking html customized files on enable to see if they are outdated.
*
* @deprecated Html customization system will be overhauled for React version of frontend.
*/
@Singleton
@Deprecated(forRemoval = true, since = "#2260") // TODO Remove after Frontend BETA
public class WebAssetVersionCheckTask extends TaskSystem.Task {

private final PlanConfig config;
Expand Down Expand Up @@ -110,7 +114,8 @@ private void runTask() {
}

private Optional<AssetInfo> findOutdatedResource(String resource) {
Optional<File> resourceFile = files.attemptToFind(resource);
Path dir = config.getResourceSettings().getCustomizationDirectory();
Optional<File> resourceFile = files.attemptToFind(dir, resource);
Optional<Long> webAssetVersion = assetVersions.getAssetVersion(resource);
if (resourceFile.isPresent() && webAssetVersion.isPresent() && webAssetVersion.get() > resourceFile.get().lastModified()) {
return Optional.of(new AssetInfo(
Expand Down
Loading

0 comments on commit 09279cb

Please sign in to comment.