Skip to content

Commit

Permalink
Merge branch 'main' into feature/2292
Browse files Browse the repository at this point in the history
  • Loading branch information
ruibaby committed May 26, 2023
2 parents 4a97dd6 + da5fb1a commit cf3331d
Show file tree
Hide file tree
Showing 38 changed files with 849 additions and 137 deletions.
Expand Up @@ -18,7 +18,7 @@
import run.halo.app.theme.DefaultTemplateEnum;
import run.halo.app.theme.finders.PostFinder;
import run.halo.app.theme.finders.SinglePageFinder;
import run.halo.app.theme.router.factories.ModelConst;
import run.halo.app.theme.router.ModelConst;

/**
* <p>The <code>head</code> html snippet injection processor for content template such as post
Expand Down
Expand Up @@ -10,7 +10,7 @@
import run.halo.app.infra.SystemConfigurableEnvironmentFetcher;
import run.halo.app.infra.SystemSetting;
import run.halo.app.theme.DefaultTemplateEnum;
import run.halo.app.theme.router.factories.ModelConst;
import run.halo.app.theme.router.ModelConst;

/**
* <p>Global custom head snippet injection for theme global setting.</p>
Expand Down
@@ -0,0 +1,21 @@
package run.halo.app.theme.finders;

import reactor.core.publisher.Mono;
import run.halo.app.core.extension.content.SinglePage;
import run.halo.app.theme.finders.vo.ListedSinglePageVo;
import run.halo.app.theme.finders.vo.SinglePageVo;

/**
* A service that converts {@link SinglePage} to {@link SinglePageVo}.
*
* @author guqing
* @since 2.6.0
*/
public interface SinglePageConversionService {

Mono<SinglePageVo> convertToVo(SinglePage singlePage, String snapshotName);

Mono<SinglePageVo> convertToVo(SinglePage singlePage);

Mono<ListedSinglePageVo> convertToListedVo(SinglePage singlePage);
}
Expand Up @@ -133,7 +133,7 @@ static Pair<String, String> postPreviousNextPair(List<String> postNames,
int index = elements.indexOf(currentName);

String previousPostName = null;
if (index != 0) {
if (index > 0) {
previousPostName = elements.get(index - 1);
}

Expand Down
@@ -0,0 +1,113 @@
package run.halo.app.theme.finders.impl;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import reactor.core.publisher.Mono;
import run.halo.app.content.SinglePageService;
import run.halo.app.core.extension.content.SinglePage;
import run.halo.app.metrics.CounterService;
import run.halo.app.metrics.MeterUtils;
import run.halo.app.theme.finders.ContributorFinder;
import run.halo.app.theme.finders.SinglePageConversionService;
import run.halo.app.theme.finders.vo.ContentVo;
import run.halo.app.theme.finders.vo.ListedSinglePageVo;
import run.halo.app.theme.finders.vo.SinglePageVo;
import run.halo.app.theme.finders.vo.StatsVo;

/**
* Default implementation of {@link SinglePageConversionService}.
*
* @author guqing
* @since 2.6.0
*/
@Component
@RequiredArgsConstructor
public class SinglePageConversionServiceImpl implements SinglePageConversionService {

private final SinglePageService singlePageService;

private final ContributorFinder contributorFinder;

private final CounterService counterService;

@Override
public Mono<SinglePageVo> convertToVo(SinglePage singlePage, String snapshotName) {
return convert(singlePage, snapshotName);
}

@Override
public Mono<SinglePageVo> convertToVo(SinglePage singlePage) {
return convert(singlePage, singlePage.getSpec().getReleaseSnapshot());
}

@Override
public Mono<ListedSinglePageVo> convertToListedVo(SinglePage singlePage) {
return Mono.fromSupplier(
() -> {
ListedSinglePageVo pageVo = ListedSinglePageVo.from(singlePage);
pageVo.setContributors(List.of());
return pageVo;
})
.flatMap(this::populateStats)
.flatMap(this::populateContributors);
}

Mono<SinglePageVo> convert(SinglePage singlePage, String snapshotName) {
Assert.notNull(singlePage, "Single page must not be null");
Assert.hasText(snapshotName, "Snapshot name must not be empty");
return Mono.just(singlePage)
.map(page -> {
SinglePageVo pageVo = SinglePageVo.from(page);
pageVo.setContributors(List.of());
pageVo.setContent(ContentVo.empty());
return pageVo;
})
.flatMap(this::populateStats)
.flatMap(this::populateContributors)
.flatMap(page -> populateContent(page, snapshotName))
.flatMap(page -> contributorFinder.getContributor(page.getSpec().getOwner())
.doOnNext(page::setOwner)
.thenReturn(page)
);
}

Mono<SinglePageVo> populateContent(SinglePageVo singlePageVo, String snapshotName) {
Assert.notNull(singlePageVo, "Single page vo must not be null");
Assert.hasText(snapshotName, "Snapshot name must not be empty");
return singlePageService.getContent(snapshotName, singlePageVo.getSpec().getBaseSnapshot())
.map(contentWrapper -> ContentVo.builder()
.content(contentWrapper.getContent())
.raw(contentWrapper.getRaw())
.build()
)
.doOnNext(singlePageVo::setContent)
.thenReturn(singlePageVo);
}

<T extends ListedSinglePageVo> Mono<T> populateStats(T pageVo) {
String name = pageVo.getMetadata().getName();
return counterService.getByName(MeterUtils.nameOf(SinglePage.class, name))
.map(counter -> StatsVo.builder()
.visit(counter.getVisit())
.upvote(counter.getUpvote())
.comment(counter.getApprovedComment())
.build()
)
.doOnNext(pageVo::setStats)
.thenReturn(pageVo);
}

<T extends ListedSinglePageVo> Mono<T> populateContributors(T pageVo) {
List<String> names = pageVo.getStatus().getContributors();
if (CollectionUtils.isEmpty(names)) {
return Mono.just(pageVo);
}
return contributorFinder.getContributors(names)
.collectList()
.doOnNext(pageVo::setContributors)
.thenReturn(pageVo);
}
}
Expand Up @@ -10,23 +10,19 @@
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import run.halo.app.content.SinglePageService;
import run.halo.app.core.extension.content.Post;
import run.halo.app.core.extension.content.SinglePage;
import run.halo.app.extension.ListResult;
import run.halo.app.extension.ReactiveExtensionClient;
import run.halo.app.metrics.CounterService;
import run.halo.app.metrics.MeterUtils;
import run.halo.app.theme.finders.ContributorFinder;
import run.halo.app.theme.finders.Finder;
import run.halo.app.theme.finders.SinglePageConversionService;
import run.halo.app.theme.finders.SinglePageFinder;
import run.halo.app.theme.finders.vo.ContentVo;
import run.halo.app.theme.finders.vo.ListedSinglePageVo;
import run.halo.app.theme.finders.vo.SinglePageVo;
import run.halo.app.theme.finders.vo.StatsVo;

/**
* A default implementation of {@link SinglePage}.
Expand All @@ -44,35 +40,15 @@ public class SinglePageFinderImpl implements SinglePageFinder {

private final ReactiveExtensionClient client;

private final SinglePageService singlePageService;

private final ContributorFinder contributorFinder;
private final SinglePageConversionService singlePagePublicQueryService;

private final CounterService counterService;
private final SinglePageService singlePageService;

@Override
public Mono<SinglePageVo> getByName(String pageName) {
return client.get(SinglePage.class, pageName)
.filter(FIXED_PREDICATE)
.map(page -> {
SinglePageVo pageVo = SinglePageVo.from(page);
pageVo.setContributors(List.of());
pageVo.setContent(ContentVo.empty());
return pageVo;
})
.flatMap(singlePageVo -> fetchStats(singlePageVo)
.doOnNext(singlePageVo::setStats)
.thenReturn(singlePageVo)
)
.flatMap(this::populateContributors)
.flatMap(page -> content(pageName)
.doOnNext(page::setContent)
.thenReturn(page)
)
.flatMap(page -> contributorFinder.getContributor(page.getSpec().getOwner())
.doOnNext(page::setOwner)
.thenReturn(page)
);
.flatMap(singlePagePublicQueryService::convertToVo);
}

@Override
Expand All @@ -98,13 +74,7 @@ public Mono<ListResult<ListedSinglePageVo>> list(@Nullable Integer page, @Nullab
return client.list(SinglePage.class, predicateToUse,
comparatorToUse, pageNullSafe(page), sizeNullSafe(size))
.flatMap(list -> Flux.fromStream(list.get())
.map(singlePage -> {
ListedSinglePageVo pageVo = ListedSinglePageVo.from(singlePage);
pageVo.setContributors(List.of());
return pageVo;
})
.flatMap(lp -> fetchStats(lp).doOnNext(lp::setStats).thenReturn(lp))
.concatMap(this::populateContributors)
.concatMap(singlePagePublicQueryService::convertToListedVo)
.collectList()
.map(pageVos -> new ListResult<>(list.getPage(), list.getSize(), list.getTotal(),
pageVos)
Expand All @@ -113,29 +83,6 @@ comparatorToUse, pageNullSafe(page), sizeNullSafe(size))
.defaultIfEmpty(new ListResult<>(0, 0, 0, List.of()));
}

<T extends ListedSinglePageVo> Mono<StatsVo> fetchStats(T pageVo) {
String name = pageVo.getMetadata().getName();
return counterService.getByName(MeterUtils.nameOf(SinglePage.class, name))
.map(counter -> StatsVo.builder()
.visit(counter.getVisit())
.upvote(counter.getUpvote())
.comment(counter.getApprovedComment())
.build()
)
.defaultIfEmpty(StatsVo.empty());
}

<T extends ListedSinglePageVo> Mono<T> populateContributors(T pageVo) {
List<String> names = pageVo.getStatus().getContributors();
if (CollectionUtils.isEmpty(names)) {
return Mono.just(pageVo);
}
return contributorFinder.getContributors(names)
.collectList()
.doOnNext(pageVo::setContributors)
.thenReturn(pageVo);
}

static Comparator<SinglePage> defaultComparator() {
Function<SinglePage, Boolean> pinned =
page -> Objects.requireNonNullElse(page.getSpec().getPinned(), false);
Expand Down
@@ -1,4 +1,4 @@
package run.halo.app.theme.router.factories;
package run.halo.app.theme.router;

/**
* Static variable keys for view model.
Expand Down
@@ -0,0 +1,53 @@
package run.halo.app.theme.router;

import java.util.HashMap;
import java.util.Map;
import run.halo.app.core.extension.content.Post;
import run.halo.app.core.extension.content.SinglePage;
import run.halo.app.extension.Scheme;
import run.halo.app.theme.DefaultTemplateEnum;
import run.halo.app.theme.finders.vo.PostVo;
import run.halo.app.theme.finders.vo.SinglePageVo;

/**
* A util class for building model map.
*
* @author guqing
* @since 2.6.0
*/
public abstract class ModelMapUtils {
private static final Scheme POST_SCHEME = Scheme.buildFromType(Post.class);
private static final Scheme SINGLE_PAGE_SCHEME = Scheme.buildFromType(SinglePage.class);

/**
* Build post view model.
*
* @param postVo post vo
* @return model map
*/
public static Map<String, Object> postModel(PostVo postVo) {
Map<String, Object> model = new HashMap<>();
model.put("name", postVo.getMetadata().getName());
model.put(ModelConst.TEMPLATE_ID, DefaultTemplateEnum.POST.getValue());
model.put("groupVersionKind", POST_SCHEME.groupVersionKind());
model.put("plural", POST_SCHEME.plural());
model.put("post", postVo);
return model;
}

/**
* Build single page view model.
*
* @param pageVo page vo
* @return model map
*/
public static Map<String, Object> singlePageModel(SinglePageVo pageVo) {
Map<String, Object> model = new HashMap<>();
model.put("name", pageVo.getMetadata().getName());
model.put("groupVersionKind", SINGLE_PAGE_SCHEME.groupVersionKind());
model.put("plural", SINGLE_PAGE_SCHEME.plural());
model.put(ModelConst.TEMPLATE_ID, DefaultTemplateEnum.SINGLE_PAGE.getValue());
model.put("singlePage", pageVo);
return model;
}
}

0 comments on commit cf3331d

Please sign in to comment.