fix image processing

This commit is contained in:
Stefan Hardegger
2025-09-27 09:15:01 +02:00
parent 2b4cb1456f
commit df5e124115
2 changed files with 92 additions and 7 deletions

View File

@@ -43,6 +43,7 @@ public class StoryService {
private final SeriesService seriesService; private final SeriesService seriesService;
private final HtmlSanitizationService sanitizationService; private final HtmlSanitizationService sanitizationService;
private final SearchServiceAdapter searchServiceAdapter; private final SearchServiceAdapter searchServiceAdapter;
private final ImageService imageService;
@Autowired @Autowired
public StoryService(StoryRepository storyRepository, public StoryService(StoryRepository storyRepository,
@@ -52,7 +53,8 @@ public class StoryService {
TagService tagService, TagService tagService,
SeriesService seriesService, SeriesService seriesService,
HtmlSanitizationService sanitizationService, HtmlSanitizationService sanitizationService,
SearchServiceAdapter searchServiceAdapter) { SearchServiceAdapter searchServiceAdapter,
ImageService imageService) {
this.storyRepository = storyRepository; this.storyRepository = storyRepository;
this.tagRepository = tagRepository; this.tagRepository = tagRepository;
this.readingPositionRepository = readingPositionRepository; this.readingPositionRepository = readingPositionRepository;
@@ -61,6 +63,7 @@ public class StoryService {
this.seriesService = seriesService; this.seriesService = seriesService;
this.sanitizationService = sanitizationService; this.sanitizationService = sanitizationService;
this.searchServiceAdapter = searchServiceAdapter; this.searchServiceAdapter = searchServiceAdapter;
this.imageService = imageService;
} }
@Transactional(readOnly = true) @Transactional(readOnly = true)
@@ -343,6 +346,34 @@ public class StoryService {
Story savedStory = storyRepository.save(story); Story savedStory = storyRepository.save(story);
// Process external images in content (now that we have a story ID)
if (savedStory.getContentHtml() != null && !savedStory.getContentHtml().trim().isEmpty()) {
try {
ImageService.ContentImageProcessingResult imageResult =
imageService.processContentImages(savedStory.getContentHtml(), savedStory.getId());
// Update content if images were processed
if (!imageResult.getProcessedContent().equals(savedStory.getContentHtml())) {
savedStory.setContentHtml(imageResult.getProcessedContent());
savedStory = storyRepository.save(savedStory);
}
// Log any warnings or downloaded images
if (imageResult.hasWarnings()) {
logger.warn("Image processing warnings for new story {}: {}",
savedStory.getId(), imageResult.getWarnings());
}
if (!imageResult.getDownloadedImages().isEmpty()) {
logger.info("Downloaded {} external images for new story {}: {}",
imageResult.getDownloadedImages().size(), savedStory.getId(),
imageResult.getDownloadedImages());
}
} catch (Exception e) {
logger.warn("Failed to process images for new story {}: {}",
savedStory.getId(), e.getMessage());
}
}
// Handle tags // Handle tags
if (story.getTags() != null && !story.getTags().isEmpty()) { if (story.getTags() != null && !story.getTags().isEmpty()) {
updateStoryTags(savedStory, story.getTags()); updateStoryTags(savedStory, story.getTags());
@@ -371,6 +402,34 @@ public class StoryService {
Story savedStory = storyRepository.save(story); Story savedStory = storyRepository.save(story);
// Process external images in content (now that we have a story ID)
if (savedStory.getContentHtml() != null && !savedStory.getContentHtml().trim().isEmpty()) {
try {
ImageService.ContentImageProcessingResult imageResult =
imageService.processContentImages(savedStory.getContentHtml(), savedStory.getId());
// Update content if images were processed
if (!imageResult.getProcessedContent().equals(savedStory.getContentHtml())) {
savedStory.setContentHtml(imageResult.getProcessedContent());
savedStory = storyRepository.save(savedStory);
}
// Log any warnings or downloaded images
if (imageResult.hasWarnings()) {
logger.warn("Image processing warnings for new story {}: {}",
savedStory.getId(), imageResult.getWarnings());
}
if (!imageResult.getDownloadedImages().isEmpty()) {
logger.info("Downloaded {} external images for new story {}: {}",
imageResult.getDownloadedImages().size(), savedStory.getId(),
imageResult.getDownloadedImages());
}
} catch (Exception e) {
logger.warn("Failed to process images for new story {}: {}",
savedStory.getId(), e.getMessage());
}
}
// Handle tags by names // Handle tags by names
if (tagNames != null && !tagNames.isEmpty()) { if (tagNames != null && !tagNames.isEmpty()) {
updateStoryTagsByNames(savedStory, tagNames); updateStoryTagsByNames(savedStory, tagNames);
@@ -588,7 +647,32 @@ public class StoryService {
story.setSummary(updateReq.getSummary()); story.setSummary(updateReq.getSummary());
} }
if (updateReq.getContentHtml() != null) { if (updateReq.getContentHtml() != null) {
story.setContentHtml(sanitizationService.sanitize(updateReq.getContentHtml())); String sanitizedContent = sanitizationService.sanitize(updateReq.getContentHtml());
// Process external images in the content
try {
ImageService.ContentImageProcessingResult imageResult =
imageService.processContentImages(sanitizedContent, story.getId());
// Use the processed content (with local image URLs)
story.setContentHtml(imageResult.getProcessedContent());
// Log any warnings or downloaded images
if (imageResult.hasWarnings()) {
logger.warn("Image processing warnings for story {}: {}",
story.getId(), imageResult.getWarnings());
}
if (!imageResult.getDownloadedImages().isEmpty()) {
logger.info("Downloaded {} external images for story {}: {}",
imageResult.getDownloadedImages().size(), story.getId(),
imageResult.getDownloadedImages());
}
} catch (Exception e) {
logger.warn("Failed to process images for story {}, using content without image processing: {}",
story.getId(), e.getMessage());
// Fallback to sanitized content without image processing
story.setContentHtml(sanitizedContent);
}
} }
if (updateReq.getSourceUrl() != null) { if (updateReq.getSourceUrl() != null) {
story.setSourceUrl(updateReq.getSourceUrl()); story.setSourceUrl(updateReq.getSourceUrl());

View File

@@ -56,7 +56,8 @@ class StoryServiceTest {
null, // tagService - not needed for reading progress tests null, // tagService - not needed for reading progress tests
null, // seriesService - not needed for reading progress tests null, // seriesService - not needed for reading progress tests
null, // sanitizationService - not needed for reading progress tests null, // sanitizationService - not needed for reading progress tests
searchServiceAdapter searchServiceAdapter,
null // imageService - not needed for reading progress tests
); );
} }