implement routes for MediaFile, MediaVideo and MediaLofi
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s

This commit is contained in:
2026-08-23 21:31:49 +02:00
parent ec274a60d9
commit 8cc58aed5b
41 changed files with 439 additions and 158 deletions
+1
View File
@@ -64,6 +64,7 @@ dependencies {
implementation libs.jackson implementation libs.jackson
implementation libs.gson implementation libs.gson
implementation libs.json implementation libs.json
implementation libs.jsoup
implementation 'org.hibernate.orm:hibernate-community-dialects' implementation 'org.hibernate.orm:hibernate-community-dialects'
testImplementation('org.springframework.boot:spring-boot-starter-test') { testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
+2
View File
@@ -20,6 +20,7 @@ lombok = "8.11"
gson = "2.9.0" gson = "2.9.0"
jackson = "2.16.1" jackson = "2.16.1"
json_simple = "1.1.1" json_simple = "1.1.1"
jsoup = "1.23.1"
mail = "1.6.2" mail = "1.6.2"
hypersistence = "3.9.10" hypersistence = "3.9.10"
jolokia = "2.6.1" jolokia = "2.6.1"
@@ -36,6 +37,7 @@ picocli = { module = "info.picocli:picocli", version.ref = "picoli" }
slf4j = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } slf4j = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
hsqldb = { module = "org.hsqldb:hsqldb", version.ref = "hsqldb" } hsqldb = { module = "org.hsqldb:hsqldb", version.ref = "hsqldb" }
gson = { module = "com.google.code.gson:gson", version.ref = "gson" } gson = { module = "com.google.code.gson:gson", version.ref = "gson" }
jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" }
jackson = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } jackson = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" }
json = { module = "com.googlecode.json-simple:json-simple", version.ref ="json_simple" } json = { module = "com.googlecode.json-simple:json-simple", version.ref ="json_simple" }
mail = { module = "com.sun.mail:javax.mail", version.ref ="mail" } mail = { module = "com.sun.mail:javax.mail", version.ref ="mail" }
@@ -14,8 +14,6 @@ import org.springframework.boot.test.context.SpringBootTest;
import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid;
import de.thpeetz.kontor.data.tysc.CardSet; import de.thpeetz.kontor.data.tysc.CardSet;
import de.thpeetz.kontor.views.tysc.CardSetForm;
import de.thpeetz.kontor.views.tysc.CardSetView;
@SpringBootTest @SpringBootTest
class CardSetViewTest { class CardSetViewTest {
@@ -14,8 +14,6 @@ import org.springframework.boot.test.context.SpringBootTest;
import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid;
import de.thpeetz.kontor.data.tysc.Card; import de.thpeetz.kontor.data.tysc.Card;
import de.thpeetz.kontor.views.tysc.CardForm;
import de.thpeetz.kontor.views.tysc.CardView;
@SpringBootTest @SpringBootTest
class CardViewTest { class CardViewTest {
@@ -14,8 +14,6 @@ import org.springframework.boot.test.context.SpringBootTest;
import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid;
import de.thpeetz.kontor.data.tysc.FieldPosition; import de.thpeetz.kontor.data.tysc.FieldPosition;
import de.thpeetz.kontor.views.tysc.PositionForm;
import de.thpeetz.kontor.views.tysc.PositionView;
@SpringBootTest @SpringBootTest
class FieldPositionViewTest { class FieldPositionViewTest {
@@ -14,8 +14,6 @@ import org.springframework.boot.test.context.SpringBootTest;
import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid;
import de.thpeetz.kontor.data.tysc.Player; import de.thpeetz.kontor.data.tysc.Player;
import de.thpeetz.kontor.views.tysc.PlayerForm;
import de.thpeetz.kontor.views.tysc.PlayerView;
@SpringBootTest @SpringBootTest
class PlayerViewTest { class PlayerViewTest {
@@ -14,8 +14,6 @@ import org.springframework.boot.test.context.SpringBootTest;
import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid;
import de.thpeetz.kontor.data.tysc.Rooster; import de.thpeetz.kontor.data.tysc.Rooster;
import de.thpeetz.kontor.views.tysc.RoosterForm;
import de.thpeetz.kontor.views.tysc.RoosterView;
@SpringBootTest @SpringBootTest
class RoosterViewTest { class RoosterViewTest {
@@ -14,8 +14,6 @@ import org.springframework.boot.test.context.SpringBootTest;
import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid;
import de.thpeetz.kontor.data.tysc.Sport; import de.thpeetz.kontor.data.tysc.Sport;
import de.thpeetz.kontor.views.tysc.SportForm;
import de.thpeetz.kontor.views.tysc.SportView;
@SpringBootTest @SpringBootTest
class SportViewTest { class SportViewTest {
@@ -14,8 +14,6 @@ import org.springframework.boot.test.context.SpringBootTest;
import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid;
import de.thpeetz.kontor.data.tysc.Team; import de.thpeetz.kontor.data.tysc.Team;
import de.thpeetz.kontor.views.tysc.TeamForm;
import de.thpeetz.kontor.views.tysc.TeamView;
@SpringBootTest @SpringBootTest
class TeamViewTest { class TeamViewTest {
@@ -14,8 +14,6 @@ import org.springframework.boot.test.context.SpringBootTest;
import com.vaadin.flow.component.grid.Grid; import com.vaadin.flow.component.grid.Grid;
import de.thpeetz.kontor.data.tysc.Vendor; import de.thpeetz.kontor.data.tysc.Vendor;
import de.thpeetz.kontor.views.tysc.VendorForm;
import de.thpeetz.kontor.views.tysc.VendorView;
@SpringBootTest @SpringBootTest
class VendorViewTest { class VendorViewTest {
@@ -25,6 +25,12 @@ public class MediaConstants {
private static final String MEDIAARTICLE = "Media Article"; private static final String MEDIAARTICLE = "Media Article";
private static final String MEDIAACTOR = "Media Actor"; private static final String MEDIAACTOR = "Media Actor";
public static final String URL = "url";
public static final String LINKTITLE = "linkTitle";
public static final String LOFI_ID = "lofi_id";
public static final String FILE_ID = "file_id";
public static final String VIDEO_ID = "video_id";
public static SideNavItem getMediaNavigation(ArrayList<String> roles) { public static SideNavItem getMediaNavigation(ArrayList<String> roles) {
SideNavItem media = new SideNavItem(MEDIA, MEDIAFILE_ROUTE, VaadinIcon.VIMEO.create()); SideNavItem media = new SideNavItem(MEDIA, MEDIAFILE_ROUTE, VaadinIcon.VIMEO.create());
media.addItem(new SideNavItem(MEDIAVIDEO, MediaVideoView.class)); media.addItem(new SideNavItem(MEDIAVIDEO, MediaVideoView.class));
@@ -0,0 +1,32 @@
package de.thpeetz.kontor.data.media;
import de.thpeetz.kontor.data.common.AbstractEntity;
import jakarta.annotation.Nullable;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "url" }) })
public class MediaLofi extends AbstractEntity {
private String url;
private boolean review;
private boolean shouldDownload;
@Nullable
private String title;
@Nullable
private String fileName;
}
@@ -4,6 +4,7 @@ import org.apache.camel.builder.RouteBuilder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import de.thpeetz.kontor.constants.MediaConstants;
import de.thpeetz.kontor.integration.services.CheckLinkProcessor; import de.thpeetz.kontor.integration.services.CheckLinkProcessor;
import de.thpeetz.kontor.services.MediaFileService; import de.thpeetz.kontor.services.MediaFileService;
@@ -32,10 +33,7 @@ public class QueueMediaLink extends RouteBuilder {
.trace(true) .trace(true)
.process(new CheckLinkProcessor(mediaFileService)) .process(new CheckLinkProcessor(mediaFileService))
.choice() .choice()
.when(exchangeProperty("linkId").isNotNull()) .when(header(MediaConstants.FILE_ID).isNotNull()).to("jms:queue:media.link.duplicate")
.to("jms:queue:media.link.add") .otherwise().to("jms:queue:media.link.add");
.otherwise()
.to("jms:queue:DLQ")
.to("jms:queue:media.link.processed");
} }
} }
@@ -1,9 +1,11 @@
package de.thpeetz.kontor.integration.routes; package de.thpeetz.kontor.integration.routes;
import org.apache.camel.builder.RouteBuilder; import org.apache.camel.builder.RouteBuilder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import de.thpeetz.kontor.integration.services.AddLinkProcessor; import de.thpeetz.kontor.integration.services.AddLinkProcessor;
import de.thpeetz.kontor.integration.services.UrlTitleProcessor;
import de.thpeetz.kontor.services.MediaFileService; import de.thpeetz.kontor.services.MediaFileService;
@Component @Component
@@ -20,11 +22,11 @@ public class QueueMediaLinkAdd extends RouteBuilder {
@Override @Override
public void configure() throws Exception { public void configure() throws Exception {
from("jms:queue:media.link.add") from("jms:queue:media.link.add")
.routeId("read-queue-media-link-add") .routeId("media.link.add")
.log("${body}") .log("${body}")
.trace(true) .trace(true)
.process(new UrlTitleProcessor())
.process(new AddLinkProcessor(mediaFileService)) .process(new AddLinkProcessor(mediaFileService))
.to("jms:queue:media.link.update_title")
.to("jms:queue:media.link.add.processed"); .to("jms:queue:media.link.add.processed");
} }
} }
@@ -4,18 +4,19 @@ import org.apache.camel.builder.RouteBuilder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import de.thpeetz.kontor.constants.MediaConstants;
import de.thpeetz.kontor.integration.services.CheckLoFiProcessor; import de.thpeetz.kontor.integration.services.CheckLoFiProcessor;
import de.thpeetz.kontor.services.MediaFileService; import de.thpeetz.kontor.services.MediaLofiService;
@Component @Component
public class QueueMediaLoFi extends RouteBuilder { public class QueueMediaLoFi extends RouteBuilder {
@Autowired @Autowired
private final MediaFileService mediaFileService; private final MediaLofiService mediaLofiService;
@Autowired @Autowired
public QueueMediaLoFi(MediaFileService mediaFileService) { public QueueMediaLoFi(MediaLofiService mediaLofiService) {
this.mediaFileService = mediaFileService; this.mediaLofiService = mediaLofiService;
} }
@Override @Override
@@ -30,12 +31,10 @@ public class QueueMediaLoFi extends RouteBuilder {
.routeId("media.lofi") .routeId("media.lofi")
.log("${body}") .log("${body}")
.trace(true) .trace(true)
.process(new CheckLoFiProcessor(mediaFileService)) .process(new CheckLoFiProcessor(mediaLofiService))
.to("jms:queue:media.lofi.processed")
.choice() .choice()
.when(exchangeProperty("linkId").isNotNull()) .when(header(MediaConstants.LOFI_ID).isNotNull()).to("jms:queue:media.lofi.duplicate")
.to("jms:queue:media.lofi.add") .otherwise().to("jms:queue:media.lofi.add");
.otherwise()
.to("jms:queue:DLQ")
.to("jms:queue:media.lofi.processed");
} }
} }
@@ -4,24 +4,28 @@ import org.apache.camel.builder.RouteBuilder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import de.thpeetz.kontor.services.MediaFileService; import de.thpeetz.kontor.integration.services.AddLofiProcessor;
import de.thpeetz.kontor.integration.services.UrlTitleProcessor;
import de.thpeetz.kontor.services.MediaLofiService;
@Component @Component
public class QueueMediaLoFiAdd extends RouteBuilder { public class QueueMediaLoFiAdd extends RouteBuilder {
@Autowired @Autowired
private final MediaFileService mediaFileService; private final MediaLofiService mediaLofiService;
@Autowired @Autowired
public QueueMediaLoFiAdd(MediaFileService mediaFileService) { public QueueMediaLoFiAdd(MediaLofiService mediaLofiService) {
this.mediaFileService = mediaFileService; this.mediaLofiService = mediaLofiService;
} }
@Override @Override
public void configure() throws Exception { public void configure() throws Exception {
from("jms:queue:media.lofi.add") from("jms:queue:media.lofi.add")
.routeId("read-queue-media-lofi-add") .routeId("media.lofi.add")
.log("${body}") .log("${body}")
.process(new UrlTitleProcessor())
.process(new AddLofiProcessor(mediaLofiService))
.to("jms:queue:media.lofi.add.processed"); .to("jms:queue:media.lofi.add.processed");
} }
} }
@@ -4,18 +4,19 @@ import org.apache.camel.builder.RouteBuilder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import de.thpeetz.kontor.integration.services.CheckLoFiProcessor; import de.thpeetz.kontor.constants.MediaConstants;
import de.thpeetz.kontor.services.MediaFileService; import de.thpeetz.kontor.integration.services.CheckVideoProcessor;
import de.thpeetz.kontor.services.MediaVideoService;
@Component @Component
public class QueueMediaVideo extends RouteBuilder { public class QueueMediaVideo extends RouteBuilder {
@Autowired @Autowired
private final MediaFileService mediaFileService; private final MediaVideoService mediaVideoService;
@Autowired @Autowired
public QueueMediaVideo(MediaFileService mediaFileService) { public QueueMediaVideo(MediaVideoService mediaVideoService) {
this.mediaFileService = mediaFileService; this.mediaVideoService = mediaVideoService;
} }
@Override @Override
@@ -30,12 +31,9 @@ public class QueueMediaVideo extends RouteBuilder {
.routeId("media.video") .routeId("media.video")
.log("${body}") .log("${body}")
.trace(true) .trace(true)
.process(new CheckLoFiProcessor(mediaFileService)) .process(new CheckVideoProcessor(mediaVideoService))
.choice() .choice()
.when(exchangeProperty("linkId").isNotNull()) .when(header(MediaConstants.VIDEO_ID).isNotNull()).to("jms:queue:media.video.duplicate")
.to("jms:queue:media.video.add") .otherwise().to("jms:queue:media.video.add");
.otherwise()
.to("jms:queue:DLQ")
.to("jms:queue:media.video.processed");
} }
} }
@@ -4,24 +4,30 @@ import org.apache.camel.builder.RouteBuilder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import de.thpeetz.kontor.services.MediaFileService; import de.thpeetz.kontor.integration.services.AddVideoProcessor;
import de.thpeetz.kontor.integration.services.UrlTitleProcessor;
import de.thpeetz.kontor.services.MediaVideoService;
@Component @Component
public class QueueMediaVideoAdd extends RouteBuilder { public class QueueMediaVideoAdd extends RouteBuilder {
@SuppressWarnings("unused")
@Autowired @Autowired
private final MediaFileService mediaFileService; private final MediaVideoService mediaVideoService;
@Autowired @Autowired
public QueueMediaVideoAdd(MediaFileService mediaFileService) { public QueueMediaVideoAdd(MediaVideoService mediaVideoService) {
this.mediaFileService = mediaFileService; this.mediaVideoService = mediaVideoService;
} }
@Override @Override
public void configure() throws Exception { public void configure() throws Exception {
from("jms:queue:media.video.add") from("jms:queue:media.video.add")
.routeId("read-queue-media-video-add") .routeId("media.video.add")
.log("${body}") .log("${body}")
.trace(true)
.process(new UrlTitleProcessor())
.process(new AddVideoProcessor(mediaVideoService))
.to("jms:queue:media.video.add.processed"); .to("jms:queue:media.video.add.processed");
} }
} }
@@ -1,16 +1,14 @@
package de.thpeetz.kontor.integration.services; package de.thpeetz.kontor.integration.services;
import com.fasterxml.jackson.core.type.TypeReference; import de.thpeetz.kontor.constants.MediaConstants;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.thpeetz.kontor.data.media.MediaFile; import de.thpeetz.kontor.data.media.MediaFile;
import de.thpeetz.kontor.services.MediaFileService; import de.thpeetz.kontor.services.MediaFileService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.camel.Exchange; import org.apache.camel.Exchange;
import org.apache.camel.Processor; import org.apache.camel.Processor;
import org.json.simple.JSONObject;
import java.util.HashMap; import org.json.simple.parser.JSONParser;
import java.util.Map; import org.json.simple.parser.ParseException;
@Slf4j @Slf4j
public class AddLinkProcessor implements Processor { public class AddLinkProcessor implements Processor {
@@ -23,32 +21,33 @@ public class AddLinkProcessor implements Processor {
@Override @Override
public void process(Exchange exchange) throws Exception { public void process(Exchange exchange) throws Exception {
ObjectMapper objectMapper = new ObjectMapper(); String messageBody = exchange.getIn().getBody(String.class);
HashMap<String, String> myMap = objectMapper.readValue(exchange.getIn().getBody().toString(), log.info("MediaFile URL to add: {}", messageBody);
new TypeReference<HashMap<String, String>>() { String title = exchange.getIn().getHeader(MediaConstants.LINKTITLE).toString();
});
String url = myMap.get("url"); JSONParser parser = new JSONParser();
log.info("found url: {}", url); try {
MediaFile mediaFile = mediaFileService.findAllMediaFilesByUrl(url); JSONObject jsonObject = (JSONObject) parser.parse(messageBody);
if (mediaFile == null) { String url = (String) jsonObject.get(MediaConstants.URL);
log.info("URL not found, create MediaFile"); MediaFile mediaFile = new MediaFile();
mediaFile = new MediaFile();
mediaFile.setUrl(url); mediaFile.setUrl(url);
mediaFile.setPath(""); mediaFile.setPath("");
mediaFile.setCloudLink(""); mediaFile.setCloudLink("");
mediaFile.setFileName(""); mediaFile.setFileName("");
mediaFile.setTitle(""); mediaFile.setTitle(title);
mediaFile.setReview(true); mediaFile.setReview(true);
mediaFile.setShouldDownload(true); mediaFile.setShouldDownload(true);
MediaFile mediaFileResult = mediaFileService.saveMediaFile(mediaFile); MediaFile mediaFileResult = mediaFileService.saveMediaFile(mediaFile);
log.info("created MediaFile with {}", mediaFileResult.getId()); if (mediaFileResult != null) {
exchange.getMessage().getHeaders().put("mediafile_id", mediaFileResult.getId()); log.info("MediaFile saved: {}", mediaFileResult.toString());
exchange.getIn().setHeader(MediaConstants.FILE_ID, mediaFileResult.getId());
} else { } else {
log.info("found MediaFile with {}", mediaFile.getId()); log.info("MediaFile could not saved: {}", url);
exchange.getMessage().getHeaders().put("mediafile_id", mediaFile.getId()); exchange.getIn().setHeader(MediaConstants.FILE_ID, null);
}
} catch (ParseException pe) {
log.info("parse exception: {}", pe.toString());
exchange.getIn().setHeader(MediaConstants.FILE_ID, null);
} }
log.info("found MediaFile: {}", mediaFile);
Map<String, Object> map = exchange.getMessage().getHeaders();
log.info("Headers: {}", map);
} }
} }
@@ -1,22 +0,0 @@
package de.thpeetz.kontor.integration.services;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.HashMap;
@Service
@Slf4j
public class AddLinkService {
public void fromQueue(String messageBody) throws JsonProcessingException {
log.info("get body: {}", messageBody);
ObjectMapper objectMapper = new ObjectMapper();
HashMap<String,String> myMap = objectMapper.readValue(messageBody, new TypeReference<HashMap<String,String>>() {});
String url = myMap.get("url");
log.info("found url: {}", url);
}
}
@@ -0,0 +1,52 @@
package de.thpeetz.kontor.integration.services;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import de.thpeetz.kontor.constants.MediaConstants;
import de.thpeetz.kontor.data.media.MediaLofi;
import de.thpeetz.kontor.services.MediaLofiService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class AddLofiProcessor implements Processor {
private MediaLofiService mediaLofiService;
public AddLofiProcessor(MediaLofiService medialLofiService) {
this.mediaLofiService = medialLofiService;
}
@Override
public void process(Exchange exchange) throws Exception {
String messageBody = exchange.getIn().getBody(String.class);
log.info("LoFi URL to add: {}", messageBody);
String title = exchange.getIn().getHeader(MediaConstants.LINKTITLE).toString();
JSONParser parser = new JSONParser();
try {
JSONObject jsonObject = (JSONObject) parser.parse(messageBody);
String url = (String) jsonObject.get(MediaConstants.URL);
MediaLofi mediaLofi = new MediaLofi();
mediaLofi.setUrl(url);
mediaLofi.setTitle(title);
mediaLofi.setFileName("");
mediaLofi.setReview(false);
mediaLofi.setShouldDownload(false);
mediaLofi = this.mediaLofiService.saveMediaLofi(mediaLofi);
if (mediaLofi != null) {
log.info("MediaLofi saved: {}", mediaLofi.toString());
exchange.getIn().setHeader(MediaConstants.LOFI_ID, mediaLofi.getId());
} else {
log.info("MediaLofi could not saved: {}", url);
exchange.getIn().setHeader(MediaConstants.LOFI_ID, null);
}
} catch (ParseException pe) {
log.info("parse exception: {}", pe.toString());
exchange.getIn().setHeader(MediaConstants.LOFI_ID, null);
}
}
}
@@ -0,0 +1,54 @@
package de.thpeetz.kontor.integration.services;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import de.thpeetz.kontor.constants.MediaConstants;
import de.thpeetz.kontor.data.media.MediaVideo;
import de.thpeetz.kontor.services.MediaVideoService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class AddVideoProcessor implements Processor {
private final MediaVideoService mediaVideoService;
public AddVideoProcessor(MediaVideoService mediaVideoService) {
this.mediaVideoService = mediaVideoService;
}
@Override
public void process(Exchange exchange) throws Exception {
String messageBody = exchange.getIn().getBody(String.class);
log.info("MediaVideo URL to add: {}", messageBody);
String title = exchange.getIn().getHeader(MediaConstants.LINKTITLE).toString();
JSONParser parser = new JSONParser();
try {
JSONObject jsonObject = (JSONObject) parser.parse(messageBody);
String url = (String) jsonObject.get(MediaConstants.URL);
MediaVideo mediaVideo = new MediaVideo();
mediaVideo.setUrl(url);
mediaVideo.setPath("");
mediaVideo.setCloudLink("");
mediaVideo.setFileName("");
mediaVideo.setTitle(title);
mediaVideo.setReview(true);
mediaVideo.setShouldDownload(true);
MediaVideo mediaVideoResult = mediaVideoService.saveMediaVideo(mediaVideo);
if (mediaVideoResult != null) {
log.info("MediaVideo saved: {}", mediaVideoResult.toString());
exchange.getIn().setHeader(MediaConstants.VIDEO_ID, mediaVideoResult.getId());
} else {
log.info("MediaFile could not saved: {}", url);
exchange.getIn().setHeader(MediaConstants.VIDEO_ID, null);
}
} catch (ParseException pe) {
log.info("parse exception: {}", pe.toString());
exchange.getIn().setHeader(MediaConstants.VIDEO_ID, null);
}
}
}
@@ -1,17 +1,13 @@
package de.thpeetz.kontor.integration.services; package de.thpeetz.kontor.integration.services;
// import java.nio.charset.StandardCharsets;
// import java.util.HashMap;
import org.apache.camel.Exchange; import org.apache.camel.Exchange;
import org.apache.camel.Processor; import org.apache.camel.Processor;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
// import com.fasterxml.jackson.core.type.TypeReference; import de.thpeetz.kontor.constants.MediaConstants;
// import com.fasterxml.jackson.databind.ObjectMapper; import de.thpeetz.kontor.data.media.MediaFile;
import de.thpeetz.kontor.services.MediaFileService; import de.thpeetz.kontor.services.MediaFileService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -29,22 +25,21 @@ public class CheckLinkProcessor implements Processor {
String messageBody = exchange.getIn().getBody(String.class); String messageBody = exchange.getIn().getBody(String.class);
log.info("message body: {}", messageBody); log.info("message body: {}", messageBody);
// ObjectMapper objectMapper = new ObjectMapper();
// HashMap<String, String> myMap = objectMapper.readValue(messageBody, new TypeReference<HashMap<String, String>>() {});
// String url = myMap.get("url");
// log.info("found url: {}", url);
// exchange.getIn().setHeader("linkId", null);
// exchange.setProperty("linkId", null);
JSONParser parser = new JSONParser(); JSONParser parser = new JSONParser();
try { try {
JSONObject jsonObject = (JSONObject) parser.parse(messageBody); JSONObject jsonObject = (JSONObject) parser.parse(messageBody);
String url = (String)jsonObject.get("url"); String url = (String) jsonObject.get(MediaConstants.URL);
MediaFile mediaFile = mediaFileService.findAllMediaFilesByUrl(url);
if (mediaFile != null) {
log.info("found url: {}", url); log.info("found url: {}", url);
exchange.getIn().setHeader("linkId", null); exchange.getIn().setHeader(MediaConstants.FILE_ID, mediaFile.getId());
} else {
log.info("url not found: {}", url);
exchange.getIn().setHeader(MediaConstants.FILE_ID, null);
}
} catch (ParseException pe) { } catch (ParseException pe) {
log.info("parse exception: {}", pe.toString()); log.info("parse exception: {}", pe.toString());
exchange.getIn().setHeader("linkId", null); exchange.getIn().setHeader(MediaConstants.FILE_ID, null);
} }
} }
} }
@@ -6,16 +6,18 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import de.thpeetz.kontor.services.MediaFileService; import de.thpeetz.kontor.constants.MediaConstants;
import de.thpeetz.kontor.data.media.MediaLofi;
import de.thpeetz.kontor.services.MediaLofiService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class CheckLoFiProcessor implements Processor { public class CheckLoFiProcessor implements Processor {
private final MediaFileService mediaFileService; private final MediaLofiService medialLofiService;
public CheckLoFiProcessor(MediaFileService mediaFileService) { public CheckLoFiProcessor(MediaLofiService medialLofiService) {
this.mediaFileService = mediaFileService; this.medialLofiService = medialLofiService;
} }
@Override @Override
@@ -26,12 +28,18 @@ public class CheckLoFiProcessor implements Processor {
JSONParser parser = new JSONParser(); JSONParser parser = new JSONParser();
try { try {
JSONObject jsonObject = (JSONObject) parser.parse(messageBody); JSONObject jsonObject = (JSONObject) parser.parse(messageBody);
String url = (String) jsonObject.get("url"); String url = (String) jsonObject.get(MediaConstants.URL);
MediaLofi mediaLofi = medialLofiService.findAllMediaLofiByUrl(url);
if (mediaLofi != null) {
log.info("found url: {}", url); log.info("found url: {}", url);
exchange.getIn().setHeader("linkId", null); exchange.getIn().setHeader(MediaConstants.LOFI_ID, mediaLofi.getId());
} else {
log.info("url not found: {}", url);
exchange.getIn().setHeader(MediaConstants.LOFI_ID, null);
}
} catch (ParseException pe) { } catch (ParseException pe) {
log.info("parse exception: {}", pe.toString()); log.info("parse exception: {}", pe.toString());
exchange.getIn().setHeader("linkId", null); exchange.getIn().setHeader(MediaConstants.LOFI_ID, null);
} }
} }
} }
@@ -6,16 +6,17 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import de.thpeetz.kontor.services.MediaFileService; import de.thpeetz.kontor.services.MediaVideoService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class CheckVideoProcessor implements Processor { public class CheckVideoProcessor implements Processor {
private final MediaFileService mediaFileService; @SuppressWarnings("unused")
private final MediaVideoService mediaVideoService;
public CheckVideoProcessor(MediaFileService mediaFileService) { public CheckVideoProcessor(MediaVideoService mediaVideoService) {
this.mediaFileService = mediaFileService; this.mediaVideoService = mediaVideoService;
} }
@Override @Override
@@ -0,0 +1,40 @@
package de.thpeetz.kontor.integration.services;
import java.io.IOException;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import de.thpeetz.kontor.constants.MediaConstants;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class UrlTitleProcessor implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
String messageBody = exchange.getIn().getBody(String.class);
log.info("URL to check: {}", messageBody);
JSONParser parser = new JSONParser();
try {
JSONObject jsonObject = (JSONObject) parser.parse(messageBody);
String url = (String) jsonObject.get(MediaConstants.URL);
Document doc = Jsoup.connect(url).get();
String title = doc.title();
log.info("URL Title: {}", title);
exchange.getIn().setHeader(MediaConstants.LINKTITLE, title);
} catch (IOException io) {
log.info("IOException: {}", io.toString());
exchange.getIn().setHeader(MediaConstants.LINKTITLE, "");
} catch (ParseException pe) {
log.info("parse exception: {}", pe.toString());
exchange.getIn().setHeader(MediaConstants.LINKTITLE, "");
}
}
}
@@ -0,0 +1,33 @@
package de.thpeetz.kontor.repository.media;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import de.thpeetz.kontor.data.media.MediaLofi;
public interface MediaLofiRepository extends JpaRepository<MediaLofi, String> {
@Query("select m from MediaLofi m " +
"where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%'))")
List<MediaLofi> search(@Param("searchTerm") String searchTerm);
List<MediaLofi> findByShouldDownload(Boolean shouldDownload);
List<MediaLofi> findByReview(Boolean review);
List<MediaLofi> findByReviewAndShouldDownload(Boolean review, Boolean shouldDownload);
MediaLofi findByUrl(String url);
@Query("select m from MediaLofi m " +
"where lower(m.url) like lower(concat('%', :searchTerm, '%')) or lower(m.title) like lower(concat('%', :searchTerm, '%')) "
+
"AND m.review=:review AND m.shouldDownload=:download")
List<MediaLofi> search(
@Param("searchTerm") String searchTerm,
@Param("review") boolean searchReview,
@Param("download") boolean searchDownload);
}
@@ -0,0 +1,86 @@
package de.thpeetz.kontor.services;
import java.util.List;
import org.springframework.stereotype.Service;
import de.thpeetz.kontor.data.media.MediaLofi;
import de.thpeetz.kontor.repository.media.MediaLofiRepository;
import de.thpeetz.kontor.views.common.SearchFilter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class MediaLofiService {
private final MediaLofiRepository mediaLofiRepository;
public MediaLofiService(MediaLofiRepository mediaLofiRepository) {
this.mediaLofiRepository = mediaLofiRepository;
}
public List<MediaLofi> findAllMediaLofisByString(String stringFilter) {
List<MediaLofi> results;
if (stringFilter == null || stringFilter.isEmpty()) {
results = mediaLofiRepository.findAll();
} else {
results = mediaLofiRepository.search(stringFilter);
}
log.debug("Found " + results.size() + " entries");
return results;
}
public MediaLofi findAllMediaLofiByUrl(String url) {
return mediaLofiRepository.findByUrl(url);
}
public List<MediaLofi> findAllMediaLofis(SearchFilter searchFilter) {
if (searchFilter == null) {
return mediaLofiRepository.findAll();
} else {
if (searchFilter.getSearchTerm() != null && searchFilter.getFilterOptions().isEmpty()) {
log.info("find MediaFiles by using searchTerm: {}", searchFilter.getSearchTerm());
List<MediaLofi> results = mediaLofiRepository.search(searchFilter.getSearchTerm());
log.info("found {} entries", results.size());
return results;
}
if (searchFilter.getFilterOptions().size() == 1) {
log.info("using searchFilter: {}", searchFilter);
String filter = searchFilter.getFilterOptions().get(0).getName();
Boolean filterValue = searchFilter.getFilterOptions().get(0).getValue();
if (filter == "Überprüfung") {
List<MediaLofi> results = mediaLofiRepository.findByReview(filterValue);
log.info("found {} entries", results.size());
return results;
}
if (filter == "Download") {
List<MediaLofi> results = mediaLofiRepository.findByShouldDownload(filterValue);
log.info("found {} entries", results.size());
return results;
}
}
if (searchFilter.getFilterOptions().size() == 2) {
log.info("using searchFilter: {}", searchFilter);
List<MediaLofi> results = mediaLofiRepository.search(searchFilter.getSearchTerm(),
searchFilter.getFilterOptions().get(0).getValue(),
searchFilter.getFilterOptions().get(1).getValue());
log.info("found {} entries", results.size());
return results;
}
}
log.info("noch filter used");
return mediaLofiRepository.findAll();
}
public MediaLofi saveMediaLofi(MediaLofi mediaLofi) {
if (mediaLofi == null) {
log.warn("MediaLofi is null. Are you sure you have connected your form to the application?");
return null;
}
return mediaLofiRepository.save(mediaLofi);
}
public void deleteMediaLofi(MediaLofi mediaLofi) {
mediaLofiRepository.delete(mediaLofi);
}
}
@@ -25,12 +25,12 @@ public class MediaVideoService {
} }
} }
public void saveMediaVideo(MediaVideo mediaVideo) { public MediaVideo saveMediaVideo(MediaVideo mediaVideo) {
if (mediaVideo == null) { if (mediaVideo == null) {
log.warn("MediaFile is null. Are you sure you have connected your form to the application?"); log.warn("MediaFile is null. Are you sure you have connected your form to the application?");
return; return null;
} }
mediaVideoRepository.save(mediaVideo); return mediaVideoRepository.save(mediaVideo);
} }
public void deleteMediaVideo(MediaVideo mediaVideo) { public void deleteMediaVideo(MediaVideo mediaVideo) {
@@ -19,13 +19,15 @@ import jakarta.annotation.security.PermitAll;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@Route(value="user/profile", layout = MainLayout.class) @Route(value = "user/profile", layout = MainLayout.class)
@PermitAll @PermitAll
@PageTitle("Profile | User | Kontor") @PageTitle("Profile | User | Kontor")
public class UserProfileView extends VerticalLayout { public class UserProfileView extends VerticalLayout {
@SuppressWarnings("unused")
private SecurityService securityService; private SecurityService securityService;
@SuppressWarnings("unused")
private AdminService adminService; private AdminService adminService;
TextField firstName = new TextField("First name"); TextField firstName = new TextField("First name");
@@ -22,12 +22,12 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class ArtistForm extends FormLayout { public class ArtistForm extends FormLayout {
TextField name = new TextField("Name"); public TextField name = new TextField("Name");
TextField weblink = new TextField("Link"); TextField weblink = new TextField("Link");
Grid<ComicWork> comicWorks = new Grid<>(ComicWork.class); Grid<ComicWork> comicWorks = new Grid<>(ComicWork.class);
Button save = new Button("Save"); public Button save = new Button("Save");
Button delete = new Button("Delete"); public Button delete = new Button("Delete");
Button close = new Button("Cancel"); Button close = new Button("Cancel");
Binder<Artist> binder = new BeanValidationBinder<>(Artist.class); Binder<Artist> binder = new BeanValidationBinder<>(Artist.class);
@@ -28,7 +28,7 @@ public class ComicForm extends FormLayout {
private static final Logger log = LoggerFactory.getLogger(ComicForm.class); private static final Logger log = LoggerFactory.getLogger(ComicForm.class);
TextField title = new TextField("Title"); public TextField title = new TextField("Title");
ComboBox<Publisher> publisher = new ComboBox<>("Publisher"); ComboBox<Publisher> publisher = new ComboBox<>("Publisher");
TextField weblink = new TextField("Link"); TextField weblink = new TextField("Link");
Checkbox currentOrder = new Checkbox("Current order"); Checkbox currentOrder = new Checkbox("Current order");
@@ -18,10 +18,13 @@ import org.springframework.boot.info.BuildProperties;
@Slf4j @Slf4j
public class ComicLayout extends AppLayout { public class ComicLayout extends AppLayout {
@SuppressWarnings("unused")
private final AdminService adminService; private final AdminService adminService;
@SuppressWarnings("unused")
private final SecurityService securityService; private final SecurityService securityService;
@SuppressWarnings("unused")
private final BuildProperties buildProperties; private final BuildProperties buildProperties;
public ComicLayout(AdminService adminService, SecurityService securityService, BuildProperties buildProperties) { public ComicLayout(AdminService adminService, SecurityService securityService, BuildProperties buildProperties) {
@@ -44,4 +47,3 @@ public class ComicLayout extends AppLayout {
return navigation; return navigation;
} }
} }
@@ -19,7 +19,7 @@ import de.thpeetz.kontor.data.comics.ComicWork;
import de.thpeetz.kontor.data.comics.Worktype; import de.thpeetz.kontor.data.comics.Worktype;
public class ComicWorkForm extends FormLayout { public class ComicWorkForm extends FormLayout {
ComboBox<Comic> comic = new ComboBox<>("Comic"); public ComboBox<Comic> comic = new ComboBox<>("Comic");
ComboBox<Artist> artist = new ComboBox<>("Artist"); ComboBox<Artist> artist = new ComboBox<>("Artist");
ComboBox<Worktype> workType = new ComboBox<>("Worktype"); ComboBox<Worktype> workType = new ComboBox<>("Worktype");
@@ -29,7 +29,7 @@ public class IssueForm extends FormLayout {
ComboBox<Comic> comic = new ComboBox<>("Comic"); ComboBox<Comic> comic = new ComboBox<>("Comic");
ComboBox<Volume> volume = new ComboBox<>("Volume"); ComboBox<Volume> volume = new ComboBox<>("Volume");
TextField issueNumber = new TextField("Issue number"); public TextField issueNumber = new TextField("Issue number");
TextField title = new TextField("Full Title"); TextField title = new TextField("Full Title");
YearMonthField publishedOn = new YearMonthField(); YearMonthField publishedOn = new YearMonthField();
Checkbox isRead = new Checkbox("Read"); Checkbox isRead = new Checkbox("Read");
@@ -61,7 +61,7 @@ public class IssueForm extends FormLayout {
issueWorks.getColumnByKey("workType.name").setHeader("Work type"); issueWorks.getColumnByKey("workType.name").setHeader("Work type");
issueWorks.getColumnByKey("artist.name").setHeader("Artist"); issueWorks.getColumnByKey("artist.name").setHeader("Artist");
issueWorks.getColumns().forEach(col -> col.setAutoWidth(true)); issueWorks.getColumns().forEach(col -> col.setAutoWidth(true));
add(comic, volume, issueNumber, title, publishedOn, isRead, inStock,issueWorks, createButtonsLayout()); add(comic, volume, issueNumber, title, publishedOn, isRead, inStock, issueWorks, createButtonsLayout());
} }
private HorizontalLayout createButtonsLayout() { private HorizontalLayout createButtonsLayout() {
@@ -20,8 +20,6 @@ import de.thpeetz.kontor.constants.ComicConstants;
import de.thpeetz.kontor.data.comics.Comic; import de.thpeetz.kontor.data.comics.Comic;
import de.thpeetz.kontor.data.comics.Issue; import de.thpeetz.kontor.data.comics.Issue;
import de.thpeetz.kontor.services.ComicService; import de.thpeetz.kontor.services.ComicService;
import de.thpeetz.kontor.views.comics.IssueForm.DeleteEvent;
import de.thpeetz.kontor.views.comics.IssueForm.SaveEvent;
import de.thpeetz.kontor.views.common.ColumnToggleContextMenu; import de.thpeetz.kontor.views.common.ColumnToggleContextMenu;
import de.thpeetz.kontor.views.common.MainLayout; import de.thpeetz.kontor.views.common.MainLayout;
import de.thpeetz.kontor.views.common.StatusIcon; import de.thpeetz.kontor.views.common.StatusIcon;
@@ -62,7 +60,8 @@ public class IssueView extends VerticalLayout {
.setHeader("Published").setResizable(true).setSortable(true); .setHeader("Published").setResizable(true).setSortable(true);
Grid.Column<Issue> isReadColumn = grid.addComponentColumn(issueColumn -> StatusIcon.create(issueColumn.getIsRead())) Grid.Column<Issue> isReadColumn = grid.addComponentColumn(issueColumn -> StatusIcon.create(issueColumn.getIsRead()))
.setHeader("Gelesen?").setWidth("6rem").setSortable(true); .setHeader("Gelesen?").setWidth("6rem").setSortable(true);
Grid.Column<Issue> inStockColumn = grid.addComponentColumn(issueColumn -> StatusIcon.create(issueColumn.getInStock())) Grid.Column<Issue> inStockColumn = grid
.addComponentColumn(issueColumn -> StatusIcon.create(issueColumn.getInStock()))
.setHeader("Im Bestand?").setWidth("6rem").setSortable(true); .setHeader("Im Bestand?").setWidth("6rem").setSortable(true);
ComboBox<Comic> comicFilter = new ComboBox<>("Comic"); ComboBox<Comic> comicFilter = new ComboBox<>("Comic");
@Getter @Getter
@@ -20,7 +20,7 @@ import java.util.List;
public class StoryArcForm extends FormLayout { public class StoryArcForm extends FormLayout {
ComboBox<Comic> comic = new ComboBox<>("Comic"); ComboBox<Comic> comic = new ComboBox<>("Comic");
TextField name = new TextField("Story Arc Name"); public TextField name = new TextField("Story Arc Name");
Button save = new Button("Save"); Button save = new Button("Save");
Button delete = new Button("Delete"); Button delete = new Button("Delete");
@@ -44,7 +44,7 @@ public class StoryArcView extends VerticalLayout {
updateList(); updateList();
} }
StoryArcForm getForm() { public StoryArcForm getForm() {
return form; return form;
} }
@@ -18,7 +18,7 @@ import de.thpeetz.kontor.data.comics.Comic;
import de.thpeetz.kontor.data.comics.TradePaperback; import de.thpeetz.kontor.data.comics.TradePaperback;
public class TradePaperBackForm extends FormLayout { public class TradePaperBackForm extends FormLayout {
TextField name = new TextField("Name"); public TextField name = new TextField("Name");
ComboBox<Comic> comic = new ComboBox<>("Comic"); ComboBox<Comic> comic = new ComboBox<>("Comic");
TextField issueStart = new TextField("Issue Start"); TextField issueStart = new TextField("Issue Start");
TextField issueEnd = new TextField("Issue End"); TextField issueEnd = new TextField("Issue End");
@@ -44,7 +44,7 @@ public class VolumeView extends VerticalLayout {
updateList(); updateList();
} }
VolumeForm getForm() { public VolumeForm getForm() {
return form; return form;
} }
@@ -24,7 +24,7 @@ public class WorktypeForm extends FormLayout {
private static final Logger log = LoggerFactory.getLogger(WorktypeForm.class); private static final Logger log = LoggerFactory.getLogger(WorktypeForm.class);
TextField name = new TextField("Name"); public TextField name = new TextField("Name");
Grid<ComicWork> comicWorks = new Grid<>(ComicWork.class); Grid<ComicWork> comicWorks = new Grid<>(ComicWork.class);
Button save = new Button("Save"); Button save = new Button("Save");