Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions app/src/main/java/run/halo/feed/provider/TagPostRssProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package run.halo.feed.provider;

import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import run.halo.app.content.PostContentService;
import run.halo.app.extension.ListResult;
import run.halo.app.extension.ReactiveExtensionClient;
import run.halo.app.infra.ExternalLinkProcessor;
import run.halo.app.infra.ExternalUrlSupplier;
import run.halo.app.infra.SystemInfoGetter;
import run.halo.app.plugin.ReactiveSettingFetcher;
import run.halo.feed.BasicProp;
import run.halo.feed.RSS2;
import run.halo.feed.RssRouteItem;
import run.halo.feed.service.PostService;

@Component
public class TagPostRssProvider extends AbstractPostRssProvider implements RssRouteItem {

public TagPostRssProvider(PostService postService, ReactiveExtensionClient client,
ExternalLinkProcessor externalLinkProcessor, ReactiveSettingFetcher settingFetcher,
PostContentService postContentService, ExternalUrlSupplier externalUrlSupplier,
SystemInfoGetter systemInfoGetter) {
super(postService, client, externalLinkProcessor, settingFetcher, postContentService,
externalUrlSupplier, systemInfoGetter);
}

@Override
public Mono<String> pathPattern() {
return BasicProp.getBasicProp(settingFetcher)
.filter(BasicProp::isEnableCategories)
.map(prop -> "/tags/{slug}.xml");
}

@Override
@NonNull
public String displayName() {
return "标签文章订阅";
}

@Override
public String description() {
return "按标签订阅站点文章";
}

public Mono<RSS2> handler(ServerRequest request) {
var slug = request.pathVariable("slug");
return super.handler(request)
.flatMap(rss2 -> postService.getTagBySlug(slug)
.doOnNext(tag -> {
var displayName = tag.getSpec().getDisplayName();
var permalink = tag.getStatusOrDefault().getPermalink();
rss2.setTitle("标签:" + displayName + " - " + rss2.getTitle());
rss2.setLink(externalLinkProcessor.processLink(permalink));
})
.thenReturn(rss2)
);
}

@Override
protected Flux<PostWithContent> listPosts(ServerRequest request) {
var tagSlug = request.pathVariable("slug");
return listPostsByFunc(basicProp ->
postService.listPostByTagSlug(basicProp.getOutputNum(), tagSlug)
.flatMapIterable(ListResult::getItems)
);
}
}
5 changes: 5 additions & 0 deletions app/src/main/java/run/halo/feed/service/PostService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@
import reactor.core.publisher.Mono;
import run.halo.app.core.extension.content.Category;
import run.halo.app.core.extension.content.Post;
import run.halo.app.core.extension.content.Tag;
import run.halo.app.extension.ListResult;

public interface PostService {
Mono<ListResult<Post>> listPosts(int size);

Mono<ListResult<Post>> listPostByCategorySlug(int size, String categorySlug);

Mono<ListResult<Post>> listPostByTagSlug(int size, String tagSlug);

Mono<ListResult<Post>> listPostByAuthor(int size, String author);

Mono<Category> getCategoryBySlug(String categorySlug);

Mono<Tag> getTagBySlug(String slug);
}
22 changes: 22 additions & 0 deletions app/src/main/java/run/halo/feed/service/PostServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import reactor.core.publisher.Mono;
import run.halo.app.core.extension.content.Category;
import run.halo.app.core.extension.content.Post;
import run.halo.app.core.extension.content.Tag;
import run.halo.app.extension.ListOptions;
import run.halo.app.extension.ListResult;
import run.halo.app.extension.PageRequestImpl;
Expand Down Expand Up @@ -39,6 +40,17 @@ public Mono<ListResult<Post>> listPostByCategorySlug(int size, String categorySl
});
}

@Override
public Mono<ListResult<Post>> listPostByTagSlug(int size, String slug) {
return getTagBySlug(slug)
.flatMap(tag -> {
var tagName = tag.getMetadata().getName();
return client.listBy(Post.class,
buildPostListOptions(in("spec.tags", tagName)),
PageRequestImpl.ofSize(size).withSort(defaultSort()));
});
}

@Override
public Mono<ListResult<Post>> listPostByAuthor(int size, String author) {
return client.listBy(Post.class, buildPostListOptions(in("spec.owner", author)),
Expand All @@ -55,6 +67,16 @@ public Mono<Category> getCategoryBySlug(String categorySlug) {
.flatMap(listResult -> Mono.justOrEmpty(ListResult.first(listResult)));
}

@Override
public Mono<Tag> getTagBySlug(String slug) {
return client.listBy(Tag.class, ListOptions.builder()
.fieldQuery(equal("spec.slug", slug))
.build(),
PageRequestImpl.ofSize(1)
)
.flatMap(listResult -> Mono.justOrEmpty(ListResult.first(listResult)));
}

ListOptions buildPostListOptions() {
return buildPostListOptions(null);
}
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/resources/extensions/ext-definition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ spec:
---
apiVersion: plugin.halo.run/v1alpha1
kind: ExtensionDefinition
metadata:
name: feed-tag-post-rss-item
spec:
className: run.halo.feed.provider.TagPostRssProvider
extensionPointName: feed-rss-route-item
displayName: "标签文章订阅"
description: "用于生成按照标签订阅文章列表的 RSS 订阅源"
---
apiVersion: plugin.halo.run/v1alpha1
kind: ExtensionDefinition
metadata:
name: feed-author-post-rss-item
spec:
Expand Down