Skip to content

Commit

Permalink
refactor: add extension point definition
Browse files Browse the repository at this point in the history
  • Loading branch information
guqing committed Dec 10, 2024
1 parent a60f14f commit 62922bb
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 11 deletions.
5 changes: 5 additions & 0 deletions api/src/main/java/run/halo/feed/TelemetryEventInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@

import java.util.Objects;
import lombok.Data;
import lombok.Getter;
import lombok.experimental.Accessors;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.NonNull;

@Data
@Accessors(chain = true)
public class TelemetryEventInfo {
private String pageUrl;
private String screen;
private String language;
private String languageRegion;
private String title;
private String referrer;
private String ip;
private String userAgent;
private String browser;
private String os;

@Getter(onMethod_ = @NonNull)
private HttpHeaders headers;

@Override
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/run/halo/feed/RssXmlBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ private String getDescriptionWithTelemetry(RSS2.Item item) {
);

// Append telemetry image to description
return item.getDescription() + telemetryImageHtml;
return telemetryImageHtml + item.getDescription();
}

static <T> List<T> nullSafeList(List<T> list) {
Expand Down
32 changes: 22 additions & 10 deletions app/src/main/java/run/halo/feed/telemetry/TelemetryEndpoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerRequest;
Expand All @@ -16,10 +19,15 @@
@RequiredArgsConstructor
public class TelemetryEndpoint {
public static final String TELEMETRY_PATH = "/plugins/feed/assets/telemetry.gif";
static final String ONE_PIXEL_GIF_BASE64 =
"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
static final Resource ONE_PIXEL;
private final TelemetryRecorderDelegator telemetryRecorderDelegator;

static {
// RSS readers may thumbnail images, and using base64 images may cause RSS readers to
// fail to parse correctly.
ONE_PIXEL = new ClassPathResource("1pixel.png", TelemetryEndpoint.class.getClassLoader());
}

@Bean
public RouterFunction<ServerResponse> telemetryImageRouter() {
return RouterFunctions.route()
Expand All @@ -28,16 +36,15 @@ public RouterFunction<ServerResponse> telemetryImageRouter() {
return ServerResponse.ok()
.header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_GIF_VALUE)
.cacheControl(CacheControl.noCache())
.bodyValue(ONE_PIXEL_GIF_BASE64);
.bodyValue(ONE_PIXEL);
})
.build();
}

private TelemetryEventInfo createEventInfo(ServerRequest request) {
var userAgent = request.headers().firstHeader(HttpHeaders.USER_AGENT);
var browser = BrowserDetector.detectBrowser(userAgent);
var acceptLang = request.headers().firstHeader(HttpHeaders.ACCEPT_LANGUAGE);
return new TelemetryEventInfo()
var eventInfo = new TelemetryEventInfo()
.setTitle(queryParamOrNull(request, "title"))
.setPageUrl(queryParamOrNull(request, "url"))
.setBrowser(browser.nameVersion())
Expand All @@ -46,13 +53,18 @@ private TelemetryEventInfo createEventInfo(ServerRequest request) {
.setReferrer(request.headers().firstHeader(HttpHeaders.REFERER))
.setScreen(browser.screen())
.setUserAgent(userAgent)
.setLanguage(parseLanguage(acceptLang))
.setHeaders(request.headers().asHttpHeaders());
}

private String parseLanguage(String acceptLanguage) {
var languages = AcceptLanguageParser.parseAcceptLanguage(acceptLanguage);
return languages.isEmpty() ? null : languages.get(0).code();
var acceptLang = request.headers().firstHeader(HttpHeaders.ACCEPT_LANGUAGE);
var languages = AcceptLanguageParser.parseAcceptLanguage(acceptLang);
if (!CollectionUtils.isEmpty(languages)) {
var lang = languages.get(0);
eventInfo.setLanguage(languages.get(0).code());
if (lang.region() != null) {
eventInfo.setLanguageRegion(lang.code() + "-" + lang.region());
}
}
return eventInfo;
}

private static String queryParamOrNull(ServerRequest request, String name) {
Expand Down
Binary file added app/src/main/resources/1pixel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions app/src/main/resources/extensions/ext-definition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ spec:
icon: "/plugins/PluginFeed/assets/logo.svg"
---
apiVersion: plugin.halo.run/v1alpha1
kind: ExtensionPointDefinition
metadata:
name: feed-telemetry-recorder
spec:
className: run.halo.feed.TelemetryRecorder
displayName: "遥测内容访问量记录器"
description: "用于扩展 RSS 内容访问量的存储方式,如上报到 Umami"
type: MULTI_INSTANCE
icon: "/plugins/PluginFeed/assets/logo.svg"
---
apiVersion: plugin.halo.run/v1alpha1
kind: ExtensionDefinition
metadata:
name: feed-category-post-rss-item
Expand Down

0 comments on commit 62922bb

Please sign in to comment.