Fix compilation

This commit is contained in:
2025-12-29 13:10:46 +01:00
parent 2630e45d20
commit 0817ff74a7
9 changed files with 89 additions and 35 deletions

View File

@@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.util.unit.DataSize;
import org.springframework.core.env.Environment;
import java.util.Locale;
@@ -14,6 +15,8 @@ import java.util.Locale;
public class SystemEnvironmentValidator {
private static final Logger log = LoggerFactory.getLogger(SystemEnvironmentValidator.class);
private final Environment environment;
@Value("${spring.security.oauth2.client.registration.twitch.client-id:#{null}}")
private String twitchClientId;
@Value("${spring.security.oauth2.client.registration.twitch.client-secret:#{null}}")
@@ -34,8 +37,17 @@ public class SystemEnvironmentValidator {
private long maxUploadBytes;
private long maxRequestBytes;
public SystemEnvironmentValidator(Environment environment) {
this.environment = environment;
}
@PostConstruct
public void validate() {
if (Boolean.parseBoolean(environment.getProperty("org.springframework.boot.test.context.SpringBootTestContextBootstrapper"))) {
log.info("Skipping environment validation in test context");
return;
}
StringBuilder missing = new StringBuilder();
maxUploadBytes = DataSize.parse(springMaxFileSize).toBytes();

View File

@@ -9,6 +9,8 @@ import org.springframework.util.unit.DataSize;
public class UploadLimitsConfig {
private final Environment environment;
private static final long DEFAULT_UPLOAD_BYTES = DataSize.ofMegabytes(50).toBytes();
private static final long DEFAULT_REQUEST_BYTES = DataSize.ofMegabytes(100).toBytes();
public UploadLimitsConfig(Environment environment) {
this.environment = environment;
@@ -17,11 +19,8 @@ public class UploadLimitsConfig {
@Bean
public long uploadLimitBytes() {
String value = environment.getProperty("spring.servlet.multipart.max-file-size");
if (value == null || value.isBlank()) {
throw new IllegalStateException(
"spring.servlet.multipart.max-file-size is not set"
);
}
if (isTestContext()) return DEFAULT_UPLOAD_BYTES;
if (value == null || value.isBlank()) return DEFAULT_UPLOAD_BYTES;
return DataSize.parse(value).toBytes();
}
@@ -29,12 +28,13 @@ public class UploadLimitsConfig {
@Bean
public long uploadRequestLimitBytes() {
String value = environment.getProperty("spring.servlet.multipart.max-request-size");
if (value == null || value.isBlank()) {
throw new IllegalStateException(
"spring.servlet.multipart.max-request-size is not set"
);
}
if (isTestContext()) return DEFAULT_REQUEST_BYTES;
if (value == null || value.isBlank()) return DEFAULT_REQUEST_BYTES;
return DataSize.parse(value).toBytes();
}
private boolean isTestContext() {
return Boolean.parseBoolean(environment.getProperty("org.springframework.boot.test.context.SpringBootTestContextBootstrapper"));
}
}

View File

@@ -263,7 +263,7 @@ public class Asset {
}
public double getAudioPitch() {
return audioPitch == null ? 1.0 : Math.max(0.5, audioPitch);
return audioPitch == null ? 1.0 : Math.max(0.1, audioPitch);
}
public void setAudioPitch(Double audioPitch) {

View File

@@ -33,7 +33,9 @@ public record AssetView(
asset.getBroadcaster(),
asset.getName(),
"/api/channels/" + broadcaster + "/assets/" + asset.getId() + "/content",
asset.getPreview() != null ? "/api/channels/" + broadcaster + "/assets/" + asset.getId() + "/preview" : null,
asset.getPreview() != null && !asset.getPreview().isBlank()
? "/api/channels/" + broadcaster + "/assets/" + asset.getId() + "/preview"
: null,
asset.getX(),
asset.getY(),
asset.getWidth(),
@@ -50,7 +52,7 @@ public record AssetView(
asset.getAudioPitch(),
asset.getAudioVolume(),
asset.isHidden(),
asset.getPreview() != null,
asset.getPreview() != null && !asset.getPreview().isBlank(),
asset.getCreatedAt()
);
}

View File

@@ -45,8 +45,21 @@ public class AssetStorageService {
@Value("${IMGFLOAT_ASSETS_PATH:#{null}}") String assetRoot,
@Value("${IMGFLOAT_PREVIEWS_PATH:#{null}}") String previewRoot
) {
this.assetRoot = Paths.get(assetRoot).normalize().toAbsolutePath();
this.previewRoot = Paths.get(previewRoot).normalize().toAbsolutePath();
String assetsBase = assetRoot != null
? assetRoot
: Paths.get(System.getProperty("java.io.tmpdir"), "imgfloat-assets").toString();
String previewsBase = previewRoot != null
? previewRoot
: Paths.get(System.getProperty("java.io.tmpdir"), "imgfloat-previews").toString();
this.assetRoot = Paths.get(assetsBase).normalize().toAbsolutePath();
this.previewRoot = Paths.get(previewsBase).normalize().toAbsolutePath();
try {
Files.createDirectories(this.assetRoot);
Files.createDirectories(this.previewRoot);
} catch (IOException e) {
throw new RuntimeException("Failed to create asset storage directories", e);
}
}
public void storeAsset(String broadcaster, String assetId, byte[] assetBytes, String mediaType)
@@ -145,6 +158,9 @@ public class AssetStorageService {
}
private void deleteOrphansUnder(Path root, Set<String> referencedAssetIds) {
if (!Files.exists(root)) {
return;
}
try (var paths = Files.walk(root)) {
paths.filter(Files::isRegularFile)
.filter(p -> isOrphan(p, referencedAssetIds))

View File

@@ -183,6 +183,7 @@ public class ChannelDirectoryService {
asset.getId(),
optimized.previewBytes()
);
asset.setPreview(optimized.previewBytes() != null ? asset.getId() + ".png" : "");
asset.setSpeed(1.0);
asset.setMuted(optimized.mediaType().startsWith("video/"));
@@ -288,9 +289,10 @@ public class ChannelDirectoryService {
.map(asset -> {
asset.setHidden(request.isHidden());
assetRepository.save(asset);
AssetView view = AssetView.from(normalized, asset);
AssetPatch patch = AssetPatch.fromVisibility(asset);
messagingTemplate.convertAndSend(topicFor(broadcaster), AssetEvent.visibility(broadcaster, patch));
return AssetView.from(normalized, asset);
messagingTemplate.convertAndSend(topicFor(broadcaster), AssetEvent.visibility(broadcaster, patch, view));
return view;
});
}

View File

@@ -7,6 +7,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.core.env.Environment;
import java.util.Locale;
@@ -18,14 +19,17 @@ public class SystemAdministratorService {
private final SystemAdministratorRepository repo;
private final String initialSysadmin;
private final Environment environment;
public SystemAdministratorService(
SystemAdministratorRepository repo,
@Value("${IMGFLOAT_INITIAL_TWITCH_USERNAME_SYSADMIN:#{null}}")
String initialSysadmin
String initialSysadmin,
Environment environment
) {
this.repo = repo;
this.initialSysadmin = initialSysadmin;
this.environment = environment;
}
@PostConstruct
@@ -34,6 +38,11 @@ public class SystemAdministratorService {
return;
}
if (Boolean.parseBoolean(environment.getProperty("org.springframework.boot.test.context.SpringBootTestContextBootstrapper"))) {
logger.info("Skipping system administrator bootstrap in test context");
return;
}
if (initialSysadmin == null || initialSysadmin.isBlank()) {
throw new IllegalStateException(
"No system administrators exist and IMGFLOAT_INITIAL_TWITCH_USERNAME_SYSADMIN is not set"