Browse Source

added CKeller parser

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
main
Stephan Richter 4 months ago
parent
commit
5cea69ebab
  1. 112
      de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/CKeller.java

112
de.srsoftware.cal.importer/src/main/java/de/srsoftware/cal/importer/weimar/CKeller.java

@ -1,4 +1,114 @@ @@ -1,4 +1,114 @@
/* © SRSoftware 2024 */
package de.srsoftware.cal.importer.weimar;
public class CKeller {
import static de.srsoftware.tools.Error.error;
import static de.srsoftware.tools.Optionals.nullable;
import static de.srsoftware.tools.Result.transform;
import static de.srsoftware.tools.Tag.*;
import static de.srsoftware.tools.TagFilter.*;
import static java.util.Optional.empty;
import de.srsoftware.cal.BaseAppointment;
import de.srsoftware.cal.Util;
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.Tag;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
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;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public class CKeller implements Importer {
private static final String BASE_URL = "http://c-keller.de";
private static final Pattern YEAR_PATTERN = Pattern.compile("^(\\d{4}):?$");
private static final Pattern EVENT_PATTERN = Pattern.compile("\\D*(\\d\\d?).(\\d\\d?). *([^&]+)&[^;]+;(.*)");
private static final String LOCATION = "C-Keller, Markt 21, 99423 Weimar";
private static final LocalTime START_TIME = LocalTime.of(19,0);
private final Link link;
public CKeller() throws MalformedURLException {
link = new Link(URI.create(BASE_URL).toURL(),"Homepage");
}
@Override
public String description() {
return "Importer für Events des C-Keller in Weimar";
}
@Override
public Stream<Appointment> fetch() throws IOException {
return Payload.of(BASE_URL)
.map(Util::url)
.map(Util::open)
.map(Util::preload)
.map(Util::parseXML)
.map(this::extract)
.optional()
.orElseGet(List::of)
.stream();
}
private Result<List<Appointment>> extract(Result<Tag> tagResult) {
var list = new ArrayList<Appointment>();
if (tagResult.optional().isEmpty()) return transform(tagResult);
Util.dump(tagResult.optional().get());
var divs = tagResult.optional().get()
.find(attributeEquals(ID,"col2_content")).stream()
.flatMap(tag -> tag.children().stream())
.toList();
Tag last = null;
var now = LocalDate.now();
for (var div : divs){
if ("textumschluss".equals(div.get(ID))){
createEvent(last,div,now).ifPresent(list::add);
}
last = div;
}
return Payload.of(list);
}
private Optional<Appointment> createEvent(Tag cal, Tag text, LocalDate now) {
var day = cal.find(attributeEquals(CLASS, "calday")).stream()
.map(Tag::strip).map(Util::parseInt).findAny().orElseGet(() -> error("No date")).optional();
if (day.isEmpty()) return empty();
Stream<Result<Integer>> stream = cal.find(attributeEquals(CLASS, "calmonth")).stream().map(Tag::strip).flatMap(s -> Util.toNumericMonth(s).stream());
Optional<Integer> mon = stream.findAny().orElse(error("Error")).optional();
if (mon.isEmpty()) return empty();
var title = text.find(attributeEquals(CLASS,"fett")).stream().map(Tag::strip).findAny();
if (title.isEmpty()) return empty();
var desc = text.find(attributeEquals(CLASS,"kalenderi")).stream().map(Tag::strip).findAny();
var date = LocalDate.of(now.getYear(),mon.get(),day.get());
if (date.isBefore(now)) date = date.withYear(now.getYear()+1);
var start = LocalDateTime.of(date,START_TIME);
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)
.forEach(app::add);
app.addLinks(link);
app.tags("C-Keller","Weimar");
return Optional.of(app);
}
private Result<Attachment> 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");
if (url.startsWith("./")) url = url.substring(2);
if (!url.contains("://")) url = BASE_URL + "/" + url;
return Payload.of(url).map(Util::url).map(Util::toAttachment);
}
}

Loading…
Cancel
Save