Skip to content

Commit

Permalink
pref: RSS/Atom (#1342)
Browse files Browse the repository at this point in the history
* 1.Add the lastBuildDate in RSS.
2.Add the updated in Atom.
3.Change the date format in RSS and Atom
4.Add the lastModified in the response header.

* fix code style
  • Loading branch information
lay-g authored Apr 8, 2021
1 parent 1a3254d commit 6ac9c7d
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import java.util.OptionalLong;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RegExUtils;
import org.springframework.data.domain.Page;
Expand Down Expand Up @@ -47,6 +52,8 @@ public class ContentFeedController {

private static final String XML_MEDIA_TYPE = MediaType.APPLICATION_XML_VALUE + UTF_8_SUFFIX;

private static final String LAST_MODIFIED_HEADER = "Last-Modified";

private final PostService postService;

private final CategoryService categoryService;
Expand All @@ -70,7 +77,7 @@ public ContentFeedController(PostService postService,
}

/**
* Get post rss
* Get post rss.
*
* @param model model
* @return rss xml content
Expand All @@ -79,8 +86,13 @@ public ContentFeedController(PostService postService,
*/
@GetMapping(value = {"feed", "feed.xml", "rss", "rss.xml"}, produces = XML_MEDIA_TYPE)
@ResponseBody
public String feed(Model model) throws IOException, TemplateException {
model.addAttribute("posts", buildPosts(buildPostPageable(optionService.getRssPageSize())));
public String feed(Model model, HttpServletResponse response)
throws IOException, TemplateException {
List<PostDetailVO> posts = buildPosts(buildPostPageable(optionService.getRssPageSize()));
model.addAttribute("posts", posts);
Timestamp lastModified = this.getLastModifiedTime(posts);
this.lastModified2ResponseHeader(response, lastModified);
model.addAttribute("lastModified", lastModified);
Template template = freeMarker.getConfiguration().getTemplate("common/web/rss.ftl");
return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
}
Expand All @@ -97,13 +109,18 @@ public String feed(Model model) throws IOException, TemplateException {
@GetMapping(value = {"feed/categories/{slug}",
"feed/categories/{slug}.xml"}, produces = XML_MEDIA_TYPE)
@ResponseBody
public String feed(Model model, @PathVariable(name = "slug") String slug)
public String feed(Model model, @PathVariable(name = "slug") String slug,
HttpServletResponse response)
throws IOException, TemplateException {
Category category = categoryService.getBySlugOfNonNull(slug);
CategoryDTO categoryDTO = categoryService.convertTo(category);
List<PostDetailVO> posts =
buildCategoryPosts(buildPostPageable(optionService.getRssPageSize()), categoryDTO);
model.addAttribute("category", categoryDTO);
model.addAttribute("posts",
buildCategoryPosts(buildPostPageable(optionService.getRssPageSize()), categoryDTO));
model.addAttribute("posts", posts);
Timestamp lastModified = this.getLastModifiedTime(posts);
this.lastModified2ResponseHeader(response, lastModified);
model.addAttribute("lastModified", lastModified);
Template template = freeMarker.getConfiguration().getTemplate("common/web/rss.ftl");
return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
}
Expand All @@ -118,8 +135,13 @@ public String feed(Model model, @PathVariable(name = "slug") String slug)
*/
@GetMapping(value = {"atom", "atom.xml"}, produces = XML_MEDIA_TYPE)
@ResponseBody
public String atom(Model model) throws IOException, TemplateException {
model.addAttribute("posts", buildPosts(buildPostPageable(optionService.getRssPageSize())));
public String atom(Model model, HttpServletResponse response)
throws IOException, TemplateException {
List<PostDetailVO> posts = buildPosts(buildPostPageable(optionService.getRssPageSize()));
model.addAttribute("posts", posts);
Timestamp lastModified = this.getLastModifiedTime(posts);
this.lastModified2ResponseHeader(response, lastModified);
model.addAttribute("lastModified", lastModified);
Template template = freeMarker.getConfiguration().getTemplate("common/web/atom.ftl");
return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
}
Expand All @@ -136,13 +158,18 @@ public String atom(Model model) throws IOException, TemplateException {
@GetMapping(value = {"atom/categories/{slug}",
"atom/categories/{slug}.xml"}, produces = XML_MEDIA_TYPE)
@ResponseBody
public String atom(Model model, @PathVariable(name = "slug") String slug)
public String atom(Model model, @PathVariable(name = "slug") String slug,
HttpServletResponse response)
throws IOException, TemplateException {
Category category = categoryService.getBySlugOfNonNull(slug);
CategoryDTO categoryDTO = categoryService.convertTo(category);
List<PostDetailVO> posts =
buildCategoryPosts(buildPostPageable(optionService.getRssPageSize()), categoryDTO);
model.addAttribute("category", categoryDTO);
model.addAttribute("posts",
buildCategoryPosts(buildPostPageable(optionService.getRssPageSize()), categoryDTO));
model.addAttribute("posts", posts);
Timestamp lastModified = this.getLastModifiedTime(posts);
this.lastModified2ResponseHeader(response, lastModified);
model.addAttribute("lastModified", lastModified);
Template template = freeMarker.getConfiguration().getTemplate("common/web/atom.ftl");
return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
}
Expand Down Expand Up @@ -248,4 +275,19 @@ private List<PostDetailVO> buildCategoryPosts(@NonNull Pageable pageable,
});
return posts.getContent();
}

private Timestamp getLastModifiedTime(List<PostDetailVO> posts) {
OptionalLong lastModifiedTimestamp =
posts.stream().mapToLong(post -> post.getEditTime().getTime()).max();
if (lastModifiedTimestamp.isEmpty()) {
return new Timestamp(System.currentTimeMillis());
}
return new Timestamp(lastModifiedTimestamp.getAsLong());
}

private void lastModified2ResponseHeader(HttpServletResponse response, Timestamp time) {
SimpleDateFormat dateFormat =
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
response.setHeader(LAST_MODIFIED_HEADER, dateFormat.format(time));
}
}
2 changes: 1 addition & 1 deletion src/main/resources/templates/common/web/atom.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<subtitle type="text">${user.description!}</subtitle>
</#if>
</#if>
<updated>${.now?iso_local}</updated>
<updated>${lastModified?iso_local}</updated>
<#if category??>
<id>${category.fullPath!}</id>
<#else>
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/templates/common/web/rss.ftl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<#setting locale="en_US">
<rss version="2.0">
<channel>
<#if category??>
Expand All @@ -21,6 +22,7 @@
</#if>
</#if>
<generator>Halo ${version!}</generator>
<lastBuildDate>${lastModified?string('EEE, dd MMM yyyy HH:mm:ss z')}</lastBuildDate>
<#if posts?? && posts?size gt 0>
<#list posts as post>
<item>
Expand All @@ -35,7 +37,7 @@
<![CDATA[${post.summary!}]]>
</#if>
</description>
<pubDate>${post.createTime?iso_local}</pubDate>
<pubDate>${post.createTime?string('EEE, dd MMM yyyy HH:mm:ss z')}</pubDate>
</item>
</#list>
</#if>
Expand Down

0 comments on commit 6ac9c7d

Please sign in to comment.