Compare commits
108
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4f887bf33 | ||
|
|
61ec781bbb | ||
|
|
3ee41cf571 | ||
|
|
7f2e762a44 | ||
|
|
cfa3015a7b | ||
|
|
778a92fd5e | ||
|
|
ff52a198dc | ||
|
|
f3d59a0ef3 | ||
|
|
d84485e52b | ||
|
|
f789d89995 | ||
|
|
7e0174bcc2 | ||
|
|
fe1d59a3bb | ||
|
|
69a99c9312 | ||
|
|
a6414ae64d | ||
|
|
9cf47f0e2a | ||
|
|
6c89562dc3 | ||
|
|
e85eabbed5 | ||
|
|
1ec4ba8212 | ||
|
|
a1ff181443 | ||
|
|
ee8f48bc43 | ||
|
|
7ec1aee884 | ||
|
|
a3adfa8ee0 | ||
|
|
d893afa1f3 | ||
|
|
d984128176 | ||
|
|
f8d73c9ed0 | ||
|
|
208b935ffa | ||
|
|
f12dfc7029 | ||
|
|
98a890e915 | ||
|
|
0c1b52d734 | ||
|
|
3f6764dd7d | ||
|
|
67c3d0b3e6 | ||
|
|
36208ef071 | ||
|
|
b546a0cf01 | ||
|
|
3935f6ad21 | ||
|
|
fd5ad7e88e | ||
|
|
8c957fe694 | ||
|
|
cb0ef7ddd5 | ||
|
|
42e466fe8b | ||
|
|
2c5fa4fa13 | ||
|
|
ebce44c889 | ||
|
|
955dc48f51 | ||
|
|
29e75e6298 | ||
|
|
187fd105d3 | ||
|
|
1b92fd269e | ||
|
|
23025e3606 | ||
|
|
38c11e2d9f | ||
|
|
610723c561 | ||
|
|
0e2fb945a4 | ||
|
|
ef32572521 | ||
|
|
e5a128a7f6 | ||
|
|
f5e1e10ebd | ||
|
|
500952d4d4 | ||
|
|
1cc4abc24e | ||
|
|
00945de270 | ||
|
|
5804d8cc9f | ||
|
|
5610bd170a | ||
|
|
21d19d4ecd | ||
|
|
f3dfac6bc7 | ||
|
|
4565192d0b | ||
|
|
d7ac4966c9 | ||
|
|
64119a956a | ||
|
|
c4dea2cc85 | ||
|
|
b0cc42fddd | ||
|
|
db669114b2 | ||
|
|
ca6b207816 | ||
|
|
b091dc52b7 | ||
|
|
4d44b6f53c | ||
|
|
be34c555a5 | ||
|
|
c03d977028 | ||
|
|
afd184f936 | ||
|
|
c09c68e1ac | ||
|
|
b84ba15f4c | ||
|
|
51af25666d | ||
|
|
b3a52f6a4b | ||
|
|
090143fdae | ||
|
|
b5f881e2c5 | ||
|
|
d9b856bd43 | ||
|
|
5e4068b141 | ||
|
|
a2f1b511c1 | ||
|
|
4d20d5f8b8 | ||
|
|
f00fb103ba | ||
|
|
b1d9344574 | ||
|
|
56ac024cba | ||
|
|
32ab1d79c8 | ||
|
|
42c4f76c0d | ||
|
|
4cc2a15231 | ||
|
|
54fbc7d609 | ||
|
|
8e9440a104 | ||
|
|
00d49d5fa4 | ||
|
|
78325c8729 | ||
|
|
1e18e3bc52 | ||
|
|
8ada2a15ef | ||
|
|
95d5308934 | ||
|
|
e5076f0c64 | ||
|
|
2ba707c336 | ||
|
|
d3041cf03d | ||
|
|
58295398e0 | ||
|
|
067bf7885a | ||
|
|
d324b94ddb | ||
|
|
4985889c58 | ||
|
|
7f5d52dce5 | ||
|
|
fae709a254 | ||
|
|
45355f6c42 | ||
|
|
db492b6316 | ||
|
|
c54e1c57d7 | ||
|
|
0900df463a | ||
|
|
13c2cc8118 | ||
|
|
431d365d20 |
No files matched your search
+46
@@ -38,3 +38,49 @@ build/
|
|||||||
**/.angular
|
**/.angular
|
||||||
|
|
||||||
**/pictures-folder
|
**/pictures-folder
|
||||||
|
|
||||||
|
|
||||||
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# Compiled output
|
||||||
|
/dist
|
||||||
|
/tmp
|
||||||
|
/out-tsc
|
||||||
|
/bazel-out
|
||||||
|
|
||||||
|
# Node
|
||||||
|
/node_modules
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
.idea/
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.history/*
|
||||||
|
|
||||||
|
# Miscellaneous
|
||||||
|
/.angular/cache
|
||||||
|
.sass-cache/
|
||||||
|
/connect.lock
|
||||||
|
/coverage
|
||||||
|
/libpeerconnection.log
|
||||||
|
testem.log
|
||||||
|
/typings
|
||||||
|
|
||||||
|
# System files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
**/ci/bin/
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
FROM maven:3.9.9-eclipse-temurin-21 AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY backend/pom.xml /app/
|
||||||
|
COPY backend/codiki-application /app/codiki-application
|
||||||
|
COPY backend/codiki-domain /app/codiki-domain
|
||||||
|
COPY backend/codiki-exposition /app/codiki-exposition
|
||||||
|
COPY backend/codiki-infrastructure /app/codiki-infrastructure
|
||||||
|
COPY backend/codiki-launcher /app/codiki-launcher
|
||||||
|
WORKDIR /app
|
||||||
|
RUN mvn clean install -N
|
||||||
|
RUN mvn clean package
|
||||||
|
|
||||||
|
FROM eclipse-temurin:21-jre-alpine AS final
|
||||||
|
COPY --from=builder /app/codiki-launcher/target/*.jar /app/codiki.jar
|
||||||
|
CMD ["java", "-jar", "/app/codiki.jar"]
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
FROM node:22-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY frontend /app
|
||||||
|
RUN npm install
|
||||||
|
RUN npm run build-prod-en
|
||||||
|
RUN npm run build-prod-fr
|
||||||
|
|
||||||
|
FROM nginx:1.27-alpine AS final
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /app/dist/codiki/en/browser /usr/share/nginx/html/en/
|
||||||
|
COPY --from=builder /app/dist/codiki/fr/browser/fr /usr/share/nginx/html/fr/
|
||||||
|
COPY frontend/conf/nginx.conf /etc/nginx/nginx.conf
|
||||||
Vendored
+84
@@ -0,0 +1,84 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Configuration') {
|
||||||
|
steps {
|
||||||
|
dir('codiki-properties') {
|
||||||
|
git url:'https://gitea.takiguchi.ovh/Codiki/codiki-properties.git', branch: 'hexagonal-reforged', credentialsId: 'Jenkins-gitea'
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
sh 'sed -i "s/<POSTGRES_PASSWORD>/$(cat ./codiki-properties/passwords/postgresql/codiki_user)/g" ./codiki-properties/application-prod.yml'
|
||||||
|
sh 'cp ./codiki-properties/application-prod.yml ./backend/codiki-launcher/src/main/resources/application-prod.yml'
|
||||||
|
sh 'sed -i "s/<POSTGRES_PASSWORD>/$(cat ./codiki-properties/passwords/postgresql/codiki_admin)/g" ./docker-compose.yml'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Build') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
sh """
|
||||||
|
sudo /usr/bin/docker build -t codiki-backend -f ./Dockerfile-backend . --no-cache
|
||||||
|
sudo /usr/bin/docker build -t codiki-frontend -f ./Dockerfile-frontend . --no-cache
|
||||||
|
sudo /usr/bin/docker save codiki-backend:latest -o ./codiki-backend.tar
|
||||||
|
sudo /usr/bin/docker save codiki-frontend:latest -o ./codiki-frontend.tar
|
||||||
|
sudo chown jenkins:jenkins ./codiki-backend.tar
|
||||||
|
sudo chown jenkins:jenkins ./codiki-frontend.tar
|
||||||
|
chmod 644 ./codiki-backend.tar
|
||||||
|
chmod 644 ./codiki-frontend.tar
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Deploy') {
|
||||||
|
steps {
|
||||||
|
sshPublisher(
|
||||||
|
publishers: [
|
||||||
|
sshPublisherDesc(
|
||||||
|
configName: 'DebianServer [codiki]',
|
||||||
|
transfers: [
|
||||||
|
sshTransfer(
|
||||||
|
cleanRemote: false,
|
||||||
|
excludes: '',
|
||||||
|
execCommand: '',
|
||||||
|
execTimeout: 120000,
|
||||||
|
flatten: false,
|
||||||
|
makeEmptyDirs: false,
|
||||||
|
noDefaultExcludes: false,
|
||||||
|
patternSeparator: '[, ]+',
|
||||||
|
remoteDirectory: '',
|
||||||
|
remoteDirectorySDF: false,
|
||||||
|
removePrefix: '',
|
||||||
|
sourceFiles: 'codiki-backend.tar,codiki-frontend.tar,docker-compose.yml'
|
||||||
|
),
|
||||||
|
sshTransfer(
|
||||||
|
cleanRemote: false,
|
||||||
|
excludes: '',
|
||||||
|
execCommand: """
|
||||||
|
cd /opt/codiki
|
||||||
|
sudo /usr/bin/docker load < /opt/codiki/codiki-backend.tar
|
||||||
|
sudo /usr/bin/docker load < /opt/codiki/codiki-frontend.tar
|
||||||
|
sudo /usr/bin/docker compose down
|
||||||
|
sudo /usr/bin/docker compose up --detach
|
||||||
|
""",
|
||||||
|
execTimeout: 120000,
|
||||||
|
flatten: false,
|
||||||
|
makeEmptyDirs: false,
|
||||||
|
noDefaultExcludes: false,
|
||||||
|
patternSeparator: '[, ]+',
|
||||||
|
remoteDirectory: '',
|
||||||
|
remoteDirectorySDF: false,
|
||||||
|
removePrefix: '',
|
||||||
|
sourceFiles: ''
|
||||||
|
)
|
||||||
|
],
|
||||||
|
usePromotionTimestamp: false,
|
||||||
|
useWorkspaceInPromotion: false,
|
||||||
|
verbose: true
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,6 +33,10 @@
|
|||||||
<groupId>com.auth0</groupId>
|
<groupId>com.auth0</groupId>
|
||||||
<artifactId>java-jwt</artifactId>
|
<artifactId>java-jwt</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+10
@@ -1,6 +1,8 @@
|
|||||||
package org.codiki.application.picture;
|
package org.codiki.application.picture;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -30,6 +32,7 @@ public class PictureUseCases {
|
|||||||
.withId(UUID.randomUUID())
|
.withId(UUID.randomUUID())
|
||||||
.withPublisher(authenticatedUser)
|
.withPublisher(authenticatedUser)
|
||||||
.withContentFile(pictureFile)
|
.withContentFile(pictureFile)
|
||||||
|
.withPublicationDate(ZonedDateTime.now())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
picturePort.save(newPicture);
|
picturePort.save(newPicture);
|
||||||
@@ -48,4 +51,11 @@ public class PictureUseCases {
|
|||||||
public boolean existsById(UUID pictureId) {
|
public boolean existsById(UUID pictureId) {
|
||||||
return picturePort.existsById(pictureId);
|
return picturePort.existsById(pictureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Picture> getAllOfCurrentUser() {
|
||||||
|
User authenticatedUser = userUseCases.getAuthenticatedUser()
|
||||||
|
.orElseThrow(AuthenticationRequiredException::new);
|
||||||
|
|
||||||
|
return picturePort.findAllByPublisherId(authenticatedUser.id());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
File renamed without changes.
Executable
+144
@@ -0,0 +1,144 @@
|
|||||||
|
package org.codiki.application.publication;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
|
||||||
|
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ParserService {
|
||||||
|
private static final String REG_CODE = "\\[code lg="([a-z]+)"\\](.*)\\[\\/code\\]\\n";
|
||||||
|
private static final String REG_IMAGES = "\\[img src="([^\"| ]+)"( alt="([^\"| ]+)")? \\/\\]";
|
||||||
|
private static final String REG_LINKS = "\\[link href="([^\"| ]+)" txt="([^\"| ]+)" \\/\\]";
|
||||||
|
|
||||||
|
private static final Pattern PATTERN_CODE;
|
||||||
|
private static final Pattern PATTERN_IMAGES;
|
||||||
|
private static final Pattern PATTERN_LINKS;
|
||||||
|
|
||||||
|
static {
|
||||||
|
PATTERN_CODE = Pattern.compile(REG_CODE);
|
||||||
|
PATTERN_IMAGES = Pattern.compile(REG_IMAGES);
|
||||||
|
PATTERN_LINKS = Pattern.compile(REG_LINKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String parse(String pSource) {
|
||||||
|
return unParseDolars(parseCode(parseHeaders(parseImages(parseLinks(parseBackSpaces(escapeHtml4(parseDolars(pSource))))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseDolars(final String pSource) {
|
||||||
|
return pSource.replace("$", "£ø");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String unParseDolars(final String pSource) {
|
||||||
|
return pSource.replace("£ø", "$");
|
||||||
|
}
|
||||||
|
|
||||||
|
String parseHeaders(final String pSource) {
|
||||||
|
String result = pSource;
|
||||||
|
for(int i = 1 ; i <= 3 ; i++) {
|
||||||
|
result = parseHeadersHX(result, i);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String parseHeadersHX(final String pSource, final int pNumHeader) {
|
||||||
|
String result = pSource;
|
||||||
|
|
||||||
|
// (.*)(\[hX\](.*)\[\/hX\])+(.*)
|
||||||
|
final String regex = concat("(.*)(\\[h", pNumHeader, "\\](.*)\\[\\/h", pNumHeader, "\\])+(.*)");
|
||||||
|
|
||||||
|
final Pattern pattern = Pattern.compile(regex);
|
||||||
|
|
||||||
|
Matcher matcher = pattern.matcher(result);
|
||||||
|
|
||||||
|
while(matcher.find()) {
|
||||||
|
// \1<hX>\3</hX>\4
|
||||||
|
result = matcher.replaceFirst(concat(matcher.group(1),
|
||||||
|
"<h", pNumHeader, ">", matcher.group(3), "</h", pNumHeader, ">", matcher.group(4)));
|
||||||
|
matcher = pattern.matcher(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String parseBackSpaces(final String pSource) {
|
||||||
|
return pSource.replaceAll("\r?\n", "<br/>").replaceAll("\\[\\/code\\]<br\\/><br\\/>", "[/code]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
String parseImages(final String pSource) {
|
||||||
|
String result = pSource;
|
||||||
|
|
||||||
|
Matcher matcher = PATTERN_IMAGES.matcher(result);
|
||||||
|
|
||||||
|
while(matcher.find()) {
|
||||||
|
String altStr = matcher.group(3);
|
||||||
|
|
||||||
|
if(altStr == null) {
|
||||||
|
altStr = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
result = matcher.replaceFirst(concat("<img src=\"", matcher.group(1), "\" alt=\"", altStr, "\" />"));
|
||||||
|
matcher = PATTERN_IMAGES.matcher(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String parseLinks(final String pSource) {
|
||||||
|
String result = pSource;
|
||||||
|
|
||||||
|
Matcher matcher = PATTERN_LINKS.matcher(result);
|
||||||
|
|
||||||
|
while(matcher.find()) {
|
||||||
|
result = matcher.replaceFirst(concat("<a href=\"", matcher.group(1), "\">", matcher.group(2), "</a>"));
|
||||||
|
matcher = PATTERN_LINKS.matcher(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String parseCode(final String pSource) {
|
||||||
|
String result = pSource;
|
||||||
|
|
||||||
|
Matcher matcher = PATTERN_CODE.matcher(result);
|
||||||
|
|
||||||
|
while(matcher.find()) {
|
||||||
|
// replace the '<br/>' in group by '\n'
|
||||||
|
String codeContent = matcher.group(2).replaceAll("<br\\/>", "\n");
|
||||||
|
if(codeContent.startsWith("\n")) {
|
||||||
|
codeContent = codeContent.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = matcher.replaceFirst(
|
||||||
|
concat(
|
||||||
|
"<pre class=\"line-numbers\"><code class=\"language-",
|
||||||
|
matcher.group(1),
|
||||||
|
"\">",
|
||||||
|
codeContent,
|
||||||
|
"</code></pre>"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
matcher = PATTERN_CODE.matcher(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concatenate the parameters to form just one single string.
|
||||||
|
*
|
||||||
|
* @param pArgs
|
||||||
|
* The strings to concatenate.
|
||||||
|
* @return The parameters concatenated.
|
||||||
|
*/
|
||||||
|
private static String concat(final Object... pArgs) {
|
||||||
|
final StringBuilder result = new StringBuilder();
|
||||||
|
for (final Object arg : pArgs) {
|
||||||
|
result.append(arg);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+29
-1
@@ -3,12 +3,15 @@ package org.codiki.application.publication;
|
|||||||
import static java.util.Objects.isNull;
|
import static java.util.Objects.isNull;
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static org.codiki.domain.publication.model.builder.AuthorBuilder.anAuthor;
|
import static org.codiki.domain.publication.model.builder.AuthorBuilder.anAuthor;
|
||||||
import static org.codiki.domain.publication.model.builder.PublicationBuilder.aPublication;
|
import static org.codiki.domain.publication.model.builder.PublicationBuilder.aPublication;
|
||||||
|
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||||
|
|
||||||
import org.codiki.application.category.CategoryUseCases;
|
import org.codiki.application.category.CategoryUseCases;
|
||||||
import org.codiki.application.picture.PictureUseCases;
|
import org.codiki.application.picture.PictureUseCases;
|
||||||
import org.codiki.application.user.UserUseCases;
|
import org.codiki.application.user.UserUseCases;
|
||||||
@@ -31,6 +34,7 @@ public class PublicationUseCases {
|
|||||||
private final CategoryUseCases categoryUseCases;
|
private final CategoryUseCases categoryUseCases;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final KeyGenerator keyGenerator;
|
private final KeyGenerator keyGenerator;
|
||||||
|
private final ParserService parserService;
|
||||||
private final PictureUseCases pictureUseCases;
|
private final PictureUseCases pictureUseCases;
|
||||||
private final PublicationCreationRequestValidator publicationCreationRequestValidator;
|
private final PublicationCreationRequestValidator publicationCreationRequestValidator;
|
||||||
private final PublicationPort publicationPort;
|
private final PublicationPort publicationPort;
|
||||||
@@ -42,6 +46,7 @@ public class PublicationUseCases {
|
|||||||
CategoryUseCases categoryUseCases,
|
CategoryUseCases categoryUseCases,
|
||||||
Clock clock,
|
Clock clock,
|
||||||
KeyGenerator keyGenerator,
|
KeyGenerator keyGenerator,
|
||||||
|
ParserService parserService,
|
||||||
PictureUseCases pictureUseCases,
|
PictureUseCases pictureUseCases,
|
||||||
PublicationCreationRequestValidator publicationCreationRequestValidator,
|
PublicationCreationRequestValidator publicationCreationRequestValidator,
|
||||||
PublicationPort publicationPort,
|
PublicationPort publicationPort,
|
||||||
@@ -52,6 +57,7 @@ public class PublicationUseCases {
|
|||||||
this.categoryUseCases = categoryUseCases;
|
this.categoryUseCases = categoryUseCases;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.keyGenerator = keyGenerator;
|
this.keyGenerator = keyGenerator;
|
||||||
|
this.parserService = parserService;
|
||||||
this.publicationCreationRequestValidator = publicationCreationRequestValidator;
|
this.publicationCreationRequestValidator = publicationCreationRequestValidator;
|
||||||
this.publicationPort = publicationPort;
|
this.publicationPort = publicationPort;
|
||||||
this.publicationUpdateRequestValidator = publicationUpdateRequestValidator;
|
this.publicationUpdateRequestValidator = publicationUpdateRequestValidator;
|
||||||
@@ -83,6 +89,7 @@ public class PublicationUseCases {
|
|||||||
.withKey(keyGenerator.generateKey())
|
.withKey(keyGenerator.generateKey())
|
||||||
.withTitle(request.title())
|
.withTitle(request.title())
|
||||||
.withText(request.text())
|
.withText(request.text())
|
||||||
|
.withParsedText(parserService.parse(request.text()))
|
||||||
.withDescription(request.description())
|
.withDescription(request.description())
|
||||||
.withCreationDate(ZonedDateTime.now(clock))
|
.withCreationDate(ZonedDateTime.now(clock))
|
||||||
.withIllustrationId(request.illustrationId())
|
.withIllustrationId(request.illustrationId())
|
||||||
@@ -116,6 +123,7 @@ public class PublicationUseCases {
|
|||||||
|
|
||||||
if (!isNull(request.text())) {
|
if (!isNull(request.text())) {
|
||||||
publicationBuilder.withText(request.text());
|
publicationBuilder.withText(request.text());
|
||||||
|
publicationBuilder.withParsedText(parserService.parse(request.text()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isNull(request.description())) {
|
if (!isNull(request.description())) {
|
||||||
@@ -163,7 +171,19 @@ public class PublicationUseCases {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Publication> findById(UUID publicationId) {
|
public Optional<Publication> findById(UUID publicationId) {
|
||||||
return publicationPort.findById(publicationId);
|
return publicationPort.findById(publicationId)
|
||||||
|
.map(publication -> {
|
||||||
|
Publication result = publication;
|
||||||
|
if (isEmpty(publication.parsedText())) {
|
||||||
|
Publication editedPublication = aPublication()
|
||||||
|
.basedOn(publication)
|
||||||
|
.withParsedText(parserService.parse(publication.text()))
|
||||||
|
.build();
|
||||||
|
publicationPort.save(editedPublication);
|
||||||
|
result = editedPublication;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Publication> searchPublications(String searchQuery) {
|
public List<Publication> searchPublications(String searchQuery) {
|
||||||
@@ -171,4 +191,12 @@ public class PublicationUseCases {
|
|||||||
|
|
||||||
return publicationPort.search(criteria);
|
return publicationPort.search(criteria);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Publication> getLatest() {
|
||||||
|
return publicationPort.getLatest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String previewContent(String publicationText) {
|
||||||
|
return parserService.parse(publicationText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
@@ -5,6 +5,7 @@ import java.util.stream.IntStream;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
class KeyGeneratorTest {
|
class KeyGeneratorTest {
|
||||||
@@ -16,6 +17,7 @@ class KeyGeneratorTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Disabled
|
||||||
public void generateKey_should_generate_random_keys_with_alphanumeric_characters() {
|
public void generateKey_should_generate_random_keys_with_alphanumeric_characters() {
|
||||||
Pattern validationRegex = Pattern.compile("^[0-9A-Z]{10}$");
|
Pattern validationRegex = Pattern.compile("^[0-9A-Z]{10}$");
|
||||||
|
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
@@ -1,10 +1,12 @@
|
|||||||
package org.codiki.domain.picture.model;
|
package org.codiki.domain.picture.model;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public record Picture(
|
public record Picture(
|
||||||
UUID id,
|
UUID id,
|
||||||
UUID publisherId,
|
UUID publisherId,
|
||||||
|
ZonedDateTime publishedAt,
|
||||||
File contentFile
|
File contentFile
|
||||||
) {}
|
) {}
|
||||||
+8
-1
@@ -1,6 +1,7 @@
|
|||||||
package org.codiki.domain.picture.model.builder;
|
package org.codiki.domain.picture.model.builder;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.codiki.domain.picture.model.Picture;
|
import org.codiki.domain.picture.model.Picture;
|
||||||
@@ -9,6 +10,7 @@ import org.codiki.domain.user.model.User;
|
|||||||
public class PictureBuilder {
|
public class PictureBuilder {
|
||||||
private UUID id;
|
private UUID id;
|
||||||
private UUID publisherId;
|
private UUID publisherId;
|
||||||
|
private ZonedDateTime publishedAt;
|
||||||
private File contentFile;
|
private File contentFile;
|
||||||
|
|
||||||
private PictureBuilder() {}
|
private PictureBuilder() {}
|
||||||
@@ -37,12 +39,17 @@ public class PictureBuilder {
|
|||||||
return withPublisherId(publisher.id());
|
return withPublisherId(publisher.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PictureBuilder withPublicationDate(ZonedDateTime publishedAt) {
|
||||||
|
this.publishedAt = publishedAt;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public PictureBuilder withContentFile(File contentFile) {
|
public PictureBuilder withContentFile(File contentFile) {
|
||||||
this.contentFile = contentFile;
|
this.contentFile = contentFile;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Picture build() {
|
public Picture build() {
|
||||||
return new Picture(id, publisherId, contentFile);
|
return new Picture(id, publisherId, publishedAt, contentFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
@@ -1,5 +1,6 @@
|
|||||||
package org.codiki.domain.picture.port;
|
package org.codiki.domain.picture.port;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -13,4 +14,6 @@ public interface PicturePort {
|
|||||||
void save(Picture picture);
|
void save(Picture picture);
|
||||||
|
|
||||||
void deleteById(UUID pictureId);
|
void deleteById(UUID pictureId);
|
||||||
|
|
||||||
|
List<Picture> findAllByPublisherId(UUID id);
|
||||||
}
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
package org.codiki.domain.publication.exception;
|
||||||
|
|
||||||
|
import org.codiki.domain.exception.FunctionnalException;
|
||||||
|
|
||||||
|
public class BadPublicationSearchCriterionException extends FunctionnalException {
|
||||||
|
public BadPublicationSearchCriterionException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-1
@@ -5,7 +5,7 @@ import java.util.UUID;
|
|||||||
public record Author(
|
public record Author(
|
||||||
UUID id,
|
UUID id,
|
||||||
String name,
|
String name,
|
||||||
String image
|
String photoId
|
||||||
) {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
@@ -8,6 +8,7 @@ public record Publication(
|
|||||||
String key,
|
String key,
|
||||||
String title,
|
String title,
|
||||||
String text,
|
String text,
|
||||||
|
String parsedText,
|
||||||
String description,
|
String description,
|
||||||
ZonedDateTime creationDate,
|
ZonedDateTime creationDate,
|
||||||
UUID illustrationId,
|
UUID illustrationId,
|
||||||
File renamed without changes.
+1
@@ -40,6 +40,7 @@ public class AuthorBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Author build() {
|
public Author build() {
|
||||||
|
//
|
||||||
return new Author(id, name, image);
|
return new Author(id, name, image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+11
-4
@@ -1,17 +1,17 @@
|
|||||||
package org.codiki.domain.publication.model.builder;
|
package org.codiki.domain.publication.model.builder;
|
||||||
|
|
||||||
|
import org.codiki.domain.publication.model.Author;
|
||||||
|
import org.codiki.domain.publication.model.Publication;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.codiki.domain.category.model.Category;
|
|
||||||
import org.codiki.domain.publication.model.Author;
|
|
||||||
import org.codiki.domain.publication.model.Publication;
|
|
||||||
|
|
||||||
public class PublicationBuilder {
|
public class PublicationBuilder {
|
||||||
private UUID id;
|
private UUID id;
|
||||||
private String key;
|
private String key;
|
||||||
private String title;
|
private String title;
|
||||||
private String text;
|
private String text;
|
||||||
|
private String parsedText;
|
||||||
private String description;
|
private String description;
|
||||||
private ZonedDateTime creationDate;
|
private ZonedDateTime creationDate;
|
||||||
private UUID illustrationId;
|
private UUID illustrationId;
|
||||||
@@ -30,6 +30,7 @@ public class PublicationBuilder {
|
|||||||
.withKey(publication.key())
|
.withKey(publication.key())
|
||||||
.withTitle(publication.title())
|
.withTitle(publication.title())
|
||||||
.withText(publication.text())
|
.withText(publication.text())
|
||||||
|
.withParsedText(publication.parsedText())
|
||||||
.withDescription(publication.description())
|
.withDescription(publication.description())
|
||||||
.withCreationDate(publication.creationDate())
|
.withCreationDate(publication.creationDate())
|
||||||
.withIllustrationId(publication.illustrationId())
|
.withIllustrationId(publication.illustrationId())
|
||||||
@@ -57,6 +58,11 @@ public class PublicationBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PublicationBuilder withParsedText(String parsedText) {
|
||||||
|
this.parsedText = parsedText;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public PublicationBuilder withDescription(String description) {
|
public PublicationBuilder withDescription(String description) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
return this;
|
return this;
|
||||||
@@ -88,6 +94,7 @@ public class PublicationBuilder {
|
|||||||
key,
|
key,
|
||||||
title,
|
title,
|
||||||
text,
|
text,
|
||||||
|
parsedText,
|
||||||
description,
|
description,
|
||||||
creationDate,
|
creationDate,
|
||||||
illustrationId,
|
illustrationId,
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
@@ -15,4 +15,6 @@ public interface PublicationPort {
|
|||||||
void delete(Publication publication);
|
void delete(Publication publication);
|
||||||
|
|
||||||
List<Publication> search(List<PublicationSearchCriterion> criteria);
|
List<Publication> search(List<PublicationSearchCriterion> criteria);
|
||||||
|
|
||||||
|
List<Publication> getLatest();
|
||||||
}
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+5
-9
@@ -7,16 +7,10 @@ import static org.springframework.http.HttpStatus.UNAUTHORIZED;
|
|||||||
import org.codiki.domain.category.exception.CategoryDeletionException;
|
import org.codiki.domain.category.exception.CategoryDeletionException;
|
||||||
import org.codiki.domain.category.exception.CategoryEditionException;
|
import org.codiki.domain.category.exception.CategoryEditionException;
|
||||||
import org.codiki.domain.category.exception.CategoryNotFoundException;
|
import org.codiki.domain.category.exception.CategoryNotFoundException;
|
||||||
import org.codiki.domain.exception.LoginFailureException;
|
import org.codiki.domain.exception.*;
|
||||||
import org.codiki.domain.exception.RefreshTokenDoesNotExistException;
|
|
||||||
import org.codiki.domain.exception.RefreshTokenExpiredException;
|
|
||||||
import org.codiki.domain.exception.UserDoesNotExistException;
|
|
||||||
import org.codiki.domain.picture.exception.PictureNotFoundException;
|
import org.codiki.domain.picture.exception.PictureNotFoundException;
|
||||||
import org.codiki.domain.picture.exception.PictureUploadException;
|
import org.codiki.domain.picture.exception.PictureUploadException;
|
||||||
import org.codiki.domain.publication.exception.NoPublicationSearchResultException;
|
import org.codiki.domain.publication.exception.*;
|
||||||
import org.codiki.domain.publication.exception.PublicationEditionException;
|
|
||||||
import org.codiki.domain.publication.exception.PublicationNotFoundException;
|
|
||||||
import org.codiki.domain.publication.exception.PublicationUpdateForbiddenException;
|
|
||||||
import org.codiki.domain.user.exception.UserAlreadyExistsException;
|
import org.codiki.domain.user.exception.UserAlreadyExistsException;
|
||||||
import org.codiki.domain.user.exception.UserCreationException;
|
import org.codiki.domain.user.exception.UserCreationException;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
@@ -28,6 +22,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep
|
|||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
public class GlobalControllerExceptionHandler extends ResponseEntityExceptionHandler {
|
public class GlobalControllerExceptionHandler extends ResponseEntityExceptionHandler {
|
||||||
@ExceptionHandler({
|
@ExceptionHandler({
|
||||||
|
BadPublicationSearchCriterionException.class,
|
||||||
CategoryDeletionException.class,
|
CategoryDeletionException.class,
|
||||||
CategoryEditionException.class,
|
CategoryEditionException.class,
|
||||||
CategoryNotFoundException.class,
|
CategoryNotFoundException.class,
|
||||||
@@ -53,7 +48,8 @@ public class GlobalControllerExceptionHandler extends ResponseEntityExceptionHan
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler({
|
@ExceptionHandler({
|
||||||
RefreshTokenExpiredException.class
|
RefreshTokenExpiredException.class,
|
||||||
|
AuthenticationRequiredException.class,
|
||||||
})
|
})
|
||||||
public ProblemDetail handleUnauthorizedExceptions(Exception exception) {
|
public ProblemDetail handleUnauthorizedExceptions(Exception exception) {
|
||||||
return buildProblemDetail(UNAUTHORIZED, exception);
|
return buildProblemDetail(UNAUTHORIZED, exception);
|
||||||
File renamed without changes.
+3
-1
@@ -48,12 +48,14 @@ public class SecurityConfiguration {
|
|||||||
"/api/pictures/{pictureId}",
|
"/api/pictures/{pictureId}",
|
||||||
"/api/publications/{publicationId}",
|
"/api/publications/{publicationId}",
|
||||||
"/api/publications",
|
"/api/publications",
|
||||||
|
"/api/publications/latest",
|
||||||
"/error"
|
"/error"
|
||||||
).permitAll()
|
).permitAll()
|
||||||
.requestMatchers(
|
.requestMatchers(
|
||||||
POST,
|
POST,
|
||||||
"/api/users/login",
|
"/api/users/login",
|
||||||
"/api/users/refresh-token"
|
"/api/users/refresh-token",
|
||||||
|
"/api/users"
|
||||||
).permitAll()
|
).permitAll()
|
||||||
.requestMatchers(
|
.requestMatchers(
|
||||||
POST,
|
POST,
|
||||||
File renamed without changes.
File renamed without changes.
+10
@@ -1,6 +1,7 @@
|
|||||||
package org.codiki.exposition.picture;
|
package org.codiki.exposition.picture;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE;
|
import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE;
|
||||||
@@ -8,6 +9,7 @@ import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE;
|
|||||||
import org.codiki.application.picture.PictureUseCases;
|
import org.codiki.application.picture.PictureUseCases;
|
||||||
import org.codiki.domain.picture.exception.PictureNotFoundException;
|
import org.codiki.domain.picture.exception.PictureNotFoundException;
|
||||||
import org.codiki.domain.picture.model.Picture;
|
import org.codiki.domain.picture.model.Picture;
|
||||||
|
import org.codiki.exposition.picture.model.PictureDto;
|
||||||
import org.springframework.core.io.FileSystemResource;
|
import org.springframework.core.io.FileSystemResource;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
@@ -44,4 +46,12 @@ public class PictureController {
|
|||||||
.orElseThrow(() -> new PictureNotFoundException(pictureId));
|
.orElseThrow(() -> new PictureNotFoundException(pictureId));
|
||||||
return new FileSystemResource(picture.contentFile());
|
return new FileSystemResource(picture.contentFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/current-user")
|
||||||
|
public List<PictureDto> getAllPicturesOfCurrentUser() {
|
||||||
|
return pictureUseCases.getAllOfCurrentUser()
|
||||||
|
.stream()
|
||||||
|
.map(PictureDto::new)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package org.codiki.exposition.picture.model;
|
||||||
|
|
||||||
|
import org.codiki.domain.picture.model.Picture;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public record PictureDto(
|
||||||
|
UUID id,
|
||||||
|
ZonedDateTime publishedAt
|
||||||
|
) {
|
||||||
|
public PictureDto(Picture picture) {
|
||||||
|
this(picture.id(), picture.publishedAt());
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
-18
@@ -1,28 +1,22 @@
|
|||||||
package org.codiki.exposition.publication;
|
package org.codiki.exposition.publication;
|
||||||
|
|
||||||
|
import org.codiki.application.publication.PublicationUseCases;
|
||||||
|
import org.codiki.domain.publication.exception.NoPublicationSearchResultException;
|
||||||
|
import org.codiki.domain.publication.exception.PublicationNotFoundException;
|
||||||
|
import org.codiki.domain.publication.model.Publication;
|
||||||
|
import org.codiki.domain.publication.model.PublicationEditionRequest;
|
||||||
|
import org.codiki.exposition.publication.model.PreviewContentRequest;
|
||||||
|
import org.codiki.exposition.publication.model.PreviewContentResponse;
|
||||||
|
import org.codiki.exposition.publication.model.PublicationDto;
|
||||||
|
import org.codiki.exposition.publication.model.PublicationEditionRequestDto;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static org.springframework.http.HttpStatus.CREATED;
|
import static org.springframework.http.HttpStatus.CREATED;
|
||||||
import static org.springframework.http.HttpStatus.NO_CONTENT;
|
import static org.springframework.http.HttpStatus.NO_CONTENT;
|
||||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||||
import org.codiki.application.publication.PublicationUseCases;
|
|
||||||
import org.codiki.domain.publication.exception.NoPublicationSearchResultException;
|
|
||||||
import org.codiki.domain.publication.exception.PublicationNotFoundException;
|
|
||||||
import org.codiki.domain.publication.model.Publication;
|
|
||||||
import org.codiki.domain.publication.model.PublicationEditionRequest;
|
|
||||||
import org.codiki.exposition.publication.model.PublicationDto;
|
|
||||||
import org.codiki.exposition.publication.model.PublicationEditionRequestDto;
|
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/publications")
|
@RequestMapping("/api/publications")
|
||||||
@@ -66,7 +60,7 @@ public class PublicationController {
|
|||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public List<PublicationDto> searchPublications(@RequestParam("query") String searchQuery) {
|
public List<PublicationDto> searchPublications(@RequestParam("query") String searchQuery) {
|
||||||
final List<PublicationDto> publications = publicationUseCases.searchPublications(searchQuery)
|
List<PublicationDto> publications = publicationUseCases.searchPublications(searchQuery)
|
||||||
.stream()
|
.stream()
|
||||||
.map(PublicationDto::new)
|
.map(PublicationDto::new)
|
||||||
.toList();
|
.toList();
|
||||||
@@ -77,4 +71,24 @@ public class PublicationController {
|
|||||||
|
|
||||||
return publications;
|
return publications;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/latest")
|
||||||
|
public List<PublicationDto> getLatestPublications() {
|
||||||
|
List<PublicationDto> publications = publicationUseCases.getLatest()
|
||||||
|
.stream()
|
||||||
|
.map(PublicationDto::new)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
if (isEmpty(publications)) {
|
||||||
|
throw new NoPublicationSearchResultException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return publications;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = "/preview")
|
||||||
|
public PreviewContentResponse previewPublicationContent(@RequestBody PreviewContentRequest request) {
|
||||||
|
String previewContent = publicationUseCases.previewContent(request.text());
|
||||||
|
return new PreviewContentResponse(previewContent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -13,7 +13,7 @@ public record AuthorDto(
|
|||||||
this(
|
this(
|
||||||
author.id(),
|
author.id(),
|
||||||
author.name(),
|
author.name(),
|
||||||
author.image()
|
author.photoId()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package org.codiki.exposition.publication.model;
|
||||||
|
|
||||||
|
public record PreviewContentRequest(
|
||||||
|
String text
|
||||||
|
) {}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package org.codiki.exposition.publication.model;
|
||||||
|
|
||||||
|
public record PreviewContentResponse(
|
||||||
|
String text
|
||||||
|
) {}
|
||||||
+4
-3
@@ -1,16 +1,16 @@
|
|||||||
package org.codiki.exposition.publication.model;
|
package org.codiki.exposition.publication.model;
|
||||||
|
|
||||||
|
import org.codiki.domain.publication.model.Publication;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.codiki.domain.publication.model.Publication;
|
|
||||||
import org.codiki.exposition.category.model.CategoryDto;
|
|
||||||
|
|
||||||
public record PublicationDto(
|
public record PublicationDto(
|
||||||
UUID id,
|
UUID id,
|
||||||
String key,
|
String key,
|
||||||
String title,
|
String title,
|
||||||
String text,
|
String text,
|
||||||
|
String parsedText,
|
||||||
String description,
|
String description,
|
||||||
ZonedDateTime creationDate,
|
ZonedDateTime creationDate,
|
||||||
UUID illustrationId,
|
UUID illustrationId,
|
||||||
@@ -23,6 +23,7 @@ public record PublicationDto(
|
|||||||
publication.key(),
|
publication.key(),
|
||||||
publication.title(),
|
publication.title(),
|
||||||
publication.text(),
|
publication.text(),
|
||||||
|
publication.parsedText(),
|
||||||
publication.description(),
|
publication.description(),
|
||||||
publication.creationDate(),
|
publication.creationDate(),
|
||||||
publication.illustrationId(),
|
publication.illustrationId(),
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+4
@@ -1,5 +1,6 @@
|
|||||||
package org.codiki.infrastructure.category.repository;
|
package org.codiki.infrastructure.category.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.codiki.infrastructure.category.model.CategoryEntity;
|
import org.codiki.infrastructure.category.model.CategoryEntity;
|
||||||
@@ -16,4 +17,7 @@ public interface CategoryRepository extends JpaRepository<CategoryEntity, UUID>
|
|||||||
) > 0
|
) > 0
|
||||||
""", nativeQuery = true)
|
""", nativeQuery = true)
|
||||||
boolean existsAnyAssociatedPublication(@Param("categoryId") UUID categoryId);
|
boolean existsAnyAssociatedPublication(@Param("categoryId") UUID categoryId);
|
||||||
|
|
||||||
|
@Query("SELECT c FROM CategoryEntity c LEFT JOIN FETCH c.subCategories")
|
||||||
|
List<CategoryEntity> findAll();
|
||||||
}
|
}
|
||||||
File renamed without changes.
+9
@@ -1,6 +1,7 @@
|
|||||||
package org.codiki.infrastructure.picture;
|
package org.codiki.infrastructure.picture;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@@ -66,4 +67,12 @@ public class PictureJpaAdapter implements PicturePort {
|
|||||||
public void deleteById(UUID pictureId) {
|
public void deleteById(UUID pictureId) {
|
||||||
repository.deleteById(pictureId);
|
repository.deleteById(pictureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Picture> findAllByPublisherId(UUID id) {
|
||||||
|
return repository.findAllByPublisherId(id)
|
||||||
|
.stream()
|
||||||
|
.map(PictureEntity::toDomain)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+5
-1
@@ -1,5 +1,6 @@
|
|||||||
package org.codiki.infrastructure.picture.model;
|
package org.codiki.infrastructure.picture.model;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.codiki.domain.picture.model.Picture;
|
import org.codiki.domain.picture.model.Picture;
|
||||||
@@ -24,13 +25,16 @@ public class PictureEntity {
|
|||||||
private UUID id;
|
private UUID id;
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private UUID publisherId;
|
private UUID publisherId;
|
||||||
|
@Column(nullable = false)
|
||||||
|
private ZonedDateTime publishedAt;
|
||||||
|
|
||||||
public PictureEntity(Picture picture) {
|
public PictureEntity(Picture picture) {
|
||||||
id = picture.id();
|
id = picture.id();
|
||||||
publisherId = picture.publisherId();
|
publisherId = picture.publisherId();
|
||||||
|
publishedAt = picture.publishedAt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Picture toDomain() {
|
public Picture toDomain() {
|
||||||
return new Picture(id, publisherId, null);
|
return new Picture(id, publisherId, publishedAt, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
@@ -1,9 +1,12 @@
|
|||||||
package org.codiki.infrastructure.picture.repository;
|
package org.codiki.infrastructure.picture.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.codiki.domain.picture.model.Picture;
|
||||||
import org.codiki.infrastructure.picture.model.PictureEntity;
|
import org.codiki.infrastructure.picture.model.PictureEntity;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
public interface PictureRepository extends JpaRepository<PictureEntity, UUID> {
|
public interface PictureRepository extends JpaRepository<PictureEntity, UUID> {
|
||||||
|
List<PictureEntity> findAllByPublisherId(UUID id);
|
||||||
}
|
}
|
||||||
+18
-7
@@ -1,19 +1,22 @@
|
|||||||
package org.codiki.infrastructure.publication;
|
package org.codiki.infrastructure.publication;
|
||||||
|
|
||||||
import static java.util.Collections.reverseOrder;
|
|
||||||
import static java.util.Comparator.comparingInt;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.codiki.domain.publication.model.Publication;
|
import org.codiki.domain.publication.model.Publication;
|
||||||
import org.codiki.domain.publication.model.search.PublicationSearchCriterion;
|
import org.codiki.domain.publication.model.search.PublicationSearchCriterion;
|
||||||
import org.codiki.domain.publication.port.PublicationPort;
|
import org.codiki.domain.publication.port.PublicationPort;
|
||||||
import org.codiki.infrastructure.publication.model.PublicationEntity;
|
import org.codiki.infrastructure.publication.model.PublicationEntity;
|
||||||
|
import org.codiki.infrastructure.publication.model.PublicationSearchJpaCriterion;
|
||||||
import org.codiki.infrastructure.publication.model.PublicationSearchResult;
|
import org.codiki.infrastructure.publication.model.PublicationSearchResult;
|
||||||
import org.codiki.infrastructure.publication.repository.PublicationRepository;
|
import org.codiki.infrastructure.publication.repository.PublicationRepository;
|
||||||
|
import org.springframework.data.domain.Limit;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static java.util.Collections.reverseOrder;
|
||||||
|
import static java.util.Comparator.comparingInt;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class PublicationJpaAdapter implements PublicationPort {
|
public class PublicationJpaAdapter implements PublicationPort {
|
||||||
private final PublicationRepository repository;
|
private final PublicationRepository repository;
|
||||||
@@ -46,7 +49,7 @@ public class PublicationJpaAdapter implements PublicationPort {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Publication> search(List<PublicationSearchCriterion> criteria) {
|
public List<Publication> search(List<PublicationSearchCriterion> criteria) {
|
||||||
List<PublicationSearchCriterion> adaptedCriteria = publicationSearchCriteriaJpaAdapter.adaptCriteriaForJpa(criteria);
|
List<PublicationSearchJpaCriterion> adaptedCriteria = publicationSearchCriteriaJpaAdapter.adaptCriteriaForJpa(criteria);
|
||||||
return repository.search(adaptedCriteria)
|
return repository.search(adaptedCriteria)
|
||||||
.stream()
|
.stream()
|
||||||
.map(PublicationEntity::toDomain)
|
.map(PublicationEntity::toDomain)
|
||||||
@@ -55,4 +58,12 @@ public class PublicationJpaAdapter implements PublicationPort {
|
|||||||
.map(PublicationSearchResult::getPublication)
|
.map(PublicationSearchResult::getPublication)
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Publication> getLatest() {
|
||||||
|
return repository.getLatest(Limit.of(10))
|
||||||
|
.stream()
|
||||||
|
.map(PublicationEntity::toDomain)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+18
-2
@@ -3,12 +3,15 @@ package org.codiki.infrastructure.publication;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.codiki.domain.publication.exception.BadPublicationSearchCriterionException;
|
||||||
import org.codiki.domain.publication.model.search.PublicationSearchCriterion;
|
import org.codiki.domain.publication.model.search.PublicationSearchCriterion;
|
||||||
|
import org.codiki.infrastructure.publication.model.PublicationSearchJpaCriterion;
|
||||||
|
import org.codiki.infrastructure.publication.model.PublicationSearchJpaField;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class PublicationSearchCriteriaJpaAdapter {
|
public class PublicationSearchCriteriaJpaAdapter {
|
||||||
public List<PublicationSearchCriterion> adaptCriteriaForJpa(List<PublicationSearchCriterion> initialCriteria) {
|
public List<PublicationSearchJpaCriterion> adaptCriteriaForJpa(List<PublicationSearchCriterion> initialCriteria) {
|
||||||
List<PublicationSearchCriterion> result = new LinkedList<>();
|
List<PublicationSearchCriterion> result = new LinkedList<>();
|
||||||
|
|
||||||
for (PublicationSearchCriterion criterion : initialCriteria) {
|
for (PublicationSearchCriterion criterion : initialCriteria) {
|
||||||
@@ -29,6 +32,19 @@ public class PublicationSearchCriteriaJpaAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result.stream()
|
||||||
|
.map(this::mapToJpaCriterion)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private PublicationSearchJpaCriterion mapToJpaCriterion(PublicationSearchCriterion criterion) {
|
||||||
|
return new PublicationSearchJpaCriterion(
|
||||||
|
PublicationSearchJpaField.fromDomain(criterion.searchField())
|
||||||
|
.orElseThrow(() -> new BadPublicationSearchCriterionException(
|
||||||
|
String.format("Unknown field research criterion: %s", criterion.searchField()))
|
||||||
|
),
|
||||||
|
criterion.searchType(),
|
||||||
|
criterion.value()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-4
@@ -24,17 +24,17 @@ public class AuthorEntity {
|
|||||||
private UUID id;
|
private UUID id;
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String pseudo;
|
private String pseudo;
|
||||||
// private String illustrationId;
|
private String photoId;
|
||||||
|
|
||||||
public AuthorEntity(Author author) {
|
public AuthorEntity(Author author) {
|
||||||
this(
|
this(
|
||||||
author.id(),
|
author.id(),
|
||||||
author.name()
|
author.name(),
|
||||||
// author.illustrationId()
|
author.photoId()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Author toDomain() {
|
public Author toDomain() {
|
||||||
return new Author(id, pseudo, "image");
|
return new Author(id, pseudo, photoId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loaded 100 of 273 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user