export txt, ics
This commit is contained in:
7
pom.xml
7
pom.xml
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.mbremer</groupId>
|
||||
<artifactId>buerokalender</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<version>1.1.0</version>
|
||||
<properties>
|
||||
<compiler-plugin.version>3.8.1</compiler-plugin.version>
|
||||
<maven.compiler.parameters>true</maven.compiler.parameters>
|
||||
@@ -103,6 +103,11 @@
|
||||
<artifactId>bootstrap-icons</artifactId>
|
||||
<version>1.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.webjars</groupId>
|
||||
<artifactId>popper.js</artifactId>
|
||||
<version>2.9.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
|
||||
@@ -20,4 +20,8 @@ public class CommonExtensions {
|
||||
public static int plus(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
public static String rightPad(String str, int length) {
|
||||
return String.format("%1$-" + length + "s", str);
|
||||
}
|
||||
}
|
||||
|
||||
35
src/main/java/de/mbremer/kalender/Event.java
Normal file
35
src/main/java/de/mbremer/kalender/Event.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package de.mbremer.kalender;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
public class Event {
|
||||
private final String created;
|
||||
private final String dtStart;
|
||||
private final String dtEnd;
|
||||
private final String uid;
|
||||
|
||||
public Event(@NotNull LocalDateTime created, LocalDate date) {
|
||||
this.created = created.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
|
||||
.replaceAll("[-:]", "") + "Z";
|
||||
this.dtStart = date.format(DateTimeFormatter.ISO_LOCAL_DATE)
|
||||
.replace("-", "");
|
||||
this.dtEnd = date.plusDays(1).format(DateTimeFormatter.ISO_LOCAL_DATE)
|
||||
.replace("-", "");
|
||||
this.uid = UUID.randomUUID().toString() + "@buerokalender";
|
||||
}
|
||||
|
||||
public String getLastModified() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public String getDtStamp() {
|
||||
return created;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package de.mbremer.kalender;
|
||||
|
||||
import de.mbremer.secutity.User;
|
||||
import io.quarkus.qute.Location;
|
||||
import io.quarkus.qute.Template;
|
||||
import io.quarkus.qute.TemplateInstance;
|
||||
import io.quarkus.security.identity.SecurityIdentity;
|
||||
@@ -14,6 +15,7 @@ import javax.transaction.Transactional;
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -28,35 +30,32 @@ public class KalenderResource {
|
||||
SecurityIdentity identity;
|
||||
@Inject
|
||||
Template kalenderpage;
|
||||
@Inject
|
||||
@Location("export/textExport.txt")
|
||||
Template textExport;
|
||||
@Location("export/icsExport.ics")
|
||||
Template icsExport;
|
||||
|
||||
@Path("")
|
||||
@GET
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
public TemplateInstance kalender() {
|
||||
return kalenderWithOffset(0);
|
||||
}
|
||||
|
||||
@Path("offset/{weeks}")
|
||||
@GET
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
public TemplateInstance kalenderWithOffset(@PathParam("weeks") int offsetInWeeks) {
|
||||
User currentUser = User.find("username", identity.getPrincipal().getName()).singleResult();
|
||||
LocalDate today = LocalDate.now();
|
||||
|
||||
LocalDate montag = today.minusDays(today.getDayOfWeek().getValue() - 1).plusDays(7 * offsetInWeeks);
|
||||
|
||||
List<KalenderTag> week = getWeek(currentUser, montag);
|
||||
public TemplateInstance kalender(@QueryParam("offset") @DefaultValue("0") int offsetInWeeks) {
|
||||
List<KalenderTag> week = getWeek(offsetInWeeks);
|
||||
|
||||
return kalenderpage
|
||||
.data("today", today)
|
||||
.data("today", LocalDate.now())
|
||||
.data("offset", offsetInWeeks)
|
||||
.data("week", week);
|
||||
}
|
||||
|
||||
private List<KalenderTag> getWeek(User currentUser, LocalDate start) {
|
||||
private List<KalenderTag> getWeek(int offsetInWeeks) {
|
||||
User currentUser = getCurrentUser();
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDate montag = today.minusDays(today.getDayOfWeek().getValue() - 1).plusDays(7 * offsetInWeeks);
|
||||
|
||||
return Stream.iterate(0, i -> i < 5, i -> ++i)
|
||||
.map(d -> {
|
||||
LocalDate day = start.plusDays(d);
|
||||
LocalDate day = montag.plusDays(d);
|
||||
KalenderTag tag = (KalenderTag) KalenderTag.find("day", day).singleResultOptional().orElse(new KalenderTag(day));
|
||||
tag.setCurrentUserInOffice(currentUser.equals(tag.getInOffice()));
|
||||
tag.setToday(LocalDate.now().equals(day));
|
||||
@@ -65,6 +64,14 @@ public class KalenderResource {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<Event> getEvents(int offsetInWeeks) {
|
||||
List<KalenderTag> week = getWeek(offsetInWeeks);
|
||||
return week.stream()
|
||||
.filter(d -> d.isCurrentUserInOffice())
|
||||
.map(d-> new Event(LocalDateTime.now(), d.getDay()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@POST
|
||||
@Transactional
|
||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||
@@ -73,7 +80,7 @@ public class KalenderResource {
|
||||
@QueryParam("offset") int offsetInWeeks, @MultipartForm KalenderTagForm kalenderForm) {
|
||||
LocalDate dayParsed = LocalDate.parse(day);
|
||||
|
||||
User currentUser = User.find("username", identity.getPrincipal().getName()).singleResult();
|
||||
User currentUser = getCurrentUser();
|
||||
try {
|
||||
KalenderTag tag = KalenderTag.find("day", dayParsed).singleResult();
|
||||
if (kalenderForm.isInOffice() && tag.getInOffice() == null) {
|
||||
@@ -87,6 +94,24 @@ public class KalenderResource {
|
||||
tag.persist();
|
||||
}
|
||||
|
||||
return kalenderWithOffset(offsetInWeeks);
|
||||
return kalender(offsetInWeeks);
|
||||
}
|
||||
|
||||
private User getCurrentUser() {
|
||||
return User.find("username", identity.getPrincipal().getName()).singleResult();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.TEXT_PLAIN)
|
||||
@Path("export/txt")
|
||||
public TemplateInstance exportTxt(@QueryParam("offset") int offset) {
|
||||
return textExport.data("week", getWeek(offset));
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces("text/calendar")
|
||||
@Path("export/ics")
|
||||
public TemplateInstance exportIcs(@QueryParam("offset") int offset) {
|
||||
return icsExport.data("events", getEvents(offset));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
{#if info}<div class="alert alert-primary" role="alert">{info}</div>{/if}
|
||||
{#insert contents}No contents!{/}
|
||||
</div>
|
||||
<script src="/webjars/popper.js/2.9.2/umd/popper.min.js"></script>
|
||||
<script src="/webjars/bootstrap/5.0.0/js/bootstrap.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
19
src/main/resources/templates/export/icsExport.ics
Normal file
19
src/main/resources/templates/export/icsExport.ics
Normal file
@@ -0,0 +1,19 @@
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
METHOD:PUBLISH
|
||||
PRODID:-//kalender.bremer.rocks//iCal Generator//DE
|
||||
{#for event in events}
|
||||
BEGIN:VEVENT
|
||||
CREATED:{event.created}
|
||||
LAST-MODIFIED:{event.lastModified}
|
||||
DTSTAMP:{event.dtStamp}
|
||||
SUMMARY:VIT
|
||||
DTSTART;VALUE=DATE:{event.dtStart}
|
||||
DTEND;VALUE=DATE:{event.dtEnd}
|
||||
URL:https://kalender.bremer.rocks
|
||||
DESCRIPTION:Arbeit im VIT-Buero
|
||||
TRANSP:TRANSPARENT
|
||||
UID:{event.uid}
|
||||
END:VEVENT
|
||||
{/for}
|
||||
END:VCALENDAR
|
||||
3
src/main/resources/templates/export/textExport.txt
Normal file
3
src/main/resources/templates/export/textExport.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
{#for day in week}
|
||||
{day.day.formatCommon.rightPad(30)} {#if day.inOffice}{day.inOffice.username}{/if}
|
||||
{/for}
|
||||
@@ -6,17 +6,17 @@
|
||||
Heute ist {today.formatCommon}
|
||||
</div>
|
||||
|
||||
<div class="mt-2">
|
||||
<div class="mt-3">
|
||||
<nav aria-label="Page navigation example">
|
||||
<ul class="pagination">
|
||||
<li class="page-item"><a class="page-link" href="/kalender">aktuelle Woche</a></li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="/kalender/offset/{offset.minus(1)}" aria-label="Previous">
|
||||
<a class="page-link" href="/kalender?offset={offset.minus(1)}" aria-label="Previous">
|
||||
<span aria-hidden="true">«</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="/kalender/offset/{offset.plus(1)}" aria-label="Next">
|
||||
<a class="page-link" href="/kalender?offset={offset.plus(1)}" aria-label="Next">
|
||||
<span aria-hidden="true">»</span>
|
||||
</a>
|
||||
</li>
|
||||
@@ -24,7 +24,7 @@
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="mt-2">
|
||||
<div>
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -57,5 +57,17 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="mt-2">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
||||
Export
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="dropdown-item" href="/kalender/export/txt?offset={offset}" target="_blank">txt für alle</a></li>
|
||||
<li><a class="dropdown-item" href="/kalender/export/ics?offset={offset}">ics für mich</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/contents}
|
||||
{/include}
|
||||
@@ -12,4 +12,9 @@ class CommonExtensionsTest {
|
||||
void testFormatCommon() {
|
||||
assertEquals("Sonntag, 4.7.2021", CommonExtensions.formatCommon(LocalDate.of(2021, 7, 4)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRightPad() {
|
||||
assertEquals("foo ", CommonExtensions.rightPad("foo", 5));
|
||||
}
|
||||
}
|
||||
34
src/test/java/de/mbremer/kalender/EventTest.java
Normal file
34
src/test/java/de/mbremer/kalender/EventTest.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package de.mbremer.kalender;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class EventTest {
|
||||
@Test
|
||||
void getCreated() {
|
||||
Event event = new Event(LocalDateTime.of(2021, 7, 18, 14, 25, 45), LocalDate.of(2022, 1, 2));
|
||||
|
||||
assertEquals("20210718T142545Z", event.getCreated());
|
||||
assertEquals("20210718T142545Z", event.getLastModified());
|
||||
assertEquals("20210718T142545Z", event.getDtStamp());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getDtstartEnd() {
|
||||
Event event = new Event(LocalDateTime.of(2021, 7, 18, 14, 25, 45), LocalDate.of(2022, 1, 2));
|
||||
|
||||
assertEquals("20220102", event.getDtStart());
|
||||
assertEquals("20220103", event.getDtEnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getUid() {
|
||||
Event event = new Event(LocalDateTime.of(2021, 7, 18, 14, 25, 45), LocalDate.of(2022, 1, 2));
|
||||
|
||||
assertTrue(event.getUid().matches("([a-f0-9]{8}(-[a-f0-9]{4}){4}[a-f0-9]{8})@buerokalender"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user