commit 8d46cf2c71b605d50d9ce04531bcdac4267d96bc
parent 9b5d3f2dcf7ed456dd279fa3bfe125ba44b7dead
Author: Wim Dupont <wim@wimdupont.com>
Date: Sat, 8 Jul 2023 13:54:40 +0200
delete guide when removed from git and minor updates
Former-commit-id: c34665b1e549f4425b9f498b56c320eb636be104
Diffstat:
6 files changed, 75 insertions(+), 29 deletions(-)
diff --git a/src/main/java/com/wimdupont/personalweb/PersonalWebApplication.java b/src/main/java/com/wimdupont/personalweb/PersonalWebApplication.java
@@ -4,13 +4,11 @@ import com.wimdupont.personalweb.service.ScheduledFileGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
-@ComponentScan
@EnableJpaAuditing
public class PersonalWebApplication {
diff --git a/src/main/java/com/wimdupont/personalweb/config/SecurityConfig.java b/src/main/java/com/wimdupont/personalweb/config/SecurityConfig.java
@@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
+import org.springframework.security.config.web.server.ServerHttpSecurity.FormLoginSpec;
import org.springframework.security.web.server.SecurityWebFilterChain;
@Configuration
@@ -14,6 +15,6 @@ public class SecurityConfig {
@Bean
public SecurityWebFilterChain filterChain(ServerHttpSecurity http) {
- return http.formLogin().disable().build();
+ return http.formLogin(FormLoginSpec::disable).build();
}
}
diff --git a/src/main/java/com/wimdupont/personalweb/model/dao/Guide.java b/src/main/java/com/wimdupont/personalweb/model/dao/Guide.java
@@ -1,5 +1,6 @@
package com.wimdupont.personalweb.model.dao;
+import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.Id;
@@ -21,6 +22,7 @@ public class Guide {
private String contentBase64;
private String htmlText;
@CreatedDate
+ @Column(updatable = false)
private LocalDateTime createdDate;
@LastModifiedDate
diff --git a/src/main/java/com/wimdupont/personalweb/service/GuideService.java b/src/main/java/com/wimdupont/personalweb/service/GuideService.java
@@ -1,6 +1,7 @@
package com.wimdupont.personalweb.service;
import com.wimdupont.personalweb.api.GitlabApi;
+import com.wimdupont.personalweb.api.dto.RepositoryFile;
import com.wimdupont.personalweb.model.GuideMeta;
import com.wimdupont.personalweb.model.dao.Guide;
import com.wimdupont.personalweb.repository.GuideRepository;
@@ -39,18 +40,38 @@ public class GuideService {
return guideRepository.findByPath(path);
}
+ public Optional<Guide> findGuideByTitle(String title) {
+ return findByPath(title + Constants.ADOC_SUFFIX);
+ }
- public List<Guide> findAllToGenerate() {
+ public List<RepositoryFile> findRepositoryFiles() {
+ var repositoryFiles = new ArrayList<RepositoryFile>();
+ gitlabApi.getRepositoryTree()
+ .orElseThrow().stream()
+ .map(repositoryTreeItem -> gitlabApi.getRepositoryFile(repositoryTreeItem.path()))
+ .forEach(repositoryFile -> repositoryFile.ifPresent(repositoryFiles::add));
+ return repositoryFiles;
+ }
+
+ public void removeNotFound(List<RepositoryFile> repositoryFiles) {
+ guideRepository.findAll().stream()
+ .filter(guide -> !repositoryFiles.stream()
+ .map(RepositoryFile::path)
+ .toList().contains(guide.getPath()))
+ .peek(guide -> LOGGER.info("Removing guide: {}", guide.getPath()))
+ .forEach(guideRepository::delete);
+ }
+
+ public List<Guide> findAllToUpsert(List<RepositoryFile> repositoryFiles) {
var guidesToGenerate = new ArrayList<Guide>();
- gitlabApi.getRepositoryTree().orElseThrow()
- .forEach(repositoryTreeItem -> gitlabApi.getRepositoryFile(repositoryTreeItem.path())
- .filter(repositoryFile -> guideRepository.findByContentSha256(repositoryFile.contentSha256()).isEmpty())
- .map(repositoryFile -> Guide.Builder.newBuilder()
- .contentSha256(repositoryFile.contentSha256())
- .contentBase64(repositoryFile.contentBase64())
- .path(repositoryFile.path())
- .build())
- .ifPresent(guidesToGenerate::add));
+ repositoryFiles.stream()
+ .filter(repositoryFile -> guideRepository.findByContentSha256(repositoryFile.contentSha256()).isEmpty())
+ .map(repositoryFile -> Guide.Builder.newBuilder()
+ .contentSha256(repositoryFile.contentSha256())
+ .contentBase64(repositoryFile.contentBase64())
+ .path(repositoryFile.path())
+ .build())
+ .forEach(guidesToGenerate::add);
if (guidesToGenerate.isEmpty()) {
LOGGER.info("No new guides to generate.");
@@ -58,8 +79,4 @@ public class GuideService {
return guidesToGenerate;
}
-
- public Optional<Guide> findGuideByTitle(String title) {
- return findByPath(title + Constants.ADOC_SUFFIX);
- }
}
diff --git a/src/main/java/com/wimdupont/personalweb/service/ScheduledFileGenerator.java b/src/main/java/com/wimdupont/personalweb/service/ScheduledFileGenerator.java
@@ -39,25 +39,28 @@ public class ScheduledFileGenerator {
@Scheduled(cron = "0 0 0 * * *")
public void generate() {
LOG.info("File generator started.");
- generateHtmlFiles(articleService);
+ generateHtmlFiles();
rssFeedGenerator.generate();
- generateGuides(guideService);
+ updateGuides();
+ LOG.info("File generator completed.");
}
- private void generateGuides(GuideService guideService) {
- for (Guide guide : guideService.findAllToGenerate()) {
+ private void updateGuides() {
+ var repositoryFiles = guideService.findRepositoryFiles();
+ guideService.removeNotFound(repositoryFiles);
+ for (Guide guide : guideService.findAllToUpsert(repositoryFiles)) {
guide.setHtmlText(adocConverter.convert(new String(Base64.getDecoder()
.decode(guide.getContentBase64().getBytes(StandardCharsets.UTF_8)))));
- LOG.info("Guide saved: {}", guideService.save(guide));
+ LOG.info("Guide saved: {}", guideService.save(guide).getPath());
}
}
- private void generateHtmlFiles(AdocFileService adocFileService) {
- File[] files = adocFileService.getAdocFiles();
+ private void generateHtmlFiles() {
+ File[] files = articleService.getAdocFiles();
if (files != null) {
- createHtmlDir(adocFileService);
+ createHtmlDir();
for (File adocFile : files) {
- String articlePathName = adocFileService.toHtmlPathName(adocFile);
+ String articlePathName = articleService.toHtmlPathName(adocFile);
if (adocFile.isFile() && adocFile.getName().endsWith(ADOC_SUFFIX) && !new File(articlePathName).exists()) {
try {
String htmlArticle = adocConverter.convert(adocFile);
@@ -74,11 +77,11 @@ public class ScheduledFileGenerator {
}
}
- private void createHtmlDir(AdocFileService adocFileService) {
- File htmlArticlesDir = new File(adocFileService.getHtmlDirectory());
+ private void createHtmlDir() {
+ File htmlArticlesDir = new File(articleService.getHtmlDirectory());
if (!htmlArticlesDir.exists()) {
if (htmlArticlesDir.mkdir()) {
- LOG.debug("Directory is created: {}", adocFileService.getHtmlDirectory());
+ LOG.debug("Directory is created: {}", articleService.getHtmlDirectory());
}
}
}
diff --git a/src/test/java/com/wimdupont/personalweb/converter/GuideMetaToDtoConverterTest.java b/src/test/java/com/wimdupont/personalweb/converter/GuideMetaToDtoConverterTest.java
@@ -0,0 +1,25 @@
+package com.wimdupont.personalweb.converter;
+
+import com.wimdupont.personalweb.model.GuideMeta;
+import com.wimdupont.personalweb.model.dto.GuideMetaDto;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class GuideMetaToDtoConverterTest {
+
+ private GuideMetaToDtoConverter converter;
+ private final GuideMeta guideMeta = () -> "guide.adoc";
+
+ @BeforeEach
+ void setup() {
+ converter = new GuideMetaToDtoConverter();
+ }
+
+ @Test
+ void convert() {
+ GuideMetaDto result = converter.convertForMetaData(guideMeta);
+ Assertions.assertEquals(result.title(), guideMeta.getPath().replace(".adoc", ""));
+ }
+
+}