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,16 +34,21 @@ 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,
ImageRepository imageRepository,
PostRepository postRepository,
UserRepository userRepository,
VersionRepository versionRepository,
UserMapper userMapper,
PictureMapper pictureMapper,
CategoryMapper categoryMapper, PublicationMapper publicationMapper
CategoryRepository categoryRepository,
ImageRepository imageRepository,
PostRepository postRepository,
UserRepository userRepository,
VersionRepository versionRepository,
UserMapper userMapper,
PictureMapper pictureMapper,
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