package de.uni_goettingen.sub.commons.ocr.abbyy.server; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import de.uni_goettingen.sub.commons.ocr.abbyy.server.hotfolder.Hotfolder; import de.uni_goettingen.sub.commons.ocr.abbyy.server.hotfolder.HotfolderProvider; import de.uni_goettingen.sub.commons.ocr.api.OcrImage; import de.uni_goettingen.sub.commons.ocr.api.OcrOutput; import de.unigoettingen.sub.commons.ocr.util.Pause; public class HotfolderManager { private final static Logger logger = LoggerFactory.getLogger(HotfolderManager.class); private Hotfolder hotfolder; static Object monitor = new Object(); private HotfolderProvider hotfolderProvider = new HotfolderProvider(); private Pause pause = new Pause(); private XmlParser xmlParser = new XmlParser(); public HotfolderManager(String serverUrl, String user, String password) { hotfolder = hotfolderProvider.createHotfolder(serverUrl, user, password); } // for unit tests HotfolderManager(Hotfolder initHotfolder) { hotfolder = initHotfolder; } void setPause(Pause newPause) { pause = newPause; } void setXmlParser(XmlParser newParser) { xmlParser = newParser; } public void deleteOutputs(List<OcrOutput> outputs) throws IOException { for (OcrOutput out : outputs) { AbbyyOutput abbyyOut = (AbbyyOutput) out; URI remoteUri = abbyyOut.getRemoteUri(); hotfolder.deleteIfExists(remoteUri); } } public void deleteImages(List<OcrImage> images) throws IOException { for (OcrImage ocrImage : images) { AbbyyImage image = (AbbyyImage) ocrImage; URI remoteUri = image.getRemoteUri(); hotfolder.deleteIfExists(remoteUri); URI errorImageUri = image.getErrorUri(); hotfolder.deleteIfExists(errorImageUri); } } public void copyImagesToHotfolder(List<OcrImage> ocrImages) throws IOException { for (OcrImage ocrImage : ocrImages) { AbbyyImage image = (AbbyyImage) ocrImage; URI fromUri = image.getLocalUri(); URI toUri = image.getRemoteUri(); hotfolder.upload(fromUri, toUri); } } public void retrieveResults(List<OcrOutput> ocrOutputs) throws IOException { for (OcrOutput entry : ocrOutputs) { AbbyyOutput o = (AbbyyOutput) entry; URI remoteUri = o.getRemoteUri(); URI localUri = o.getLocalUri(); hotfolder.download(remoteUri, localUri); hotfolder.deleteIfExists(remoteUri); } } public void createAndSendTicket(AbbyyTicket abbyyTicket, String name) throws IOException, URISyntaxException { String ticketFileName = name + ".xml"; URI inputTicketUri = abbyyTicket.getRemoteInputUri(); OutputStream os = hotfolder.createTmpFile(ticketFileName); abbyyTicket.write(os); if (os != null) os.close(); //TODO: remove // URI ticketLogPath = new java.io.File("/home/dennis/temp/tickets/" + ticketFileName).toURI(); // hotfolder.copyTmpFile(ticketFileName, ticketLogPath); hotfolder.copyTmpFile(ticketFileName, inputTicketUri); hotfolder.deleteTmpFile(ticketFileName); } public void waitForResults(long timeout, long waitInterval, List<OcrOutput> outputs, URI errorResultXmlUri) throws TimeoutException, IOException { long start = System.currentTimeMillis(); List<URI> mustBeThereUris = extractFromOutputs(outputs); outerLoop: while (true) { checkIfError(start, timeout, errorResultXmlUri); for (URI expectedUri : mustBeThereUris) { if (!hotfolder.exists(expectedUri)) { logger.debug(expectedUri.toString() + " is not yet available"); waitALittle(waitInterval); continue outerLoop; } } logger.debug("Got all files."); break; } } private List<URI> extractFromOutputs(List<OcrOutput> outputs) { List<URI> mustBeThereUris = new ArrayList<URI>(); for (OcrOutput out : outputs) { final AbbyyOutput output = (AbbyyOutput) out; URI uri = output.getRemoteUri(); mustBeThereUris.add(uri); } return mustBeThereUris; } private void checkIfError(long start, long timeout, URI errorResultXmlUri) throws TimeoutException, IOException { if (System.currentTimeMillis() > start + timeout) { logger.error("Waited too long for results."); throw new TimeoutException("Waited too long for results."); } if (hotfolder.exists(errorResultXmlUri)) { logger.error("Server reported an OCR error in file: " + errorResultXmlUri); throw new IOException("Server reported an OCR error in file: " + errorResultXmlUri); } } private void waitALittle(long waitInterval) { logger.debug("Waiting for " + waitInterval + " milli seconds (" + waitInterval/1000/60 + " minutes)"); pause.forMilliseconds(waitInterval); } public boolean enoughSpaceAvailable(long maxSpace, URI inputFolder, URI outputFolder, URI errorFolder) throws IOException { long totalFileSize = hotfolder.getUsedSpace(inputFolder) + hotfolder.getUsedSpace(outputFolder) + hotfolder.getUsedSpace(errorFolder); logger.debug("TotalFileSize = " + totalFileSize); if (totalFileSize >= maxSpace) { logger.warn("Size of files is too high. Allowed space for all files is " + maxSpace + ". Size of files in hotfolder: " + totalFileSize + "."); return false; } else { return true; } } public void deleteTicket(AbbyyTicket abbyyTicket) throws IOException, URISyntaxException { hotfolder.deleteIfExists(abbyyTicket.getRemoteInputUri()); hotfolder.deleteIfExists(abbyyTicket.getRemoteErrorUri()); } public String readFromErrorFile(URI errorResultUri, String processName) { String errorDescription = ""; logger.debug("Trying to parse file " + errorResultUri + " (" + processName + ")"); try { if (hotfolder.exists(errorResultUri)) { InputStream is = new ByteArrayInputStream(hotfolder.getResponse(errorResultUri)); errorDescription = xmlParser.readErrorFromResultXml(is, processName); //hotfolder.deleteIfExists(errorResultUri); } } catch (IOException e) { logger.warn("Could not read the error from file " + errorResultUri); } return errorDescription; } }