new features:

- database now ignoring duplicates isntead of failing
- automatic loading of importer plugins
- automatic tagging

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2025-01-01 02:09:18 +01:00
parent 50e7f2e71d
commit 211c92b0e3
10 changed files with 341 additions and 21 deletions
+1 -1
View File
@@ -5,6 +5,6 @@ dependencies {
implementation("de.srsoftware:tools.optionals:1.0.0")
implementation("de.srsoftware:tools.util:1.3.0")
implementation("de.srsoftware:tools.web:1.3.8")
implementation("de.srsoftware:tools.web:1.3.9")
implementation("org.json:json:20240303")
}
@@ -46,6 +46,7 @@ public abstract class BaseImporter implements Importer {
.flatMap(tag -> tag.find(TagFilter.ofType("img")).stream())
.map(tag -> tag.get("src"))
.filter(Objects::nonNull)
.map(url -> url.contains("://") ? url : baseUrl()+url)
.map(Payload::of)
.map(BaseImporter::url)
.map(BaseImporter::toAttachment)
@@ -59,9 +60,11 @@ public abstract class BaseImporter implements Importer {
}
protected Result<String> extractDescription(Tag eventTag) {
Result<Tag> titleTag = extractDescriptionTag(eventTag);
if (titleTag.optional().isEmpty()) return transform(titleTag);
var inner = titleTag.optional().flatMap(tag -> tag.inner(2));
Result<Tag> descriptionTag = extractDescriptionTag(eventTag);
if (descriptionTag.optional().isEmpty()) return transform(descriptionTag);
Tag tag = descriptionTag.optional().get();
tag.find(t -> t.is("iframe")).forEach(Tag::remove);
var inner = tag.inner(2);
if (inner.isPresent()) return Payload.of(inner.get());
return error("No description found");
}
@@ -105,6 +108,7 @@ public abstract class BaseImporter implements Importer {
var event = new BaseAppointment(id, title, description, start, end, location) //
.add(extractAttachments(eventTag))
.addLinks(extractLinks(eventTag))
.addLinks(eventPage)
.tags(extractTags(eventTag));
extractCoords(eventTag).optional().ifPresent(event::coords);
@@ -184,13 +188,13 @@ public abstract class BaseImporter implements Importer {
@Override
public Stream<Appointment> fetch() {
var url = Payload.of(programURL());
Stream<Result<String>> stream = url(url)
Stream<Result<String>> urls = url(url)
.map(this::open) //
.map(this::preload)
.map(this::parseXML)
.map(this::extractEventUrls)
.stream();
return stream //
return urls //
.map(BaseImporter::url)
.map(this::loadEvent)
.peek(e -> {