From f670de09d9f5947f00a93b34b1dc4d8ca70bf88c Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Tue, 8 Sep 2020 17:58:46 +0400 Subject: [PATCH] * Images: added cleanup routine on startup (app will fix and delete all broken or temporary images files, see #6267); --- .../src/main/java/mage/client/MageFrame.java | 7 ++- .../plugins/card/utils/CardImageUtils.java | 63 ++++++++++++++++++- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index dfba5b8de5dc..c5de22b0bfac 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -55,6 +55,7 @@ import org.mage.card.arcane.ManaSymbols; import org.mage.plugins.card.images.DownloadPicturesService; import org.mage.plugins.card.info.CardInfoPaneImpl; +import org.mage.plugins.card.utils.CardImageUtils; import org.mage.plugins.card.utils.impl.ImageManagerImpl; import javax.imageio.ImageIO; @@ -235,11 +236,15 @@ public void windowClosing(WindowEvent e) { RepositoryUtil.bootstrapLocalDb(); // re-create database on empty (e.g. after new build cleaned db on startup) if (RepositoryUtil.CARD_DB_RECREATE_BY_CLIENT_SIDE && RepositoryUtil.isDatabaseEmpty()) { - LOGGER.info("DB: creating cards database"); + LOGGER.info("DB: creating cards database..."); CardScanner.scan(); LOGGER.info("Done."); } + // IMAGES CHECK + LOGGER.info("Images: search broken files..."); + CardImageUtils.checkAndFixImageFiles(); + if (RateCard.PRELOAD_CARD_RATINGS_ON_STARTUP) { RateCard.bootstrapCardsAndRatings(); } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java index 77bbf87f9bc7..6349fe917286 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java @@ -19,6 +19,13 @@ import java.net.InetSocketAddress; import java.net.Proxy; import java.net.URL; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Locale; import java.util.prefs.Preferences; @@ -26,7 +33,7 @@ public final class CardImageUtils { private static final HashMap pathCache = new HashMap<>(); - private static final Logger log = Logger.getLogger(CardImageUtils.class); + private static final Logger LOGGER = Logger.getLogger(CardImageUtils.class); /** * @param card @@ -54,7 +61,7 @@ public static String generateTokenImagePath(CardDownloadData card) { //log.warn("Token image file not found. Set: " + card.getSet() + " Token Set Code: " + card.getTokenSetCode() + " Name: " + card.getName() + " File path: " + getTokenImagePath(card)); } else { - log.warn("Trying to get token path for non token card. Set: " + card.getSet() + " Set Code: " + card.getTokenSetCode() + " Name: " + card.getName()); + LOGGER.warn("Trying to get token path for non token card. Set: " + card.getSet() + " Set Code: " + card.getTokenSetCode() + " Name: " + card.getName()); } return null; } @@ -296,4 +303,56 @@ public static Document downloadHtmlDocument(String urlString) throws NumberForma } return doc; } + + public static void checkAndFixImageFiles() { + // search broken files and delete it (zero size files) + // search temp files and delete it (.tmp files from zip library) + Path rootPath = new File(CardImageUtils.getImagesDir()).toPath(); + Collection brokenFilesList = new ArrayList<>(); + Collection tempFilesList = new ArrayList<>(); + try { + Files.walkFileTree(rootPath, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + // 1. broken files (need zero size files): delete with warning + if (attrs.size() == 0) { + brokenFilesList.add(file); + return FileVisitResult.CONTINUE; + } + + // 2. temp files delete without warning + if (file.toString().endsWith(".tmp")) { + tempFilesList.add(file); + } + + return FileVisitResult.CONTINUE; + } + }); + } catch (IOException e) { + LOGGER.error("Can't load files list from images folder: " + rootPath.toAbsolutePath().toString(), e); + } + + // temp files must be deleted without errors + for (Path tempFile : tempFilesList) { + try { + Files.delete(tempFile); + } catch (Throwable e) { + // ignore any error (e.g. it opened by xmage app) + } + } + + // broken files must be informed + if (!brokenFilesList.isEmpty()) { + LOGGER.warn("Images: found " + brokenFilesList.size() + " broken files. Trying to fix it..."); + for (Path brokenFile : brokenFilesList) { + try { + Files.delete(brokenFile); + } catch (Throwable e) { + // stop clean on any error + LOGGER.error("Images check: ERROR, can't delete broken file: " + brokenFile.toAbsolutePath().toString(), e); + break; + } + } + } + } }