From 80f92263b37a736bb61bd271b57c92e2cd92525b Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Mon, 31 Aug 2026 15:05:21 +0200 Subject: [PATCH] updated libraries, adapted code to library changes Signed-off-by: Stephan Richter --- de.srsoftware.cal.api/build.gradle.kts | 2 +- de.srsoftware.cal.app/build.gradle.kts | 9 +- .../de/srsoftware/cal/app/AutoImporter.java | 12 +- de.srsoftware.cal.base/build.gradle.kts | 7 +- .../java/de/srsoftware/cal/BaseImporter.java | 122 +++++++++++------- .../de/srsoftware/cal/SinglePageImporter.java | 37 ++++-- .../src/main/java/de/srsoftware/cal/Util.java | 39 +++--- de.srsoftware.cal.db/build.gradle.kts | 5 +- .../java/de/srsoftware/cal/db/Database.java | 16 +-- .../java/de/srsoftware/cal/db/MariaDB.java | 6 +- .../java/de/srsoftware/cal/db/NotFound.java | 2 +- .../java/de/srsoftware/cal/db/SQlite.java | 6 +- .../main/java/de/srsoftware/cal/db/SqlDb.java | 48 +++---- .../java/de/srsoftware/cal/db/SqlError.java | 2 +- de.srsoftware.cal.importer/build.gradle.kts | 5 +- .../srsoftware/cal/importer/erfurt/Eburg.java | 22 ++-- .../cal/importer/erfurt/FromHell.java | 28 ++-- .../erfurt/GewerkschaftshausErfurt.java | 24 ++-- .../srsoftware/cal/importer/gera/AtParty.java | 30 ++--- .../cal/importer/jena/CafeWagner.java | 25 ++-- .../cal/importer/jena/CosmicDawn.java | 25 ++-- .../srsoftware/cal/importer/jena/FHaus.java | 28 ++-- .../cal/importer/jena/Kassablanca.java | 21 +-- .../cal/importer/jena/Psychochor.java | 22 ++-- .../cal/importer/jena/Rosenkeller.java | 32 ++--- .../cal/importer/leipzig/Bandhaus.java | 34 ++--- .../cal/importer/neustadt/Wotufa.java | 26 ++-- .../cal/importer/weimar/CKeller.java | 22 ++-- .../cal/importer/weimar/Gerberstrasse.java | 20 +-- .../cal/importer/weimar/Kasseturm.java | 22 ++-- de.srsoftware.cal.web/build.gradle.kts | 5 +- .../java/de/srsoftware/cal/ApiEndpoint.java | 100 +++++++------- .../main/java/de/srsoftware/cal/Forward.java | 3 +- .../java/de/srsoftware/cal/IndexHandler.java | 9 +- .../java/de/srsoftware/cal/StaticHandler.java | 7 +- 35 files changed, 450 insertions(+), 373 deletions(-) diff --git a/de.srsoftware.cal.api/build.gradle.kts b/de.srsoftware.cal.api/build.gradle.kts index e8ea51a..5ceae66 100644 --- a/de.srsoftware.cal.api/build.gradle.kts +++ b/de.srsoftware.cal.api/build.gradle.kts @@ -1,6 +1,6 @@ description = "OpenCloudCal : API" dependencies { - implementation("de.srsoftware:tools.util:1.3.0") + implementation("de.srsoftware:tools.util:2.1.1") implementation("org.json:json:20240303") } diff --git a/de.srsoftware.cal.app/build.gradle.kts b/de.srsoftware.cal.app/build.gradle.kts index ad9530d..358732b 100644 --- a/de.srsoftware.cal.app/build.gradle.kts +++ b/de.srsoftware.cal.app/build.gradle.kts @@ -14,11 +14,12 @@ dependencies { implementation("de.srsoftware:configuration.api:1.0.0") implementation("de.srsoftware:configuration.json:1.0.1") - implementation("de.srsoftware:tools.http:1.2.4") - implementation("de.srsoftware:tools.logging:1.2.0") + implementation("de.srsoftware:tools.container:1.0.6") + implementation("de.srsoftware:tools.http:6.0.5") + implementation("de.srsoftware:tools.logging:1.3.2") implementation("de.srsoftware:tools.plugin:1.0.2") - implementation("de.srsoftware:tools.util:1.3.0") - implementation("de.srsoftware:tools.web:1.3.14") + implementation("de.srsoftware:tools.util:2.1.1") + implementation("de.srsoftware:tools.web:1.3.16") implementation("com.mysql:mysql-connector-j:9.1.0") implementation("org.json:json:20240303") } diff --git a/de.srsoftware.cal.app/src/main/java/de/srsoftware/cal/app/AutoImporter.java b/de.srsoftware.cal.app/src/main/java/de/srsoftware/cal/app/AutoImporter.java index 62ea9b6..223cea3 100644 --- a/de.srsoftware.cal.app/src/main/java/de/srsoftware/cal/app/AutoImporter.java +++ b/de.srsoftware.cal.app/src/main/java/de/srsoftware/cal/app/AutoImporter.java @@ -219,7 +219,8 @@ public class AutoImporter implements Runnable, ClassListener { if (lastImport == null || Duration.between(lastImport,now).minusHours(6).isPositive()) { for (var importer : importers) { try { - importer.fetch().map(AutoImporter::autoAddTags).forEach(event -> saveOrUpdate(event,importer)); + var events = importer.fetch().map(AutoImporter::autoAddTags).toList(); + for (var event : events) saveOrUpdate(event, importer); } catch (IOException e) { LOG.log(WARNING, "{0}.fetch() failed", importer, e); } @@ -274,15 +275,16 @@ public class AutoImporter implements Runnable, ClassListener { } else { res = db.add(appointment); } - var saved = res.optional(); + Optional saved = res.optional(); + var name = importer.getClass().getSimpleName(); if (saved.isPresent()){ if (loaded.isPresent()) { - LOG.log(INFO, "UPDATED: {0} from {1}.", saved.get(),importer.getClass().getSimpleName()); + LOG.log(INFO, "UPDATED: {0} from {1}.", saved.get().title(),name); } else { - LOG.log(INFO, "CREATED: {0} from {1}.", saved.get(),importer.getClass().getSimpleName()); + LOG.log(INFO, "CREATED: {0} from {1}.", saved.get().title(),name); } } else { - LOG.log(WARNING,"Failed to save {0} from {1}!",appointment,importer.getClass().getSimpleName()); + LOG.log(WARNING,"Failed to save {0} from {1}!",appointment,name); } } diff --git a/de.srsoftware.cal.base/build.gradle.kts b/de.srsoftware.cal.base/build.gradle.kts index 7c2913f..f44d14b 100644 --- a/de.srsoftware.cal.base/build.gradle.kts +++ b/de.srsoftware.cal.base/build.gradle.kts @@ -3,9 +3,10 @@ description = "OpenCloudCal : Base" dependencies { implementation(project(":de.srsoftware.cal.api")) - implementation("de.srsoftware:tools.mime:1.1.0") + implementation("de.srsoftware:tools.container:1.0.6") + implementation("de.srsoftware:tools.mime:1.1.4") implementation("de.srsoftware:tools.optionals:1.0.0") - implementation("de.srsoftware:tools.util:1.3.0") - implementation("de.srsoftware:tools.web:1.3.14") + implementation("de.srsoftware:tools.util:2.1.1") + implementation("de.srsoftware:tools.web:1.3.16") implementation("org.json:json:20240303") } diff --git a/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/BaseImporter.java b/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/BaseImporter.java index 71b8b1d..a2a085f 100644 --- a/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/BaseImporter.java +++ b/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/BaseImporter.java @@ -2,18 +2,23 @@ package de.srsoftware.cal; import static de.srsoftware.cal.Util.*; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Error.error; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.HREF; import static de.srsoftware.tools.TagFilter.*; +import static java.lang.System.Logger.Level.DEBUG; import de.srsoftware.cal.api.*; import de.srsoftware.tools.*; +import de.srsoftware.tools.container.Container; +import de.srsoftware.tools.container.Payload; + import java.io.InputStream; import java.net.*; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -40,22 +45,22 @@ public abstract class BaseImporter implements Importer { .map(Payload::of) .map(Util::url) .map(Util::toAttachment) - .map(Result::optional) + .map(Container::optional) .flatMap(Optional::stream) .toList(); } protected abstract Predicate extractAttachmentsFilter(); - protected Result extractAttachmentsTag(Tag eventTag) { + protected Container extractAttachmentsTag(Tag eventTag) { var list = eventTag.find(extractAttachmentsFilter()); if (list.isEmpty()) return error("Failed to find attachments tag"); return Payload.of(list.getFirst()); } - protected Result extractDescription(Tag eventTag) { - Result descriptionTag = extractDescriptionTag(eventTag); + protected Container extractDescription(Tag eventTag) { + Container descriptionTag = extractDescriptionTag(eventTag); if (descriptionTag.optional().isEmpty()) return transform(descriptionTag); Tag tag = descriptionTag.optional().get(); tag.find(ofType("iframe")).forEach(Tag::remove); @@ -65,29 +70,29 @@ public abstract class BaseImporter implements Importer { protected abstract Predicate extractDescriptionFilter(); - protected Result extractDescriptionTag(Tag eventTag){ + protected Container extractDescriptionTag(Tag eventTag){ var list = eventTag.find(extractDescriptionFilter()); if (list.isEmpty()) return error("Failed to find description tag"); return Payload.of(list.getFirst()); } - protected abstract Result extractCoords(Tag eventTag); + protected abstract Container extractCoords(Tag eventTag); - protected Result extractEnd(Tag eventTag) { - Result date = extractEndDate(eventTag); - Result time = extractEndTime(eventTag); + protected Container extractEnd(Tag eventTag) { + Container date = extractEndDate(eventTag); + Container time = extractEndTime(eventTag); return combine(date,time); } - protected Result extractEndDate(Tag eventTag) { - Result endDateTag = extractEndDateTag(eventTag); + protected Container extractEndDate(Tag eventTag) { + Container endDateTag = extractEndDateTag(eventTag); var opt = endDateTag.optional(); if (opt.isEmpty()) return transform(endDateTag); return parseEndDate(opt.get().strip()); } - protected Result extractEndDateTag(Tag eventTag) { + protected Container extractEndDateTag(Tag eventTag) { var list = eventTag.find(extractEndDateFilter()); if (list.isEmpty()) return error("Failed to find end date tag"); return Payload.of(list.getFirst()); @@ -95,14 +100,14 @@ public abstract class BaseImporter implements Importer { protected abstract Predicate extractEndDateFilter(); - protected Result extractEndTime(Tag eventTag) { - Result endTimeTag = extractEndTimeTag(eventTag); + protected Container extractEndTime(Tag eventTag) { + Container endTimeTag = extractEndTimeTag(eventTag); var opt = endTimeTag.optional(); if (opt.isEmpty()) return transform(endTimeTag); return parseEndTime(opt.get().strip()); } - protected Result extractEndTimeTag(Tag eventTag) { + protected Container extractEndTimeTag(Tag eventTag) { var list = eventTag.find(extractEndTimeFilter()); if (list.isEmpty()) return error("Failed to find end time tag"); return Payload.of(list.getFirst()); @@ -111,7 +116,7 @@ public abstract class BaseImporter implements Importer { protected abstract Predicate extractEndTimeFilter(); - protected Result extractEvent(Result domResult, Link eventPage) { + protected Container extractEvent(Container domResult, Link eventPage) { var opt = domResult.optional(); if (opt.isEmpty()) return transform(domResult); var eventTag = opt.get(); @@ -159,7 +164,7 @@ public abstract class BaseImporter implements Importer { * @param pageResult * @return */ - protected Result extractEventTag(Result pageResult){ + protected Container extractEventTag(Container pageResult){ var opt = pageResult.optional(); if (opt.isEmpty()) return transform(pageResult); var list = opt.get().find(extractEventTagFilter()); @@ -170,7 +175,7 @@ public abstract class BaseImporter implements Importer { protected abstract Predicate extractEventTagFilter(); - protected abstract Result> extractEventUrls(Result programPage); + protected abstract Container> extractEventUrls(Container programPage); protected List extractLinks(Tag appointmentTag) { var tag = extractLinksTag(appointmentTag); @@ -190,7 +195,7 @@ public abstract class BaseImporter implements Importer { .toList(); } - protected Result extractLinksTag(Tag eventTag) { + protected Container extractLinksTag(Tag eventTag) { var list = eventTag.find(extractLinksFilter()); if (list.isEmpty()) return error("Failed to find links tag"); return Payload.of(list.getFirst()); @@ -198,13 +203,13 @@ public abstract class BaseImporter implements Importer { protected abstract Predicate extractLinksFilter(); - protected Result extractLocation(Tag eventTag) { - Result locationTag = extractLocationTag(eventTag); + protected Container extractLocation(Tag eventTag) { + Container locationTag = extractLocationTag(eventTag); if (locationTag.optional().isEmpty()) return transform(locationTag); return Payload.of(locationTag.optional().get().strip()); } - protected Result extractLocationTag(Tag eventTag){ + protected Container extractLocationTag(Tag eventTag){ var list = eventTag.find(extractLocationFilter()); if (list.isEmpty()) return error("Failed to find location tag"); return Payload.of(list.getFirst()); @@ -213,20 +218,20 @@ public abstract class BaseImporter implements Importer { protected abstract Predicate extractLocationFilter(); - protected Result extractStart(Tag eventTag) { - Result date = extractStartDate(eventTag); - Result time = extractStartTime(eventTag); + protected Container extractStart(Tag eventTag) { + Container date = extractStartDate(eventTag); + Container time = extractStartTime(eventTag); return combine(date,time); } - protected Result extractStartDate(Tag eventTag) { - Result startDateTag = extractStartDateTag(eventTag); + protected Container extractStartDate(Tag eventTag) { + Container startDateTag = extractStartDateTag(eventTag); var opt = startDateTag.optional(); if (opt.isEmpty()) return transform(startDateTag); return parseStartDate(opt.get().strip()); } - protected Result extractStartDateTag(Tag eventTag) { + protected Container extractStartDateTag(Tag eventTag) { var list = eventTag.find(extractStartDateFilter()); if (list.isEmpty()) return error("Failed to find start date tag"); return Payload.of(list.getFirst()); @@ -234,14 +239,14 @@ public abstract class BaseImporter implements Importer { protected abstract Predicate extractStartDateFilter(); - protected Result extractStartTime(Tag eventTag) { - Result startTimeTag = extractStartTimeTag(eventTag); + protected Container extractStartTime(Tag eventTag) { + Container startTimeTag = extractStartTimeTag(eventTag); var opt = startTimeTag.optional(); if (opt.isEmpty()) return transform(startTimeTag); return parseStartTime(opt.get().strip()); } - protected Result extractStartTimeTag(Tag eventTag) { + protected Container extractStartTimeTag(Tag eventTag) { var list = eventTag.find(extractStartTimeFilter()); if (list.isEmpty()) return error("Failed to find start time tag"); return Payload.of(list.getFirst()); @@ -252,14 +257,14 @@ public abstract class BaseImporter implements Importer { protected abstract List extractTags(Tag eventTag); - protected Result extractTitle(Tag eventTag) { - Result titleTag = extractTitleTag(eventTag); + protected Container extractTitle(Tag eventTag) { + Container titleTag = extractTitleTag(eventTag); if (titleTag.optional().isEmpty()) return transform(titleTag); var inner = titleTag.optional().flatMap(tag -> tag.inner(2)); return inner.isPresent() ? Payload.of(inner.get().trim()) : error("No title found"); } - protected Result extractTitleTag(Tag eventTag){ + protected Container extractTitleTag(Tag eventTag){ var list = eventTag.find(extractTitleFilter()); if (list.isEmpty()) return error("Failed to find title tag"); return Payload.of(list.getFirst()); @@ -269,8 +274,31 @@ public abstract class BaseImporter implements Importer { @Override public Stream fetch() { - var url = Payload.of(programURL()); - Stream> urls = url(url) + String url = programURL(); + LOG.log(DEBUG,"Fetching {0}",url); + var _url_str_ = Payload.of(url); + var _url_ = url(_url_str_); + var _input_stream_ = open(_url_); + var _preloaded_stream_ = preload(_input_stream_); + var _tag_ = Util.parseXML(_preloaded_stream_); + var _url_strings_ = extractEventUrls(_tag_); + + if (!(_url_strings_ instanceof Payload> _list_)) return Stream.of(); + List list = _list_.get(); + List result = new ArrayList<>(); + for (var url_string : list){ + _url_ = url(Payload.of(url_string)); + var _appointment_ = loadEvent(_url_); + if (_appointment_ instanceof Payload _payload_) { + result.add(_payload_.get()); + } else LOG.log(System.Logger.Level.WARNING,_appointment_); + } + return result.stream(); + + /* + var url = Payload.of(programURL()); + + Stream> urls = url(url) .map(Util::open) // .map(this::preload) .map(Util::parseXML) @@ -280,19 +308,19 @@ public abstract class BaseImporter implements Importer { .map(Util::url) .map(this::loadEvent) .peek(res -> { if (res.optional().isEmpty()) LOG.log(System.Logger.Level.WARNING,res); }) - .flatMap(result -> result.optional().stream()); + .flatMap(result -> result.optional().stream());*/ } - protected static Result invalidParameter(Result result) { + protected static Container invalidParameter(Container result) { return error("Invalid parameter: %s", result.getClass().getSimpleName()); } - protected static Result link(Result url, String text) { + protected static Container link(Container url, String text) { var opt = url.optional(); return opt.isEmpty() ? transform(url) : Payload.of(new Link(opt.get(), text)); } - protected Result loadEvent(Result urlResult) { + protected Container loadEvent(Container urlResult) { var link = urlResult // .optional() .map(url -> new Link(url, "Event-Seite")) @@ -307,15 +335,15 @@ public abstract class BaseImporter implements Importer { - protected abstract Result parseEndDate(String string); - protected abstract Result parseEndTime(String string); + protected abstract Container parseEndDate(String string); + protected abstract Container parseEndTime(String string); - protected abstract Result parseStartDate(String string); - protected abstract Result parseStartTime(String string); + protected abstract Container parseStartDate(String string); + protected abstract Container parseStartTime(String string); - protected Result preload(Result inputStream) { + protected Container preload(Container inputStream) { return Util.preload(inputStream); } diff --git a/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/SinglePageImporter.java b/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/SinglePageImporter.java index 2857fc1..7a81a14 100644 --- a/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/SinglePageImporter.java +++ b/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/SinglePageImporter.java @@ -5,10 +5,11 @@ import static de.srsoftware.cal.Util.url; import de.srsoftware.cal.api.Appointment; import de.srsoftware.cal.api.Link; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; @@ -20,28 +21,36 @@ public abstract class SinglePageImporter extends BaseImporter{ @Override public Stream fetch() { - var programPage = Payload.of(programURL()); - var eventLink = programPage // + var programPage = Payload.of(programURL()); + var eventLink = programPage .map(Util::url).optional() .map(url -> new Link(url, "Event-Seite")) .orElse(null); - Stream> eventTags = url(programPage).map(Util::open).map(Util::preload) + Container> eventTags = url(programPage) + .map(Util::open) + .map(Util::preload) .map(Util::parseXML) - .map(this::extractEventTags) - .stream(); + .map(this::extractEventTags); - return eventTags.map(tagResult -> extractEvent(tagResult, eventLink)) - .peek(res -> { - if (res.optional().isEmpty()) LOG.log(System.Logger.Level.WARNING, res); - }) - .flatMap(res -> res.optional().stream()); + if (!(eventTags instanceof Payload> _list_)) return Stream.of(); + + var result = new ArrayList(); + for (var tag : _list_.get()){ + Container evt = extractEvent(Payload.of(tag), eventLink); + if (evt instanceof Payload p) { + result.add(p.get()); + } else LOG.log(System.Logger.Level.WARNING, evt); + + } + + return result.stream(); } - protected abstract Result> extractEventTags(Result tagResult); + protected abstract Container> extractEventTags(Container tagResult); @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { return null; // not needed by this fetch implementation } } diff --git a/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/Util.java b/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/Util.java index 47bd656..a9331c1 100644 --- a/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/Util.java +++ b/de.srsoftware.cal.base/src/main/java/de/srsoftware/cal/Util.java @@ -1,14 +1,19 @@ /* © SRSoftware 2026 */ package de.srsoftware.cal; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; import static de.srsoftware.tools.Tag.STYLE; +import static de.srsoftware.tools.container.Container.transform; +import static de.srsoftware.tools.container.Error.error; + +import static java.lang.System.Logger.Level.DEBUG; import static java.lang.System.Logger.Level.WARNING; import de.srsoftware.cal.api.Attachment; import de.srsoftware.cal.api.Coords; import de.srsoftware.tools.*; +import de.srsoftware.tools.container.Container; +import de.srsoftware.tools.container.Payload; + import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; @@ -51,7 +56,7 @@ public class Util { private Util(){} - public static Result combine(Result date, Result time) { + public static Container combine(Container date, Container time) { if (date.optional().isEmpty())return transform(date); if (time.optional().isEmpty())return transform(time); return Payload.of(LocalDateTime.of(date.optional().get(),time.optional().get())); @@ -88,7 +93,7 @@ public class Util { } } - public static Result extractCoords(String coords) { + public static Container extractCoords(String coords) { if (coords == null) return error("Argument is null"); if (coords.isBlank()) return error("Argument is blank"); var parts = coords.split(","); @@ -102,7 +107,7 @@ public class Util { } } - public static Result open(Result url) { + public static Container open(Container url) { var opt = url.optional(); if (opt.isEmpty()) return transform(url); try { @@ -125,7 +130,7 @@ public class Util { .replace(":","/"); } - public static Result parseGermanDate(String s){ + public static Container parseGermanDate(String s){ var match = GERMAN_DATE_PATTERN.matcher(" "+s.trim()+" "); if (match.find()){ var day = Integer.parseInt(match.group(1)); @@ -136,7 +141,7 @@ public class Util { return error("Failed to find date"); } - public static Result parseLongGermanDate(String s){ + public static Container parseLongGermanDate(String s){ var match = GERMAN_DATE_PATTERN_LONG.matcher(" "+s+" "); if (match.find()){ var day = Integer.parseInt(match.group(1)); @@ -149,7 +154,7 @@ public class Util { return error("Failed to find date"); } - public static Result parseGermanTime(String s){ + public static Container parseGermanTime(String s){ var match = GERMAN_TIME_PATTERN.matcher(" "+s.trim()+" "); if (match.find()){ var hour = Integer.parseInt(match.group(1)); @@ -161,12 +166,12 @@ public class Util { return error("Failed to find time"); } - public static Result parseXML(Result inputStream) { + public static Container parseXML(Container inputStream) { var opt = inputStream.optional(); return opt.isEmpty() ? transform((inputStream)) : XMLParser.parse(opt.get()); } - public static Result preload(Result inputStream) { + public static Container preload(Container inputStream) { var opt = inputStream.optional(); if (opt.isEmpty()) return transform(inputStream); try { @@ -176,7 +181,7 @@ public class Util { } } - public static Result toNumericMonth(String month) { + public static Container toNumericMonth(String month) { month = month.toLowerCase(); if (month.startsWith("ja")) return Payload.of(1); if (month.startsWith("f")) return Payload.of(2); @@ -199,7 +204,7 @@ public class Util { * @param prodId the producer id of this icalendar * @return the completed ical string */ - public static Result wrapIcal(Result ical, String prodId) { + public static Container wrapIcal(Container ical, String prodId) { if (ical instanceof Payload payload){ var calendar = new StringBuilder(); calendar.append(contentLine(BEGIN,VCALENDAR)); @@ -212,7 +217,7 @@ public class Util { return ical; } - public static Result extractBackgroundImage(Tag tag, String baseUrl) { + public static Container extractBackgroundImage(Tag tag, String baseUrl) { var style = tag.get(STYLE); if (style != null){ var matcher = BG_IMAGE_URL.matcher(style); @@ -224,7 +229,7 @@ public class Util { return error("Failed to findbackground image url in %s",tag); } - public static Result toAttachment(Result urlResult) { + public static Container toAttachment(Container urlResult) { var opt = urlResult.optional(); if (opt.isEmpty()) return transform(urlResult); try { @@ -236,7 +241,7 @@ public class Util { } } - public static Result parseInt(String s){ + public static Container parseInt(String s){ try { return Payload.of(Integer.parseInt(s)); } catch (NumberFormatException e){ @@ -244,7 +249,7 @@ public class Util { } } - public static Result url(Result urlResult) { + public static Container url(Container urlResult) { if (urlResult.optional().isEmpty()) return transform(urlResult); var url = urlResult.optional().get(); try { @@ -254,7 +259,7 @@ public class Util { } } - public static Result parseGermanDateWithoutYear(String string) { + public static Container parseGermanDateWithoutYear(String string) { var matcher = GERMAN_DATE_WITHOUT_YEAR.matcher(string); if (matcher.find()){ int day = Integer.parseInt(matcher.group(1)); diff --git a/de.srsoftware.cal.db/build.gradle.kts b/de.srsoftware.cal.db/build.gradle.kts index 92b3f8b..5b1dbe5 100644 --- a/de.srsoftware.cal.db/build.gradle.kts +++ b/de.srsoftware.cal.db/build.gradle.kts @@ -4,8 +4,9 @@ dependencies { implementation(project(":de.srsoftware.cal.api")) implementation(project(":de.srsoftware.cal.base")) - implementation("de.srsoftware:tools.jdbc:1.3.0") + implementation("de.srsoftware:tools.container:1.0.6") + implementation("de.srsoftware:tools.jdbc:2.0.8") implementation("de.srsoftware:tools.optionals:1.0.0") - implementation("de.srsoftware:tools.util:1.3.0") + implementation("de.srsoftware:tools.util:2.1.1") implementation("org.xerial:sqlite-jdbc:3.49.0.0") } diff --git a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/Database.java b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/Database.java index ea8ce06..c750abb 100644 --- a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/Database.java +++ b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/Database.java @@ -2,7 +2,7 @@ package de.srsoftware.cal.db; import de.srsoftware.cal.api.Appointment; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Container; import java.time.LocalDateTime; import java.util.Collection; import java.util.List; @@ -17,9 +17,9 @@ public interface Database { * @param appointment the appointment to store * @return a clone of the provided appointment with id field set */ - Result add(Appointment appointment); + Container add(Appointment appointment); - Result> findTags(String infix); + Container> findTags(String infix); /** * list appointments unfiltered @@ -29,7 +29,7 @@ public interface Database { * @param till restrict appointments to times before this date time * @return list of appointments in this time span */ - Result> list(LocalDateTime from, LocalDateTime till, Integer count, Integer offset, Collection tags); + Container> list(LocalDateTime from, LocalDateTime till, Integer count, Integer offset, Collection tags); /** * list appointments @@ -40,11 +40,11 @@ public interface Database { */ List listByTags(Set tags, Integer count, Integer offset); - Result loadEvent(long id); + Container loadEvent(long id); - Result loadEvent(String location, LocalDateTime start); + Container loadEvent(String location, LocalDateTime start); - Result removeAppointment(long id); + Container removeAppointment(long id); - Result update(Appointment baseAppointment); + Container update(Appointment baseAppointment); } diff --git a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/MariaDB.java b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/MariaDB.java index 456b4e8..c3b33fb 100644 --- a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/MariaDB.java +++ b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/MariaDB.java @@ -1,13 +1,17 @@ package de.srsoftware.cal.db; +import de.srsoftware.tools.jdbc.Query; + import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; +import static de.srsoftware.tools.jdbc.Query.Dialect.MARIADB; + public class MariaDB extends SqlDb{ protected MariaDB(Connection conn) throws SQLException { - super(conn); + super(conn, MARIADB); } public static Database connect(String jdbc, String user, String pass) throws SQLException { diff --git a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/NotFound.java b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/NotFound.java index a3901bb..ba64163 100644 --- a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/NotFound.java +++ b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/NotFound.java @@ -1,7 +1,7 @@ /* © SRSoftware 2026 */ package de.srsoftware.cal.db; -import de.srsoftware.tools.Error; +import de.srsoftware.tools.container.Error; import java.util.Collection; import java.util.Map; diff --git a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SQlite.java b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SQlite.java index c7744bc..7774dce 100644 --- a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SQlite.java +++ b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SQlite.java @@ -1,14 +1,18 @@ package de.srsoftware.cal.db; +import de.srsoftware.tools.jdbc.Query; + import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; +import static de.srsoftware.tools.jdbc.Query.Dialect.SQLITE; + public class SQlite extends SqlDb { protected SQlite(Connection conn) throws SQLException { - super(conn); + super(conn, SQLITE); } @Override diff --git a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SqlDb.java b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SqlDb.java index 1a9801d..f22b9c7 100644 --- a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SqlDb.java +++ b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SqlDb.java @@ -4,9 +4,9 @@ package de.srsoftware.cal.db; import static de.srsoftware.cal.Util.extractCoords; import static de.srsoftware.cal.db.Fields.*; import static de.srsoftware.cal.db.Fields.ALL; -import static de.srsoftware.tools.Error.error; +import static de.srsoftware.tools.container.Error.error; import static de.srsoftware.tools.Optionals.*; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.jdbc.Condition.*; import static de.srsoftware.tools.jdbc.Query.*; import static java.lang.System.Logger.Level.*; @@ -15,8 +15,8 @@ import de.srsoftware.cal.BaseAppointment; import de.srsoftware.cal.api.Appointment; import de.srsoftware.cal.api.Attachment; import de.srsoftware.cal.api.Link; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.jdbc.Query; import java.net.MalformedURLException; import java.net.URI; @@ -38,10 +38,12 @@ public abstract class SqlDb implements Database { private static final String TAG_SEARCH = "tag_search"; private static final String URLS = "urls"; private static final String VALUE = "value"; + private final Dialect dialect; protected Connection connection; - protected SqlDb(Connection conn) throws SQLException { + protected SqlDb(Connection conn, Dialect dialect) throws SQLException { connection = conn; + this.dialect = dialect; applyUpdates(); } @@ -107,7 +109,7 @@ public abstract class SqlDb implements Database { } @Override - public Result add(Appointment appointment) { + public Container add(Appointment appointment) { try { var start = Timestamp.valueOf(appointment.start()); var end = appointment.end().map(Timestamp::valueOf).orElse(null); @@ -142,7 +144,7 @@ public abstract class SqlDb implements Database { if (assignQuery == null) assignQuery = insertInto(APPOINTMENT_ATTACHMENTS, AID, UID, MIME); if (urlId.isPresent()) assignQuery.values(saved.id(), urlId.get(), attachment.mime()); } - if (assignQuery != null) assignQuery.ignoreDuplicates().execute(connection).close(); + if (assignQuery != null) assignQuery.ignoreDuplicates(dialect).execute(connection).close(); } private void writeLinks(Appointment saved) throws SQLException { // link to links @@ -153,7 +155,7 @@ public abstract class SqlDb implements Database { if (assignQuery == null) assignQuery = insertInto(APPOINTMENT_URLS, AID, UID, DESCRIPTION); if (urlId.isPresent()) assignQuery.values(saved.id(), urlId.get(), link.desciption()); } - if (assignQuery != null) assignQuery.ignoreDuplicates().execute(connection).close(); + if (assignQuery != null) assignQuery.ignoreDuplicates(dialect).execute(connection).close(); } private void writeTags(Appointment saved) throws SQLException { @@ -164,7 +166,7 @@ public abstract class SqlDb implements Database { if (assignQuery == null) assignQuery = insertInto(APPOINTMENT_TAGS, AID, TID); if (tagId.isPresent()) assignQuery.values(saved.id(), tagId.get()); } - if (assignQuery != null) assignQuery.ignoreDuplicates().execute(connection).close(); + if (assignQuery != null) assignQuery.ignoreDuplicates(dialect).execute(connection).close(); } private Optional getOrCreateUrl(URL url) throws SQLException { @@ -199,7 +201,7 @@ public abstract class SqlDb implements Database { @Override - public Result> findTags(String infix) { + public Container> findTags(String infix) { try { List results = new ArrayList<>(); var rs = select(KEYWORD).from(TAGS).where(KEYWORD, like("%%%s%%".formatted(infix))).sort(KEYWORD).exec(connection); @@ -213,7 +215,7 @@ public abstract class SqlDb implements Database { } @Override - public Result> list(LocalDateTime from, LocalDateTime till, Integer count, Integer offset, Collection tags) { + public Container> list(LocalDateTime from, LocalDateTime till, Integer count, Integer offset, Collection tags) { List aids = null; if (tags != null && !tags.isEmpty()){ var query = select(AID).from(TAG_SEARCH); @@ -233,7 +235,7 @@ public abstract class SqlDb implements Database { .from(APPOINTMENTS) .leftJoin(AID, "appointment_tags", AID) .leftJoin("tid", "tags", "tid") - .groupBy(AID) + .groupBy(APPOINTMENTS+"."+AID) .sort("start ASC"); if (aids != null && !aids.isEmpty()) query.where(APPOINTMENTS+"."+AID,in(aids.toArray())); if (from != null) query.where(START, moreThan(Timestamp.valueOf(from))); @@ -284,10 +286,10 @@ public abstract class SqlDb implements Database { } @Override - public Result loadEvent(long id) { + public Container loadEvent(long id) { try { var rs = select(ALL).from(APPOINTMENTS).where(AID, equal(id)).exec(connection); - Result result = rs.next() ? createAppointmentOf(rs).map(this::loadExtra) : NotFound.of("Failed to find appointment with id %s", id); + Container result = rs.next() ? createAppointmentOf(rs).map(this::loadExtra) : NotFound.of("Failed to find appointment with id %s", id); rs.getStatement().close(); rs.close(); return result; @@ -297,10 +299,10 @@ public abstract class SqlDb implements Database { } @Override - public Result loadEvent(String location, LocalDateTime start) { + public Container loadEvent(String location, LocalDateTime start) { try { var rs = select(ALL).from(APPOINTMENTS).where(LOCATION, equal(location)).where(START, equal(Timestamp.valueOf(start))).exec(connection); - Result result = rs.next() ? createAppointmentOf(rs).map(this::loadExtra) : error("Failed to find appointment starting %s @ %s", start, location); + Container result = rs.next() ? createAppointmentOf(rs).map(this::loadExtra) : error("Failed to find appointment starting %s @ %s", start, location); rs.getStatement().close(); rs.close(); return result; @@ -309,11 +311,11 @@ public abstract class SqlDb implements Database { } } - private Result loadExtra(Result res) { + private Container loadExtra(Container res) { return loadTags(res).map(this::loadLinks).map(this::loadAttachments); } - private Result loadTags(Result res) { + private Container loadTags(Container res) { if (res.optional().isEmpty()) return transform(res); BaseAppointment event = res.optional().get(); var id = event.id(); @@ -328,7 +330,7 @@ public abstract class SqlDb implements Database { } } - private Result loadLinks(Result res) { + private Container loadLinks(Container res) { if (res.optional().isEmpty()) return transform(res); BaseAppointment event = res.optional().get(); var id = event.id(); @@ -352,7 +354,7 @@ public abstract class SqlDb implements Database { } } - private Result loadAttachments(Result res) { + private Container loadAttachments(Container res) { if (res.optional().isEmpty()) return transform(res); BaseAppointment event = res.optional().get(); var id = event.id(); @@ -376,7 +378,7 @@ public abstract class SqlDb implements Database { } } - private Result createAppointmentOf(ResultSet results) throws SQLException { + private Container createAppointmentOf(ResultSet results) throws SQLException { var id = results.getInt(AID); var title = results.getString(TITLE); var description = results.getString(DESCRIPTION); @@ -407,7 +409,7 @@ public abstract class SqlDb implements Database { } @Override - public Result removeAppointment(long id) { + public Container removeAppointment(long id) { try { delete().from(APPOINTMENTS).where(AID, equal(id)).execute(connection); delete().from(APPOINTMENT_TAGS).where(AID, equal(id)).execute(connection); @@ -420,7 +422,7 @@ public abstract class SqlDb implements Database { } @Override - public Result update(Appointment event) { + public Container update(Appointment event) { var start = Timestamp.valueOf(event.start()); var end = event.end().map(Timestamp::valueOf).orElse(null); var coords = event.coords().map(Object::toString).orElse(null); diff --git a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SqlError.java b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SqlError.java index 7eb1e6b..89cbb97 100644 --- a/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SqlError.java +++ b/de.srsoftware.cal.db/src/main/java/de/srsoftware/cal/db/SqlError.java @@ -1,7 +1,7 @@ /* © SRSoftware 2026 */ package de.srsoftware.cal.db; -import de.srsoftware.tools.Error; +import de.srsoftware.tools.container.Error; import java.sql.SQLException; import java.util.Collection; import java.util.List; diff --git a/de.srsoftware.cal.importer/build.gradle.kts b/de.srsoftware.cal.importer/build.gradle.kts index bcc323a..a30b7de 100644 --- a/de.srsoftware.cal.importer/build.gradle.kts +++ b/de.srsoftware.cal.importer/build.gradle.kts @@ -3,7 +3,8 @@ description = "OpenCloudCal : Importers" dependencies { implementation(project(":de.srsoftware.cal.api")) implementation(project(":de.srsoftware.cal.base")) + implementation("de.srsoftware:tools.container:1.0.6") implementation("de.srsoftware:tools.optionals:1.0.0") - implementation("de.srsoftware:tools.util:1.3.0") - implementation("de.srsoftware:tools.web:1.3.14") + implementation("de.srsoftware:tools.util:2.1.1") + implementation("de.srsoftware:tools.web:1.3.16") } diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/Eburg.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/Eburg.java index 6cc403e..9d22360 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/Eburg.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/Eburg.java @@ -2,8 +2,8 @@ package de.srsoftware.cal.importer.erfurt; import static de.srsoftware.cal.Util.url; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Error.error; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.CLASS; import static de.srsoftware.tools.Tag.HREF; import static de.srsoftware.tools.TagFilter.*; @@ -12,8 +12,8 @@ import de.srsoftware.cal.BaseImporter; import de.srsoftware.cal.Util; import de.srsoftware.cal.api.Coords; import de.srsoftware.cal.api.Link; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.security.NoSuchAlgorithmException; import java.time.LocalDate; @@ -52,7 +52,7 @@ public static final String DEFAULT_LOCATION = "Engelsburg, Allerheiligenstraße } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { return Payload.of(DEFAULT_COORDS); } @@ -72,7 +72,7 @@ public static final String DEFAULT_LOCATION = "Engelsburg, Allerheiligenstraße } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { if (programPage.optional().isEmpty()) return transform(programPage); var tag = programPage.optional().get(); var list = tag.find(attributeHas(CLASS,"program-teaser")).stream() @@ -96,7 +96,7 @@ public static final String DEFAULT_LOCATION = "Engelsburg, Allerheiligenstraße } @Override - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { var res = super.extractLocation(eventTag); var loc = DEFAULT_LOCATION + (res.optional().isPresent() ? ", "+res.optional().get() : ""); return Payload.of(loc); @@ -128,17 +128,17 @@ public static final String DEFAULT_LOCATION = "Engelsburg, Allerheiligenstraße } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return null; } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return null; } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { var matcher = DATE_PATTERN.matcher(string); if (matcher.find()){ int day = Integer.parseInt(matcher.group(1)); @@ -155,7 +155,7 @@ public static final String DEFAULT_LOCATION = "Engelsburg, Allerheiligenstraße } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { var matcher = DATE_PATTERN.matcher(string); if (matcher.find()){ int hour = Integer.parseInt(matcher.group(3)); diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/FromHell.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/FromHell.java index 1d90659..870cb46 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/FromHell.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/FromHell.java @@ -3,9 +3,9 @@ package de.srsoftware.cal.importer.erfurt; import static de.srsoftware.cal.Util.parseGermanTime; import static de.srsoftware.cal.Util.parseLongGermanDate; -import static de.srsoftware.tools.Error.error; +import static de.srsoftware.tools.container.Error.error; import static de.srsoftware.tools.Optionals.nullIfEmpty; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.*; import static de.srsoftware.tools.TagFilter.*; import static java.nio.charset.StandardCharsets.UTF_8; @@ -14,8 +14,8 @@ import de.srsoftware.cal.BaseImporter; import de.srsoftware.cal.api.Attachment; import de.srsoftware.cal.api.Coords; import de.srsoftware.cal.api.Link; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Strings; import de.srsoftware.tools.Tag; import java.io.ByteArrayInputStream; @@ -66,7 +66,7 @@ private static final String DEFAULT_LOCATION = "Club From Hell, Flughafenstraße } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { var res = super.extractLocation(eventTag); if (res.optional().isEmpty()) return transform(res); var location = res.optional().get().trim(); @@ -91,7 +91,7 @@ private static final String DEFAULT_LOCATION = "Club From Hell, Flughafenstraße } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { var opt = programPage.optional(); if (opt.isEmpty()) return transform(programPage); var list = opt.get().find(attributeContains(CLASS,"pane-events-uebersicht-alle-liste")).stream() @@ -119,7 +119,7 @@ private static final String DEFAULT_LOCATION = "Club From Hell, Flughafenstraße } @Override - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { var res = super.extractLocation(eventTag); if (res.optional().isEmpty()) return transform(res); var location = res.optional().get().trim(); @@ -156,8 +156,8 @@ private static final String DEFAULT_LOCATION = "Club From Hell, Flughafenstraße return List.copyOf(tags); } - protected Result extractTitle(Tag eventTag) { - Result titleTag = extractTitleTag(eventTag); + protected Container extractTitle(Tag eventTag) { + Container titleTag = extractTitleTag(eventTag); if (titleTag.optional().isEmpty()) return transform(titleTag); var inner = titleTag.optional().map(Tag::strip); return inner.isPresent() ? Payload.of(inner.get().trim()) : error("No title found"); @@ -169,22 +169,22 @@ private static final String DEFAULT_LOCATION = "Club From Hell, Flughafenstraße } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return parseLongGermanDate(string); } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return parseGermanTime(string); } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { return parseLongGermanDate(string); } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return parseGermanTime(string); } @@ -195,7 +195,7 @@ private static final String DEFAULT_LOCATION = "Club From Hell, Flughafenstraße * @return ausgehender InputStream, verpackt in Result */ @Override - protected Result preload(Result inputStream) { + protected Container preload(Container inputStream) { var opt = inputStream.optional(); if (opt.isEmpty()) return transform(inputStream); try { diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/GewerkschaftshausErfurt.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/GewerkschaftshausErfurt.java index 64bdce0..887172f 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/GewerkschaftshausErfurt.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/erfurt/GewerkschaftshausErfurt.java @@ -2,8 +2,8 @@ package de.srsoftware.cal.importer.erfurt; import static de.srsoftware.cal.Util.parseGermanTime; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Error.error; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.*; import static de.srsoftware.tools.TagFilter.*; import static java.nio.charset.StandardCharsets.UTF_8; @@ -13,8 +13,8 @@ import de.srsoftware.cal.Util; import de.srsoftware.cal.api.Attachment; import de.srsoftware.cal.api.Coords; import de.srsoftware.cal.api.Link; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -66,7 +66,7 @@ public class GewerkschaftshausErfurt extends BaseImporter { } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { var res = super.extractLocation(eventTag); if (res.optional().isEmpty()) return transform(res); var location = res.optional().get(); @@ -96,7 +96,7 @@ public class GewerkschaftshausErfurt extends BaseImporter { } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { var opt = programPage.optional(); if (opt.isEmpty()) return transform(programPage); var list = opt.get().find(attributeEquals(ID,"events-list")).stream() @@ -123,7 +123,7 @@ public class GewerkschaftshausErfurt extends BaseImporter { } @Override - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { var res = super.extractLocation(eventTag); if (res.optional().isEmpty()) return transform(res); var location = res.optional().get(); @@ -176,22 +176,22 @@ public class GewerkschaftshausErfurt extends BaseImporter { } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return null; } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return null; } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { return Util.parseGermanDateWithoutYear(string); } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return parseGermanTime(string); } @@ -202,7 +202,7 @@ public class GewerkschaftshausErfurt extends BaseImporter { * @return ausgehender InputStream, verpackt in Result */ @Override - protected Result preload(Result inputStream) { + protected Container preload(Container inputStream) { var opt = inputStream.optional(); if (opt.isEmpty()) return transform(inputStream); try { diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/gera/AtParty.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/gera/AtParty.java index 2d4d310..a6dac6a 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/gera/AtParty.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/gera/AtParty.java @@ -2,8 +2,8 @@ package de.srsoftware.cal.importer.gera; import static de.srsoftware.cal.Util.*; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Error.error; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.CLASS; import static de.srsoftware.tools.Tag.HREF; import static de.srsoftware.tools.TagFilter.*; @@ -13,8 +13,8 @@ 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.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -54,13 +54,13 @@ public class AtParty extends BaseImporter { //.map(AtParty::dropQuery) .map(Util::url) .map(Util::toAttachment) - .map(Result::optional) + .map(Container::optional) .flatMap(Optional::stream) .forEach(combined::add); return List.copyOf(combined); } - private static Result dropQuery(Result s) { + private static Container dropQuery(Container s) { var opt = s.optional(); if (opt.isEmpty()) return s; return Payload.of(opt.get().replaceAll("\\?.*","")); @@ -77,7 +77,7 @@ public class AtParty extends BaseImporter { } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { var res = super.extractLocation(eventTag); var opt = res.optional(); if (opt.isEmpty()) return transform(res); @@ -107,7 +107,7 @@ public class AtParty extends BaseImporter { } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { var opt = programPage.optional(); if (opt.isEmpty()) return transform(programPage); var list = opt.get().find(IS_ANCHOR) @@ -126,7 +126,7 @@ public class AtParty extends BaseImporter { } @Override - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { var res = super.extractLocation(eventTag); var opt = res.optional(); if (opt.isEmpty()) return transform(res); @@ -175,7 +175,7 @@ public class AtParty extends BaseImporter { } @Override - protected Result extractTitle(Tag eventTag) { + protected Container extractTitle(Tag eventTag) { var res = super.extractTitle(eventTag); var opt = res.optional(); return opt.isEmpty() ? res : Payload.of(opt.get().split("\\|")[0].trim()); @@ -187,22 +187,22 @@ public class AtParty extends BaseImporter { } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return null; } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return null; } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { return parseLongGermanDate(string); } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return parseGermanTime(string); } @@ -213,7 +213,7 @@ public class AtParty extends BaseImporter { * @return ausgehender InputStream, verpackt in Result */ @Override - protected Result preload(Result inputStream) { + protected Container preload(Container inputStream) { var opt = inputStream.optional(); if (opt.isEmpty()) return transform(inputStream); try { diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/CafeWagner.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/CafeWagner.java index cb2e273..fd10779 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/CafeWagner.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/CafeWagner.java @@ -3,9 +3,9 @@ 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.container.Error.error; import static de.srsoftware.tools.Optionals.emptyIfNull; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.*; import static de.srsoftware.tools.TagFilter.*; @@ -14,6 +14,9 @@ import de.srsoftware.cal.Util; import de.srsoftware.cal.api.Attachment; import de.srsoftware.cal.api.Coords; import de.srsoftware.tools.*; +import de.srsoftware.tools.container.Container; +import de.srsoftware.tools.container.Payload; + import java.security.NoSuchAlgorithmException; import java.time.LocalDate; import java.time.LocalTime; @@ -50,7 +53,7 @@ public class CafeWagner extends BaseImporter { .map(tag -> extractBackgroundImage(tag,baseUrl())) .map(Util::url) .map(Util::toAttachment) - .map(Result::optional) + .map(Container::optional) .flatMap(Optional::stream) .forEach(combined::add); return List.copyOf(combined); @@ -67,14 +70,14 @@ public class CafeWagner extends BaseImporter { } @Override - protected Result extractDescriptionTag(Tag eventTag){ + protected Container 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 extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { var res = super.extractLocation(eventTag); if (res instanceof Payload payload){ var location = payload.get().toLowerCase(); @@ -99,7 +102,7 @@ public class CafeWagner extends BaseImporter { } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { var opt = programPage.optional(); if (opt.isEmpty()) return transform(programPage); var list = opt.get().find(attributeEquals(CLASS,"event-calendar")); @@ -120,7 +123,7 @@ public class CafeWagner extends BaseImporter { } @Override - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { var res = super.extractLocation(eventTag); if (res instanceof Payload payload){ var location = payload.get().toLowerCase(); @@ -163,17 +166,17 @@ public class CafeWagner extends BaseImporter { } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return null; } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return null; } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { var matcher = DATE_FORMAT.matcher(string); if (matcher.find()){ var day = Integer.parseInt(matcher.group(1)); @@ -186,7 +189,7 @@ public class CafeWagner extends BaseImporter { } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return Util.parseGermanTime(string); } diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/CosmicDawn.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/CosmicDawn.java index fb85521..6bee73f 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/CosmicDawn.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/CosmicDawn.java @@ -3,8 +3,8 @@ package de.srsoftware.cal.importer.jena; import static de.srsoftware.cal.Util.parseGermanDate; import static de.srsoftware.cal.Util.parseGermanTime; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Error.error; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.CLASS; import static de.srsoftware.tools.TagFilter.*; import static java.nio.charset.StandardCharsets.UTF_8; @@ -13,6 +13,9 @@ import de.srsoftware.cal.BaseImporter; import de.srsoftware.cal.api.Attachment; import de.srsoftware.cal.api.Coords; import de.srsoftware.tools.*; +import de.srsoftware.tools.container.Container; +import de.srsoftware.tools.container.Payload; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -61,7 +64,7 @@ private static final String DEFAULT_LOCATION = "Cosmic Dawn e.V., Spitzweidenweg } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { return Payload.of(DEFAULT_COORDS); } @@ -75,7 +78,7 @@ private static final String DEFAULT_LOCATION = "Cosmic Dawn e.V., Spitzweidenweg return null; } - protected Result extractEventTag(Result pageResult) { + protected Container extractEventTag(Container pageResult) { var res = super.extractEventTag(pageResult); // remove youtube embeddings if (res instanceof Payload payload) payload.get().find(attributeContains(CLASS,"youtube")).forEach(Tag::remove); @@ -88,7 +91,7 @@ private static final String DEFAULT_LOCATION = "Cosmic Dawn e.V., Spitzweidenweg } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { var page = programPage.optional(); if (page.isEmpty()) return transform(programPage); var list = page.get().find(attributeEquals("class","event_listings_main")); @@ -105,7 +108,7 @@ private static final String DEFAULT_LOCATION = "Cosmic Dawn e.V., Spitzweidenweg } @Override - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { return Payload.of(DEFAULT_LOCATION); } @@ -135,22 +138,22 @@ private static final String DEFAULT_LOCATION = "Cosmic Dawn e.V., Spitzweidenweg } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return null; } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return null; } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { return parseGermanDate(string); } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return parseGermanTime(string); } @@ -161,7 +164,7 @@ private static final String DEFAULT_LOCATION = "Cosmic Dawn e.V., Spitzweidenweg * @return ausgehender InputStream, verpackt in Result */ @Override - protected Result preload(Result inputStream) { + protected Container preload(Container inputStream) { var opt = inputStream.optional(); if (opt.isEmpty()) return transform(inputStream); try { diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/FHaus.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/FHaus.java index 9ae49bc..f3225c5 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/FHaus.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/FHaus.java @@ -2,15 +2,15 @@ package de.srsoftware.cal.importer.jena; import static de.srsoftware.cal.Util.parseGermanTime; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Error.error; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.*; import static de.srsoftware.tools.TagFilter.*; import de.srsoftware.cal.BaseImporter; import de.srsoftware.cal.api.Coords; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.security.NoSuchAlgorithmException; import java.time.LocalDate; @@ -51,7 +51,7 @@ public class FHaus extends BaseImporter { } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { return Payload.of(DEFAULT_COORDS); } @@ -71,7 +71,7 @@ public class FHaus extends BaseImporter { } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { var opt = programPage.optional(); if (opt.isEmpty()) return transform(programPage); List urls = opt.get().find(attributeEquals(CLASS,"tribe-events-calendar-list")) @@ -91,7 +91,7 @@ public class FHaus extends BaseImporter { } @Override - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { return Payload.of(DEFAULT_LOCATION); } @@ -100,14 +100,14 @@ public class FHaus extends BaseImporter { return null; } - protected Result extractStartDate(Tag eventTag) { - Result startDateTag = extractStartDateTag(eventTag); + protected Container extractStartDate(Tag eventTag) { + Container startDateTag = extractStartDateTag(eventTag); var opt = startDateTag.optional(); if (opt.isEmpty()) return transform(startDateTag); return parseStartDate(opt.get().get(TITLE)); } - protected Result extractStartDateTag(Tag eventTag) { + protected Container extractStartDateTag(Tag eventTag) { var list = eventTag.find(extractStartDateFilter()); if (list.isEmpty()) { return error("Failed to find start date tag"); @@ -136,7 +136,7 @@ public class FHaus extends BaseImporter { } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { try { return Payload.of(LocalDate.parse(string, DateTimeFormatter.ISO_DATE)); } catch (Exception e){ @@ -145,12 +145,12 @@ public class FHaus extends BaseImporter { } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return parseGermanTime(string); } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { try { return Payload.of(LocalDate.parse(string, DateTimeFormatter.ISO_DATE)); } catch (Exception e){ @@ -159,7 +159,7 @@ public class FHaus extends BaseImporter { } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return parseGermanTime(string); } diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Kassablanca.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Kassablanca.java index ee816b0..6d24355 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Kassablanca.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Kassablanca.java @@ -2,7 +2,7 @@ package de.srsoftware.cal.importer.jena; import static de.srsoftware.cal.Util.*; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.CLASS; import static de.srsoftware.tools.Tag.DIV; import static de.srsoftware.tools.TagFilter.*; @@ -10,6 +10,9 @@ import static de.srsoftware.tools.TagFilter.*; import de.srsoftware.cal.BaseImporter; import de.srsoftware.cal.api.Coords; import de.srsoftware.tools.*; +import de.srsoftware.tools.container.Container; +import de.srsoftware.tools.container.Payload; + import java.security.NoSuchAlgorithmException; import java.time.LocalDate; import java.time.LocalTime; @@ -46,7 +49,7 @@ public class Kassablanca extends BaseImporter { } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { return Payload.of(COORDS); } @@ -66,7 +69,7 @@ public class Kassablanca extends BaseImporter { } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { if (programPage.optional().isEmpty()) return transform(programPage); List list = programPage.optional() .get() // @@ -86,7 +89,7 @@ public class Kassablanca extends BaseImporter { } @Override - protected Result extractLinksTag(Tag eventTag) { + protected Container extractLinksTag(Tag eventTag) { var top = eventTag.find(attributeEquals(CLASS,"se-container")); var bottom = eventTag.find(attributeEquals(CLASS, "se-content")); var common = Tag.of(DIV).addAll(top).addAll(bottom); @@ -94,7 +97,7 @@ public class Kassablanca extends BaseImporter { } @Override - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { return Payload.of(LOCATION); } @@ -124,22 +127,22 @@ public class Kassablanca extends BaseImporter { } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return null; } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return null; } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { return parseGermanDate(string); } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return parseGermanTime(string); } diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Psychochor.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Psychochor.java index 91f81a7..940aed8 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Psychochor.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Psychochor.java @@ -1,8 +1,8 @@ /* © SRSoftware 2026 */ package de.srsoftware.cal.importer.jena; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Error.error; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.CLASS; import static de.srsoftware.tools.Tag.ID; import static de.srsoftware.tools.TagFilter.*; @@ -10,8 +10,8 @@ import static de.srsoftware.tools.TagFilter.*; import de.srsoftware.cal.SinglePageImporter; import de.srsoftware.cal.Util; import de.srsoftware.cal.api.Coords; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.security.NoSuchAlgorithmException; import java.time.LocalDate; @@ -48,7 +48,7 @@ public class Psychochor extends SinglePageImporter { } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { var list = eventTag.find(ofType("iframe")); if (list.isEmpty()) return error("No iframe found"); return list.stream().map(iframe -> iframe.get("data-src-cmplz")) @@ -57,7 +57,7 @@ public class Psychochor extends SinglePageImporter { .orElseGet(() -> error("No coordinates found!")); } - private Result parseCoords(String s) { + private Container parseCoords(String s) { // TODO: diese Koordinaten sind immer irgendwie daneben!? var latitude = LATITUDE.matcher(s); var longitude = LONGITUDE.matcher(s); @@ -90,7 +90,7 @@ public class Psychochor extends SinglePageImporter { } @Override - protected Result> extractEventTags(Result tagResult) { + protected Container> extractEventTags(Container tagResult) { var opt = tagResult.optional(); if (opt.isEmpty()) return transform(tagResult); @@ -135,17 +135,17 @@ public class Psychochor extends SinglePageImporter { } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return null; } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return null; } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { var matcher = DATE_TIME_PATTERN.matcher(string); if (matcher.find()){ int year = Integer.parseInt(matcher.group(1)); @@ -159,7 +159,7 @@ public class Psychochor extends SinglePageImporter { } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { var matcher = DATE_TIME_PATTERN.matcher(string); if (matcher.find()){ int hour = Integer.parseInt(matcher.group(4)); diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Rosenkeller.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Rosenkeller.java index 048c603..b085a53 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Rosenkeller.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/jena/Rosenkeller.java @@ -2,15 +2,15 @@ package de.srsoftware.cal.importer.jena; import static de.srsoftware.cal.Util.parseGermanTime; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Error.error; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.*; import static de.srsoftware.tools.TagFilter.*; import de.srsoftware.cal.BaseImporter; import de.srsoftware.cal.api.Coords; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.security.NoSuchAlgorithmException; import java.time.LocalDate; @@ -51,12 +51,12 @@ public class Rosenkeller extends BaseImporter { } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { return Payload.of(COORDS); } - protected Result extractEndDate(Tag eventTag) { - Result endDateTag = extractEndDateTag(eventTag); + protected Container extractEndDate(Tag eventTag) { + Container endDateTag = extractEndDateTag(eventTag); var opt = endDateTag.optional(); if (opt.isEmpty()) return transform(endDateTag); return parseEndDate(opt.get().get(TITLE)); @@ -78,7 +78,7 @@ public class Rosenkeller extends BaseImporter { } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { if (programPage.optional().isEmpty()) return transform(programPage); List list = programPage.optional() .get() // @@ -97,7 +97,7 @@ public class Rosenkeller extends BaseImporter { } @Override - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { return Payload.of(DEFAULT_LOCATION); } @@ -106,14 +106,14 @@ public class Rosenkeller extends BaseImporter { return null; } - protected Result extractStartDate(Tag eventTag) { - Result startDateTag = extractStartDateTag(eventTag); + protected Container extractStartDate(Tag eventTag) { + Container startDateTag = extractStartDateTag(eventTag); var opt = startDateTag.optional(); if (opt.isEmpty()) return transform(startDateTag); return parseStartDate(opt.get().get(TITLE)); } - protected Result extractStartDateTag(Tag eventTag) { + protected Container extractStartDateTag(Tag eventTag) { var list = eventTag.find(extractStartDateFilter()); if (list.isEmpty()) { return error("Failed to find start date tag"); @@ -142,7 +142,7 @@ public class Rosenkeller extends BaseImporter { } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { try { return Payload.of(LocalDate.parse(string, DateTimeFormatter.ISO_DATE)); } catch (Exception e){ @@ -151,12 +151,12 @@ public class Rosenkeller extends BaseImporter { } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return parseGermanTime(string); } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { try { return Payload.of(LocalDate.parse(string, DateTimeFormatter.ISO_DATE)); } catch (Exception e){ @@ -165,7 +165,7 @@ public class Rosenkeller extends BaseImporter { } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return parseGermanTime(string); } diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/leipzig/Bandhaus.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/leipzig/Bandhaus.java index 3c1eff9..18142bd 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/leipzig/Bandhaus.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/leipzig/Bandhaus.java @@ -2,16 +2,16 @@ package de.srsoftware.cal.importer.leipzig; import static de.srsoftware.cal.Util.parseGermanTime; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Error.error; +import static de.srsoftware.tools.container.Container.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.Coords; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.security.NoSuchAlgorithmException; import java.time.LocalDate; @@ -49,7 +49,7 @@ public class Bandhaus extends BaseImporter { } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { var list = eventTag.find(attributeHas(CLASS,"evo_location_address")); if (list.isEmpty()) return error("Failed to locate address → failed to locate coords"); var loc = list.getFirst().strip(); @@ -74,7 +74,7 @@ public class Bandhaus extends BaseImporter { } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { var opt = programPage.optional(); if (opt.isEmpty())return transform(programPage); var list = opt.get().find(attributeEquals(ID, "evcal_list")).stream() @@ -91,14 +91,14 @@ public class Bandhaus extends BaseImporter { return attributeEquals("itemprop","description"); } - protected Result extractLocationTag(Tag eventTag){ + protected Container extractLocationTag(Tag eventTag){ var list = eventTag.find(extractLocationFilter()).stream() .flatMap(tag -> tag.find(IS_PARAGRAPH).stream()).toList(); if (list.isEmpty()) return error("Failed to find location tag"); return Payload.of(Tag.of(DIV).addAll(list)); } - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { var location = eventTag.find(extractLocationFilter()).stream() .flatMap(tag -> tag.find(IS_PARAGRAPH).stream()) .map(Tag::strip).collect(Collectors.joining(", ")); @@ -112,17 +112,17 @@ public class Bandhaus extends BaseImporter { } @Override - protected Result extractStartDate(Tag eventTag) { - Result startDateTag = extractStartDateTag(eventTag); + protected Container extractStartDate(Tag eventTag) { + Container startDateTag = extractStartDateTag(eventTag); var opt = startDateTag.optional(); if (opt.isEmpty()) return transform(startDateTag); var dateTag = opt.get(); - Result year = dateTag.find(withAttribute("data-syr")).stream() + Container year = dateTag.find(withAttribute("data-syr")).stream() .map(tag -> tag.get("data-syr")) .map(Util::parseInt).findAny().orElseGet(() -> error("Failed to find start date")); - Result day = dateTag.find(attributeEquals(CLASS, "date")).stream() + Container day = dateTag.find(attributeEquals(CLASS, "date")).stream() .map(Tag::strip).map(Util::parseInt).findAny().orElseGet(() -> error("Failed to find start date")); - Result month = dateTag.find(attributeEquals(CLASS, "month")).stream() + Container month = dateTag.find(attributeEquals(CLASS, "month")).stream() .map(Tag::strip).map(Util::toNumericMonth).findAny().orElseGet(() -> error("Failed to find start date")); if (year.optional().isEmpty()) return transform(year); if (month.optional().isEmpty()) return transform(month); @@ -151,22 +151,22 @@ public class Bandhaus extends BaseImporter { } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return null; } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return null; } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { return null; } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return parseGermanTime(string+" "); } diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/neustadt/Wotufa.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/neustadt/Wotufa.java index 08b9f7e..e67118d 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/neustadt/Wotufa.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/neustadt/Wotufa.java @@ -3,8 +3,8 @@ package de.srsoftware.cal.importer.neustadt; import static de.srsoftware.cal.Util.parseGermanDate; import static de.srsoftware.cal.Util.parseGermanTime; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Error.error; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.CLASS; import static de.srsoftware.tools.Tag.HREF; import static de.srsoftware.tools.TagFilter.*; @@ -12,8 +12,8 @@ import static java.util.function.Predicate.not; import de.srsoftware.cal.BaseImporter; import de.srsoftware.cal.api.Coords; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.security.NoSuchAlgorithmException; import java.time.LocalDate; @@ -53,7 +53,7 @@ public class Wotufa extends BaseImporter { } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { return Payload.of(DEFAULT_COORDS); } @@ -73,7 +73,7 @@ public class Wotufa extends BaseImporter { } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { var opt = programPage.optional(); if (opt.isEmpty()) return transform(programPage); List list = opt.get().find(IS_ANCHOR) @@ -93,8 +93,8 @@ public class Wotufa extends BaseImporter { } @Override - protected Result extractLocation(Tag eventTag) { - Result locationTag = extractLocationTag(eventTag); + protected Container extractLocation(Tag eventTag) { + Container locationTag = extractLocationTag(eventTag); if (locationTag.optional().isEmpty()) return transform(locationTag); var loc = locationTag.optional().get().strip(); @@ -117,7 +117,7 @@ public class Wotufa extends BaseImporter { return cellWithContext("Zeit").or(cellWithContext("Details")); } - protected Result extractStartTimeTag(Tag eventTag) { + protected Container extractStartTimeTag(Tag eventTag) { var list = eventTag.find(extractStartTimeFilter()); if (list.isEmpty()) return error("Failed to find start time tag"); return Payload.of(new Tag("group").addAll(list)); @@ -140,22 +140,22 @@ public class Wotufa extends BaseImporter { } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return null; } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return null; } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { return parseGermanDate(string); } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return parseGermanTime(string).map(res -> res.optional().isEmpty() ? Payload.of(DEFAULT_TIME) : res); } diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/CKeller.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/CKeller.java index 22ba83e..949373b 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/CKeller.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/CKeller.java @@ -1,8 +1,8 @@ /* © SRSoftware 2026 */ package de.srsoftware.cal.importer.weimar; -import static de.srsoftware.tools.Error.error; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Error.error; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.*; import static de.srsoftware.tools.TagFilter.*; import static java.util.Optional.empty; @@ -13,8 +13,8 @@ import de.srsoftware.cal.api.Appointment; import de.srsoftware.cal.api.Attachment; import de.srsoftware.cal.api.Importer; import de.srsoftware.cal.api.Link; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.io.IOException; import java.net.MalformedURLException; @@ -57,7 +57,7 @@ public class CKeller implements Importer { .stream(); } - private Result> extract(Result tagResult) { + private Container> extract(Container tagResult) { var list = new ArrayList(); if (tagResult.optional().isEmpty()) return transform(tagResult); var divs = tagResult.optional().get() @@ -80,8 +80,12 @@ public class CKeller implements Importer { .map(Tag::strip).map(Util::parseInt).findAny().orElseGet(() -> error("No date")).optional(); if (day.isEmpty()) return empty(); - Stream> stream = cal.find(attributeEquals(CLASS, "calmonth")).stream().map(Tag::strip).flatMap(s -> Util.toNumericMonth(s).stream()); - Optional mon = stream.findAny().orElse(error("Error")).optional(); + Optional mon = empty(); + for (Tag calmonth : cal.find(attributeEquals(CLASS, "calmonth"))){ + mon = Util.toNumericMonth(calmonth.strip()).optional(); + if (mon.isPresent()) break; + } + if (mon.isEmpty()) return empty(); var title = text.find(attributeEquals(CLASS,"fett")).stream().map(Tag::strip).findAny(); if (title.isEmpty()) return empty(); @@ -93,14 +97,14 @@ public class CKeller implements Importer { var app = new BaseAppointment(0,title.get(),desc.orElse(title.get()),start,null,LOCATION); text.find(IS_IMAGE).stream().map(tag -> imageToAttachment(tag)) - .map(Result::optional).flatMap(Optional::stream) + .map(Container::optional).flatMap(Optional::stream) .forEach(app::add); app.addLinks(link); app.tags("C-Keller","Weimar"); return Optional.of(app); } - private Result imageToAttachment(Tag img) { + private Container imageToAttachment(Tag img) { var parent = img.parent(); String url = parent.map(tag -> tag.get(HREF)).orElseGet(() -> img.get("src")); if (url == null) return error("No link found"); diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/Gerberstrasse.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/Gerberstrasse.java index a607520..bd7dd71 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/Gerberstrasse.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/Gerberstrasse.java @@ -3,14 +3,14 @@ package de.srsoftware.cal.importer.weimar; import static de.srsoftware.cal.Util.parseGermanDate; import static de.srsoftware.cal.Util.parseGermanTime; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.*; import static de.srsoftware.tools.TagFilter.*; import de.srsoftware.cal.BaseImporter; import de.srsoftware.cal.api.Coords; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.security.NoSuchAlgorithmException; import java.time.LocalDate; @@ -48,7 +48,7 @@ public class Gerberstrasse extends BaseImporter { } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { return Payload.of(DEFAULT_COORDS); } @@ -68,7 +68,7 @@ public class Gerberstrasse extends BaseImporter { } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { var opt = programPage.optional(); if (opt.isEmpty()) return transform(programPage); var list = opt.get().find(attributeEquals(CLASS,"news-list-view")).stream() @@ -89,7 +89,7 @@ public class Gerberstrasse extends BaseImporter { } @Override - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { return Payload.of(DEFAULT_LOCATION); } @@ -119,22 +119,22 @@ public class Gerberstrasse extends BaseImporter { } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return null; } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return null; } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { return parseGermanDate(string); } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return parseGermanTime(string); } diff --git a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/Kasseturm.java b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/Kasseturm.java index 9b26c43..0d7f08b 100644 --- a/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/Kasseturm.java +++ b/de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/Kasseturm.java @@ -1,7 +1,7 @@ /* © SRSoftware 2026 */ package de.srsoftware.cal.importer.weimar; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Container.transform; import static de.srsoftware.tools.Tag.CLASS; import static de.srsoftware.tools.Tag.HREF; import static de.srsoftware.tools.TagFilter.*; @@ -9,8 +9,8 @@ import static de.srsoftware.tools.TagFilter.*; import de.srsoftware.cal.BaseImporter; import de.srsoftware.cal.Util; import de.srsoftware.cal.api.Coords; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import de.srsoftware.tools.Tag; import java.time.LocalDate; import java.time.LocalTime; @@ -38,7 +38,7 @@ public class Kasseturm extends BaseImporter { } @Override - protected Result extractDescriptionTag(Tag eventTag) { + protected Container extractDescriptionTag(Tag eventTag) { var desc = new Tag("div"); super.extractDescriptionTag(eventTag).optional().ifPresent(tag -> tag.find(IS_PARAGRAPH).forEach(desc::add)); return Payload.of(desc); @@ -50,7 +50,7 @@ public class Kasseturm extends BaseImporter { } @Override - protected Result extractCoords(Tag eventTag) { + protected Container extractCoords(Tag eventTag) { return Payload.of(DEFAULT_COORDS); } @@ -70,7 +70,7 @@ public class Kasseturm extends BaseImporter { } @Override - protected Result> extractEventUrls(Result programPage) { + protected Container> extractEventUrls(Container programPage) { var opt = programPage.optional(); if (opt.isEmpty()) return transform(programPage); var list = opt.get() @@ -90,7 +90,7 @@ public class Kasseturm extends BaseImporter { } @Override - protected Result extractLocation(Tag eventTag) { + protected Container extractLocation(Tag eventTag) { String loc = "Kasseturm, Goetheplatz 10, 99423 Weimar"; var opt = super.extractLocation(eventTag).optional(); return Payload.of(opt.map(s -> s.trim()+", "+loc).orElse(loc)); @@ -126,22 +126,22 @@ public class Kasseturm extends BaseImporter { } @Override - protected Result parseEndDate(String string) { + protected Container parseEndDate(String string) { return null; } @Override - protected Result parseEndTime(String string) { + protected Container parseEndTime(String string) { return null; } @Override - protected Result parseStartDate(String string) { + protected Container parseStartDate(String string) { return Util.parseGermanDate(string); } @Override - protected Result parseStartTime(String string) { + protected Container parseStartTime(String string) { return Util.parseGermanTime(string); } diff --git a/de.srsoftware.cal.web/build.gradle.kts b/de.srsoftware.cal.web/build.gradle.kts index 4ab1511..82ebfa5 100644 --- a/de.srsoftware.cal.web/build.gradle.kts +++ b/de.srsoftware.cal.web/build.gradle.kts @@ -5,8 +5,9 @@ dependencies { implementation(project(":de.srsoftware.cal.base")) implementation(project(":de.srsoftware.cal.db")) - implementation("de.srsoftware:tools.http:1.2.4") + implementation("de.srsoftware:tools.container:1.0.6") + implementation("de.srsoftware:tools.http:6.0.5") implementation("de.srsoftware:tools.optionals:1.0.0") - implementation("de.srsoftware:tools.util:1.3.0") + implementation("de.srsoftware:tools.util:2.1.1") implementation("org.json:json:20240303") } diff --git a/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/ApiEndpoint.java b/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/ApiEndpoint.java index 21566bc..478812f 100644 --- a/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/ApiEndpoint.java +++ b/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/ApiEndpoint.java @@ -4,10 +4,10 @@ package de.srsoftware.cal; import static de.srsoftware.cal.Util.extractCoords; import static de.srsoftware.cal.db.Fields.*; import static de.srsoftware.cal.db.Fields.AID; -import static de.srsoftware.tools.Error.error; +import static de.srsoftware.tools.container.Error.error; import static de.srsoftware.tools.Optionals.nullIfEmpty; import static de.srsoftware.tools.Optionals.nullable; -import static de.srsoftware.tools.Result.transform; +import static de.srsoftware.tools.container.Container.transform; import static java.time.format.DateTimeFormatter.ISO_DATE_TIME; import com.sun.net.httpserver.HttpExchange; @@ -16,9 +16,10 @@ import de.srsoftware.cal.api.Link; import de.srsoftware.cal.db.Database; import de.srsoftware.cal.db.NotFound; import de.srsoftware.tools.HttpError; +import de.srsoftware.tools.Path; import de.srsoftware.tools.PathHandler; -import de.srsoftware.tools.Payload; -import de.srsoftware.tools.Result; +import de.srsoftware.tools.container.Payload; +import de.srsoftware.tools.container.Container; import java.io.IOException; import java.time.LocalDateTime; import java.util.Arrays; @@ -45,7 +46,7 @@ public class ApiEndpoint extends PathHandler { this.db = db; } - private Result createEvent(HttpExchange ex) { + private Container createEvent(HttpExchange ex) { try { var res = toEvent(json(ex)); var opt = res.optional(); @@ -62,13 +63,13 @@ public class ApiEndpoint extends PathHandler { } } - private Result delete(String path, HttpExchange ex) { + private Container delete(Path path, HttpExchange ex) { var params = queryParam(ex); var id = params.get(ID); if (id == null) return HttpError.of(400, "Id missing"); long aid = 0; try { - aid = Long.parseLong(id); + aid = Long.parseLong(""+id); } catch (Exception e) { return HttpError.of(404, "%s is not a valid appointment id!", id); } @@ -78,7 +79,7 @@ public class ApiEndpoint extends PathHandler { return db.loadEvent(aid).map(event -> deleteEvent(event, title)).map(ApiEndpoint::httpError); } - private Result deleteEvent(Result eventResult, String title) { + private Container deleteEvent(Container eventResult, String title) { var opt = eventResult.optional(); if (opt.isEmpty()) return transform(eventResult); var event = opt.get(); @@ -87,57 +88,58 @@ public class ApiEndpoint extends PathHandler { } @Override - public boolean doDelete(String path, HttpExchange ex) throws IOException { - if ("/event".equals(path)) return sendContent(ex, delete(path, ex)); + public boolean doDelete(Path path, HttpExchange ex) throws IOException { + if (path.equals("/event")) return sendContent(ex, delete(path, ex)); return unknownPath(ex, path); } @Override - public boolean doGet(String path, HttpExchange ex) throws IOException { + public boolean doGet(Path p, HttpExchange ex) throws IOException { String hostname = hostname(ex); String urlTemplate = hostname+"/static/event?id={}"; String prodId = "OpenCloudCal@"+hostname.split("://",2)[1]; ex.getResponseHeaders().add("Access-Control-Allow-Origin","*"); + var path = p.toString(); return switch (path) { - case "/event" -> sendContent(ex,getEvent(ex).map(event -> toJson(event,urlTemplate)).map(ApiEndpoint::httpError)); - case "/event/ical"-> sendContent(ex,getEvent(ex).map(event -> toIcal(event, hostname, urlTemplate)).map(ical -> Util.wrapIcal(ical,prodId)).map(ApiEndpoint::httpError)); - case "/events/ical"-> sendContent(ex,eventList(ex).map(list -> toIcalList(list, hostname, urlTemplate)).map(ical -> Util.wrapIcal(ical,prodId)).map(ApiEndpoint::httpError)); - case "/events/json" -> sendContent(ex,eventList(ex).map(list -> toJsonList(list,urlTemplate)).map(ApiEndpoint::httpError)); - case "/tags" -> listTags(ex); - default -> unknownPath(ex, path); + case "event" -> sendContent(ex,(Container)getEvent(ex).map(event -> toJson(event, urlTemplate)).map(ApiEndpoint::httpError)); + case "event/ical"-> sendContent(ex,(Container)getEvent(ex).map(event -> toIcal(event, hostname, urlTemplate)).map(ical -> Util.wrapIcal(ical,prodId)).map(ApiEndpoint::httpError)); + case "events/ical"-> sendContent(ex,(Container)eventList(ex).map(list -> toIcalList(list, hostname, urlTemplate)).map(ical -> Util.wrapIcal(ical,prodId)).map(ApiEndpoint::httpError)); + case "events/json" -> sendContent(ex,(Container)eventList(ex).map(list -> toJsonList(list,urlTemplate)).map(ApiEndpoint::httpError)); + case "tags" -> listTags(ex); + default -> unknownPath(ex, p); }; } @Override - public boolean doPatch(String path, HttpExchange ex) throws IOException { - if ("/event".equals(path)) return sendContent(ex, updateEvent(ex)); + public boolean doPatch(Path path, HttpExchange ex) throws IOException { + if (path.equals("/event")) return sendContent(ex, updateEvent(ex)); return unknownPath(ex, path); } @Override - public boolean doPost(String path, HttpExchange ex) throws IOException { - if ("/event".equals(path)) return sendContent(ex, createEvent(ex)); + public boolean doPost(Path path, HttpExchange ex) throws IOException { + if (path.equals("/event")) return sendContent(ex, createEvent(ex)); return unknownPath(ex, path); } - private Result> eventList(HttpExchange ex) { + private Container> eventList(HttpExchange ex) { var param = queryParam(ex); - var tags = nullable(param.get(TAGS)).stream() + var tags = nullable((String)param.get(TAGS)).stream() .flatMap(s -> Arrays.stream(s.split(","))) .map(s -> s.trim().toLowerCase()) .toList(); - Result start = parseDate(param.get(START)); + Container start = parseDate(param.get(START)); if (start == null) start = parsePast(param.get(PAST)); - if (start instanceof de.srsoftware.tools.Error err) return err.transform(); + if (start instanceof de.srsoftware.tools.container.Error err) return err.transform(); var startDate = (start == null) ? null: start.optional().orElse(null); Integer offset = null; var o = param.get(OFFSET); - if (o != null) try { - offset = Integer.parseInt(o); + if (o instanceof String s) try { + offset = Integer.parseInt(s); } catch (NumberFormatException e) { return HttpError.of(400,"Offset (offset=%s) is not a number!", o); } @@ -145,19 +147,19 @@ public class ApiEndpoint extends PathHandler { Integer count = null; o = param.get(COUNT); - if (o != null) try { - count = Integer.parseInt(o); + if (o instanceof String s) try { + count = Integer.parseInt(s); } catch (NumberFormatException e) { return HttpError.of(400,"Count (count=%s) is not a number!", o); } - Result end = parseDate(param.get(END)); + Container end = parseDate(param.get(END)); var endDate = (end == null) ? null: end.optional().orElse(null); return db.list(startDate, endDate, count, offset, tags).map(res -> filterByTags(res, tags)); } - private Result> filterByTags(Result> res, List tags) { + private Container> filterByTags(Container> res, List tags) { if (tags == null || tags.isEmpty()) return res; var opt = res.optional(); if (opt.isEmpty()) return transform(res); @@ -165,32 +167,32 @@ public class ApiEndpoint extends PathHandler { return Payload.of(list); } - private Result getEvent(HttpExchange ex) { + private Container getEvent(HttpExchange ex) { var params = queryParam(ex); var o = params.get(ID); - if (o == null) return HttpError.of(400,"id parameter missing!"); + if (!(o instanceof String s)) return HttpError.of(400,"id parameter missing!"); try { - return db.loadEvent(Long.parseLong(o)); + return db.loadEvent(Long.parseLong(s)); } catch (NumberFormatException e) { return HttpError.of(400,e, "Illegal format for id parameter (%s)", o); } } - private static Result httpError(Result res) { + private static Container httpError(Container res) { if (res instanceof NotFound notFound) return HttpError.of(404, notFound.message()); return res; } private boolean listTags(HttpExchange ex) throws IOException { var params = queryParam(ex); - var infix = nullIfEmpty(params.get("infix")); + var infix = nullIfEmpty((String)params.get("infix")); if (infix == null) return sendContent(ex, HttpError.of(400,"No infix set in method call parameters")); var res = db.findTags(infix).map(ApiEndpoint::sortTags); return sendContent(ex, res); } - public static Result parseDate(String s) { - if (s == null) return null; + public static Container parseDate(Object o) { + if (!(o instanceof String s)) return null; var matcher = DATE_TIME.matcher(s); if (matcher.find()) { int year = Integer.parseInt(matcher.group(1)); @@ -204,9 +206,9 @@ public class ApiEndpoint extends PathHandler { return error("invalid date time format: %s", s); } - public static Result parsePast(String s) { + public static Container parsePast(Object o) { var start = LocalDateTime.now().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0); - if (s == null) return Payload.of(start); + if (!(o instanceof String s)) return Payload.of(start); var matcher = PAST_PATTERN.matcher(s); if (matcher.find()) { int num = nullable(matcher.group(1)).map(Integer::parseInt).orElse(0); @@ -226,7 +228,7 @@ public class ApiEndpoint extends PathHandler { return error("invalid past format: %s", s); } - private static Result> sortTags(Result> listResult) { + private static Container> sortTags(Container> listResult) { if (listResult.optional().isEmpty()) return listResult; List list = listResult.optional().get(); while (list.size() > 15) { @@ -242,7 +244,7 @@ public class ApiEndpoint extends PathHandler { return new HashSet<>(event.tags().stream().map(String::toLowerCase).toList()).containsAll(tags); } - private Result toEvent(JSONObject json) { + private Container toEvent(JSONObject json) { var description = json.has(DESCRIPTION) ? nullIfEmpty(json.getString(DESCRIPTION)) : null; var title = json.has(TITLE) ? nullIfEmpty(json.getString(TITLE)) : null; if (title == null) return error("title missing"); @@ -274,31 +276,31 @@ public class ApiEndpoint extends PathHandler { return Payload.of(event); } - private static Result toIcal(Result res, String hostname, String urlTemplate) { + private static Container toIcal(Container res, String hostname, String urlTemplate) { var opt = res.optional(); return opt.isEmpty() ? transform(res) : Payload.of(opt.get().ical(hostname, urlTemplate)); } - private static Result toIcalList(Result> res, String hostname, String urlTemplate) { + private static Container toIcalList(Container> res, String hostname, String urlTemplate) { var opt = res.optional(); if (opt.isEmpty()) return transform(res); var list = opt.get().stream().map(event -> event.ical(hostname, urlTemplate)).collect(Collectors.joining("\n")); return Payload.of(list); } - private static Result toJson(Result res, String urlTemplate) { + private static Container toJson(Container res, String urlTemplate) { var opt = res.optional(); return opt.isEmpty() ? transform(res) : Payload.of(opt.get().json(urlTemplate)); } - private static Result> toJsonList(Result> res, String urlTemplate) { + private static Container> toJsonList(Container> res, String urlTemplate) { var opt = res.optional(); if (opt.isEmpty()) return transform(res); var list = opt.get().stream().map(event -> event.json(urlTemplate)).toList(); return Payload.of(list); } - protected static Result toLink(JSONObject json) { + protected static Container toLink(JSONObject json) { try { var description = json.getString(DESCRIPTION); return Payload.of(json.getString(URL)) @@ -309,11 +311,11 @@ public class ApiEndpoint extends PathHandler { } } - private boolean unknownPath(HttpExchange ex, String path) throws IOException { + private boolean unknownPath(HttpExchange ex, Path path) throws IOException { return sendContent(ex, HttpError.of(404, "%s is not known to this API", path)); } - private Result updateEvent(HttpExchange ex) { + private Container updateEvent(HttpExchange ex) { try { var res = toEvent(json(ex)); var opt = res.optional(); diff --git a/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/Forward.java b/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/Forward.java index 41221f5..3b904b7 100644 --- a/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/Forward.java +++ b/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/Forward.java @@ -5,13 +5,14 @@ import static de.srsoftware.tools.Optionals.nullable; import com.sun.net.httpserver.HttpExchange; import de.srsoftware.tools.HttpError; +import de.srsoftware.tools.Path; import de.srsoftware.tools.PathHandler; import java.io.IOException; public class Forward extends PathHandler { @Override - public boolean doGet(String path, HttpExchange ex) throws IOException { + public boolean doGet(Path path, HttpExchange ex) throws IOException { var params = queryParam(ex); var show = nullable(params.get("show")); if (show.isPresent()) return sendRedirect(ex,"/static/event?id="+show.get()); diff --git a/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/IndexHandler.java b/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/IndexHandler.java index 83544ae..87f54dc 100644 --- a/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/IndexHandler.java +++ b/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/IndexHandler.java @@ -2,6 +2,7 @@ package de.srsoftware.cal; import com.sun.net.httpserver.HttpExchange; +import de.srsoftware.tools.Path; import de.srsoftware.tools.PathHandler; import java.io.IOException; @@ -13,10 +14,10 @@ public class IndexHandler extends PathHandler { } @Override - public boolean doGet(String path, HttpExchange ex) throws IOException { - return switch (path) { - case "/" -> staticPages.doGet("/index", ex); - case "/favicon.ico" -> staticPages.doGet("/images/%s".formatted(path), ex); + public boolean doGet(Path path, HttpExchange ex) throws IOException { + return switch (path.toString()) { + case "/" -> staticPages.doGet(Path.of("/index"), ex); + case "/favicon.ico" -> staticPages.doGet(Path.of("/images/%s".formatted(path)), ex); default -> super.doGet(path, ex); }; } diff --git a/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/StaticHandler.java b/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/StaticHandler.java index ae7075f..604fa77 100644 --- a/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/StaticHandler.java +++ b/de.srsoftware.cal.web/src/main/java/de/srsoftware/cal/StaticHandler.java @@ -16,7 +16,8 @@ public class StaticHandler extends PathHandler { } @Override - public boolean doGet(String path, HttpExchange ex) throws IOException { + public boolean doGet(de.srsoftware.tools.Path p, HttpExchange ex) throws IOException { + var path = p.toString(); if (!path.contains(".")) path += ".html"; if (path.startsWith("/")) path = path.substring(1); var url = getClass().getClassLoader().getResource(path); @@ -24,14 +25,14 @@ public class StaticHandler extends PathHandler { var file = Path.of(staticPath.get()).resolve(path).toFile(); if (file.exists() && file.isFile()) url = file.toURI().toURL(); } - if (url == null) return PathHandler.notFound(ex); + if (url == null) return notFound(ex); var conn = url.openConnection(); var mime = conn.getContentType(); try (var input = conn.getInputStream()) { var bos = new ByteArrayOutputStream(); input.transferTo(bos); ex.getResponseHeaders().add(PathHandler.CONTENT_TYPE, mime); - return PathHandler.sendContent(ex, bos.toByteArray()); + return sendContent(ex, bos.toByteArray()); } } }