Skip to content

Commit af9c98a

Browse files
committed
Fixed recreating a comic losing track of pages [#2510]
1 parent 596194c commit af9c98a

File tree

8 files changed

+173
-128
lines changed

8 files changed

+173
-128
lines changed

comixed-adaptors/src/main/java/org/comixedproject/adaptors/comicbooks/ComicBookAdaptor.java

Lines changed: 94 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,20 @@
1818

1919
package org.comixedproject.adaptors.comicbooks;
2020

21-
import java.io.File;
22-
import java.io.FileOutputStream;
23-
import java.io.IOException;
24-
import java.io.OutputStream;
21+
import java.awt.image.BufferedImage;
22+
import java.io.*;
23+
import java.util.ArrayList;
2524
import java.util.List;
25+
import java.util.Objects;
2626
import java.util.Optional;
27+
import javax.imageio.ImageIO;
2728
import lombok.NonNull;
2829
import lombok.extern.log4j.Log4j2;
29-
import org.apache.commons.compress.utils.FileNameUtils;
3030
import org.apache.commons.io.FileUtils;
3131
import org.apache.commons.io.FilenameUtils;
32-
import org.apache.commons.lang.StringUtils;
32+
import org.apache.commons.lang3.StringUtils;
3333
import org.comixedproject.adaptors.AdaptorException;
34+
import org.comixedproject.adaptors.GenericUtilitiesAdaptor;
3435
import org.comixedproject.adaptors.archive.ArchiveAdaptor;
3536
import org.comixedproject.adaptors.archive.ArchiveAdaptorException;
3637
import org.comixedproject.adaptors.archive.model.ArchiveEntryType;
@@ -47,6 +48,7 @@
4748
import org.comixedproject.model.comicbooks.ComicBook;
4849
import org.comixedproject.model.comicbooks.ComicDetail;
4950
import org.comixedproject.model.comicpages.ComicPage;
51+
import org.comixedproject.model.comicpages.ComicPageType;
5052
import org.springframework.beans.factory.annotation.Autowired;
5153
import org.springframework.stereotype.Component;
5254

@@ -58,11 +60,13 @@
5860
@Component
5961
@Log4j2
6062
public class ComicBookAdaptor {
63+
public static final String COMIC_INFO_XML = "ComicInfo.xml";
6164
@Autowired private FileTypeAdaptor fileTypeAdaptor;
6265
@Autowired private ComicFileAdaptor comicFileAdaptor;
6366
@Autowired private ComicPageAdaptor comicPageAdaptor;
6467
@Autowired private ComicMetadataWriter comicMetadataWriter;
6568
@Autowired private FileAdaptor fileAdaptor;
69+
@Autowired private GenericUtilitiesAdaptor genericUtilitiesAdaptor;
6670

6771
/**
6872
* Creates a new comic. Determines the archive type for the underlying file.
@@ -156,11 +160,6 @@ public void save(
156160
final ArchiveAdaptor destinationArchive =
157161
this.fileTypeAdaptor.getArchiveAdaptorFor(targetArchiveType);
158162

159-
if (removeDeletedPages) {
160-
log.trace("Removing deleted pages from comic book");
161-
comicBook.removeDeletedPages();
162-
}
163-
164163
log.trace("Preparing to save comic book file");
165164
final ArchiveReadHandle readHandle =
166165
sourceArchive.openArchiveForRead(comicBook.getComicDetail().getFilename());
@@ -173,28 +172,73 @@ public void save(
173172
final ArchiveWriteHandle writeHandle =
174173
destinationArchive.openArchiveForWrite(temporaryFilename);
175174

176-
log.trace("Writing comic book pages");
177-
final int length = String.valueOf(comicBook.getPages().size()).length();
178-
for (int index = 0; index < comicBook.getPages().size(); index++) {
179-
final ComicPage page = comicBook.getPages().get(index);
180-
if (page != null) {
181-
log.trace("Reading comic book page content: {}", page.getFilename());
182-
final byte[] content = sourceArchive.readEntry(readHandle, page.getFilename());
183-
@NonNull String pageFilename = page.getFilename();
184-
if (StringUtils.isNotEmpty(pageRenamingRule)) {
185-
pageFilename =
186-
this.comicPageAdaptor.createFilenameFromRule(page, pageRenamingRule, index, length);
175+
final List<ComicPage> oldPages = this.doRemoveOldPages(comicBook);
176+
final List<ComicArchiveEntry> sourceEntries = sourceArchive.getEntries(readHandle);
177+
final int length = String.valueOf(oldPages.size()).length();
178+
log.debug("Processing source archive entries");
179+
for (int index = 0; index < sourceEntries.size(); index++) {
180+
final ComicArchiveEntry entry = sourceEntries.get(index);
181+
String entryFilename = entry.getFilename();
182+
log.trace("Loading entry: {}", entryFilename);
183+
final byte[] entryContent = sourceArchive.readEntry(readHandle, entryFilename);
184+
final ContentAdaptor contentAdaptor =
185+
this.fileTypeAdaptor.getContentAdaptorFor(entryFilename, entryContent);
186+
if (contentAdaptor != null) {
187+
log.trace("Entry type: {}", contentAdaptor.getArchiveEntryType());
188+
if (contentAdaptor.getArchiveEntryType() == ArchiveEntryType.IMAGE) {
189+
boolean includePage = true;
190+
int entryPageNumber = comicBook.getPages().size();
191+
192+
final String entryHash = this.genericUtilitiesAdaptor.createHash(entryContent);
193+
final ComicPage matchingPage =
194+
this.doFindMatchingPage(oldPages, entryFilename, entryHash);
195+
ComicPageType pageType = null;
196+
197+
if (Objects.nonNull(matchingPage)) {
198+
includePage = !matchingPage.isDeleted();
199+
pageType = matchingPage.getPageType();
200+
} else {
201+
log.debug("No matching page for: {}", entryFilename);
202+
}
203+
204+
if (includePage) {
205+
final ComicPage comicPage = new ComicPage(comicBook, entryFilename, entryPageNumber);
206+
207+
// adjust the page filenames
208+
if (!StringUtils.isBlank(pageRenamingRule)) {
209+
final String oldEntryFilename = comicPage.getFilename();
210+
entryFilename =
211+
this.comicPageAdaptor.createFilenameFromRule(
212+
FilenameUtils.getExtension(oldEntryFilename),
213+
pageRenamingRule,
214+
comicPage.getPageNumber(),
215+
length);
216+
log.debug("Renamed page: {} => {}", oldEntryFilename, entryFilename);
217+
comicPage.setFilename(entryFilename);
218+
}
219+
log.trace("Writing page: {}", entryFilename);
220+
destinationArchive.writeEntry(writeHandle, entryFilename, entryContent);
221+
final BufferedImage image = ImageIO.read(new ByteArrayInputStream(entryContent));
222+
comicPage.setWidth(image.getWidth());
223+
comicPage.setHeight(image.getHeight());
224+
comicPage.setHash(entryHash);
225+
if (Objects.nonNull(pageType)) {
226+
comicPage.setPageType(pageType);
227+
}
228+
comicBook.getPages().add(comicPage);
229+
}
230+
} else {
231+
if (!entryFilename.equalsIgnoreCase(COMIC_INFO_XML)) {
232+
log.trace("Writing non-page entry: {}", entryFilename);
233+
destinationArchive.writeEntry(writeHandle, entryFilename, entryContent);
234+
}
187235
}
188-
log.trace("Writing comic book page content: {}", pageFilename);
189-
destinationArchive.writeEntry(writeHandle, pageFilename, content);
190-
log.trace("Updating the page filename: {}", pageFilename);
191-
page.setFilename(pageFilename);
192236
}
193237
}
194238

195239
log.trace("Writing comic book metadata");
196240
destinationArchive.writeEntry(
197-
writeHandle, "ComicInfo.xml", this.comicMetadataWriter.createContent(comicBook));
241+
writeHandle, COMIC_INFO_XML, this.comicMetadataWriter.createContent(comicBook));
198242

199243
log.trace("Closing archives");
200244
sourceArchive.closeArchiveForRead(readHandle);
@@ -215,7 +259,7 @@ public void save(
215259
comicBook.getComicDetail().getFilename(),
216260
directory
217261
+ File.separator
218-
+ FileNameUtils.getBaseName(comicBook.getComicDetail().getFilename()),
262+
+ FilenameUtils.removeExtension(comicBook.getComicDetail().getFilename()),
219263
0,
220264
targetArchiveType.getExtension());
221265
log.trace("Updating filename: {}", newComicDetailFilename);
@@ -234,6 +278,28 @@ public void save(
234278
}
235279
}
236280

281+
private ComicPage doFindMatchingPage(
282+
final List<ComicPage> oldPages, final String entryFilename, final String entryHash) {
283+
return oldPages.stream()
284+
.filter(
285+
oldPage ->
286+
(oldPage.getFilename().equals(entryFilename))
287+
|| (StringUtils.isNotEmpty(oldPage.getHash())
288+
&& oldPage.getHash().equals(entryHash)))
289+
.findFirst()
290+
.orElse(null);
291+
}
292+
293+
private List<ComicPage> doRemoveOldPages(final ComicBook comicBook) {
294+
log.debug("Removing old pages from comic book");
295+
final List<ComicPage> result = new ArrayList<>();
296+
while (!comicBook.getPages().isEmpty()) {
297+
log.trace("Removing page: {}", comicBook.getPages().get(0).getFilename());
298+
result.add(comicBook.getPages().remove(0));
299+
}
300+
return result;
301+
}
302+
237303
/**
238304
* Writes the comic's metadata to a separate file. The file's name is based on that of the comic,
239305
* but with an extension of ".xml".

comixed-adaptors/src/main/java/org/comixedproject/adaptors/comicbooks/ComicPageAdaptor.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020

2121
import lombok.extern.log4j.Log4j2;
2222
import org.apache.commons.lang.StringUtils;
23-
import org.codehaus.plexus.util.FileUtils;
24-
import org.comixedproject.model.comicpages.ComicPage;
2523
import org.springframework.stereotype.Component;
2624

2725
/**
@@ -37,14 +35,14 @@ public class ComicPageAdaptor {
3735
/**
3836
* Generates a new filename for the given page with a specified length for the page number.
3937
*
40-
* @param page the page
38+
* @param extension the file extension
4139
* @param renamingRule the renaming rule
4240
* @param pageIndex the page index in the comic
4341
* @param length the length
4442
* @return the page name
4543
*/
4644
public String createFilenameFromRule(
47-
final ComicPage page, final String renamingRule, final int pageIndex, final int length) {
45+
final String extension, final String renamingRule, final int pageIndex, final int length) {
4846
log.debug("Scrubbing renaming rule: {}", renamingRule);
4947
final String rule = this.scrub(renamingRule, FORBIDDEN_RULE_CHARACTERS);
5048

@@ -55,7 +53,7 @@ public String createFilenameFromRule(
5553

5654
log.debug("Relative page name: {}", result);
5755

58-
return String.format("%s.%s", result, FileUtils.getExtension(page.getFilename()));
56+
return String.format("%s.%s", result, extension);
5957
}
6058

6159
private String scrub(final String text, final String forbidden) {

comixed-adaptors/src/test/java/org/comixedproject/adaptors/archive/Cb7ArchiveAdaptorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ void setUp() {
4545
}
4646

4747
@Test
48-
void GetEntries() throws ArchiveAdaptorException {
48+
void getEntries() throws ArchiveAdaptorException {
4949
final Cb7ArchiveReadHandle archiveHandle = adaptor.openArchiveForRead(TEST_ZIP_FILENAME);
5050
final List<ComicArchiveEntry> entries = adaptor.getEntries(archiveHandle);
5151
adaptor.closeArchiveForRead(archiveHandle);

0 commit comments

Comments
 (0)