finished rss

This commit is contained in:
Jottyfan 2022-12-17 18:44:58 +01:00
parent be0859b93f
commit c64f1f9b5f
10 changed files with 143 additions and 49 deletions

View File

@ -18,7 +18,7 @@ apply plugin: 'war'
apply plugin: 'application'
group = 'de.jottyfan.camporganizer'
version = '0.1.8'
version = '0.1.9'
sourceCompatibility = 17
mainClassName = "de.jottyfan.camporganizer.Main"

View File

@ -0,0 +1,23 @@
package de.jottyfan.camporganizer.module.admin;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
*
* @author jotty
*
*/
@Controller
public class AdminController {
@GetMapping("/admin")
public String getMain() {
return "/admin/main";
}
@GetMapping("/admin/main")
public String getMainDirectly() {
return "redirect:/admin/main";
}
}

View File

@ -1,20 +1,11 @@
package de.jottyfan.camporganizer.module.rss;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import com.rometools.rome.feed.synd.SyndFeed;
import com.rometools.rome.io.FeedException;
import com.rometools.rome.io.SyndFeedOutput;
import org.springframework.web.bind.annotation.PathVariable;
/**
*
@ -24,32 +15,11 @@ import com.rometools.rome.io.SyndFeedOutput;
@Controller
public class RssController {
private String recipientCode;
@Autowired
private RssService service;
@GetMapping("/rss")
public String toRss(HttpServletResponse response) throws IOException, FeedException {
List<RssBean> beans = new ArrayList<>();
if (recipientCode != null) {
beans = service.getRss(recipientCode);
} else {
RssBean bean = new RssBean(null);
bean.setPubdate(LocalDateTime.now());
bean.setMessage("Dieser Feed ist nicht mehr aktuell. Bitte gib einen recipientCode an.");
beans.add(bean);
}
SyndFeed feed = new RssModel().getRss(beans);
response.reset();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/rss+xml");
response.setHeader("Content-Disposition", "attachment; filename=\"onkelwernerfreizeiten.de.xml\"");
PrintWriter writer;
writer = response.getWriter();
SyndFeedOutput output = new SyndFeedOutput();
output.output(feed, writer);
response.flushBuffer();
return "error";
@GetMapping("/rss/{recipientCode}")
public void toRssDirectly(@PathVariable String recipientCode, HttpServletResponse response) {
service.getRss(recipientCode, response);
}
}

View File

@ -10,6 +10,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jooq.DSLContext;
import org.jooq.DeleteConditionStep;
import org.jooq.Record1;
import org.jooq.Record3;
import org.jooq.Record4;
import org.jooq.SelectConditionStep;
@ -57,6 +58,12 @@ public class RssGateway {
return list;
}
public List<String> getAllFeeds() {
SelectJoinStep<Record1<String>> sql = jooq.selectDistinct(T_RSS.RECIPIENT).from(T_RSS);
LOGGER.debug(sql.toString());
return sql.fetch(T_RSS.RECIPIENT);
}
public List<RssBean> getAllRss() throws DataAccessException {
SelectJoinStep<Record4<Integer, String, String, LocalDateTime>> sql = jooq
// @formatter:off

View File

@ -1,7 +1,8 @@
package de.jottyfan.camporganizer.module.rss;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
@ -30,7 +31,8 @@ public class RssModel {
SyndEntry entry = new SyndEntryImpl();
entry.setTitle("neue Aktivität");
entry.setLink("https://www.onkelwernerfreizeiten.de/camporganizer/");
entry.setUri(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(bean.getPubdate()));
LocalDateTime pubDate = bean.getPubdate() == null ? LocalDateTime.now() : bean.getPubdate();
entry.setUri(pubDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")));
entry.setPublishedDate(Timestamp.valueOf(bean.getPubdate()));
SyndContent description = new SyndContentImpl();
description.setType("text/plain");

View File

@ -1,10 +1,20 @@
package de.jottyfan.camporganizer.module.rss;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.rometools.rome.feed.synd.SyndFeed;
import com.rometools.rome.io.SyndFeedOutput;
/**
*
* @author jotty
@ -12,16 +22,40 @@ import org.springframework.stereotype.Service;
*/
@Service
public class RssService {
private static final Logger LOGGER = LogManager.getLogger(RssService.class);
@Autowired
private RssGateway repository;
/**
* get the recipient's rss feed
*
* @param recipientCode the code for the feed
* @param response the http servlet response
* @return the list of rss beans; an empty list at least
*/
public List<RssBean> getRss(String recipientCode) {
return repository.getRss(recipientCode);
public void getRss(String recipientCode, HttpServletResponse response) {
List<RssBean> beans = new ArrayList<>();
if (recipientCode != null) {
beans = repository.getRss(recipientCode);
} else {
RssBean bean = new RssBean(null);
bean.setPubdate(LocalDateTime.now());
bean.setMessage("Dieser Feed ist nicht mehr aktuell. Bitte gib einen recipientCode an.");
beans.add(bean);
}
SyndFeed feed = new RssModel().getRss(beans);
response.reset();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/rss+xml");
response.setHeader("Content-Disposition", "attachment; filename=\"onkelwernerfreizeiten.de.xml\"");
try {
PrintWriter writer = response.getWriter();
new SyndFeedOutput().output(feed, writer);
writer.flush();
response.flushBuffer();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
}

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{template}" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<title>Camp Organizer Confirmation</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<th:block layout:fragment="header">
<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')">
<li class="nav-item"><a th:href="@{/rss/admin}" class="btn btn-seconary btn-icon-silent"><i class="fas fa-rss"></i></a></li>
</ul>
<ul class="navbar-nav mb-2 mb-lg-0">
<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li>
</ul>
</th:block>
<th:block layout:fragment="content">
<div sec:authorize="hasRole('admin')">
TODO: implement
</div>
</th:block>
</body>
</html>

View File

@ -6,6 +6,9 @@
</head>
<body>
<th:block layout:fragment="header">
<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('registrator')">
<li class="nav-item"><a th:href="@{/rss/registrator}" class="btn btn-seconary btn-icon-silent"><i class="fas fa-rss"></i></a></li>
</ul>
<ul class="navbar-nav mb-2 mb-lg-0">
<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li>
</ul>

View File

@ -15,6 +15,9 @@
<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('registrator')">
<li class="nav-item"><a th:href="@{/confirmation}" class="btn btn-secondary btn-icon-silent">Bestätigung</a></li>
</ul>
<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')">
<li class="nav-item"><a th:href="@{/admin}" class="btn btn-secondary btn-icon-silent">Administration</a></li>
</ul>
<ul class="navbar-nav mb-2 mb-lg-0">
<li class="nav-item"><a href="https://www.onkelwernerfreizeiten.de/cloud" class="btn btn-secondary btn-icon-silent" target="_blank">Nextcloud</a></li>
</ul>

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{template}" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<title>Camp Organizer 2</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<th:block layout:fragment="header">
<ul class="navbar-nav mb-2 mb-lg-0">
<li class="nav-item"><a th:href="@{${keycloakProfileUrl}}" class="btn btn-secondary btn-icon-silent" target="_blank">Profil</a></li>
</ul>
<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('business')">
<li class="nav-item"><a th:href="@{/business}" class="btn btn-secondary btn-icon-silent">Abrechnung</a></li>
</ul>
<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('registrator')">
<li class="nav-item"><a th:href="@{/confirmation}" class="btn btn-secondary btn-icon-silent">Bestätigung</a></li>
</ul>
<ul class="navbar-nav mb-2 mb-lg-0">
<li class="nav-item"><a href="https://www.onkelwernerfreizeiten.de/cloud" class="btn btn-secondary btn-icon-silent" target="_blank">Nextcloud</a></li>
</ul>
</th:block>
<th:block layout:fragment="content">
<div class="mainpage">
<div th:each="f : ${feeds}">
<span th:text="${f}"></span>
</div>
</div>
</th:block>
</body>
</html>