From 500ec2b9ad9c0008d79ca2805eac2374fec96638 Mon Sep 17 00:00:00 2001 From: Jottyfan Date: Sun, 23 Oct 2022 20:04:04 +0200 Subject: [PATCH] https://gitlab.com/jottyfan/camporganizer2/-/issues/16 --- .classpath | 7 ++ .settings/org.eclipse.buildship.core.prefs | 11 --- .settings/org.eclipse.wst.common.component | 20 +++-- build.gradle | 4 +- .../module/ical/ICalController.java | 31 ++++++++ .../module/ical/IICalService.java | 23 ++++++ .../module/ical/impl/ICalGateway.java | 76 +++++++++++++++++++ .../module/ical/impl/ICalService.java | 41 ++++++++++ src/main/resources/templates/index.html | 6 +- 9 files changed, 197 insertions(+), 22 deletions(-) create mode 100644 src/main/java/de/jottyfan/camporganizer/module/ical/ICalController.java create mode 100644 src/main/java/de/jottyfan/camporganizer/module/ical/IICalService.java create mode 100644 src/main/java/de/jottyfan/camporganizer/module/ical/impl/ICalGateway.java create mode 100644 src/main/java/de/jottyfan/camporganizer/module/ical/impl/ICalService.java diff --git a/.classpath b/.classpath index f3bdce0..607b789 100644 --- a/.classpath +++ b/.classpath @@ -12,6 +12,13 @@ + + + + + + + diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs index e479558..e889521 100644 --- a/.settings/org.eclipse.buildship.core.prefs +++ b/.settings/org.eclipse.buildship.core.prefs @@ -1,13 +1,2 @@ -arguments= -auto.sync=false -build.scans.enabled=false -connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) connection.project.dir= eclipse.preferences.version=1 -gradle.user.home= -java.home= -jvm.arguments= -offline.mode=false -override.workspace.settings=false -show.console.view=false -show.executions.view=false diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index a2ed0c0..31a62d0 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,8 +1,14 @@ - - - - - - - + + + + + + + + + + + + + diff --git a/build.gradle b/build.gradle index 0331654..fcfefb2 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ apply plugin: 'war' apply plugin: 'application' group = 'de.jottyfan.camporganizer' -version = '0.0.9' +version = '0.1.0' sourceCompatibility = 17 mainClassName = "de.jottyfan.camporganizer.Main" @@ -51,6 +51,8 @@ dependencies { implementation 'org.webjars:datatables:1.11.4' implementation 'org.webjars:select2:4.0.13' + implementation 'net.sf.biweekly:biweekly:0.6.6' + implementation 'org.keycloak:keycloak-spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-jooq' diff --git a/src/main/java/de/jottyfan/camporganizer/module/ical/ICalController.java b/src/main/java/de/jottyfan/camporganizer/module/ical/ICalController.java new file mode 100644 index 0000000..8db418f --- /dev/null +++ b/src/main/java/de/jottyfan/camporganizer/module/ical/ICalController.java @@ -0,0 +1,31 @@ +package de.jottyfan.camporganizer.module.ical; + +import java.io.IOException; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +/** + * + * @author jotty + * + */ +@Controller +public class ICalController { + + @Autowired + private IICalService service; + + /** + * generate the ical response stream + * + * @throws IOException on io errors + */ + @GetMapping("/ical") + public void generate(HttpServletResponse response) throws IOException { + service.generate(response); + } +} diff --git a/src/main/java/de/jottyfan/camporganizer/module/ical/IICalService.java b/src/main/java/de/jottyfan/camporganizer/module/ical/IICalService.java new file mode 100644 index 0000000..6262941 --- /dev/null +++ b/src/main/java/de/jottyfan/camporganizer/module/ical/IICalService.java @@ -0,0 +1,23 @@ +package de.jottyfan.camporganizer.module.ical; + +import java.io.IOException; + +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author jotty + * + */ +public interface IICalService { + + /** + * generate the ical + * + * @param response the response for the output stream + * + * @return true if successful, false otherwise + * @throws IOException on io errors + */ + public Boolean generate(HttpServletResponse response) throws IOException; +} diff --git a/src/main/java/de/jottyfan/camporganizer/module/ical/impl/ICalGateway.java b/src/main/java/de/jottyfan/camporganizer/module/ical/impl/ICalGateway.java new file mode 100644 index 0000000..ed45fdb --- /dev/null +++ b/src/main/java/de/jottyfan/camporganizer/module/ical/impl/ICalGateway.java @@ -0,0 +1,76 @@ +package de.jottyfan.camporganizer.module.ical.impl; + +import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMP; +import static de.jottyfan.camporganizer.db.jooq.Tables.T_LOCATION; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.TimeZone; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jooq.DSLContext; +import org.jooq.Record5; +import org.jooq.SelectOnConditionStep; +import org.jooq.exception.DataAccessException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import biweekly.ICalendar; +import biweekly.component.VEvent; +import biweekly.io.TimezoneAssignment; +import biweekly.property.Summary; + +/** +* +* @author jotty +* +*/ +@Repository +@Transactional(transactionManager = "transactionManager") +public class ICalGateway { + private static final Logger LOGGER = LogManager.getLogger(ICalGateway.class); + + @Autowired + private DSLContext jooq; + + /** + * load all camp dates from db and generate an ical from it + * + * @return ical containing all (at least none) of the camp dates + * @throws DataAccessException + */ + public ICalendar getIcal() throws DataAccessException { + SelectOnConditionStep> sql = jooq + // @formatter:off + .select(T_CAMP.NAME, + T_CAMP.ARRIVE, + T_CAMP.DEPART, + T_LOCATION.NAME, + T_LOCATION.URL) + .from(T_CAMP) + .leftJoin(T_LOCATION).on(T_LOCATION.PK.eq(T_CAMP.FK_LOCATION)); + // @formatter:on + LOGGER.debug(sql.toString()); + ICalendar ical = new ICalendar(); + ical.getTimezoneInfo().setDefaultTimezone(TimezoneAssignment.download(TimeZone.getTimeZone("Europe/Berlin"), false)); + for (Record5 r : sql.fetch()) { + VEvent event = new VEvent(); + Summary summary = event.setSummary(r.get(T_CAMP.NAME)); + summary.setLanguage("de"); + LocalDateTime startDate = r.get(T_CAMP.ARRIVE); + LocalDateTime endDate = r.get(T_CAMP.DEPART); + // because of the specification, end dates are exclusive - and without time, the day won't be counted + endDate = endDate.plusDays(1l); + event.setLocation(r.get(T_LOCATION.NAME)); + event.setDateStart(startDate == null ? null : Date.from(startDate.atZone(ZoneId.of("Europe/Berlin")).toInstant()), false); + event.setDateEnd(endDate == null ? null : Date.from(endDate.atZone(ZoneId.of("Europe/Berlin")).toInstant()), false); + event.setUrl(r.get(T_LOCATION.URL)); + event.setDescription("zur Anmeldung: http://anmeldung.onkelwernerfreizeiten.de"); + ical.addEvent(event); + } + return ical; + } +} diff --git a/src/main/java/de/jottyfan/camporganizer/module/ical/impl/ICalService.java b/src/main/java/de/jottyfan/camporganizer/module/ical/impl/ICalService.java new file mode 100644 index 0000000..ad0d7a4 --- /dev/null +++ b/src/main/java/de/jottyfan/camporganizer/module/ical/impl/ICalService.java @@ -0,0 +1,41 @@ +package de.jottyfan.camporganizer.module.ical.impl; + +import java.io.IOException; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import biweekly.Biweekly; +import biweekly.ICalendar; +import de.jottyfan.camporganizer.module.ical.IICalService; + +/** + * + * @author jotty + * + */ +@Service +public class ICalService implements IICalService { + + @Autowired + private ICalGateway gateway; + + @Override + public Boolean generate(HttpServletResponse response) throws IOException { + ICalendar ical = gateway.getIcal(); + String content = Biweekly.write(ical).go(); + + response.setHeader("charset", "UTF-8"); + response.setHeader("Content-Type", "text/calendar"); + response.setHeader("Content-Disposition", "attachment; filename=\"onkelwernerfreizeiten.de.ics\""); + + response.getWriter().write(content); + response.getWriter().flush(); + response.flushBuffer(); + + return true; + } + +} diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html index 18a3032..acda33b 100644 --- a/src/main/resources/templates/index.html +++ b/src/main/resources/templates/index.html @@ -7,15 +7,15 @@
- - Das Buchungsportal des Onkel Werner Freizeiten e.V. + + Unsere Freizeiten
-

Unsere Freizeiten