Skip to content

Commit

Permalink
v0.1.0
Browse files Browse the repository at this point in the history
Everything is working, but the UI needs some improvement, especially searching.

Need to fix shaped recipes.
  • Loading branch information
D-Cysteine committed Jan 4, 2023
1 parent 88bcc61 commit c2d66f0
Show file tree
Hide file tree
Showing 52 changed files with 2,322 additions and 99 deletions.
19 changes: 11 additions & 8 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
buildscript {
dependencies {
classpath("com.google.protobuf:protobuf-gradle-plugin:0.9.1")
}
}

plugins {
idea
id("java")
id("org.springframework.boot") version "3.0.1"
id("io.spring.dependency-management") version "1.1.0"
}

idea {
module {
isDownloadJavadoc = true
isDownloadSources = true
}
}

group = "com.github.dcysteine.nesql.server"
version = "0.0.1"
version = "0.1.0"

repositories {
mavenCentral()
Expand All @@ -24,9 +26,10 @@ dependencies {
compileOnly("com.google.auto.value:auto-value-annotations:1.10.1")
annotationProcessor("com.google.auto.value:auto-value:1.10.1")

implementation("com.google.protobuf:protobuf-java:3.21.12")
implementation("com.google.guava:guava:31.1-jre")

implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-web")
developmentOnly("org.springframework.boot:spring-boot-devtools")
Expand Down
Binary file removed libs/NESQL-Exporter-0.0.1-sql.jar
Binary file not shown.
Binary file added libs/NESQL-Exporter-0.1.0-sql.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion src/main/java/com/github/dcysteine/nesql/server/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@EntityScan(basePackageClasses = Sql.class)
@EnableJpaRepositories(basePackageClasses = Sql.class)
public class Main {
public static final Logger LOGGER = LoggerFactory.getLogger("NESQL Server");
public static final Logger Logger = LoggerFactory.getLogger("NESQL Server");

public static void main(String[] args) {
SpringApplication.run(Main.class, args);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.github.dcysteine.nesql.server;

import com.github.dcysteine.nesql.server.config.ExternalConfig;
import com.github.dcysteine.nesql.server.util.NumberUtil;
import com.github.dcysteine.nesql.sql.base.fluid.FluidRepository;
import com.github.dcysteine.nesql.sql.base.item.ItemRepository;
import com.github.dcysteine.nesql.sql.base.recipe.RecipeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

/** Serves root-level endpoints. */
@Controller
public class RootController {
@Autowired
ExternalConfig externalConfig;

@Autowired
private ApplicationContext context;

@Autowired
private ItemRepository itemRepository;

@Autowired
private FluidRepository fluidRepository;

@Autowired
private RecipeRepository recipeRepository;

@GetMapping(value = {"/", "/index"})
public String index(Model model) {
model.addAttribute(
"itemCount", NumberUtil.formatInteger(itemRepository.count()));
model.addAttribute(
"fluidCount", NumberUtil.formatInteger(fluidRepository.count()));
model.addAttribute(
"recipeCount", NumberUtil.formatInteger(recipeRepository.count()));
return "index";
}

@GetMapping("/notfound")
public String notFound() {
return "not_found";
}

@GetMapping("/shutdown")
public String shutDown() {
if (!externalConfig.isShutdownEnabled()) {
return "shutdown_disabled";
}

// We need to actually shut down in a separate thread, so that we can proceed with serving
// the shutdown page.
new Thread(() -> SpringApplication.exit(context)).start();
return "shutdown";
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.github.dcysteine.nesql.server.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
* Class holding config values that are meant to be externally configurable via the
* {@code application.properties} file.
*/
@Component
public class ExternalConfig {
@Value("${nesql.server.repository-name}")
private String repositoryName;

@Value("${nesql.server.page-size}")
private int pageSize;

@Value("${nesql.server.enable-shutdown}")
private boolean shutdownEnabled;

@Value("${nesql.server.allow-external-users}")
private boolean externalUsersAllowed;

public String getRepositoryName() {
return repositoryName;
}

public int getPageSize() {
return pageSize;
}

public boolean isShutdownEnabled() {
return shutdownEnabled;
}

public boolean areExternalUsersAllowed() {
return externalUsersAllowed;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.github.dcysteine.nesql.server.config;

import com.google.common.base.Joiner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class WebSecurityConfig {
@Autowired
ExternalConfig externalConfig;

private static final String CONTENT_SECURITY_POLICY = Joiner.on("; ").join(
"default-src 'self'",
// This is the hash of our image onerror handler:
// this.src='/image/missing.png';this.onerror='';
"script-src 'self' 'sha256-KrWF/SaFRimyTg5FZWV3gqZlxM6hGYkkM1k3ePvN71w=' 'unsafe-hashes'");

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// TODO restrict requests to same-IP only? At least by default
http.headers().contentSecurityPolicy(CONTENT_SECURITY_POLICY);

if (!externalConfig.areExternalUsersAllowed()) {
http.authorizeRequests().anyRequest()
.access("hasIpAddress('127.0.0.1') or hasIpAddress('::1')");
}

return http.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.github.dcysteine.nesql.server.display;

import com.google.auto.value.AutoValue;

/** Immutable class representing a width and height. */
@AutoValue
public abstract class Dimension {
public static Dimension create(int width, int height) {
return new AutoValue_Dimension(width, height);
}

public static Dimension create(int width) {
return new AutoValue_Dimension(width, width);
}

public abstract int getWidth();
public abstract int getHeight();
}
31 changes: 31 additions & 0 deletions src/main/java/com/github/dcysteine/nesql/server/display/Icon.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.github.dcysteine.nesql.server.display;

import com.google.auto.value.AutoValue;

import javax.annotation.Nullable;

@AutoValue
public abstract class Icon {
public abstract String getDescription();
public abstract String getUrl();
public abstract String getImageFilePath();
@Nullable public abstract String getTopLeft();
@Nullable public abstract String getBottomRight();

public static Builder builder() {
return new AutoValue_Icon.Builder();
}

public abstract Builder toBuilder();

@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setDescription(String description);
public abstract Builder setUrl(String url);
public abstract Builder setImageFilePath(String imageFilePath);
public abstract Builder setTopLeft(@Nullable String topLeft);
public abstract Builder setBottomRight(@Nullable String bottomRight);

public abstract Icon build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.github.dcysteine.nesql.server.plugin.base;

import com.github.dcysteine.nesql.server.plugin.base.display.fluid.DisplayFluid;
import com.github.dcysteine.nesql.server.plugin.base.specs.FluidSpecs;
import com.github.dcysteine.nesql.server.plugin.base.display.BaseDisplayService;
import com.github.dcysteine.nesql.server.service.SearchService;
import com.github.dcysteine.nesql.sql.base.fluid.Fluid;
import com.github.dcysteine.nesql.sql.base.fluid.FluidRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Nullable;
import java.util.Optional;
import java.util.function.Predicate;

@Controller
@RequestMapping(path = "/fluid")
public class FluidController {
@Autowired
private FluidRepository fluidRepository;

@Autowired
private BaseDisplayService baseDisplayService;

@Autowired
private SearchService searchService;

@GetMapping(path = "/{fluid_id}")
public String view(@PathVariable(name = "fluid_id") String id, Model model) {
Optional<Fluid> fluidOptional = fluidRepository.findById(id);
if (fluidOptional.isEmpty()) {
return "not_found";
}
Fluid fluid = fluidOptional.get();
DisplayFluid displayFluid = baseDisplayService.buildDisplayFluid(fluid);

model.addAttribute("fluid", fluid);
model.addAttribute("displayFluid", displayFluid);
return "plugin/base/fluid/fluid";
}

@GetMapping(path = "/search")
public String search() {
return "plugin/base/fluid/search";
}

@GetMapping(path = "/all")
public String all(@RequestParam(defaultValue = "1") int page, Model model) {
return searchService.handleGetAll(
page, model, fluidRepository, baseDisplayService::buildDisplayFluid);
}

@GetMapping(path = "/searchresults")
public String searchResults(
@RequestParam(required = false) Optional<String> localizedName,
@RequestParam(required = false) Optional<String> internalName,
@RequestParam(required = false) Optional<Integer> fluidId,
@RequestParam(defaultValue = "1") int page,
Model model) {
@Nullable
Specification<Fluid> localizedNameSpec =
localizedName
.filter(Predicate.not(String::isEmpty))
.map(FluidSpecs::buildLocalizedNameSpec).orElse(null);

@Nullable
Specification<Fluid> internalNameSpec =
internalName
.filter(Predicate.not(String::isEmpty))
.map(FluidSpecs::buildInternalNameSpec).orElse(null);

@Nullable
Specification<Fluid> fluidIdSpec =
fluidId.map(FluidSpecs::buildFluidIdSpec).orElse(null);

Specification<Fluid> spec =
Specification.allOf(localizedNameSpec, internalNameSpec, fluidIdSpec);
return searchService.handleSearch(
page, model, fluidRepository, spec, baseDisplayService::buildDisplayFluidIcon);
}
}
Loading

0 comments on commit c2d66f0

Please sign in to comment.