Compare commits
2 Commits
a4c0a4702a
...
c7ee90cbaa
| Author | SHA1 | Date | |
|---|---|---|---|
| c7ee90cbaa | |||
| 5e453dad51 |
@@ -4,7 +4,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import io.smallrye.config.ConfigMapping;
|
||||
|
||||
@ConfigMapping(prefix = "lalafin")
|
||||
@ConfigMapping(prefix = "lalafin.core")
|
||||
public interface LalafinConfiguration {
|
||||
|
||||
public String base_url();
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package sh.rhiobet.lalafin.access;
|
||||
|
||||
import sh.rhiobet.lalafin.path.Path;
|
||||
|
||||
public interface AccessService {
|
||||
boolean checkAccess(Path path);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package sh.rhiobet.lalafin.advent;
|
||||
package sh.rhiobet.lalafin.advent.access;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
@@ -7,13 +7,13 @@ import java.util.regex.Pattern;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import sh.rhiobet.lalafin.access.AccessService;
|
||||
import sh.rhiobet.lalafin.path.Path;
|
||||
import sh.rhiobet.lalafin.advent.configuration.AdventConfiguration;
|
||||
import sh.rhiobet.lalafin.core.access.AccessService;
|
||||
import sh.rhiobet.lalafin.core.path.model.Path;
|
||||
|
||||
@ApplicationScoped
|
||||
@Named("advent")
|
||||
public class AdventAccessService implements AccessService {
|
||||
|
||||
@Inject
|
||||
AdventConfiguration adventConfiguration;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package sh.rhiobet.lalafin.advent;
|
||||
package sh.rhiobet.lalafin.advent.configuration;
|
||||
|
||||
import java.util.List;
|
||||
import io.smallrye.config.ConfigMapping;
|
||||
|
||||
@ConfigMapping(prefix = "advent")
|
||||
@ConfigMapping(prefix = "lalafin.advent")
|
||||
public interface AdventConfiguration {
|
||||
public List<AdventEvent> events();
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package sh.rhiobet.lalafin.advent.thumbnail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
|
||||
import jakarta.decorator.Decorator;
|
||||
import jakarta.decorator.Delegate;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import sh.rhiobet.lalafin.advent.access.AdventAccessService;
|
||||
import sh.rhiobet.lalafin.api.configuration.FileApiConfiguration;
|
||||
import sh.rhiobet.lalafin.core.path.model.Path;
|
||||
import sh.rhiobet.lalafin.core.path.model.PathAccessor;
|
||||
import sh.rhiobet.lalafin.core.path.plugin.PathPlugin;
|
||||
|
||||
@Decorator
|
||||
public class AdventThumbnailPathPlugin extends PathAccessor implements PathPlugin {
|
||||
@Inject
|
||||
FileApiConfiguration fileApiConfiguration;
|
||||
|
||||
@Inject
|
||||
@Named("file/thumbnail")
|
||||
@Delegate
|
||||
PathPlugin thumbnailPathPlugin;
|
||||
|
||||
@Inject
|
||||
AdventAccessService adventAccessService;
|
||||
|
||||
@Override
|
||||
public Optional<String> resolveURI(Path path) {
|
||||
if (this.adventAccessService.checkAccess(path)) {
|
||||
return this.thumbnailPathPlugin.resolveURI(path);
|
||||
} else {
|
||||
Optional<java.nio.file.Path> thumbnailAbsolutePath = getDefaultThumbnailPath(path);
|
||||
|
||||
if (thumbnailAbsolutePath.isPresent()) {
|
||||
java.nio.file.Path rootFolderPath = Paths.get(this.fileApiConfiguration.directory());
|
||||
return Optional.of(
|
||||
"/" + rootFolderPath.resolve("file").relativize(thumbnailAbsolutePath.get())
|
||||
.toString());
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream(Path path) throws IOException {
|
||||
if (this.adventAccessService.checkAccess(path)) {
|
||||
return this.thumbnailPathPlugin.getOutputStream(path);
|
||||
} else {
|
||||
throw new IOException("You don't yet have access to this resource.");
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<java.nio.file.Path> getDefaultThumbnailPath(Path path) {
|
||||
try {
|
||||
return Files.list(getAbsolutePath(path).getParent().resolve(".thumbnails"))
|
||||
.filter(f -> f.getFileName().toString().matches("^00(\\.[^.]+)*$"))
|
||||
.findFirst();
|
||||
} catch (IOException ignored) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package sh.rhiobet.lalafin.core.access;
|
||||
|
||||
import sh.rhiobet.lalafin.core.path.model.Path;
|
||||
|
||||
public interface AccessService {
|
||||
boolean checkAccess(Path path);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package sh.rhiobet.lalafin.path;
|
||||
package sh.rhiobet.lalafin.core.path.exception;
|
||||
|
||||
public class InvalidPathException extends Exception {
|
||||
public InvalidPathException(String message) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package sh.rhiobet.lalafin.path;
|
||||
package sh.rhiobet.lalafin.core.path.model;
|
||||
|
||||
import jakarta.ws.rs.core.PathSegment;
|
||||
|
||||
@@ -31,6 +31,9 @@ public final class FileSystemPath implements Path {
|
||||
|
||||
@Override
|
||||
public String getURI() {
|
||||
if (this.segments.isEmpty()) {
|
||||
return "/";
|
||||
}
|
||||
return this.segments.stream()
|
||||
.map(s -> "/" + Encode.encodePathSegment(s))
|
||||
.reduce("", String::concat);
|
||||
@@ -38,16 +41,16 @@ public final class FileSystemPath implements Path {
|
||||
|
||||
@Override
|
||||
public String getFilename() {
|
||||
return this.segments.getLast();
|
||||
return this.segments.isEmpty() ? "/" : this.segments.getLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
try {
|
||||
return Files.size(this.absolutePath);
|
||||
} catch (IOException ignored) {
|
||||
return Files.size(this.absolutePath);
|
||||
} catch (IOException ignored) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +65,7 @@ public final class FileSystemPath implements Path {
|
||||
|
||||
@Override
|
||||
public List<Path> getChildren() throws IOException {
|
||||
if (this.segments.getLast().endsWith(".zip")) {
|
||||
if (!this.segments.isEmpty() && this.segments.getLast().endsWith(".zip")) {
|
||||
try (ZipFile zipFile = new ZipFile(this.absolutePath.toFile())) {
|
||||
return zipFile.stream()
|
||||
.map(e -> (Path) new ZipEntryPath(this, e.getName()))
|
||||
@@ -1,4 +1,4 @@
|
||||
package sh.rhiobet.lalafin.path;
|
||||
package sh.rhiobet.lalafin.core.path.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -1,4 +1,4 @@
|
||||
package sh.rhiobet.lalafin.path;
|
||||
package sh.rhiobet.lalafin.core.path.model;
|
||||
|
||||
public abstract class PathAccessor {
|
||||
protected java.nio.file.Path getAbsolutePath(Path path) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package sh.rhiobet.lalafin.path;
|
||||
package sh.rhiobet.lalafin.core.path.model;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
@@ -10,6 +10,7 @@ import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import sh.rhiobet.lalafin.api.configuration.FileApiConfiguration;
|
||||
import sh.rhiobet.lalafin.core.path.exception.InvalidPathException;
|
||||
|
||||
@ApplicationScoped
|
||||
public class PathFactory {
|
||||
@@ -1,4 +1,4 @@
|
||||
package sh.rhiobet.lalafin.path;
|
||||
package sh.rhiobet.lalafin.core.path.model;
|
||||
|
||||
import jakarta.ws.rs.core.PathSegment;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package sh.rhiobet.lalafin.path;
|
||||
package sh.rhiobet.lalafin.core.path.plugin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Optional;
|
||||
|
||||
import sh.rhiobet.lalafin.core.path.model.Path;
|
||||
|
||||
public interface PathPlugin {
|
||||
Optional<String> resolveURI(Path path);
|
||||
OutputStream getOutputStream(Path path) throws IOException;
|
||||
@@ -1,4 +1,4 @@
|
||||
package sh.rhiobet.lalafin.file;
|
||||
package sh.rhiobet.lalafin.file.access;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -6,8 +6,9 @@ import io.quarkus.security.identity.SecurityIdentity;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import sh.rhiobet.lalafin.access.AccessService;
|
||||
import sh.rhiobet.lalafin.path.Path;
|
||||
import sh.rhiobet.lalafin.core.access.AccessService;
|
||||
import sh.rhiobet.lalafin.core.path.model.Path;
|
||||
import sh.rhiobet.lalafin.file.configuration.FileConfiguration;
|
||||
|
||||
@ApplicationScoped
|
||||
@Named("file/role")
|
||||
@@ -1,10 +1,10 @@
|
||||
package sh.rhiobet.lalafin.file;
|
||||
package sh.rhiobet.lalafin.file.configuration;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import io.smallrye.config.ConfigMapping;
|
||||
|
||||
@ConfigMapping(prefix = "file")
|
||||
@ConfigMapping(prefix = "lalafin.file")
|
||||
public interface FileConfiguration {
|
||||
public String directory();
|
||||
public Optional<List<String>> ignored();
|
||||
17
src/main/java/sh/rhiobet/lalafin/file/model/FileInfo.java
Normal file
17
src/main/java/sh/rhiobet/lalafin/file/model/FileInfo.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package sh.rhiobet.lalafin.file.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
|
||||
@RegisterForReflection
|
||||
public class FileInfo extends FileInfoBase {
|
||||
public String publicApiUrl;
|
||||
|
||||
public FileInfo(String filename, String thumbnailUrl, String directUrl, String publicApiUrl) {
|
||||
super(filename, "file", thumbnailUrl, directUrl);
|
||||
this.publicApiUrl = publicApiUrl;
|
||||
}
|
||||
|
||||
public FileInfo(String filename, String directUrl) {
|
||||
this(filename, "", directUrl, "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package sh.rhiobet.lalafin.file.model;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
|
||||
@RegisterForReflection
|
||||
public abstract class FileInfoBase implements Comparable<FileInfoBase> {
|
||||
public String filename;
|
||||
public String type;
|
||||
public String thumbnailUrl;
|
||||
public String directUrl;
|
||||
public String viewUrl;
|
||||
|
||||
public FileInfoBase(String filename, String type, String thumbnailUrl, String directUrl,
|
||||
String viewUrl) {
|
||||
this.filename = filename;
|
||||
this.type = type;
|
||||
this.thumbnailUrl = thumbnailUrl;
|
||||
this.directUrl = directUrl;
|
||||
this.viewUrl = viewUrl;
|
||||
}
|
||||
|
||||
public FileInfoBase(String filename, String type, String thumbnailUrl, String directUrl) {
|
||||
this(filename, type, thumbnailUrl, directUrl, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(FileInfoBase f) {
|
||||
return this.filename.compareToIgnoreCase(f.filename);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package sh.rhiobet.lalafin.file.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import sh.rhiobet.lalafin.LalafinConfiguration;
|
||||
import sh.rhiobet.lalafin.api.internal.redis.FileTokenProvider;
|
||||
import sh.rhiobet.lalafin.core.path.model.Path;
|
||||
import sh.rhiobet.lalafin.core.path.plugin.PathPlugin;
|
||||
import sh.rhiobet.lalafin.file.ThumbnailService;
|
||||
import sh.rhiobet.lalafin.file.configuration.FileConfiguration;
|
||||
|
||||
@ApplicationScoped
|
||||
public class FileMetadataService {
|
||||
@Inject
|
||||
LalafinConfiguration lalafinConfiguration;
|
||||
|
||||
@Inject
|
||||
FileConfiguration fileConfiguration;
|
||||
|
||||
@Inject
|
||||
ThumbnailService thumbnailService;
|
||||
|
||||
@Inject
|
||||
@Named("file/thumbnail")
|
||||
PathPlugin thumbnailPathPlugin;
|
||||
|
||||
public FileInfoBase getInfo(Path filePath, FileTokenProvider fileTokenProvider) {
|
||||
if (filePath.exists()) {
|
||||
Optional<String> thumbUrl = this.thumbnailPathPlugin.resolveURI(filePath);
|
||||
|
||||
if (filePath.canHaveChildren()) {
|
||||
FolderInfo folderInfo = new FolderInfo(
|
||||
filePath.getFilename(),
|
||||
thumbUrl.isPresent() ? "/file" + thumbUrl.get() : "",
|
||||
"/file" + filePath.getURI(),
|
||||
""
|
||||
);
|
||||
|
||||
try {
|
||||
for (Path child : filePath.getChildren()) {
|
||||
if (child.getFilename().startsWith(".")) {
|
||||
continue;
|
||||
}
|
||||
if (fileConfiguration.ignored().isPresent()) {
|
||||
for (String ignoreString : fileConfiguration.ignored().get()) {
|
||||
if (child.getFilename().endsWith(ignoreString)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Optional<String> childThumbUrl = this.thumbnailPathPlugin.resolveURI(child);
|
||||
|
||||
FileInfoBase contentInfo;
|
||||
if (child.canHaveChildren()) {
|
||||
contentInfo = new FolderInfo(child.getFilename(), "/file" + child.getURI());
|
||||
} else {
|
||||
contentInfo = new FileInfo(child.getFilename(), "/file" + child.getURI());
|
||||
}
|
||||
|
||||
if (childThumbUrl.isPresent()) {
|
||||
contentInfo.thumbnailUrl = "/file" + childThumbUrl.get();
|
||||
}
|
||||
|
||||
folderInfo.content.add(contentInfo);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return folderInfo;
|
||||
} else {
|
||||
FileInfo fileInfo = new FileInfo(
|
||||
filePath.getFilename(),
|
||||
thumbUrl.isPresent() ? "/file" + thumbUrl.get() : "",
|
||||
"/file" + filePath.getURI(),
|
||||
""
|
||||
);
|
||||
|
||||
return fileInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
22
src/main/java/sh/rhiobet/lalafin/file/model/FolderInfo.java
Normal file
22
src/main/java/sh/rhiobet/lalafin/file/model/FolderInfo.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package sh.rhiobet.lalafin.file.model;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
|
||||
@RegisterForReflection
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class FolderInfo extends FileInfoBase {
|
||||
public Set<FileInfoBase> content;
|
||||
public FileInfo playlist;
|
||||
|
||||
public FolderInfo(String filename, String thumbnailUrl, String directUrl, String viewUrl) {
|
||||
super(filename, "folder", thumbnailUrl, directUrl, viewUrl);
|
||||
this.content = new TreeSet<>();
|
||||
}
|
||||
|
||||
public FolderInfo(String filename, String directUrl) {
|
||||
this(filename, "", directUrl, "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package sh.rhiobet.lalafin.file.rest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.enterprise.inject.Instance;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.PathSegment;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import io.quarkus.security.Authenticated;
|
||||
import sh.rhiobet.lalafin.core.access.AccessService;
|
||||
import sh.rhiobet.lalafin.core.path.exception.InvalidPathException;
|
||||
import sh.rhiobet.lalafin.core.path.model.PathFactory;
|
||||
import sh.rhiobet.lalafin.file.model.FileInfoBase;
|
||||
import sh.rhiobet.lalafin.file.model.FileMetadataService;
|
||||
|
||||
@Authenticated
|
||||
@Path("/v1/api/private/file")
|
||||
public class FilePrivateAPI {
|
||||
@Inject
|
||||
FileMetadataService fileMetadataService;
|
||||
|
||||
@Inject
|
||||
Instance<AccessService> accessServices;
|
||||
|
||||
@Inject
|
||||
PathFactory pathFactory;
|
||||
|
||||
@GET
|
||||
@Path("/")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response getFileInfo() {
|
||||
return this.getFileInfo(new ArrayList<>());
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{names: .+}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response getFileInfo(List<PathSegment> names) {
|
||||
sh.rhiobet.lalafin.core.path.model.Path path;
|
||||
try {
|
||||
path = this.pathFactory.toPath(names);
|
||||
} catch (InvalidPathException ignored) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).build();
|
||||
}
|
||||
|
||||
if (accessServices.stream().anyMatch((a -> !a.checkAccess(path)))) {
|
||||
return Response.status(Response.Status.FORBIDDEN).build();
|
||||
}
|
||||
|
||||
FileInfoBase fileInfo = this.fileMetadataService.getInfo(path, null);
|
||||
|
||||
if (fileInfo == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
return Response.ok(fileInfo).build();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package sh.rhiobet.lalafin.thumbnail;
|
||||
package sh.rhiobet.lalafin.file.thumbnail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
@@ -10,29 +10,30 @@ import java.util.regex.Pattern;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import sh.rhiobet.lalafin.api.configuration.FileApiConfiguration;
|
||||
import sh.rhiobet.lalafin.path.FileSystemPath;
|
||||
import sh.rhiobet.lalafin.path.Path;
|
||||
import sh.rhiobet.lalafin.path.PathAccessor;
|
||||
import sh.rhiobet.lalafin.path.PathPlugin;
|
||||
import sh.rhiobet.lalafin.path.ZipEntryPath;
|
||||
import sh.rhiobet.lalafin.file.configuration.FileConfiguration;
|
||||
import sh.rhiobet.lalafin.core.path.model.FileSystemPath;
|
||||
import sh.rhiobet.lalafin.core.path.model.Path;
|
||||
import sh.rhiobet.lalafin.core.path.model.PathAccessor;
|
||||
import sh.rhiobet.lalafin.core.path.model.ZipEntryPath;
|
||||
import sh.rhiobet.lalafin.core.path.plugin.PathPlugin;
|
||||
|
||||
@ApplicationScoped
|
||||
@Named("thumbnail")
|
||||
public class ThumbnailPathPlugin extends PathAccessor implements PathPlugin {
|
||||
@Named("file/thumbnail")
|
||||
public class FileThumbnailPathPlugin extends PathAccessor implements PathPlugin {
|
||||
@Inject
|
||||
FileApiConfiguration fileApiConfiguration;
|
||||
FileConfiguration fileConfiguration;
|
||||
|
||||
@Override
|
||||
public Optional<String> resolveURI(Path path) {
|
||||
@Override
|
||||
public Optional<String> resolveURI(Path path) {
|
||||
switch (path) {
|
||||
case FileSystemPath fsp:
|
||||
Optional<java.nio.file.Path> thumbnailAbsolutePath = getThumbnailPath(path);
|
||||
|
||||
if (thumbnailAbsolutePath.isPresent()) {
|
||||
java.nio.file.Path rootFolderPath = Paths.get(this.fileApiConfiguration.directory());
|
||||
return Optional.of(rootFolderPath.resolve("file").relativize(thumbnailAbsolutePath.get())
|
||||
.toUri().getRawPath());
|
||||
java.nio.file.Path rootFolderPath = Paths.get(this.fileConfiguration.directory());
|
||||
return Optional.of(
|
||||
"/" + rootFolderPath.resolve("file").relativize(thumbnailAbsolutePath.get())
|
||||
.toString());
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
@@ -40,10 +41,10 @@ public class ThumbnailPathPlugin extends PathAccessor implements PathPlugin {
|
||||
case ZipEntryPath zep:
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream(Path path) throws IOException {
|
||||
@Override
|
||||
public OutputStream getOutputStream(Path path) throws IOException {
|
||||
switch (path) {
|
||||
case FileSystemPath fsp:
|
||||
Optional<java.nio.file.Path> thumbnailAbsolutePath = getThumbnailPath(path);
|
||||
@@ -58,16 +59,16 @@ public class ThumbnailPathPlugin extends PathAccessor implements PathPlugin {
|
||||
case ZipEntryPath zep:
|
||||
throw new IOException("A zip file is not a valid location to store a thumbnail.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<java.nio.file.Path> getThumbnailPath(Path path) {
|
||||
try {
|
||||
return Files.list(getAbsolutePath(path).getParent().resolve(".thumbnails"))
|
||||
.filter(f -> f.getFileName().toString()
|
||||
try {
|
||||
return Files.list(getAbsolutePath(path).getParent().resolve(".thumbnails"))
|
||||
.filter(f -> f.getFileName().toString()
|
||||
.matches("^" + Pattern.quote(path.getFilename()) + "(\\.[^.]+)*$"))
|
||||
.findFirst();
|
||||
} catch (IOException ignored) {
|
||||
.findFirst();
|
||||
} catch (IOException ignored) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user