Skip to content

Commit

Permalink
feat: add system info getter for plugin (#7103)
Browse files Browse the repository at this point in the history
#### 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 用于获取站点基本信息
```
  • Loading branch information
guqing authored Dec 4, 2024
1 parent fef06ed commit ead6676
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 0 deletions.
40 changes: 40 additions & 0 deletions api/src/main/java/run/halo/app/infra/SystemInfo.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
7 changes: 7 additions & 0 deletions api/src/main/java/run/halo/app/infra/SystemInfoGetter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package run.halo.app.infra;

import java.util.function.Supplier;
import reactor.core.publisher.Mono;

public interface SystemInfoGetter extends Supplier<Mono<SystemInfo>> {
}
Original file line number Diff line number Diff line change
@@ -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<SystemInfo> 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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
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;
Expand Down Expand Up @@ -97,6 +98,10 @@ public static ApplicationContext create(ApplicationContext rootContext) {
.ifUnique(userDetailsService ->
beanFactory.registerSingleton("userDetailsService", userDetailsService)
);
rootContext.getBeanProvider(SystemInfoGetter.class)
.ifUnique(systemInfoGetter ->
beanFactory.registerSingleton("systemInfoGetter", systemInfoGetter)
);
// TODO add more shared instance here

sharedContext.refresh();
Expand Down

0 comments on commit ead6676

Please sign in to comment.