Proof of Concept (POC)
This commit is contained in:
commit
bfed2d431e
10 changed files with 305 additions and 0 deletions
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
7
.idea/encodings.xml
generated
Normal file
7
.idea/encodings.xml
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
14
.idea/misc.xml
generated
Normal file
14
.idea/misc.xml
generated
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" default="true" project-jdk-name="graalvm-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
1
README.md
Normal file
1
README.md
Normal file
|
@ -0,0 +1 @@
|
|||
...TODO
|
29
pom.xml
Normal file
29
pom.xml
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.wuevents</groupId>
|
||||
<artifactId>wuevents</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>23</maven.compiler.source>
|
||||
<maven.compiler.target>23</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>1.17.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.18.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
15
src/main/java/org/wuevents/App.java
Normal file
15
src/main/java/org/wuevents/App.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package org.wuevents;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class App {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
//new Kellerperle().fetch();
|
||||
new Cairo().fetch();
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
79
src/main/java/org/wuevents/Cairo.java
Normal file
79
src/main/java/org/wuevents/Cairo.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
package org.wuevents;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.jsoup.Connection;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Element;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
class Cairo {
|
||||
|
||||
static String venue_name = "Cairo";
|
||||
static String venue_url = "https://cairo.wue.de";
|
||||
static String venue_address = "Fred-Joseph-Platz 3, 97082 Würzburg";
|
||||
|
||||
Logger logger = Logger.getLogger("org.wuevents");
|
||||
Connection connection;
|
||||
ObjectMapper objectMapper;
|
||||
|
||||
public Cairo() {
|
||||
this.connection = Jsoup.connect("https://cairo.wue.de/programm");
|
||||
this.objectMapper = new ObjectMapper();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract, transform, load (ETL)
|
||||
*/
|
||||
void fetch() throws IOException, InterruptedException {
|
||||
|
||||
var input = connection.get();
|
||||
var output = objectMapper.createObjectNode();
|
||||
|
||||
output.put("created", Instant.now().toString());
|
||||
|
||||
var venue = objectMapper.createObjectNode();
|
||||
venue.put("name", venue_name);
|
||||
venue.put("url", venue_url);
|
||||
venue.put("address", venue_address);
|
||||
output.put("venue", venue);
|
||||
|
||||
var events = objectMapper.createArrayNode();
|
||||
var items = input.select("h2.event-name > a");
|
||||
Consumer<Element> consumer = element -> events.add(event((element)));
|
||||
items.forEach(consumer);
|
||||
|
||||
output.put("events", events);
|
||||
objectMapper.writeValue(System.out, output);
|
||||
|
||||
logger.info("Cairo...................................................................[DONE]");
|
||||
}
|
||||
|
||||
JsonNode event(Element link) {
|
||||
var event = objectMapper.createObjectNode();
|
||||
try {
|
||||
var document = connection.newRequest(venue_url + link.attr("href")).get();
|
||||
var title = document.title();
|
||||
var url = venue_url + link.attr("href");
|
||||
var date = document.select(".event-date > .data-date").text();
|
||||
var begin = document.select(".event-start > .data-start").text();
|
||||
var doors = document.select(".event-entrance > .data-entrance").text();
|
||||
var description = document.select(".event-info-right").remove().text();
|
||||
|
||||
event.put("title", title);
|
||||
event.put("url", url);
|
||||
event.put("description", description);
|
||||
event.put("date", date);
|
||||
event.put("doors", doors);
|
||||
event.put("begin", begin);
|
||||
return event;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
62
src/main/java/org/wuevents/Kellerperle.java
Normal file
62
src/main/java/org/wuevents/Kellerperle.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
package org.wuevents;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.time.Instant;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
class Kellerperle {
|
||||
|
||||
static String venue_name = "Kellerperle";
|
||||
static String venue_url = "https://www.kellerperle.de";
|
||||
static String venue_address = "Am Studentenhaus 1, 97072 Würzburg";
|
||||
|
||||
Logger logger = Logger.getLogger("org.wuevents");
|
||||
|
||||
/**
|
||||
* Extract, transform, load (ETL)
|
||||
*/
|
||||
void fetch() throws IOException, InterruptedException {
|
||||
var uri = URI.create("https://www.kellerperle.de/programm.json");
|
||||
var http = HttpClient.newHttpClient();
|
||||
var request = HttpRequest.newBuilder(uri).build();
|
||||
var response = http.send(request, HttpResponse.BodyHandlers.ofInputStream());
|
||||
|
||||
var responseInputStream = response.body();
|
||||
var parser = new ObjectMapper();
|
||||
var input = parser.readTree(responseInputStream);
|
||||
var output = parser.createObjectNode();
|
||||
|
||||
output.put("created", Instant.now().toString());
|
||||
|
||||
var venue = parser.createObjectNode();
|
||||
venue.put("name", venue_name);
|
||||
venue.put("url", venue_url);
|
||||
venue.put("address", venue_address);
|
||||
output.put("venue", venue);
|
||||
|
||||
var events = parser.createArrayNode();
|
||||
for (var item : input) {
|
||||
var event = parser.createObjectNode();
|
||||
event.put("title", item.get("title"));
|
||||
event.put("url", "https://www.kellerperle.de/#/" + item.get("vaId").asText());
|
||||
event.put("description", item.get("text"));
|
||||
event.put("date", item.get("date"));
|
||||
event.put("doors", item.get("einlass"));
|
||||
event.put("begin", item.get("beginn"));
|
||||
event.put("price", item.get("ak"));
|
||||
events.add(event);
|
||||
}
|
||||
output.put("events", events);
|
||||
|
||||
parser.writeValue(System.out, output);
|
||||
|
||||
logger.info("Kellerperle.............................................................[DONE]");
|
||||
}
|
||||
|
||||
}
|
52
src/schema/schema.json
Normal file
52
src/schema/schema.json
Normal file
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://events.wue.social/schema.json",
|
||||
"title": "wuevents",
|
||||
"description": "A description of wuevents.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created": {
|
||||
"type": "string"
|
||||
},
|
||||
"venue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"address": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["name", "url", "address"]
|
||||
},
|
||||
"events": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"date": {
|
||||
"type": "string"
|
||||
},
|
||||
"doors": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["created", "venue", "events"]
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue