Add picture recovering.

This commit is contained in:
Florian THIERRY
2024-03-21 18:04:56 +01:00
parent ba408ee0a2
commit c233301314
6 changed files with 182 additions and 102 deletions

View File

@@ -1,9 +1,6 @@
package org.codiki.databaseextractor.controller;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.Buffer;
import java.util.ArrayList;
import java.util.List;
import org.codiki.databaseextractor.entity.previous.OldCategory;
@@ -37,6 +34,8 @@ public class ExportController {
private final PictureMapper pictureMapper;
private final CategoryMapper categoryMapper;
private final PublicationMapper publicationMapper;
private final SqlScriptGenerator sqlScriptGenerator;
private final PictureFileHandler pictureFileHandler;
public ExportController(
CategoryRepository categoryRepository,
@@ -46,7 +45,10 @@ public class ExportController {
VersionRepository versionRepository,
UserMapper userMapper,
PictureMapper pictureMapper,
CategoryMapper categoryMapper, PublicationMapper publicationMapper
CategoryMapper categoryMapper,
PublicationMapper publicationMapper,
SqlScriptGenerator sqlScriptGenerator,
PictureFileHandler pictureFileHandler
) {
this.categoryRepository = categoryRepository;
this.postRepository = postRepository;
@@ -57,102 +59,32 @@ public class ExportController {
this.pictureMapper = pictureMapper;
this.categoryMapper = categoryMapper;
this.publicationMapper = publicationMapper;
this.sqlScriptGenerator = sqlScriptGenerator;
this.pictureFileHandler = pictureFileHandler;
}
@GetMapping
public void exportDatabase() {
List<OldCategory> oldCategories = extractCategories();
List<Image> images = extractImages();
List<Post> posts = extractPosts();
List<OldUser> oldUsers = extractUsers();
List<Version> versions = extractVersions();
List<OldCategory> oldCategories = categoryRepository.findAll();
List<Image> images = imageRepository.findAll();
List<Post> posts = postRepository.findAll();
List<OldUser> oldUsers = userRepository.findAll();
List<Version> versions = versionRepository.findAll();
List<UserWrapper> users = userMapper.mapFrom(oldUsers);
List<PictureWrapper> pictures = pictureMapper.mapFrom(images, users);
PictureWrapper defaultPicture = pictureMapper.createDefaultPicture(users);
List<CategoryWrapper> categories = categoryMapper.mapFrom(oldCategories);
List<PublicationWrapper> publications = publicationMapper.mapFrom(posts, users, categories, pictures);
List<PublicationWrapper> publications = publicationMapper.mapFrom(posts, users, categories, pictures, defaultPicture);
List<NonCodikiPicture> nonCodikiPictures = publicationMapper.extractNonCodikiPictures(publications, pictures);
generateSqlScript(users, pictures, categories, publications);
List<PictureWrapper> allPictures = new ArrayList<>(pictures);
allPictures.add(defaultPicture);
sqlScriptGenerator.generateSqlScript(users, allPictures, categories, publications);
pictureFileHandler.copyPictureFilesWithNewFileNames(pictures);
System.out.println("yo");
}
private void generateSqlScript(
List<UserWrapper> users,
List<PictureWrapper> pictures,
List<CategoryWrapper> categories,
List<PublicationWrapper> publications
) {
String sqlScriptFilePath = "/Users/florian_thierry/Documents/Developpement/codiki-database-extractor/codiki_export.sql";
try(FileWriter fileWriter = new FileWriter(sqlScriptFilePath);
BufferedWriter writer = new BufferedWriter(fileWriter)) {
writeUsersQuery(writer, users);
writePicturesQuery(writer, pictures);
writeCategoriesQuery(writer, categories);
writePublicationsQuery(writer, publications);
} catch (IOException exception) {
System.out.println("An error occured while writing SQL script file");
}
}
private void writeUsersQuery(BufferedWriter writer, List<UserWrapper> users) throws IOException {
writer.write("-- Users insertion\n");
writer.write("INSERT INTO \"user\" (id, pseudo, email, password, photo_id) VALUES\n");
writeEntitiesQueryPart(writer, users);
}
private void writePicturesQuery(BufferedWriter writer, List<PictureWrapper> pictures) throws IOException {
writer.write("\n");
writer.write("-- Pictures insertion\n");
writer.write("INSERT INTO picture (id, publisher_id) VALUES\n");
writeEntitiesQueryPart(writer, pictures);
}
private void writeCategoriesQuery(BufferedWriter writer, List<CategoryWrapper> categories) throws IOException {
writer.write("\n");
writer.write("-- Categories insertion\n");
writer.write("INSERT INTO category (id, name, parent_category_id) VALUES\n");
writeEntitiesQueryPart(writer, categories);
}
private void writePublicationsQuery(BufferedWriter writer, List<PublicationWrapper> publications) throws IOException {
writer.write("\n");
writer.write("-- Publications insertion\n");
writer.write("INSERT INTO publication (id, key, title, text, description, creation_date, illustration_id, author_id, category_id) VALUES\n");
writeEntitiesQueryPart(writer, publications);
}
private void writeEntitiesQueryPart(BufferedWriter writer, List<? extends SqlFragmentGenerator> entities) throws IOException {
for (int i = 0; i < entities.size(); i++) {
var entity = entities.get(i);
writer.write(entity.buildSqlFragment());
if (i == entities.size() - 1) {
writer.write(";");
} else {
writer.write(",");
}
writer.write("\n");
}
}
private List<OldCategory> extractCategories() {
return categoryRepository.findAll();
}
private List<Image> extractImages() {
return imageRepository.findAll();
}
private List<Post> extractPosts() {
return postRepository.findAll();
}
private List<OldUser> extractUsers() {
return userRepository.findAll();
}
private List<Version> extractVersions() {
return versionRepository.findAll();
}
}

View File

@@ -0,0 +1,49 @@
package org.codiki.databaseextractor.controller;
import org.codiki.databaseextractor.entity.wrapper.PictureWrapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
@Component
public class PictureFileHandler {
private final String picturesSourceFolderPath;
private final String picturesTargetFolderPath;
public PictureFileHandler(
@Value("${application.pictures.folders.sources}")
String picturesSourceFolderPath,
@Value("${application.pictures.folders.targets}")
String picturesTargetFolderPath) {
this.picturesSourceFolderPath = picturesSourceFolderPath;
this.picturesTargetFolderPath = picturesTargetFolderPath;
}
public void copyPictureFilesWithNewFileNames(List<PictureWrapper> pictures) {
for (var picture : pictures) {
String sourceFilePath = buildPictureSourceFilePath(picture);
String targetFilePath = buildPictureTargetFilePath(picture);
try {
Files.copy(Path.of(sourceFilePath), Path.of(targetFilePath));
} catch (IOException exception) {
throw new RuntimeException("An error occured while copying picture " + picture.picture().id(), exception);
}
}
}
private String buildPictureSourceFilePath(PictureWrapper picture) {
return String.format("%s/%s", picturesSourceFolderPath, picture.image().getLink());
}
private String buildPictureTargetFilePath(PictureWrapper picture) {
return String.format("%s/%s", picturesTargetFolderPath, picture.picture().id());
}
public boolean exists(PictureWrapper picture) {
return Files.exists(Path.of(buildPictureSourceFilePath(picture)));
}
}

View File

@@ -0,0 +1,77 @@
package org.codiki.databaseextractor.controller;
import org.codiki.databaseextractor.entity.wrapper.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
@Component
public class SqlScriptGenerator {
private final String sqlScriptFilePath;
public SqlScriptGenerator(@Value("${application.sql-script.target-folder-path}") String sqlScriptFilePath) {
this.sqlScriptFilePath = sqlScriptFilePath;
}
public void generateSqlScript(
List<UserWrapper> users,
List<PictureWrapper> pictures,
List<CategoryWrapper> categories,
List<PublicationWrapper> publications
) {
try(FileWriter fileWriter = new FileWriter(sqlScriptFilePath);
BufferedWriter writer = new BufferedWriter(fileWriter)) {
writeUsersQuery(writer, users);
writePicturesQuery(writer, pictures);
writeCategoriesQuery(writer, categories);
writePublicationsQuery(writer, publications);
} catch (IOException exception) {
System.out.println("An error occured while writing SQL script file");
}
}
private void writeUsersQuery(BufferedWriter writer, List<UserWrapper> users) throws IOException {
writer.write("-- Users insertion\n");
writer.write("INSERT INTO \"user\" (id, pseudo, email, password, photo_id) VALUES\n");
writeEntitiesQueryPart(writer, users);
}
private void writePicturesQuery(BufferedWriter writer, List<PictureWrapper> pictures) throws IOException {
writer.write("\n");
writer.write("-- Pictures insertion\n");
writer.write("INSERT INTO picture (id, publisher_id) VALUES\n");
writeEntitiesQueryPart(writer, pictures);
}
private void writeCategoriesQuery(BufferedWriter writer, List<CategoryWrapper> categories) throws IOException {
writer.write("\n");
writer.write("-- Categories insertion\n");
writer.write("INSERT INTO category (id, name, parent_category_id) VALUES\n");
writeEntitiesQueryPart(writer, categories);
}
private void writePublicationsQuery(BufferedWriter writer, List<PublicationWrapper> publications) throws IOException {
writer.write("\n");
writer.write("-- Publications insertion\n");
writer.write("INSERT INTO publication (id, key, title, text, description, creation_date, illustration_id, author_id, category_id) VALUES\n");
writeEntitiesQueryPart(writer, publications);
}
private void writeEntitiesQueryPart(BufferedWriter writer, List<? extends SqlFragmentGenerator> entities) throws IOException {
for (int i = 0; i < entities.size(); i++) {
var entity = entities.get(i);
writer.write(entity.buildSqlFragment());
if (i == entities.size() - 1) {
writer.write(";");
} else {
writer.write(",");
}
writer.write("\n");
}
}
}

View File

@@ -3,6 +3,7 @@ package org.codiki.databaseextractor.mapper;
import java.util.List;
import java.util.UUID;
import org.codiki.databaseextractor.controller.PictureFileHandler;
import org.codiki.databaseextractor.entity.next.Picture;
import org.codiki.databaseextractor.entity.next.User;
import org.codiki.databaseextractor.entity.previous.Image;
@@ -15,9 +16,11 @@ import org.springframework.stereotype.Component;
@Component
public class PictureMapper {
private final UserHelper userHelper;
private final PictureFileHandler pictureFileHandler;
public PictureMapper(UserHelper userHelper) {
public PictureMapper(UserHelper userHelper, PictureFileHandler pictureFileHandler) {
this.userHelper = userHelper;
this.pictureFileHandler = pictureFileHandler;
}
public List<PictureWrapper> mapFrom(List<Image> images, List<UserWrapper> users) {
@@ -36,6 +39,16 @@ public class PictureMapper {
return new PictureWrapper(image, picture);
})
.filter(pictureFileHandler::exists)
.toList();
}
public PictureWrapper createDefaultPicture(List<UserWrapper> users) {
UserWrapper administrator = users.stream()
.filter(user -> user.user().email().equals("admin@admin.adm"))
.findFirst()
.orElseThrow(() -> new RuntimeException("No admin user found for default picture creation."));
return new PictureWrapper(null, new Picture(UUID.randomUUID(), administrator.user().id(), null));
}
}

View File

@@ -20,7 +20,7 @@ public class PublicationMapper {
List<Post> posts,
List<UserWrapper> users,
List<CategoryWrapper> categories,
List<PictureWrapper> pictures) {
List<PictureWrapper> pictures, PictureWrapper defaultPicture) {
return posts.stream()
.map(post -> {
CategoryWrapper publicationCategory = categories.stream()
@@ -33,11 +33,12 @@ public class PublicationMapper {
.findFirst()
.orElseThrow(() -> new RuntimeException("No any author found for post " + post.getId()));
Optional<UUID> publicationIllustrationId = Optional.of(post.getImage())
UUID publicationIllustrationId = Optional.of(post.getImage())
.filter(imageLink -> imageLink.startsWith("https://codiki.org/api/images/"))
.map(imageLink -> imageLink.substring("https://codiki.org/api/images/".length()))
.flatMap(imageKey -> findPictureByLink(pictures, imageKey))
.map(picture -> picture.picture().id());
.map(picture -> picture.picture().id())
.orElse(defaultPicture.picture().id());
Publication publication = new Publication(
UUID.randomUUID(),
@@ -46,7 +47,7 @@ public class PublicationMapper {
post.getText(),
post.getDescription(),
ZonedDateTime.ofInstant(post.getCreationDate().toInstant(), ZoneId.systemDefault()),
publicationIllustrationId.orElse(null),
publicationIllustrationId,
publicationCategory.category().id(),
publicationAuthor.user().id()
);

View File

@@ -7,3 +7,11 @@ spring:
server:
port: 8765
application:
sql-script:
target-folder-path: /Users/florian_thierry/Documents/Developpement/codiki-database-extractor/codiki_export.sql
pictures:
folders:
sources: /Users/florian_thierry/Documents/Developpement/codiki-database-extractor/pictures/sources
targets: /Users/florian_thierry/Documents/Developpement/codiki-database-extractor/pictures/targets