added importer for CafeWagner
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -214,6 +214,7 @@ public class AutoImporter implements Runnable, ClassListener {
|
|||||||
LOG.log(WARNING, "{0}.fetch() failed", importer, e);
|
LOG.log(WARNING, "{0}.fetch() failed", importer, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LOG.log(INFO,"Finished appointment updates.");
|
||||||
lastImport = LocalDateTime.now();
|
lastImport = LocalDateTime.now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,14 @@
|
|||||||
package de.srsoftware.cal;
|
package de.srsoftware.cal;
|
||||||
|
|
||||||
import static de.srsoftware.cal.Util.combine;
|
import static de.srsoftware.cal.Util.combine;
|
||||||
|
import static de.srsoftware.cal.Util.url;
|
||||||
import static de.srsoftware.tools.Error.error;
|
import static de.srsoftware.tools.Error.error;
|
||||||
import static de.srsoftware.tools.Result.transform;
|
import static de.srsoftware.tools.Result.transform;
|
||||||
import static de.srsoftware.tools.Tag.HREF;
|
import static de.srsoftware.tools.Tag.HREF;
|
||||||
import static de.srsoftware.tools.TagFilter.*;
|
import static de.srsoftware.tools.TagFilter.*;
|
||||||
import static java.lang.System.Logger.Level.WARNING;
|
|
||||||
|
|
||||||
import de.srsoftware.cal.api.*;
|
import de.srsoftware.cal.api.*;
|
||||||
import de.srsoftware.tools.*;
|
import de.srsoftware.tools.*;
|
||||||
import de.srsoftware.tools.Error;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
@@ -26,7 +25,6 @@ import java.util.function.Predicate;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public abstract class BaseImporter implements Importer {
|
public abstract class BaseImporter implements Importer {
|
||||||
private static final System.Logger LOG = System.getLogger(BaseImporter.class.getSimpleName());
|
|
||||||
private static final String SHA256 = "SHA-256";
|
private static final String SHA256 = "SHA-256";
|
||||||
private final MessageDigest digest;
|
private final MessageDigest digest;
|
||||||
|
|
||||||
@@ -48,8 +46,8 @@ public abstract class BaseImporter implements Importer {
|
|||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(url -> url.contains("://") ? url : baseUrl()+url)
|
.map(url -> url.contains("://") ? url : baseUrl()+url)
|
||||||
.map(Payload::of)
|
.map(Payload::of)
|
||||||
.map(BaseImporter::url)
|
.map(Util::url)
|
||||||
.map(BaseImporter::toAttachment)
|
.map(Util::toAttachment)
|
||||||
.map(Result::optional)
|
.map(Result::optional)
|
||||||
.flatMap(Optional::stream)
|
.flatMap(Optional::stream)
|
||||||
.toList();
|
.toList();
|
||||||
@@ -190,7 +188,7 @@ public abstract class BaseImporter implements Importer {
|
|||||||
if (href == null) return null;
|
if (href == null) return null;
|
||||||
if (!href.contains("://")) href = baseUrl()+href;
|
if (!href.contains("://")) href = baseUrl()+href;
|
||||||
var txt = anchor.strip();
|
var txt = anchor.strip();
|
||||||
return BaseImporter.url(Payload.of(href)).optional().map(url -> new Link(url,txt)).orElse(null);
|
return url(Payload.of(href)).optional().map(url -> new Link(url,txt)).orElse(null);
|
||||||
})
|
})
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.toList();
|
.toList();
|
||||||
@@ -262,7 +260,7 @@ public abstract class BaseImporter implements Importer {
|
|||||||
Result<Tag> titleTag = extractTitleTag(eventTag);
|
Result<Tag> titleTag = extractTitleTag(eventTag);
|
||||||
if (titleTag.optional().isEmpty()) return transform(titleTag);
|
if (titleTag.optional().isEmpty()) return transform(titleTag);
|
||||||
var inner = titleTag.optional().flatMap(tag -> tag.inner(2));
|
var inner = titleTag.optional().flatMap(tag -> tag.inner(2));
|
||||||
return inner.isPresent() ? Payload.of(inner.get()) : error("No title found");
|
return inner.isPresent() ? Payload.of(inner.get().trim()) : error("No title found");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Result<Tag> extractTitleTag(Tag eventTag){
|
protected Result<Tag> extractTitleTag(Tag eventTag){
|
||||||
@@ -283,11 +281,8 @@ public abstract class BaseImporter implements Importer {
|
|||||||
.map(this::extractEventUrls)
|
.map(this::extractEventUrls)
|
||||||
.stream();
|
.stream();
|
||||||
return urls //
|
return urls //
|
||||||
.map(BaseImporter::url)
|
.map(Util::url)
|
||||||
.map(this::loadEvent)
|
.map(this::loadEvent)
|
||||||
.peek(e -> {
|
|
||||||
if (e instanceof Error<Appointment> err) System.err.println(err);
|
|
||||||
})
|
|
||||||
.flatMap(result -> result.optional().stream());
|
.flatMap(result -> result.optional().stream());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,42 +346,4 @@ public abstract class BaseImporter implements Importer {
|
|||||||
|
|
||||||
protected abstract String programURL();
|
protected abstract String programURL();
|
||||||
|
|
||||||
protected static Result<Attachment> toAttachment(Result<URL> urlResult) {
|
|
||||||
var opt = urlResult.optional();
|
|
||||||
if (opt.isEmpty()) return transform(urlResult);
|
|
||||||
try {
|
|
||||||
var mime = opt.get().openConnection().getContentType();
|
|
||||||
return Payload.of(new Attachment(opt.get(), mime));
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOG.log(WARNING, "Failed to read mime type of {0}", opt.get());
|
|
||||||
return error("Failed to read mime type of %s", opt.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static Result<Integer> toNumericMonth(String month) {
|
|
||||||
month = month.toLowerCase();
|
|
||||||
if (month.startsWith("ja")) return Payload.of(1);
|
|
||||||
if (month.startsWith("f")) return Payload.of(2);
|
|
||||||
if ("may".equals(month) || "mai".equals(month)) return Payload.of(5);
|
|
||||||
if (month.startsWith("m")) return Payload.of(3);
|
|
||||||
if (month.startsWith("ap")) return Payload.of(4);
|
|
||||||
if (month.startsWith("jun")) return Payload.of(6);
|
|
||||||
if (month.startsWith("jul")) return Payload.of(7);
|
|
||||||
if (month.startsWith("au")) return Payload.of(8);
|
|
||||||
if (month.startsWith("s")) return Payload.of(9);
|
|
||||||
if (month.startsWith("o")) return Payload.of(10);
|
|
||||||
if (month.startsWith("n")) return Payload.of(11);
|
|
||||||
if (month.startsWith("d")) return Payload.of(12);
|
|
||||||
return error("Failed to recognize \"%s\" as a month!", month);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static Result<URL> url(Result<String> urlResult) {
|
|
||||||
if (urlResult.optional().isEmpty()) return transform(urlResult);
|
|
||||||
var url = urlResult.optional().get();
|
|
||||||
try {
|
|
||||||
return Payload.of(new URI(url).toURL());
|
|
||||||
} catch (MalformedURLException | URISyntaxException e) {
|
|
||||||
return error(e, "Failed to create URL of %s", url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,18 @@ package de.srsoftware.cal;
|
|||||||
|
|
||||||
import static de.srsoftware.tools.Error.error;
|
import static de.srsoftware.tools.Error.error;
|
||||||
import static de.srsoftware.tools.Result.transform;
|
import static de.srsoftware.tools.Result.transform;
|
||||||
|
import static de.srsoftware.tools.Tag.STYLE;
|
||||||
|
import static java.lang.System.Logger.Level.WARNING;
|
||||||
|
|
||||||
|
import de.srsoftware.cal.api.Attachment;
|
||||||
import de.srsoftware.cal.api.Coords;
|
import de.srsoftware.cal.api.Coords;
|
||||||
import de.srsoftware.tools.Payload;
|
import de.srsoftware.tools.Payload;
|
||||||
import de.srsoftware.tools.Result;
|
import de.srsoftware.tools.Result;
|
||||||
|
import de.srsoftware.tools.Tag;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
@@ -33,6 +41,8 @@ public class Util {
|
|||||||
|
|
||||||
public static final Pattern GERMAN_DATE_PATTERN = Pattern.compile("\\D(\\d\\d?)\\.(\\d\\d?)\\.(\\d{4})\\D");
|
public static final Pattern GERMAN_DATE_PATTERN = Pattern.compile("\\D(\\d\\d?)\\.(\\d\\d?)\\.(\\d{4})\\D");
|
||||||
public static final Pattern GERMAN_TIME_PATTERN = Pattern.compile("\\D(\\d\\d?):(\\d\\d?)(:(\\d\\d?))?\\D");
|
public static final Pattern GERMAN_TIME_PATTERN = Pattern.compile("\\D(\\d\\d?):(\\d\\d?)(:(\\d\\d?))?\\D");
|
||||||
|
private static final Pattern BG_IMAGE_URL = Pattern.compile("background(-image)?:\\surl\\(([^)]+)\\)");
|
||||||
|
private static final System.Logger LOG = System.getLogger(Util.class.getSimpleName());
|
||||||
|
|
||||||
private Util(){}
|
private Util(){}
|
||||||
|
|
||||||
@@ -114,6 +124,24 @@ public class Util {
|
|||||||
return error("Failed to find time");
|
return error("Failed to find time");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Result<Integer> toNumericMonth(String month) {
|
||||||
|
month = month.toLowerCase();
|
||||||
|
if (month.startsWith("ja")) return Payload.of(1);
|
||||||
|
if (month.startsWith("f")) return Payload.of(2);
|
||||||
|
if ("may".equals(month) || "mai".equals(month)) return Payload.of(5);
|
||||||
|
if (month.startsWith("m")) return Payload.of(3);
|
||||||
|
if (month.startsWith("ap")) return Payload.of(4);
|
||||||
|
if (month.startsWith("jun")) return Payload.of(6);
|
||||||
|
if (month.startsWith("jul")) return Payload.of(7);
|
||||||
|
if (month.startsWith("au")) return Payload.of(8);
|
||||||
|
if (month.startsWith("s")) return Payload.of(9);
|
||||||
|
if (month.startsWith("o")) return Payload.of(10);
|
||||||
|
if (month.startsWith("n")) return Payload.of(11);
|
||||||
|
if (month.startsWith("d")) return Payload.of(12);
|
||||||
|
return error("Failed to recognize \"%s\" as a month!", month);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wraps a text (list of vevents in a vcalendar, as described in th <a href="https://datatracker.ietf.org/doc/html/rfc5545#section-3.4">iCalendar spec</a>
|
* wraps a text (list of vevents in a vcalendar, as described in th <a href="https://datatracker.ietf.org/doc/html/rfc5545#section-3.4">iCalendar spec</a>
|
||||||
* @param ical the vevents list
|
* @param ical the vevents list
|
||||||
@@ -132,4 +160,38 @@ public class Util {
|
|||||||
}
|
}
|
||||||
return ical;
|
return ical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Result<String> extractBackgroundImage(Tag tag, String baseUrl) {
|
||||||
|
var style = tag.get(STYLE);
|
||||||
|
if (style != null){
|
||||||
|
var matcher = BG_IMAGE_URL.matcher(style);
|
||||||
|
if (matcher.find()) {
|
||||||
|
var link = matcher.group(2);
|
||||||
|
return Payload.of(link.contains("://") ? link : baseUrl+link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error("Failed to findbackground image url in %s",tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result<Attachment> toAttachment(Result<URL> urlResult) {
|
||||||
|
var opt = urlResult.optional();
|
||||||
|
if (opt.isEmpty()) return transform(urlResult);
|
||||||
|
try {
|
||||||
|
var mime = opt.get().openConnection().getContentType();
|
||||||
|
return Payload.of(new Attachment(opt.get(), mime));
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.log(WARNING, "Failed to read mime type of {0}", opt.get());
|
||||||
|
return error("Failed to read mime type of %s", opt.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result<URL> url(Result<String> urlResult) {
|
||||||
|
if (urlResult.optional().isEmpty()) return transform(urlResult);
|
||||||
|
var url = urlResult.optional().get();
|
||||||
|
try {
|
||||||
|
return Payload.of(new URI(url).toURL());
|
||||||
|
} catch (MalformedURLException | URISyntaxException e) {
|
||||||
|
return error(e, "Failed to create URL of %s", url);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,197 @@
|
|||||||
|
/* © SRSoftware 2024 */
|
||||||
|
package de.srsoftware.cal.importer.jena;
|
||||||
|
|
||||||
|
import static de.srsoftware.cal.Util.extractBackgroundImage;
|
||||||
|
import static de.srsoftware.cal.Util.toNumericMonth;
|
||||||
|
import static de.srsoftware.tools.Error.error;
|
||||||
|
import static de.srsoftware.tools.Optionals.emptyIfNull;
|
||||||
|
import static de.srsoftware.tools.Result.transform;
|
||||||
|
import static de.srsoftware.tools.Tag.*;
|
||||||
|
import static de.srsoftware.tools.TagFilter.*;
|
||||||
|
|
||||||
|
import de.srsoftware.cal.BaseImporter;
|
||||||
|
import de.srsoftware.cal.Util;
|
||||||
|
import de.srsoftware.cal.api.Attachment;
|
||||||
|
import de.srsoftware.cal.api.Coords;
|
||||||
|
import de.srsoftware.tools.*;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class CafeWagner extends BaseImporter {
|
||||||
|
private static final Pattern DATE_FORMAT = Pattern.compile("(\\d\\d?)\\.\\s+(\\w+)\\s+(\\d{4})");
|
||||||
|
private static final String LOCATION_MVZ = "MVZ_Wagner, Kochstraße 2a, 07745 Jena";
|
||||||
|
private static final String DEFAULT_LOCATION = "Café Wagner, Wagnergasse 26, 07743 Jena";
|
||||||
|
private static final Coords MVZ_COORDS = new Coords(50.92532, 11.57909);
|
||||||
|
private static final Coords DEFAULT_COORDS = new Coords(50.93121, 11.58023);
|
||||||
|
|
||||||
|
public CafeWagner() throws NoSuchAlgorithmException {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String baseUrl() {
|
||||||
|
return "https://www.cafewagner.de";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String description() {
|
||||||
|
return "Importiert Events des Café Wagner in Jena";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Attachment> extractAttachments(Tag eventTag) {
|
||||||
|
var combined = new HashSet<>(super.extractAttachments(eventTag));
|
||||||
|
eventTag.find(attributeHas(CLASS,"image")).stream()
|
||||||
|
.map(tag -> extractBackgroundImage(tag,baseUrl()))
|
||||||
|
.map(Util::url)
|
||||||
|
.map(Util::toAttachment)
|
||||||
|
.map(Result::optional)
|
||||||
|
.flatMap(Optional::stream)
|
||||||
|
.forEach(combined::add);
|
||||||
|
return List.copyOf(combined);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<Tag> extractAttachmentsFilter() {
|
||||||
|
return ofType("main");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<Tag> extractDescriptionFilter() {
|
||||||
|
return attributeHas(CLASS,"text-component");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Result<Tag> extractDescriptionTag(Tag eventTag){
|
||||||
|
var list = eventTag.find(extractDescriptionFilter());
|
||||||
|
if (list.isEmpty()) return error("Failed to find description tag");
|
||||||
|
return Payload.of(new Tag(DIV).addAll(list));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Result<Coords> extractCoords(Tag eventTag) {
|
||||||
|
var res = super.extractLocation(eventTag);
|
||||||
|
if (res instanceof Payload<String> payload){
|
||||||
|
var location = payload.get().toLowerCase();
|
||||||
|
return Payload.of(location.contains("mvz") ? MVZ_COORDS : DEFAULT_COORDS);
|
||||||
|
}
|
||||||
|
return Payload.of(DEFAULT_COORDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<Tag> extractEndDateFilter() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<Tag> extractEndTimeFilter() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<Tag> extractEventTagFilter() {
|
||||||
|
return ofType("main");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Result<List<String>> extractEventUrls(Result<Tag> programPage) {
|
||||||
|
var opt = programPage.optional();
|
||||||
|
if (opt.isEmpty()) return transform(programPage);
|
||||||
|
var list = opt.get().find(attributeEquals(CLASS,"event-calendar"));
|
||||||
|
if (list.isEmpty())return error("calendar div not found");
|
||||||
|
var calendar = list.getFirst();
|
||||||
|
var urls = calendar.find(IS_ANCHOR).stream()
|
||||||
|
.map(anchor -> anchor.get(HREF))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.distinct()
|
||||||
|
.map(url -> url.contains("://") ? url : baseUrl()+url)
|
||||||
|
.toList();
|
||||||
|
return Payload.of(urls);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<Tag> extractLinksFilter() {
|
||||||
|
return ofType("main");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Result<String> extractLocation(Tag eventTag) {
|
||||||
|
var res = super.extractLocation(eventTag);
|
||||||
|
if (res instanceof Payload<String> payload){
|
||||||
|
var location = payload.get().toLowerCase();
|
||||||
|
return Payload.of(location.contains("mvz") ? LOCATION_MVZ : DEFAULT_LOCATION);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<Tag> extractLocationFilter() {
|
||||||
|
return attributeHas(CLASS,"event-location");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<Tag> extractStartDateFilter() {
|
||||||
|
return ofType("time").and(tag -> !emptyIfNull(tag.get("datetime")).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<Tag> extractStartTimeFilter() {
|
||||||
|
return ofType("time").and(tag -> !emptyIfNull(tag.get("datetime")).isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<String> extractTags(Tag eventTag) {
|
||||||
|
var tags = new HashSet<String>();
|
||||||
|
tags.add("CafeWagner");
|
||||||
|
tags.add("Jena");
|
||||||
|
eventTag.find(attributeEquals(CLASS,"tag")).stream()
|
||||||
|
.flatMap(tag -> tag.find(ofType("span")).stream())
|
||||||
|
.map(Tag::strip)
|
||||||
|
.map(String::trim)
|
||||||
|
.forEach(tags::add);
|
||||||
|
return List.copyOf(tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<Tag> extractTitleFilter() {
|
||||||
|
return ofType("h1");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Result<LocalDate> parseEndDate(String string) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Result<LocalTime> parseEndTime(String string) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Result<LocalDate> parseStartDate(String string) {
|
||||||
|
var matcher = DATE_FORMAT.matcher(string);
|
||||||
|
if (matcher.find()){
|
||||||
|
var day = Integer.parseInt(matcher.group(1));
|
||||||
|
var month = toNumericMonth(matcher.group(2));
|
||||||
|
if (month.optional().isEmpty()) return transform(month);
|
||||||
|
var year = Integer.parseInt(matcher.group(3));
|
||||||
|
return Payload.of(LocalDate.of(year,month.optional().get(),day));
|
||||||
|
}
|
||||||
|
return error("Failed to recognize date in %s",string);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Result<LocalTime> parseStartTime(String string) {
|
||||||
|
return Util.parseGermanTime(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String programURL() {
|
||||||
|
return baseUrl()+"/de";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,6 @@ import static de.srsoftware.tools.TagFilter.*;
|
|||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
import de.srsoftware.cal.BaseImporter;
|
import de.srsoftware.cal.BaseImporter;
|
||||||
import de.srsoftware.cal.Util;
|
|
||||||
import de.srsoftware.cal.api.Coords;
|
import de.srsoftware.cal.api.Coords;
|
||||||
import de.srsoftware.tools.*;
|
import de.srsoftware.tools.*;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
@@ -22,7 +21,6 @@ import java.nio.file.Path;
|
|||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.util.DuplicateFormatFlagsException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|||||||
@@ -13,9 +13,6 @@ import de.srsoftware.tools.Payload;
|
|||||||
import de.srsoftware.tools.Result;
|
import de.srsoftware.tools.Result;
|
||||||
import de.srsoftware.tools.Tag;
|
import de.srsoftware.tools.Tag;
|
||||||
import de.srsoftware.tools.TagFilter;
|
import de.srsoftware.tools.TagFilter;
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
|
|||||||
@@ -251,8 +251,8 @@ public class ApiEndpoint extends PathHandler {
|
|||||||
json.getJSONArray(ATTACHMENTS).forEach(att -> {
|
json.getJSONArray(ATTACHMENTS).forEach(att -> {
|
||||||
Payload //
|
Payload //
|
||||||
.of(att.toString())
|
.of(att.toString())
|
||||||
.map(BaseImporter::url)
|
.map(Util::url)
|
||||||
.map(BaseImporter::toAttachment)
|
.map(Util::toAttachment)
|
||||||
.optional()
|
.optional()
|
||||||
.ifPresent(event::add);
|
.ifPresent(event::add);
|
||||||
});
|
});
|
||||||
@@ -293,7 +293,7 @@ public class ApiEndpoint extends PathHandler {
|
|||||||
try {
|
try {
|
||||||
var description = json.getString(DESCRIPTION);
|
var description = json.getString(DESCRIPTION);
|
||||||
return Payload.of(json.getString(URL))
|
return Payload.of(json.getString(URL))
|
||||||
.map(BaseImporter::url)
|
.map(Util::url)
|
||||||
.map(url -> BaseImporter.link(url, description));
|
.map(url -> BaseImporter.link(url, description));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return error(e, "Failed to create link from %s", json);
|
return error(e, "Failed to create link from %s", json);
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
</span>
|
</span>
|
||||||
<table id="eventlist">
|
<table id="eventlist">
|
||||||
<tr class="head">
|
<tr class="head">
|
||||||
<th>ID</th>
|
|
||||||
<th>Start
|
<th>Start
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ function addRow(json){
|
|||||||
var tagList = json.tags.join(' ');
|
var tagList = json.tags.join(' ');
|
||||||
row.setAttribute('class',tagList);
|
row.setAttribute('class',tagList);
|
||||||
}
|
}
|
||||||
addCell(row,json.id,json.id);
|
//addCell(row,json.id,json.id);
|
||||||
addCell(row,json.start,json.id);
|
addCell(row,json.start,json.id);
|
||||||
addCell(row,json.end,json.id);
|
addCell(row,json.end,json.id);
|
||||||
addCell(row,json.title,json.id);
|
addCell(row,json.title,json.id);
|
||||||
|
|||||||
Reference in New Issue
Block a user