/* * @copyright 2013 Philip Warner * @license GNU General Public License * * This file is part of Book Catalogue. * * Book Catalogue is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Book Catalogue is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Book Catalogue. If not, see <http://www.gnu.org/licenses/>. */ package com.eleybourn.bookcatalogue.backup; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import com.eleybourn.bookcatalogue.BookCatalogueApp; import com.eleybourn.bookcatalogue.CatalogueDBAdapter; import com.eleybourn.bookcatalogue.utils.StorageUtils; /** * Class to find covers for an importer when the import is reading from a local directory. * * @author pjw */ public class LocalCoverFinder implements Importer.CoverFinder { /** The root path to search for files */ private final String mSrc; private final String mDst; private final boolean mIsForeign; private final String mSharedStoragePath; private CatalogueDBAdapter mDbHelper; public LocalCoverFinder(String srcPath, String dstPath) { mSrc = srcPath; mDst = dstPath; mIsForeign = !mSrc.equals(mDst); mSharedStoragePath = StorageUtils.getSharedStorage().getAbsolutePath(); mDbHelper = new CatalogueDBAdapter(BookCatalogueApp.context); mDbHelper.open(); } public void copyOrRenameCoverFile(String srcUuid, long srcId, long dstId) throws IOException { if (srcUuid != null && !srcUuid.equals("")) { // Only copy UUID files if they are foreign...since they already exists, otherwise. if (mIsForeign) copyCoverImageIfMissing(srcUuid); } else { if (srcId != 0) { // This will be a rename or a copy if (mIsForeign) copyCoverImageIfMissing(srcId, dstId); else renameCoverImageIfMissing(srcId, dstId); } } } private File findExternalCover(String name) { // Find the original, if present. File orig = new File(mSrc + "/" + name + ".jpg"); if (!orig.exists()) { orig = new File(mSrc + "/" + name + ".png"); } // Nothing to copy? if (!orig.exists()) return null; else return orig; } /** * Find the current cover file (or new file) based on the passed source and UUID. * * @param orig Original file to be copied/renamed if no existing file. * @param newUuid UUID of file * * @return Existing file (if length > 0), or new file object */ private File getNewCoverFile(File orig, String newUuid) { File newFile; // Check for ANY current image; delete empty ones and retry newFile = CatalogueDBAdapter.fetchThumbnailByUuid(newUuid); while (newFile.exists()) { if (newFile.length() > 0) return newFile; else newFile.delete(); newFile = CatalogueDBAdapter.fetchThumbnailByUuid(newUuid); } // Get the new path based on the input file type. if (orig.getAbsolutePath().toLowerCase().endsWith(".png")) newFile = new File(mSharedStoragePath + "/" + newUuid + ".png"); else newFile = new File(mSharedStoragePath + "/" + newUuid + ".jpg"); return newFile; } /** * Copy a specified source file into the default cover location for a new file. * DO NO OVERWRITE EXISTING FILES. * * @param orig * @param newUuid * @throws IOException */ private void copyFileToCoverImageIfMissing(File orig, String newUuid) throws IOException { // Nothing to copy? if (orig == null || !orig.exists() || orig.length() == 0) return; // Check for ANY current image File newFile = getNewCoverFile(orig, newUuid); if (newFile.exists()) return; // Copy it. InputStream in = null; OutputStream out = null; try { // Open in & out in = new FileInputStream(orig); out = new FileOutputStream(newFile); // Get a buffer byte[] buffer = new byte[8192]; int nRead = 0; // Copy while( (nRead = in.read(buffer)) > 0){ out.write(buffer, 0, nRead); } // Close both. We close them here so exceptions are signalled in.close(); in = null; out.close(); out = null; } finally { // If not already closed, close. try { if (in != null) in.close(); } catch (Exception e) {}; try { if (out != null) out.close(); } catch (Exception e) {}; } } /** * Rename/move a specified source file into the default cover location for a new file. * DO NO OVERWRITE EXISTING FILES. * * @param orig * @param newUuid * @throws IOException */ private void renameFileToCoverImageIfMissing(File orig, String newUuid) throws IOException { // Nothing to copy? if (orig == null || !orig.exists() || orig.length() == 0) return; // Check for ANY current image File newFile = getNewCoverFile(orig, newUuid); if (newFile.exists()) return; orig.renameTo(newFile); } /** * Copy the ID-based cover from its current location to the correct location in shared * storage, if it exists. * * @param externalId The file ID in external media * @param newId The new file ID * @throws IOException */ private void renameCoverImageIfMissing(long externalId, long newId) throws IOException { File orig = findExternalCover(Long.toString(externalId)); // Nothing to copy? if (orig == null || !orig.exists() || orig.length() == 0) return; String newUuid = mDbHelper.getBookUuid(newId); renameFileToCoverImageIfMissing(orig, newUuid); } /** * Copy the ID-based cover from its current location to the correct location in shared * storage, if it exists. * * @param externalId The file ID in external media * @param newId The new file ID * @throws IOException */ private void copyCoverImageIfMissing(long externalId, long newId) throws IOException { File orig = findExternalCover(Long.toString(externalId)); // Nothing to copy? if (orig == null || !orig.exists() || orig.length() == 0) return; String newUuid = mDbHelper.getBookUuid(newId); copyFileToCoverImageIfMissing(orig, newUuid); } /** * Copy the UUID-based cover from its current location to the correct location in shared * storage, if it exists. * * @param uuid * @throws IOException */ private void copyCoverImageIfMissing(String uuid) throws IOException { File orig = findExternalCover(uuid); // Nothing to copy? if (orig == null || !orig.exists()) return; copyFileToCoverImageIfMissing(orig, uuid); } }