From ead667683c881b026ffdb4ace552562fb63993a6 Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Wed, 4 Dec 2024 15:53:10 +0800 Subject: [PATCH] feat: add system info getter for plugin (#7103) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area core /milestone 2.20.x #### What this PR does / why we need it: 为插件提供 SystemInfoGetter 用于获取站点基本信息 站点标题描述和系统版本这些信息对于插件来说是很有必要的避免插件要直接查询 system ConfigMap 来获取,如 RSS 和 通知器扩展等插件都会需要用到 ```json { "title" : "guqing's blog", "subtitle" : "副标题", "logo" : "/upload/myavatar.png", "favicon" : "/upload/myavatar.png", "url" : "http://localhost:8090", "version" : { "majorVersion" : 2, "minorVersion" : 20, "normalVersion" : "2.20.10", "preRelease" : true, "publicApiStable" : true, "patchVersion" : 10, "preReleaseVersion" : "SNAPSHOT", "buildMetadata" : "", "stable" : false }, "seo" : { "blockSpiders" : false, "keywords" : "keyword1,keyword2", "description" : "站点描述" }, "locale" : "zh_CN_#Hans", "timeZone" : "Asia/Shanghai", "activatedThemeName" : "theme-earth" } ``` #### Does this PR introduce a user-facing change? ```release-note 开发者相关:为插件提供 SystemInfoGetter 用于获取站点基本信息 ``` --- .../java/run/halo/app/infra/SystemInfo.java | 40 +++++++++++ .../run/halo/app/infra/SystemInfoGetter.java | 7 ++ .../halo/app/infra/SystemInfoGetterImpl.java | 71 +++++++++++++++++++ .../SharedApplicationContextFactory.java | 5 ++ 4 files changed, 123 insertions(+) create mode 100644 api/src/main/java/run/halo/app/infra/SystemInfo.java create mode 100644 api/src/main/java/run/halo/app/infra/SystemInfoGetter.java create mode 100644 application/src/main/java/run/halo/app/infra/SystemInfoGetterImpl.java diff --git a/api/src/main/java/run/halo/app/infra/SystemInfo.java b/api/src/main/java/run/halo/app/infra/SystemInfo.java new file mode 100644 index 000000000..d184ef18f --- /dev/null +++ b/api/src/main/java/run/halo/app/infra/SystemInfo.java @@ -0,0 +1,40 @@ +package run.halo.app.infra; + +import com.github.zafarkhaja.semver.Version; +import java.net.URL; +import java.util.Locale; +import java.util.TimeZone; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class SystemInfo { + private String title; + + private String subtitle; + + private String logo; + + private String favicon; + + private URL url; + + private Version version; + + private SeoProp seo; + + private Locale locale; + + private TimeZone timeZone; + + private String activatedThemeName; + + @Data + @Accessors(chain = true) + public static class SeoProp { + private boolean blockSpiders; + private String keywords; + private String description; + } +} diff --git a/api/src/main/java/run/halo/app/infra/SystemInfoGetter.java b/api/src/main/java/run/halo/app/infra/SystemInfoGetter.java new file mode 100644 index 000000000..293ada78e --- /dev/null +++ b/api/src/main/java/run/halo/app/infra/SystemInfoGetter.java @@ -0,0 +1,7 @@ +package run.halo.app.infra; + +import java.util.function.Supplier; +import reactor.core.publisher.Mono; + +public interface SystemInfoGetter extends Supplier> { +} diff --git a/application/src/main/java/run/halo/app/infra/SystemInfoGetterImpl.java b/application/src/main/java/run/halo/app/infra/SystemInfoGetterImpl.java new file mode 100644 index 000000000..ad2bfd136 --- /dev/null +++ b/application/src/main/java/run/halo/app/infra/SystemInfoGetterImpl.java @@ -0,0 +1,71 @@ +package run.halo.app.infra; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.Locale; +import java.util.TimeZone; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +@Component +@RequiredArgsConstructor +public class SystemInfoGetterImpl implements SystemInfoGetter { + private final SystemConfigurableEnvironmentFetcher environmentFetcher; + private final SystemVersionSupplier systemVersionSupplier; + private final ExternalUrlSupplier externalUrlSupplier; + private final ServerProperties serverProperties; + private final WebFluxProperties webFluxProperties; + + @Override + public Mono get() { + var systemInfo = new SystemInfo() + .setVersion(systemVersionSupplier.get()) + .setUrl(getExternalUrl()) + // TODO populate locale and timezone from system settings in the future + .setLocale(Locale.getDefault()) + .setTimeZone(TimeZone.getDefault()); + + var basicMono = + environmentFetcher.fetch(SystemSetting.Basic.GROUP, SystemSetting.Basic.class) + .doOnNext(basic -> systemInfo.setTitle(basic.getTitle()) + .setSubtitle(basic.getSubtitle()) + .setLogo(basic.getLogo()) + .setFavicon(basic.getFavicon()) + ); + + var seoMono = environmentFetcher.fetch(SystemSetting.Seo.GROUP, SystemSetting.Seo.class) + .doOnNext(seo -> systemInfo.setSeo(new SystemInfo.SeoProp() + .setBlockSpiders(BooleanUtils.isTrue(seo.blockSpiders)) + .setKeywords(seo.getKeywords()) + .setDescription(seo.getDescription()) + )); + + var themeMono = + environmentFetcher.fetch(SystemSetting.Theme.GROUP, SystemSetting.Theme.class) + .doOnNext(theme -> systemInfo.setActivatedThemeName(theme.getActive())); + return Mono.when(basicMono, seoMono, themeMono) + .thenReturn(systemInfo); + } + + private URL getExternalUrl() { + var url = externalUrlSupplier.getRaw(); + if (url != null) { + return url; + } + var port = serverProperties.getPort(); + var basePath = StringUtils.defaultIfBlank(webFluxProperties.getBasePath(), "/"); + try { + var uriStr = "http://localhost:" + port + basePath; + return URI.create(StringUtils.removeEnd(uriStr, "/")).toURL(); + } catch (MalformedURLException e) { + // Should not happen + throw new RuntimeException("Cannot create URL from server properties.", e); + } + } +} diff --git a/application/src/main/java/run/halo/app/plugin/SharedApplicationContextFactory.java b/application/src/main/java/run/halo/app/plugin/SharedApplicationContextFactory.java index e8e23316c..77766304f 100644 --- a/application/src/main/java/run/halo/app/plugin/SharedApplicationContextFactory.java +++ b/application/src/main/java/run/halo/app/plugin/SharedApplicationContextFactory.java @@ -17,6 +17,7 @@ import run.halo.app.extension.ReactiveExtensionClient; import run.halo.app.infra.BackupRootGetter; import run.halo.app.infra.ExternalLinkProcessor; import run.halo.app.infra.ExternalUrlSupplier; +import run.halo.app.infra.SystemInfoGetter; import run.halo.app.notification.NotificationCenter; import run.halo.app.notification.NotificationReasonEmitter; import run.halo.app.plugin.extensionpoint.ExtensionGetter; @@ -97,6 +98,10 @@ public enum SharedApplicationContextFactory { .ifUnique(userDetailsService -> beanFactory.registerSingleton("userDetailsService", userDetailsService) ); + rootContext.getBeanProvider(SystemInfoGetter.class) + .ifUnique(systemInfoGetter -> + beanFactory.registerSingleton("systemInfoGetter", systemInfoGetter) + ); // TODO add more shared instance here sharedContext.refresh();