Skip to content

Commit

Permalink
chore: rename thumbnail parameter from width to size for clarity (#6533)
Browse files Browse the repository at this point in the history
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.19.x

#### What this PR does / why we need it:
重命名缩略图大小的参数名以便和主题端 finder 用法保持一致
同时确保通过 encode 或者没有 encode 的 uri 都可以获取到缩略图

#### Does this PR introduce a user-facing change?
```release-note
None
```
  • Loading branch information
guqing authored Aug 27, 2024
1 parent ac0700e commit a5c6d66
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import lombok.experimental.UtilityClass;
import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;
import run.halo.app.core.extension.attachment.Attachment;

@UtilityClass
Expand Down Expand Up @@ -41,16 +38,4 @@ public static URL toUrl(@NonNull URI uri) {
throw new IllegalArgumentException(e);
}
}

/**
* Encode uri string to URI.
* This method will decode the uri string first and then encode it.
*/
public static URI encodeUri(String uriStr) {
var decodedUriStr = UriUtils.decode(uriStr, StandardCharsets.UTF_8);
return UriComponentsBuilder.fromUriString(decodedUriStr)
.encode(StandardCharsets.UTF_8)
.build()
.toUri();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public interface LocalThumbnailService {
* @return The original image URI, {@link NotFoundException} will be thrown if the thumbnail
* record does not exist by the given thumbnail URI
*/
Mono<URI> getOriginalImageUri(String thumbnailUri);
Mono<URI> getOriginalImageUri(URI thumbnailUri);

/**
* <p>Gets thumbnail file resource for the given year, size and filename.</p>
Expand All @@ -29,7 +29,7 @@ public interface LocalThumbnailService {
* @param thumbnailUri The thumbnail URI string
* @return The thumbnail file resource
*/
Mono<Resource> getThumbnail(String thumbnailUri);
Mono<Resource> getThumbnail(URI thumbnailUri);

/**
* <p>Gets thumbnail file resource for the given URI and size.</p>
Expand Down Expand Up @@ -77,5 +77,5 @@ public interface LocalThumbnailService {

Path toFilePath(String thumbRelativeUnixPath);

String buildThumbnailUri(String year, ThumbnailSize size, String filename);
URI buildThumbnailUri(String year, ThumbnailSize size, String filename);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -138,8 +140,15 @@ private static String doGetFormatName(File file) throws IOException {

static class ImageDownloader {
public Path downloadFile(URL url) throws IOException {
var encodedUri = AttachmentUtils.encodeUri(url.toString());
return downloadFileInternal(encodedUri.toURL());
return downloadFileInternal(encodedUrl(url));
}

private static URL encodedUrl(URL url) {
try {
return new URL(url.toURI().toASCIIString());
} catch (MalformedURLException | URISyntaxException e) {
throw new IllegalArgumentException(e);
}
}

Path downloadFileInternal(URL url) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package run.halo.app.core.attachment;

import java.math.BigInteger;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
Expand Down Expand Up @@ -34,4 +35,8 @@ public static String generateSignature(String input) {
throw new RuntimeException(ALGORITHM + " algorithm not found", e);
}
}

public static String generateSignature(URI uri) {
return generateSignature(uri.toASCIIString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ static String getYear() {
}

@Override
public Mono<URI> getOriginalImageUri(String thumbnailUri) {
public Mono<URI> getOriginalImageUri(URI thumbnailUri) {
return fetchThumbnail(thumbnailUri)
.map(local -> URI.create(local.getSpec().getImageUri()));
}

@Override
public Mono<Resource> getThumbnail(String thumbnailUri) {
public Mono<Resource> getThumbnail(URI thumbnailUri) {
Assert.notNull(thumbnailUri, "Thumbnail URI must not be null.");
return fetchThumbnail(thumbnailUri)
.flatMap(thumbnail -> {
Expand All @@ -100,7 +100,7 @@ public Mono<Resource> getThumbnail(URI originalImageUri, ThumbnailSize size) {
.flatMap(this::generate);
}

private Mono<LocalThumbnail> fetchThumbnail(String thumbnailUri) {
private Mono<LocalThumbnail> fetchThumbnail(URI thumbnailUri) {
Assert.notNull(thumbnailUri, "Thumbnail URI must not be null.");
var thumbSignature = ThumbnailSigner.generateSignature(thumbnailUri);
return client.listBy(LocalThumbnail.class, ListOptions.builder()
Expand Down Expand Up @@ -171,10 +171,10 @@ public Mono<LocalThumbnail> create(URL imageUrl, ThumbnailSize size) {
thumbnail.setSpec(new LocalThumbnail.Spec()
.setImageSignature(signatureForImageUri(imageUri))
.setFilePath(toRelativeUnixPath(filePath))
.setImageUri(ensureInSiteUriIsRelative(imageUri).toString())
.setImageUri(ensureInSiteUriIsRelative(imageUri).toASCIIString())
.setSize(size)
.setThumbSignature(thumbSignature)
.setThumbnailUri(thumbnailUri));
.setThumbnailUri(thumbnailUri.toASCIIString()));
return client.create(thumbnail);
});
}
Expand Down Expand Up @@ -236,8 +236,9 @@ public Path toFilePath(String relativeUnixPath) {
}

@Override
public String buildThumbnailUri(String year, ThumbnailSize size, String filename) {
return "/upload/thumbnails/%s/w%s/%s".formatted(year, size.getWidth(), filename);
public URI buildThumbnailUri(String year, ThumbnailSize size, String filename) {
return URI.create("/upload/thumbnails/%s/w%s/%s".formatted(year, size.getWidth(),
filename));
}

private String toRelativeUnixPath(Path filePath) {
Expand Down Expand Up @@ -266,7 +267,7 @@ private Mono<Void> deleteFile(Path path) {
* image URL to the external URL.</p>
*/
String signatureForImageUri(URI imageUri) {
var uriToSign = ensureInSiteUriIsRelative(imageUri).toString();
var uriToSign = ensureInSiteUriIsRelative(imageUri);
return ThumbnailSigner.generateSignature(uriToSign);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public Mono<URI> generate(URI imageUri, ThumbnailSize size) {
var imageUrl = imageUrlOpt.get();
return fetchThumbnail(imageUri, size)
.map(thumbnail -> URI.create(thumbnail.getSpec().getThumbnailUri()))
.switchIfEmpty(create(imageUrl, size))
.switchIfEmpty(Mono.defer(() -> create(imageUrl, size)))
.onErrorResume(Throwable.class, e -> {
log.warn("Failed to generate thumbnail for image: {}", imageUrl, e);
return Mono.just(URI.create(imageUrl.toString()));
Expand Down Expand Up @@ -108,8 +108,8 @@ Mono<URI> create(URL imageUrl, ThumbnailSize size) {
thumb.getMetadata().setGenerateName("thumb-");
thumb.setSpec(new Thumbnail.Spec()
.setSize(size)
.setThumbnailUri(uri.toString())
.setImageUri(imageUri.toString())
.setThumbnailUri(uri.toASCIIString())
.setImageUri(imageUri.toASCIIString())
.setImageSignature(signatureFor(imageUri))
);
return client.create(thumb)
Expand All @@ -119,7 +119,7 @@ Mono<URI> create(URL imageUrl, ThumbnailSize size) {

private String signatureFor(URI imageUri) {
var uri = localThumbnailService.ensureInSiteUriIsRelative(imageUri);
return ThumbnailSigner.generateSignature(uri.toString());
return ThumbnailSigner.generateSignature(uri);
}

Mono<Thumbnail> fetchThumbnail(URI imageUri, ThumbnailSize size) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import lombok.experimental.Accessors;
import org.springframework.lang.NonNull;
import run.halo.app.core.attachment.AttachmentRootGetter;
import run.halo.app.core.attachment.ThumbnailSigner;
import run.halo.app.core.attachment.ThumbnailSize;
import run.halo.app.extension.AbstractExtension;
import run.halo.app.extension.GVK;
Expand All @@ -33,10 +32,6 @@ public void setStatus(Status status) {
this.status = (status == null ? new Status() : status);
}

public static String signatureFor(String imageUri) {
return ThumbnailSigner.generateSignature(imageUri);
}

@Data
@Accessors(chain = true)
@Schema(name = "LocalThumbnailSpec")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package run.halo.app.theme.endpoint;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
import static org.apache.commons.lang3.StringUtils.removeStart;
import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder;
import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder;

Expand All @@ -27,7 +26,6 @@
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.AttachmentUtils;
import run.halo.app.core.attachment.LocalThumbnailService;
import run.halo.app.core.attachment.ThumbnailService;
import run.halo.app.core.attachment.ThumbnailSize;
Expand Down Expand Up @@ -64,7 +62,7 @@ public RouterFunction<ServerResponse> endpoint() {

private Mono<ServerResponse> getThumbnailByUri(ServerRequest request) {
var query = new ThumbnailQuery(request.queryParams());
return thumbnailService.generate(query.getUri(), query.getWidth())
return thumbnailService.generate(query.getUri(), query.getSize())
.defaultIfEmpty(query.getUri())
.flatMap(uri -> ServerResponse.permanentRedirect(uri).build());
}
Expand All @@ -82,17 +80,20 @@ public URI getUri() {
if (StringUtils.isBlank(uriStr)) {
throw new ServerWebInputException("Required parameter 'uri' is missing");
}
return AttachmentUtils.encodeUri(uriStr);
try {
return URI.create(uriStr);
} catch (IllegalArgumentException e) {
throw new ServerWebInputException("Invalid URI: " + uriStr);
}
}

@Schema(requiredMode = REQUIRED)
public ThumbnailSize getWidth() {
var width = params.getFirst("width");
if (StringUtils.isBlank(width)) {
throw new ServerWebInputException("Required parameter 'width' is missing");
public ThumbnailSize getSize() {
var size = params.getFirst("size");
if (StringUtils.isBlank(size)) {
throw new ServerWebInputException("Required parameter 'size' is missing");
}
// Remove the 'w' prefix
return ThumbnailSize.fromWidth(removeStart(width, 'w'));
return ThumbnailSize.fromName(size);
}

public static void buildParameters(Builder builder) {
Expand All @@ -103,8 +104,8 @@ public static void buildParameters(Builder builder) {
.required(true))
.parameter(parameterBuilder()
.in(ParameterIn.QUERY)
.name("width")
.description("The width of the thumbnail")
.name("size")
.description("The size of the thumbnail,available values are s,m,l,xl")
.required(true));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
public interface ThumbnailFinder {

/**
* Generate thumbnail url from given image url and size.
* Generate thumbnail uri from given image uri and size.
*
* @param size the size of thumbnail to generate
* @return the generated thumbnail url
*/
Mono<String> gen(String url, String size);
Mono<String> gen(String uri, String size);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public class ThumbnailFinderImpl implements ThumbnailFinder {
private final ThumbnailService thumbnailService;

@Override
public Mono<String> gen(String url, String size) {
return thumbnailService.generate(URI.create(url), ThumbnailSize.fromName(size))
public Mono<String> gen(String uriStr, String size) {
return thumbnailService.generate(URI.create(uriStr), ThumbnailSize.fromName(size))
.map(URI::toString)
.defaultIfEmpty(url);
.defaultIfEmpty(uriStr);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.assertj.core.api.Assertions.assertThat;

import java.net.URI;
import org.junit.jupiter.api.Test;

/**
Expand All @@ -18,4 +19,21 @@ void generateSignature() {
assertThat(signature).isEqualTo(
"ed2e575a1d298e08df19dca9733da3f46eab5b157b1b8f9ed02f31b2f907ec79");
}
}

@Test
void generateSignatureWithUri() {
var uri = URI.create("https://example.com/example.jpg");
var signature = ThumbnailSigner.generateSignature(uri);
assertThat(signature).isEqualTo(
"35b8dc8b5b518222245b3f74ea3c3b292e31eb0d888102b5e5a9cdbe4fb7a976");

uri = URI.create("/upload/%E4%B8%AD%E6%96%87%E5%A4%B4%E5%83%8F%20hello%25avatar.png");
signature = ThumbnailSigner.generateSignature(uri);
var avatarPngHash = "7dc5019aea284094c5ba9c4404e3cedf779a2fec0d836cbdf542da3cb373dd3c";
assertThat(signature).isEqualTo(avatarPngHash);

uri = URI.create("/upload/中文头像%20hello%25avatar.png");
signature = ThumbnailSigner.generateSignature(uri);
assertThat(signature).isEqualTo(avatarPngHash);
}
}
Loading

0 comments on commit a5c6d66

Please sign in to comment.