From 7c1c25348ff85b4c8b87d517cfe5068763aca0b8 Mon Sep 17 00:00:00 2001 From: John Niang Date: Fri, 26 Sep 2025 15:28:01 +0800 Subject: [PATCH] Refactor thumbnail handling to streamline thumbnail URI generation and enhance image processing --- .../app/core/attachment/ThumbnailSize.java | 10 ++ .../content/HtmlThumbnailSrcsetInjector.java | 92 -------------- .../content/PageContentThumbnailHandler.java | 41 ------- .../content/PostContentThumbnailHandler.java | 40 ------ .../ThumbnailImgTagPostProcessor.java | 111 +++++++++++++++++ .../app/core/attachment/ThumbnailUtils.java | 26 ++++ .../LocalAttachmentUploadHandler.java | 17 +-- .../reconciler/LocalThumbnailsReconciler.java | 3 +- .../endpoint/theme/ThumbnailEndpoint.java | 114 ++++-------------- .../finders/impl/ThumbnailFinderImpl.java | 15 +-- .../HtmlThumbnailSrcsetInjectorTest.java | 46 ------- 11 files changed, 178 insertions(+), 337 deletions(-) delete mode 100644 application/src/main/java/run/halo/app/content/HtmlThumbnailSrcsetInjector.java delete mode 100644 application/src/main/java/run/halo/app/content/PageContentThumbnailHandler.java delete mode 100644 application/src/main/java/run/halo/app/content/PostContentThumbnailHandler.java create mode 100644 application/src/main/java/run/halo/app/core/attachment/ThumbnailImgTagPostProcessor.java delete mode 100644 application/src/test/java/run/halo/app/content/HtmlThumbnailSrcsetInjectorTest.java diff --git a/api/src/main/java/run/halo/app/core/attachment/ThumbnailSize.java b/api/src/main/java/run/halo/app/core/attachment/ThumbnailSize.java index bdc7035c1..4f48a39c2 100644 --- a/api/src/main/java/run/halo/app/core/attachment/ThumbnailSize.java +++ b/api/src/main/java/run/halo/app/core/attachment/ThumbnailSize.java @@ -1,5 +1,6 @@ package run.halo.app.core.attachment; +import java.util.Optional; import lombok.Getter; @Getter @@ -40,4 +41,13 @@ public enum ThumbnailSize { } throw new IllegalArgumentException("No such thumbnail size: " + name); } + + public static Optional optionalValueOf(String name) { + for (ThumbnailSize value : values()) { + if (value.name().equalsIgnoreCase(name)) { + return Optional.of(value); + } + } + return Optional.empty(); + } } diff --git a/application/src/main/java/run/halo/app/content/HtmlThumbnailSrcsetInjector.java b/application/src/main/java/run/halo/app/content/HtmlThumbnailSrcsetInjector.java deleted file mode 100644 index 1cffc0756..000000000 --- a/application/src/main/java/run/halo/app/content/HtmlThumbnailSrcsetInjector.java +++ /dev/null @@ -1,92 +0,0 @@ -package run.halo.app.content; - -import java.net.URI; -import java.util.function.Function; -import lombok.experimental.UtilityClass; -import org.apache.commons.lang3.StringUtils; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.select.Elements; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import run.halo.app.core.attachment.ThumbnailService; -import run.halo.app.core.attachment.ThumbnailSize; - -@UtilityClass -public class HtmlThumbnailSrcsetInjector { - static final String SRC = "src"; - static final String SRCSET = "srcset"; - - /** - * Inject srcset attribute to img tags in the given html. - */ - public static Mono injectSrcset(String html, - Function> srcSetValueGenerator) { - Document document = Jsoup.parseBodyFragment(html); - document.outputSettings(new Document.OutputSettings().prettyPrint(false)); - - Elements imgTags = document.select("img[src]"); - return Flux.fromIterable(imgTags) - .filter(element -> { - String src = element.attr(SRC); - return !element.hasAttr(SRCSET) && isValidSrc(src); - }) - .flatMap(img -> { - String src = img.attr(SRC); - return srcSetValueGenerator.apply(src) - .filter(StringUtils::isNotBlank) - .doOnNext(srcsetValue -> { - img.attr(SRCSET, srcsetValue); - img.attr("sizes", buildSizesAttr()); - }); - }) - .then(Mono.fromSupplier(() -> document.body().html())); - } - - static String buildSizesAttr() { - var sb = new StringBuilder(); - var delimiter = ", "; - var sizes = ThumbnailSize.values(); - for (int i = 0; i < sizes.length; i++) { - var size = sizes[i]; - sb.append("(max-width: ").append(size.getWidth()).append("px)") - .append(" ") - .append(size.getWidth()) - .append("px"); - if (i < sizes.length - 1) { - sb.append(delimiter); - } - } - return sb.toString(); - } - - /** - * Generate srcset attribute value for the given src. - */ - public static Mono generateSrcset(URI src, ThumbnailService thumbnailService) { - return Flux.fromArray(ThumbnailSize.values()) - .flatMap(size -> thumbnailService.get(src, size) - .map(thumbnail -> thumbnail.toString() + " " + size.getWidth() + "w") - ) - .collect(StringBuilder::new, (builder, srcsetValue) -> { - if (!builder.isEmpty()) { - builder.append(", "); - } - builder.append(srcsetValue); - }) - .map(StringBuilder::toString); - } - - private static boolean isValidSrc(String src) { - if (StringUtils.isBlank(src)) { - return false; - } - try { - URI.create(src); - return true; - } catch (IllegalArgumentException e) { - // ignore - } - return false; - } -} diff --git a/application/src/main/java/run/halo/app/content/PageContentThumbnailHandler.java b/application/src/main/java/run/halo/app/content/PageContentThumbnailHandler.java deleted file mode 100644 index 1cc686454..000000000 --- a/application/src/main/java/run/halo/app/content/PageContentThumbnailHandler.java +++ /dev/null @@ -1,41 +0,0 @@ -package run.halo.app.content; - -import static run.halo.app.content.HtmlThumbnailSrcsetInjector.generateSrcset; - -import java.net.URI; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; -import reactor.core.publisher.Mono; -import run.halo.app.core.attachment.ThumbnailService; -import run.halo.app.theme.ReactiveSinglePageContentHandler; - -/** - * A single page content handler to handle post html content and generate thumbnail by the img tag. - * - * @author guqing - * @since 2.21.0 - */ -@Slf4j -@Component -@RequiredArgsConstructor -public class PageContentThumbnailHandler implements ReactiveSinglePageContentHandler { - private final ThumbnailService thumbnailService; - - @Override - public Mono handle( - @NonNull SinglePageContentContext singlePageContent) { - var html = singlePageContent.getContent(); - return HtmlThumbnailSrcsetInjector.injectSrcset(html, - src -> generateSrcset(URI.create(src), thumbnailService) - ) - .onErrorResume(throwable -> { - log.debug("Failed to inject srcset to page content, fallback to original content", - throwable); - return Mono.just(html); - }) - .doOnNext(singlePageContent::setContent) - .thenReturn(singlePageContent); - } -} diff --git a/application/src/main/java/run/halo/app/content/PostContentThumbnailHandler.java b/application/src/main/java/run/halo/app/content/PostContentThumbnailHandler.java deleted file mode 100644 index 9a94e4ed4..000000000 --- a/application/src/main/java/run/halo/app/content/PostContentThumbnailHandler.java +++ /dev/null @@ -1,40 +0,0 @@ -package run.halo.app.content; - -import static run.halo.app.content.HtmlThumbnailSrcsetInjector.generateSrcset; - -import java.net.URI; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; -import reactor.core.publisher.Mono; -import run.halo.app.core.attachment.ThumbnailService; -import run.halo.app.theme.ReactivePostContentHandler; - -/** - * A post content handler to handle post html content and generate thumbnail by the img tag. - * - * @author guqing - * @since 2.19.0 - */ -@Slf4j -@Component -@RequiredArgsConstructor -public class PostContentThumbnailHandler implements ReactivePostContentHandler { - private final ThumbnailService thumbnailService; - - @Override - public Mono handle(@NonNull PostContentContext postContent) { - var html = postContent.getContent(); - return HtmlThumbnailSrcsetInjector.injectSrcset(html, - src -> generateSrcset(URI.create(src), thumbnailService) - ) - .onErrorResume(throwable -> { - log.debug("Failed to inject srcset to post content, fallback to original content", - throwable); - return Mono.just(html); - }) - .doOnNext(postContent::setContent) - .thenReturn(postContent); - } -} diff --git a/application/src/main/java/run/halo/app/core/attachment/ThumbnailImgTagPostProcessor.java b/application/src/main/java/run/halo/app/core/attachment/ThumbnailImgTagPostProcessor.java new file mode 100644 index 000000000..5e383c147 --- /dev/null +++ b/application/src/main/java/run/halo/app/core/attachment/ThumbnailImgTagPostProcessor.java @@ -0,0 +1,111 @@ +package run.halo.app.core.attachment; + +import static org.thymeleaf.templatemode.TemplateMode.HTML; + +import java.net.URI; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FilenameUtils; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; +import org.thymeleaf.context.ITemplateContext; +import org.thymeleaf.engine.ElementNames; +import org.thymeleaf.model.IAttribute; +import org.thymeleaf.model.IProcessableElementTag; +import org.thymeleaf.processor.element.MatchingElementName; +import org.thymeleaf.spring6.context.SpringContextUtils; +import org.thymeleaf.spring6.context.webflux.SpringWebFluxThymeleafRequestContext; +import reactor.core.publisher.Mono; +import run.halo.app.infra.ExternalUrlSupplier; +import run.halo.app.theme.dialect.ElementTagPostProcessor; + +@Slf4j +@Component +class ThumbnailImgTagPostProcessor implements ElementTagPostProcessor { + + private final MatchingElementName matchingElementName; + + private final ExternalUrlSupplier externalUrlSupplier; + + public ThumbnailImgTagPostProcessor(ExternalUrlSupplier externalUrlSupplier) { + this.externalUrlSupplier = externalUrlSupplier; + this.matchingElementName = + MatchingElementName.forElementName(HTML, ElementNames.forHTMLName("img")); + } + + + @Override + public Mono process(ITemplateContext context, + IProcessableElementTag tag) { + if (!matchingElementName.matches(tag.getElementDefinition().getElementName())) { + return Mono.empty(); + } + if (tag.hasAttribute("srcset")) { + return Mono.empty(); + } + var srcValue = Optional.ofNullable(tag.getAttribute("src")) + .map(IAttribute::getValue) + .filter(StringUtils::hasText) + .map(URI::create); + if (srcValue.isEmpty()) { + log.debug("Skip processing img tag without src attribute"); + return Mono.empty(); + } + // get img tag + var imageUri = srcValue.get(); + + if (imageUri.isAbsolute()) { + // check if the uri is belonged to current site + var requestContext = SpringContextUtils.getRequestContext(context); + if (!(requestContext instanceof SpringWebFluxThymeleafRequestContext wrc)) { + log.debug("Skip processing img tag with absolute url: {}, " + + "because the request context is not webflux", imageUri); + return Mono.empty(); + } + var externalUri = externalUrlSupplier.get(); + if (!externalUri.isAbsolute()) { + externalUri = wrc.getServerWebExchange().getRequest().getURI(); + } + if (!Objects.equals(externalUri.getAuthority(), imageUri.getAuthority())) { + log.debug(""" + Skip processing img tag with external absolute url: {} because \ + the url does not belong to the current site\ + """, imageUri); + return Mono.empty(); + } + } + + var fileSuffix = FilenameUtils.getExtension(imageUri.getPath()); + if (!ThumbnailUtils.isSupportedImage(fileSuffix)) { + log.debug("Skip processing img tag with unsupported image suffix: {}", fileSuffix); + return Mono.empty(); + } + + // build thumbnails + var thumbnails = ThumbnailUtils.buildSrcsetMap(imageUri); + if (CollectionUtils.isEmpty(thumbnails)) { + log.debug("Skip processing img tag because the image is not supported: {}", imageUri); + return Mono.empty(); + } + var modelFactory = context.getModelFactory(); + tag = modelFactory.setAttribute(tag, "size", """ + (max-width: 400px) 400px, \ + (max-width: 800px) 800px, \ + (max-width: 1200px) 1200px, \ + (max-width: 1600px) 1600px\ + """); + + var srcset = thumbnails.keySet().stream() + .map(size -> { + var uri = thumbnails.get(size); + return uri + " " + size.getWidth() + "w"; + }) + .collect(Collectors.joining(", ")); + tag = modelFactory.setAttribute(tag, "srcset", srcset); + return Mono.just(tag); + } + +} diff --git a/application/src/main/java/run/halo/app/core/attachment/ThumbnailUtils.java b/application/src/main/java/run/halo/app/core/attachment/ThumbnailUtils.java index 09f12d388..b776eefba 100644 --- a/application/src/main/java/run/halo/app/core/attachment/ThumbnailUtils.java +++ b/application/src/main/java/run/halo/app/core/attachment/ThumbnailUtils.java @@ -1,9 +1,14 @@ package run.halo.app.core.attachment; +import java.net.URI; +import java.util.Arrays; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import org.apache.commons.io.FilenameUtils; import org.springframework.http.MediaType; import org.springframework.util.MimeType; +import org.springframework.web.util.UriComponentsBuilder; public enum ThumbnailUtils { ; @@ -33,4 +38,25 @@ public enum ThumbnailUtils { return SUPPORTED_IMAGE_MIME_TYPES.stream() .anyMatch(supported -> supported.isCompatibleWith(mimeType)); } + + /** + * Build a map of thumbnail size to its corresponding URI based on the given permalink. + * + * @param permalink permalink of the attachment in local storage + * @return a map where the key is the thumbnail size and the value is the URI of the thumbnail + */ + public static Map buildSrcsetMap(URI permalink) { + var fileSuffix = FilenameUtils.getExtension(permalink.getPath()); + if (!isSupportedImage(fileSuffix)) { + return Map.of(); + } + return Arrays.stream(ThumbnailSize.values()) + .collect(Collectors.toMap(t -> t, t -> { + var prefix = "/thumbnails/w" + t.getWidth(); + return UriComponentsBuilder.fromUri(permalink) + .replacePath(prefix + permalink.getPath()) + .build() + .toUri(); + })); + } } diff --git a/application/src/main/java/run/halo/app/core/attachment/endpoint/LocalAttachmentUploadHandler.java b/application/src/main/java/run/halo/app/core/attachment/endpoint/LocalAttachmentUploadHandler.java index 5dcf0a774..41cda91da 100644 --- a/application/src/main/java/run/halo/app/core/attachment/endpoint/LocalAttachmentUploadHandler.java +++ b/application/src/main/java/run/halo/app/core/attachment/endpoint/LocalAttachmentUploadHandler.java @@ -21,7 +21,6 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; @@ -311,20 +310,8 @@ class LocalAttachmentUploadHandler implements AttachmentHandler { || !StringUtils.hasText(attachment.getStatus().getPermalink())) { return Mono.just(Map.of()); } - var mediaType = MediaType.parseMediaType(attachment.getSpec().getMediaType()); - if (!ThumbnailUtils.isSupportedImage(mediaType)) { - return Mono.just(Map.of()); - } - - var thumbnails = Arrays.stream(ThumbnailSize.values()) - .collect(Collectors.toMap(t -> t, t -> { - var permalink = URI.create(attachment.getStatus().getPermalink()); - var prefix = "/thumbnails/w" + t.getWidth(); - return UriComponentsBuilder.fromUri(permalink) - .replacePath(prefix + permalink.getPath()) - .build() - .toUri(); - })); + var permalinkUri = URI.create(attachment.getStatus().getPermalink()); + var thumbnails = ThumbnailUtils.buildSrcsetMap(permalinkUri); return Mono.just(thumbnails); } diff --git a/application/src/main/java/run/halo/app/core/attachment/reconciler/LocalThumbnailsReconciler.java b/application/src/main/java/run/halo/app/core/attachment/reconciler/LocalThumbnailsReconciler.java index 900f57ff2..2623dfbfc 100644 --- a/application/src/main/java/run/halo/app/core/attachment/reconciler/LocalThumbnailsReconciler.java +++ b/application/src/main/java/run/halo/app/core/attachment/reconciler/LocalThumbnailsReconciler.java @@ -18,7 +18,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Sort; -import org.springframework.stereotype.Component; import run.halo.app.core.attachment.AttachmentRootGetter; import run.halo.app.core.attachment.AttachmentUtils; import run.halo.app.core.attachment.LocalThumbnailService; @@ -36,7 +35,7 @@ import run.halo.app.extension.controller.Reconciler; import run.halo.app.infra.ExternalLinkProcessor; @Slf4j -@Component +// @Component @RequiredArgsConstructor public class LocalThumbnailsReconciler implements Reconciler { private final LocalThumbnailService localThumbnailService; diff --git a/application/src/main/java/run/halo/app/core/endpoint/theme/ThumbnailEndpoint.java b/application/src/main/java/run/halo/app/core/endpoint/theme/ThumbnailEndpoint.java index 0edc18e7f..494ad0b22 100644 --- a/application/src/main/java/run/halo/app/core/endpoint/theme/ThumbnailEndpoint.java +++ b/application/src/main/java/run/halo/app/core/endpoint/theme/ThumbnailEndpoint.java @@ -6,34 +6,28 @@ import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder; import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.media.Schema; -import java.io.IOException; import java.net.URI; -import java.time.Instant; -import java.util.Optional; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springdoc.core.fn.builders.operation.Builder; import org.springdoc.webflux.core.fn.SpringdocRouteBuilder; -import org.springframework.boot.autoconfigure.web.WebProperties; -import org.springframework.context.annotation.Bean; import org.springframework.core.io.Resource; -import org.springframework.http.CacheControl; -import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; -import org.springframework.web.reactive.function.BodyInserters; -import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.server.ServerWebInputException; import reactor.core.publisher.Mono; -import run.halo.app.core.attachment.LocalThumbnailService; -import run.halo.app.core.attachment.ThumbnailService; import run.halo.app.core.attachment.ThumbnailSize; +import run.halo.app.core.extension.attachment.Attachment; import run.halo.app.core.extension.endpoint.CustomEndpoint; +import run.halo.app.extension.ExtensionUtil; import run.halo.app.extension.GroupVersion; +import run.halo.app.extension.ListOptions; +import run.halo.app.extension.ReactiveExtensionClient; +import run.halo.app.extension.index.query.QueryFactory; /** * Thumbnail endpoint for thumbnail resource access. @@ -44,10 +38,8 @@ import run.halo.app.extension.GroupVersion; @Component @RequiredArgsConstructor public class ThumbnailEndpoint implements CustomEndpoint { - private final WebClient webClient = WebClient.builder().build(); - private final LocalThumbnailService localThumbnailService; - private final WebProperties webProperties; - private final ThumbnailService thumbnailService; + + private final ReactiveExtensionClient client; @Override public RouterFunction endpoint() { @@ -66,27 +58,25 @@ public class ThumbnailEndpoint implements CustomEndpoint { private Mono getThumbnailByUri(ServerRequest request) { var query = new ThumbnailQuery(request.queryParams()); - return thumbnailService.get(query.getUri(), query.getSize()) - .filterWhen(uri -> isAccessible(request, uri)) - .defaultIfEmpty(query.getUri()) - .flatMap(uri -> ServerResponse.temporaryRedirect(uri).build()); - } - - Mono isAccessible(ServerRequest request, URI uri) { - var url = Optional.of(uri) - .filter(URI::isAbsolute) - .orElseGet(() -> request.uriBuilder().replacePath(uri.toASCIIString()).build()); - // resource handler does not support head access for Halo, so use get request here - return webClient.get() - .uri(url) - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range - .header(HttpHeaders.RANGE, "bytes=0-0") - .exchangeToMono(response -> { - var statusCode = response.statusCode(); - return Mono.just(statusCode.is2xxSuccessful() || statusCode.is3xxRedirection()); + var size = query.getSize(); + var uri = query.getUri().toASCIIString(); + var listOptions = ListOptions.builder() + .andQuery(ExtensionUtil.notDeleting()) + .andQuery(QueryFactory.equal("status.permalink", uri)) + .build(); + // query by permalink + return client.listAll(Attachment.class, listOptions, ExtensionUtil.defaultSort()) + // find the first one + .next() + .mapNotNull(attachment -> { + var thumbnails = attachment.getStatus().getThumbnails(); + return thumbnails.get(size.name()); }) - .onErrorReturn(false) - .defaultIfEmpty(false); + .defaultIfEmpty(uri) + .flatMap(thumbnailLink -> ServerResponse.status(HttpStatus.FOUND) + .location(URI.create(thumbnailLink)) + .build() + ); } static class ThumbnailQuery { @@ -132,61 +122,9 @@ public class ThumbnailEndpoint implements CustomEndpoint { } } - @Bean - RouterFunction localThumbnailResourceRouter() { - return RouterFunctions.route() - .GET("/upload/thumbnails/{year}/w{width}/{fileName}", request -> { - var width = request.pathVariable("width"); - var year = request.pathVariable("year"); - var fileName = request.pathVariable("fileName"); - var size = ThumbnailSize.fromWidth(width); - var thumbnailUri = localThumbnailService.buildThumbnailUri(year, size, fileName); - return localThumbnailService.getThumbnail(thumbnailUri) - .flatMap(resource -> getResourceResponse(request, resource)) - .switchIfEmpty(Mono.defer( - () -> localThumbnailService.getOriginalImageUri(thumbnailUri) - .flatMap(this::fallback)) - ); - }) - - .build(); - } - @Override public GroupVersion groupVersion() { return new GroupVersion("api.storage.halo.run", "v1alpha1"); } - private Mono getResourceResponse(ServerRequest request, Resource resource) { - var resourceProperties = webProperties.getResources(); - final var useLastModified = resourceProperties.getCache().isUseLastModified(); - final var cacheControl = getCacheControl(resourceProperties); - var bodyBuilder = ServerResponse.ok().cacheControl(cacheControl); - try { - if (useLastModified) { - var lastModified = Instant.ofEpochMilli(resource.lastModified()); - return request.checkNotModified(lastModified) - .switchIfEmpty(Mono.defer(() -> bodyBuilder.lastModified(lastModified) - .body(BodyInserters.fromResource(resource)) - )); - } - return bodyBuilder.body(BodyInserters.fromResource(resource)); - } catch (IOException e) { - return Mono.error(e); - } - } - - private Mono fallback(URI imageUri) { - return ServerResponse.temporaryRedirect(imageUri).build(); - } - - private static CacheControl getCacheControl(WebProperties.Resources resourceProperties) { - var cacheControl = resourceProperties.getCache() - .getCachecontrol() - .toHttpCacheControl(); - if (cacheControl == null) { - cacheControl = CacheControl.empty(); - } - return cacheControl; - } } diff --git a/application/src/main/java/run/halo/app/theme/finders/impl/ThumbnailFinderImpl.java b/application/src/main/java/run/halo/app/theme/finders/impl/ThumbnailFinderImpl.java index 9ea14868a..8c529715a 100644 --- a/application/src/main/java/run/halo/app/theme/finders/impl/ThumbnailFinderImpl.java +++ b/application/src/main/java/run/halo/app/theme/finders/impl/ThumbnailFinderImpl.java @@ -1,11 +1,8 @@ package run.halo.app.theme.finders.impl; -import java.net.URI; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import reactor.core.publisher.Mono; -import run.halo.app.core.attachment.ThumbnailService; -import run.halo.app.core.attachment.ThumbnailSize; import run.halo.app.theme.finders.Finder; import run.halo.app.theme.finders.ThumbnailFinder; @@ -13,18 +10,10 @@ import run.halo.app.theme.finders.ThumbnailFinder; @Finder("thumbnail") @RequiredArgsConstructor public class ThumbnailFinderImpl implements ThumbnailFinder { - private final ThumbnailService thumbnailService; @Override public Mono gen(String uriStr, String size) { - return Mono.fromSupplier(() -> URI.create(uriStr)) - .flatMap(uri -> thumbnailService.get(uri, ThumbnailSize.fromName(size))) - .map(URI::toString) - .onErrorResume(Throwable.class, e -> { - log.debug("Failed to generate thumbnail for [{}], error: [{}]", uriStr, - e.getMessage()); - return Mono.just(uriStr); - }) - .defaultIfEmpty(uriStr); + // TODO Implement me + return Mono.just(uriStr); } } diff --git a/application/src/test/java/run/halo/app/content/HtmlThumbnailSrcsetInjectorTest.java b/application/src/test/java/run/halo/app/content/HtmlThumbnailSrcsetInjectorTest.java deleted file mode 100644 index 597645786..000000000 --- a/application/src/test/java/run/halo/app/content/HtmlThumbnailSrcsetInjectorTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package run.halo.app.content; - -import static org.assertj.core.api.Assertions.assertThat; -import static run.halo.app.content.HtmlThumbnailSrcsetInjector.buildSizesAttr; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; - -/** - * Tests for {@link HtmlThumbnailSrcsetInjector}. - * - * @author guqing - * @since 2.19.0 - */ -class HtmlThumbnailSrcsetInjectorTest { - - @Test - void injectSrcset() { - String html = """ -
- test - -
- """; - var result = HtmlThumbnailSrcsetInjector.injectSrcset(html, - src -> Mono.just(src + " 480w, " + src + " 800w")).block(); - assertThat(result).isEqualToIgnoringWhitespace(""" -
- test - -
- """); - } - - @Test - void buildSizesTest() { - var sizes = buildSizesAttr(); - assertThat(sizes).isEqualToIgnoringWhitespace(""" - (max-width: 400px) 400px, (max-width: 800px) 800px, - (max-width: 1200px) 1200px, (max-width: 1600px) 1600px - """); - } -}