From c29bac08d869c7c349428afb42502e1dbc0300a1 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 27 Nov 2017 08:09:52 +0400 Subject: [PATCH] Refactor and fixed and images downloading and paths loading: - Added new images and symbols downloading; - Fixed user defined images path (now work for all images: cards, symbols, temp downloading); - Fixed not working cancel button at download window (it close window, but tasks is working, download and didn't save); - Fixed temp files trash all around images folder (on cancel button); - Fixed not saving new downloaded cards on cancel button (zip file didn't close on cancel); --- .../src/main/java/mage/client/MageFrame.java | 2 + .../java/mage/client/constants/Constants.java | 3 + .../collection/viewer/MageBook.java | 2 +- .../mage/client/plugins/impl/Plugins.java | 9 +- .../org/mage/card/arcane/ManaSymbols.java | 30 +-- .../org/mage/plugins/card/CardPluginImpl.java | 18 +- .../dl/sources/DirectLinksForDownload.java | 33 +--- .../plugins/card/dl/sources/GathererSets.java | 36 ++-- .../card/dl/sources/GathererSymbols.java | 33 +--- .../plugins/card/images/DownloadPictures.java | 187 ++++++++++++++---- .../mage/plugins/card/images/ImageCache.java | 4 +- .../plugins/card/utils/CardImageUtils.java | 156 +++++++++------ .../mage/interfaces/plugin/CardPlugin.java | 5 +- 13 files changed, 303 insertions(+), 215 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 425172f7a6..dfa734f1af 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -92,6 +92,8 @@ import org.mage.plugins.card.images.DownloadPictures; import org.mage.plugins.card.info.CardInfoPaneImpl; import org.mage.plugins.card.utils.impl.ImageManagerImpl; +import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; + /** * @author BetaSteward_at_googlemail.com */ diff --git a/Mage.Client/src/main/java/mage/client/constants/Constants.java b/Mage.Client/src/main/java/mage/client/constants/Constants.java index d9261f3198..f5f2e21e6a 100644 --- a/Mage.Client/src/main/java/mage/client/constants/Constants.java +++ b/Mage.Client/src/main/java/mage/client/constants/Constants.java @@ -77,6 +77,9 @@ public final class Constants { public static final Rectangle CARD_SIZE_FULL = new Rectangle(101, 149); public static final Rectangle THUMBNAIL_SIZE_FULL = new Rectangle(102, 146); + // resources - default images + public static final String RESOURCE_PATH_DEFAUL_IMAGES = File.separator + "default"; + // resources - symbols public static final String RESOURCE_PATH_SYMBOLS = File.separator + "symbols"; public static final String RESOURCE_SYMBOL_FOLDER_SMALL = "small"; diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java b/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java index 6c5600abf3..2dd577bd08 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/collection/viewer/MageBook.java @@ -204,7 +204,7 @@ public class MageBook extends JComponent { if (setImage != null) { tab.setOverlayImage(setImage); } else { - System.out.println("Couldn't find symbol image: " + "/plugins/images/sets/" + set + "-C.jpg"); + System.out.println("Couldn't find symbol image: " + set + "-C.jpg"); } tab.setSet(set); tab.setBounds(0, y, 39, 120); diff --git a/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java index 6f21093520..3696f8e9b2 100644 --- a/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java +++ b/Mage.Client/src/main/java/mage/client/plugins/impl/Plugins.java @@ -29,13 +29,14 @@ import mage.view.PermanentView; import net.xeoh.plugins.base.PluginManager; import net.xeoh.plugins.base.impl.PluginManagerFactory; import org.apache.log4j.Logger; -import org.mage.card.arcane.ManaSymbols; import org.mage.plugins.card.CardPluginImpl; import org.mage.plugins.theme.ThemePluginImpl; +import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; + public enum Plugins implements MagePlugins { instance; - public static final String PLUGINS_DIRECTORY = File.separator + "plugins"; + public static final String PLUGINS_DIRECTORY = "plugins"; private static final Logger LOGGER = Logger.getLogger(Plugins.class); private static PluginManager pm; @@ -49,6 +50,7 @@ public enum Plugins implements MagePlugins { @Override public void loadPlugins() { + LOGGER.info("Loading plugins..."); pm = PluginManagerFactory.createPluginManager(); pm.addPluginsFrom(new File(PLUGINS_DIRECTORY + File.separator).toURI()); @@ -132,9 +134,8 @@ public enum Plugins implements MagePlugins { @Override public void downloadSymbols() { - String path = ManaSymbols.getImagesDir() + File.separator; if (this.cardPlugin != null) { - this.cardPlugin.downloadSymbols(path); + this.cardPlugin.downloadSymbols(getImagesDir()); } } diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java index dde7cad79d..9d2587321c 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java @@ -22,7 +22,6 @@ import javax.imageio.ImageIO; import javax.swing.*; import mage.cards.repository.ExpansionRepository; -import mage.client.dialog.PreferencesDialog; import mage.client.util.GUISizeHelper; import mage.client.util.ImageHelper; import mage.client.util.gui.BufferedImageBuilder; @@ -39,6 +38,8 @@ import mage.client.constants.Constants; import mage.client.constants.Constants.ResourceSymbolSize; import mage.client.constants.Constants.ResourceSetSize; +import org.mage.plugins.card.utils.CardImageUtils; + public final class ManaSymbols { private static final Logger LOGGER = Logger.getLogger(ManaSymbols.class); @@ -411,33 +412,10 @@ public final class ManaSymbols { } } - public static String getImagesDir(){ - // return real images dir (path without separator) - - String path = null; - - // user path - if (PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true").equals("true")){ - path = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); - } - - // default path - if (path == null) { - path = Constants.IO.DEFAULT_IMAGES_DIR; - } - - while(path.endsWith(File.separator)) - { - path = path.substring(0, path.length() - 1); - } - - return path; - } - private static String getResourceSymbolsPath(ResourceSymbolSize needSize){ // return real path to symbols (default or user defined) - String path = getImagesDir() + Constants.RESOURCE_PATH_SYMBOLS + File.separator; + String path = CardImageUtils.getImagesDir() + Constants.RESOURCE_PATH_SYMBOLS + File.separator; // folder by sizes switch (needSize) { @@ -473,7 +451,7 @@ public final class ManaSymbols { private static String getResourceSetsPath(ResourceSetSize needSize){ // return real path to sets icons (default or user defined) - String path = getImagesDir() + Constants.RESOURCE_PATH_SYMBOLS + File.separator; + String path = CardImageUtils.getImagesDir() + Constants.RESOURCE_PATH_SYMBOLS + File.separator; // folder by sizes switch (needSize) { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java index 933fad9491..5825c34def 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/CardPluginImpl.java @@ -6,7 +6,6 @@ import mage.client.dialog.PreferencesDialog; import mage.client.util.GUISizeHelper; import mage.constants.Rarity; import mage.interfaces.plugin.CardPlugin; -import mage.utils.CardUtil; import mage.view.CardView; import mage.view.CounterView; import mage.view.PermanentView; @@ -19,7 +18,6 @@ import org.mage.card.arcane.*; import org.mage.plugins.card.dl.DownloadGui; import org.mage.plugins.card.dl.DownloadJob; import org.mage.plugins.card.dl.Downloader; -import org.mage.plugins.card.dl.sources.CardFrames; import org.mage.plugins.card.dl.sources.DirectLinksForDownload; import org.mage.plugins.card.dl.sources.GathererSets; import org.mage.plugins.card.dl.sources.GathererSymbols; @@ -525,30 +523,30 @@ public class CardPluginImpl implements CardPlugin { /** * Download various symbols (mana, tap, set). * - * @param imagesPath Path to check in and store symbols to. Can be null, in - * such case default path should be used. + * @param imagesDir Path to check in and store symbols to. Can't be null. */ @Override - public void downloadSymbols(String imagesPath) { + public void downloadSymbols(String imagesDir) { final DownloadGui g = new DownloadGui(new Downloader()); - Iterable it = new GathererSymbols(imagesPath); - + Iterable it = new GathererSymbols(); for (DownloadJob job : it) { g.getDownloader().add(job); } - it = new GathererSets(imagesPath); + it = new GathererSets(); for (DownloadJob job : it) { g.getDownloader().add(job); } - it = new CardFrames(imagesPath); + /* + it = new CardFrames(imagesDir); // TODO: delete frames download (not need now) for (DownloadJob job : it) { g.getDownloader().add(job); } + */ - it = new DirectLinksForDownload(imagesPath); + it = new DirectLinksForDownload(); for (DownloadJob job : it) { g.getDownloader().add(job); } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/DirectLinksForDownload.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/DirectLinksForDownload.java index 374257a693..7896fa26ef 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/DirectLinksForDownload.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/DirectLinksForDownload.java @@ -11,9 +11,12 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; + +import mage.client.constants.Constants; import org.mage.plugins.card.dl.DownloadJob; import static org.mage.plugins.card.dl.DownloadJob.fromURL; import static org.mage.plugins.card.dl.DownloadJob.toFile; +import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; /** * Used when we need to point to direct links to download resources from. @@ -33,15 +36,13 @@ public class DirectLinksForDownload implements Iterable { directLinks.put(cardbackFilename, backsideUrl); } - private static final String DEFAULT_IMAGES_PATH = File.separator + "default"; - private static final File DEFAULT_OUT_DIR = new File("plugins" + File.separator + "images" + DEFAULT_IMAGES_PATH); - public static File outDir = DEFAULT_OUT_DIR; + public static File outDir; - public DirectLinksForDownload(String path) { - if (path == null) { - useDefaultDir(); - } else { - changeOutDir(path); + public DirectLinksForDownload() { + outDir = new File(getImagesDir() + Constants.RESOURCE_PATH_DEFAUL_IMAGES); + + if (!outDir.exists()){ + outDir.mkdirs(); } } @@ -55,20 +56,4 @@ public class DirectLinksForDownload implements Iterable { } return jobs.iterator(); } - - private void changeOutDir(String path) { - File file = new File(path + DEFAULT_IMAGES_PATH); - if (file.exists()) { - outDir = file; - } else { - file.mkdirs(); - if (file.exists()) { - outDir = file; - } - } - } - - private void useDefaultDir() { - outDir = DEFAULT_OUT_DIR; - } } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSets.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSets.java index 496768a6cf..8406c4e541 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSets.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSets.java @@ -9,11 +9,14 @@ import java.util.Iterator; import mage.cards.ExpansionSet; import mage.cards.Sets; +import mage.client.constants.Constants; import mage.constants.Rarity; import org.mage.plugins.card.dl.DownloadJob; import static org.mage.plugins.card.dl.DownloadJob.fromURL; import static org.mage.plugins.card.dl.DownloadJob.toFile; +import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; + import org.apache.log4j.Logger; public class GathererSets implements Iterable { @@ -36,13 +39,11 @@ public class GathererSets implements Iterable { } } + private static File outDir; + private static final int DAYS_BEFORE_RELEASE_TO_DOWNLOAD = +14; // Try to load the symbolsBasic eralies 14 days before release date private static final Logger logger = Logger.getLogger(GathererSets.class); - private static final String SETS_PATH = File.separator + "sets"; - private static final File DEFAULT_OUT_DIR = new File("plugins" + File.separator + "images" + SETS_PATH); - private static File outDir = DEFAULT_OUT_DIR; - private static final String[] symbolsBasic = {"10E", "9ED", "8ED", "7ED", "6ED", "5ED", "4ED", "3ED", "2ED", "LEB", "LEA", "HOP", "ARN", "ATQ", "LEG", "DRK", "FEM", "HML", @@ -150,11 +151,12 @@ public class GathererSets implements Iterable { codeReplacements.put("CHR", "CH"); } - public GathererSets(String path) { - if (path == null) { - useDefaultDir(); - } else { - changeOutDir(path); + public GathererSets() { + + outDir = new File(getImagesDir() + Constants.RESOURCE_PATH_SYMBOLS); + + if (!outDir.exists()){ + outDir.mkdirs(); } } @@ -311,20 +313,4 @@ public class GathererSets implements Iterable { String url = "http://gatherer.wizards.com/Handlers/Image.ashx?type=symbol&set=" + set + "&size=small&rarity=" + urlRarity; return new DownloadJob(set + '-' + rarity, fromURL(url), toFile(dst)); } - - private void changeOutDir(String path) { - File file = new File(path + SETS_PATH); - if (file.exists()) { - outDir = file; - } else { - file.mkdirs(); - if (file.exists()) { - outDir = file; - } - } - } - - private void useDefaultDir() { - outDir = DEFAULT_OUT_DIR; - } } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSymbols.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSymbols.java index 995b182e5b..6a6061e06c 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSymbols.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/GathererSymbols.java @@ -9,9 +9,12 @@ import com.google.common.collect.AbstractIterator; import java.io.File; import static java.lang.String.format; import java.util.Iterator; + +import mage.client.constants.Constants; import org.mage.plugins.card.dl.DownloadJob; import static org.mage.plugins.card.dl.DownloadJob.fromURL; import static org.mage.plugins.card.dl.DownloadJob.toFile; +import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; /** * The class GathererSymbols. @@ -23,9 +26,7 @@ public class GathererSymbols implements Iterable { //TODO chaos and planeswalker symbol //chaos: http://gatherer.wizards.com/Images/Symbols/chaos.gif - private static final String SYMBOLS_PATH = File.separator + "symbols"; - private static final File DEFAULT_OUT_DIR = new File("plugins" + File.separator + "images" + SYMBOLS_PATH); - private static File outDir = DEFAULT_OUT_DIR; + private static File outDir; private static final String urlFmt = "http://gatherer.wizards.com/handlers/image.ashx?size=%1$s&name=%2$s&type=symbol"; @@ -38,11 +39,11 @@ public class GathererSymbols implements Iterable { "X", "S", "T", "Q", "C", "E"}; private static final int minNumeric = 0, maxNumeric = 16; - public GathererSymbols(String path) { - if (path == null) { - useDefaultDir(); - } else { - changeOutDir(path); + public GathererSymbols() { + outDir = new File(getImagesDir() + Constants.RESOURCE_PATH_SYMBOLS); + + if (!outDir.exists()){ + outDir.mkdirs(); } } @@ -115,20 +116,4 @@ public class GathererSymbols implements Iterable { } }; } - - private void changeOutDir(String path) { - File file = new File(path + SYMBOLS_PATH); - if (file.exists()) { - outDir = file; - } else { - file.mkdirs(); - if (file.exists()) { - outDir = file; - } - } - } - - private void useDefaultDir() { - outDir = DEFAULT_OUT_DIR; - } } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index 5a28e783bb..578cb6d5c8 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -459,7 +459,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab */ List cardsToDownload = Collections.synchronizedList(new ArrayList<>()); allCardsUrls.parallelStream().forEach(card -> { - TFile file = new TFile(CardImageUtils.generateImagePath(card)); + File file = new TFile(CardImageUtils.buildImagePathToCard(card)); logger.debug(card.getName() + " (is_token=" + card.isToken() + "). Image is here:" + file.getAbsolutePath() + " (exists=" + file.exists() + ')'); if (!file.exists()) { logger.debug("Missing: " + file.getAbsolutePath()); @@ -675,38 +675,78 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab @Override public void run() { - StringBuilder filePath = new StringBuilder(); - File temporaryFile = null; - TFile outputFile = null; + if (cancel) { + synchronized (sync) { + update(cardIndex + 1, count); + } + return; + } + + TFile fileTempImage; + TFile destFile; try { - filePath.append(Constants.IO.DEFAULT_IMAGES_DIR); - if (!useSpecifiedPaths && card != null) { - filePath.append(card.hashCode()).append('.').append(card.getName().replace(":", "").replace("//", "-")).append(".jpg"); - temporaryFile = new File(filePath.toString()); - } - String imagePath; - if (useSpecifiedPaths) { - if (card != null && card.isToken()) { - imagePath = CardImageUtils.getTokenBasePath() + actualFilename; - } else if (card != null) { - imagePath = CardImageUtils.getImageBasePath() + actualFilename; - } else { - imagePath = Constants.IO.DEFAULT_IMAGES_DIR; - } - String tmpFile = filePath + "temporary" + actualFilename; - temporaryFile = new File(tmpFile); - if (!temporaryFile.exists()) { - temporaryFile.getParentFile().mkdirs(); + if (card == null){ + synchronized (sync) { + update(cardIndex + 1, count); } - } else { - imagePath = CardImageUtils.generateImagePath(card); + return; } - outputFile = new TFile(imagePath); - if (!outputFile.exists()) { - outputFile.getParentFile().mkdirs(); + // gen temp file (download to images folder) + String tempPath = CardImageUtils.getImagesDir() + File.separator + "downloading" + File.separator; + if(useSpecifiedPaths){ + fileTempImage = new TFile(tempPath + actualFilename + "-" + card.hashCode() + ".jpg"); + }else{ + fileTempImage = new TFile(tempPath + CardImageUtils.prepareCardNameForFile(card.getName()) + "-" + card.hashCode() + ".jpg"); } + if(!fileTempImage.getParentFile().exists()){ + fileTempImage.getParentFile().mkdirs(); + } + + // gen dest file name + if(useSpecifiedPaths) + { + if(card.isToken()){ + destFile = new TFile(CardImageUtils.buildImagePathToSet(card) + actualFilename + ".jpg"); + }else{ + destFile = new TFile(CardImageUtils.buildImagePathToTokens() + actualFilename + ".jpg"); + } + }else{ + destFile = new TFile(CardImageUtils.buildImagePathToCard(card)); + } + + // FILE already exists (in zip or in dir) + if (destFile.exists()){ + synchronized (sync) { + update(cardIndex + 1, count); + } + return; + } + + // zip can't be read + TFile testArchive = destFile.getTopLevelArchive(); + if (testArchive != null && testArchive.exists()) { + try { + testArchive.list(); + } catch (Exception e) { + logger.error("Error reading archive, may be it was corrapted. Try to delete it: " + testArchive.toString()); + + synchronized (sync) { + update(cardIndex + 1, count); + } + return; + } + } + + /* + if(!destFile.getParentFile().exists()){ + destFile.getParentFile().mkdirs(); + } + */ + + /* + // WTF start?! TODO: wtf File existingFile = new File(imagePath.replaceFirst("\\w{3}.zip", "")); if (existingFile.exists()) { try { @@ -724,7 +764,86 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } return; } + // WTF end?! + */ + + // START to download + cardImageSource.doPause(url.getPath()); + URLConnection httpConn = url.openConnection(p); + httpConn.connect(); + int responseCode = ((HttpURLConnection) httpConn).getResponseCode(); + + if (responseCode == 200){ + // download OK + // save data to temp + BufferedOutputStream out; + try (BufferedInputStream in = new BufferedInputStream(httpConn.getInputStream())) { + out = new BufferedOutputStream(new TFileOutputStream(fileTempImage)); + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) != -1) { + // user cancelled + if (cancel) { + in.close(); + out.flush(); + out.close(); + + // stop download, save current state and exit + TFile archive = destFile.getTopLevelArchive(); + ///* not need to unmout/close - it's auto action + if (archive != null && archive.exists()){ + logger.info("User canceled download. Closing archive file: " + destFile.toString()); + try { + TVFS.umount(archive); + }catch (Exception e) { + logger.error("Can't close archive file: " + e.getMessage(), e); + } + + }//*/ + try { + TFile.rm(fileTempImage); + }catch (Exception e) { + logger.error("Can't delete temp file: " + e.getMessage(), e); + } + return; + } + out.write(buf, 0, len); + } + } + // TODO: remove to finnaly section? + out.flush(); + out.close(); + + // TODO: add two faces card correction? (WTF) + + // SAVE final data + if (fileTempImage.exists()) { + if (!destFile.getParentFile().exists()){ + destFile.getParentFile().mkdirs(); + } + new TFile(fileTempImage).cp_rp(destFile); + try { + TFile.rm(fileTempImage); + }catch (Exception e) { + logger.error("Can't delete temp file: " + e.getMessage(), e); + } + + } + }else{ + // download ERROR + logger.warn("Image download for " + card.getName() + + (!card.getDownloadName().equals(card.getName()) ? " downloadname: " + card.getDownloadName() : "") + + '(' + card.getSet() + ") failed - responseCode: " + responseCode + " url: " + url.toString() + ); + + if (logger.isDebugEnabled()) { + // Shows the returned html from the request to the web server + logger.debug("Returned HTML ERROR:\n" + convertStreamToString(((HttpURLConnection) httpConn).getErrorStream())); + } + } + + /* // Logger.getLogger(this.getClass()).info(url.toString()); boolean useTempFile = false; int responseCode = 0; @@ -733,7 +852,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab if (temporaryFile != null && temporaryFile.length() > 100) { useTempFile = true; } else { - cardImageSource.doPause(url.getPath()); httpConn = url.openConnection(p); httpConn.connect(); @@ -765,6 +883,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab out.close(); } + // TODO: WTF?! start if (card != null && card.isTwoFacedCard()) { BufferedImage image = ImageIO.read(temporaryFile); if (image.getHeight() == 470) { @@ -787,6 +906,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab outputFile.getParentFile().mkdirs(); new TFile(temporaryFile).cp_rp(outputFile); } + // WTF?! end } else { if (card != null && !useSpecifiedPaths) { logger.warn("Image download for " + card.getName() @@ -797,16 +917,15 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab logger.debug("Returned HTML ERROR:\n" + convertStreamToString(((HttpURLConnection) httpConn).getErrorStream())); } } + */ } catch (AccessDeniedException e) { - logger.error("The file " + (outputFile != null ? outputFile.toString() : "to add the image of " + card.getName() + '(' + card.getSet() + ')') + " can't be accessed. Try rebooting your system to remove the file lock."); + logger.error("Can't access to files: " + card.getName() + "(" + card.getSet() + "). Try rebooting your system to remove the file lock."); } catch (Exception e) { - logger.error(e, e); + logger.error(e.getMessage(), e); } finally { - if (temporaryFile != null) { - temporaryFile.delete(); - } } + synchronized (sync) { update(cardIndex + 1, count); } @@ -843,7 +962,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } else { List remainingCards = Collections.synchronizedList(new ArrayList<>()); DownloadPictures.this.allCardsMissingImage.parallelStream().forEach(cardDownloadData -> { - TFile file = new TFile(CardImageUtils.generateImagePath(cardDownloadData)); + TFile file = new TFile(CardImageUtils.buildImagePathToCard(cardDownloadData)); if (!file.exists()) { remainingCards.add(cardDownloadData); } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java index 3b1c9eda8d..337b3daeb5 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java @@ -94,7 +94,7 @@ public final class ImageCache { path = DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename; // TODO: replace empty token by other default card, not cardback } } else { - path = CardImageUtils.generateImagePath(info); + path = CardImageUtils.buildImagePathToCard(info); } if (path == null) { @@ -263,7 +263,7 @@ public final class ImageCache { path = DirectLinksForDownload.outDir + File.separator + DirectLinksForDownload.cardbackFilename; // TODO: replace empty token by other default card, not cardback } } else { - path = CardImageUtils.generateImagePath(info); + path = CardImageUtils.buildImagePathToCard(info); } if (thumbnail && path.endsWith(".jpg")) { 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 ac3c11a46d..7a05d50d4c 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 @@ -1,5 +1,6 @@ package org.mage.plugins.card.utils; +import java.io.File; import java.net.InetSocketAddress; import java.net.Proxy; import java.util.HashMap; @@ -63,7 +64,7 @@ public final class CardImageUtils { } private static String getTokenImagePath(CardDownloadData card) { - String filename = generateImagePath(card); + String filename = buildImagePathToCard(card); TFile file = new TFile(filename); if (!file.exists()) { @@ -74,12 +75,12 @@ public final class CardImageUtils { if (!file.exists()) { CardDownloadData updated = new CardDownloadData(card); updated.setName(card.getName() + " 1"); - filename = generateImagePath(updated); + filename = buildImagePathToCard(updated); file = new TFile(filename); if (!file.exists()) { updated = new CardDownloadData(card); updated.setName(card.getName() + " 2"); - filename = generateImagePath(updated); + filename = buildImagePathToCard(updated); } } @@ -121,87 +122,118 @@ public final class CardImageUtils { return set; } - private static String getImageDir(CardDownloadData card, String imagesPath) { + public static String prepareCardNameForFile(String cardName){ + return cardName.replace(":", "").replace("\"", "").replace("//", "-"); + } + + public static String getImagesDir(){ + // return real images dir (path without separator) + + String path = null; + + // user path + if (!PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true").equals("true")){ + path = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); + } + + // default path + if (path == null) { + path = Constants.IO.DEFAULT_IMAGES_DIR; + } + + while(path.endsWith(File.separator)) + { + path = path.substring(0, path.length() - 1); + } + + return path; + } + + public static String buildImagePathToTokens() { + String imagesPath = getImagesDir() + File.separator; + + + if (PreferencesDialog.isSaveImagesToZip()) { + return imagesPath + "TOK.zip" + TFile.separator; + } else { + return imagesPath + "TOK" + TFile.separator; + } + } + + private static String buildImagePathToTokenDescriptor(CardDownloadData card) { + return buildImagePathToTokens() + card.getTokenDescriptor() + ".full.jpg"; + } + + public static String buildImagePathToSet(CardDownloadData card) { + if (card.getSet() == null) { - return ""; + throw new IllegalArgumentException("Card " + card.getName() + " have empty set."); } - String set = updateSet(card.getSet(), false).toUpperCase(); - String imagesDir = (imagesPath != null ? imagesPath : Constants.IO.DEFAULT_IMAGES_DIR); + + String set = updateSet(card.getSet(), false).toUpperCase(); // TODO: research auto-replace... old code? + if (card.isToken()) { - return buildTokenPath(imagesDir, set); + return buildImagePathToSetAsToken(set); } else { - return buildPath(imagesDir, set); + return buildImagePathToSetAsCard(set); } } - public static String getImageBasePath() { - String useDefault = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true"); - String imagesPath = Objects.equals(useDefault, "true") ? Constants.IO.DEFAULT_IMAGES_DIR : PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); + private static String buildImagePathToSetAsCard(String set) { + String imagesPath = getImagesDir() + File.separator; - if (imagesPath != null && !imagesPath.endsWith(TFile.separator)) { - imagesPath += TFile.separator; - } - return imagesPath; - } - - public static String getTokenBasePath() { - String imagesPath = getImageBasePath(); - - String finalPath = ""; if (PreferencesDialog.isSaveImagesToZip()) { - finalPath = imagesPath + "TOK" + ".zip" + TFile.separator; + return imagesPath + set + ".zip" + File.separator; } else { - finalPath = imagesPath + "TOK" + TFile.separator; - } - return finalPath; - } - - private static String getTokenDescriptorImagePath(CardDownloadData card) { - return getTokenBasePath() + card.getTokenDescriptor() + ".full.jpg"; - } - - private static String buildTokenPath(String imagesDir, String set) { - if (PreferencesDialog.isSaveImagesToZip()) { - return imagesDir + TFile.separator + "TOK" + ".zip" + TFile.separator + set; - } else { - return imagesDir + TFile.separator + "TOK" + TFile.separator + set; + return imagesPath + set + File.separator; } } - private static String buildPath(String imagesDir, String set) { - if (PreferencesDialog.isSaveImagesToZip()) { - return imagesDir + TFile.separator + set + ".zip" + TFile.separator + set; - } else { - return imagesDir + TFile.separator + set; - } + private static String buildImagePathToSetAsToken(String set) { + return buildImagePathToTokens() + set + File.separator; } - public static String generateImagePath(CardDownloadData card) { - String useDefault = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true"); - String imagesPath = Objects.equals(useDefault, "true") ? null : PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); + public static String buildImagePathToCard(CardDownloadData card) { - String imageDir = getImageDir(card, imagesPath); - String imageName; + String setPath = buildImagePathToSet(card); - String type = card.getType() != 0 ? ' ' + Integer.toString(card.getType()) : ""; - String name = card.getFileName().isEmpty() ? card.getName().replace(":", "").replace("\"", "").replace("//", "-") : card.getFileName(); - - if (card.getUsesVariousArt()) { - imageName = name + '.' + card.getCollectorId() + ".full.jpg"; - } else { - imageName = name + type + ".full.jpg"; + String prefixType = ""; + if(card.getType() != 0){ + prefixType = " " + Integer.toString(card.getType()); } - if (new TFile(imageDir).exists() && !new TFile(imageDir + TFile.separator + imageName).exists()) { - for (String fileName : new TFile(imageDir).list()) { - if (fileName.toLowerCase().equals(imageName.toLowerCase())) { - imageName = fileName; - break; + String cardName = card.getFileName(); + if (cardName.isEmpty()){ + cardName = prepareCardNameForFile(card.getName()); + } + + String finalFileName = ""; + if (card.getUsesVariousArt()){ + finalFileName = cardName + '.' + card.getCollectorId() + ".full.jpg"; + }else{ + finalFileName = cardName + prefixType + ".full.jpg"; + } + + // if image file exists, correct name (for case sensitive systems) + // use TFile for zips + TFile dirFile = new TFile(setPath); + TFile imageFile = new TFile(setPath + finalFileName); + // warning, zip files can be broken + try{ + if (dirFile.exists() && !imageFile.exists()) { + // search like names + for (String fileName: dirFile.list()) { + if (fileName.toLowerCase().equals(finalFileName.toLowerCase())) { + finalFileName = fileName; + break; + } } } + }catch (Exception ex) { + log.error("Can't read card name from file, may be it broken: " + setPath); } - return imageDir + TFile.separator + imageName; + return setPath + finalFileName; } public static String generateFaceImagePath(String cardname, String set) { @@ -216,7 +248,7 @@ public final class CardImageUtils { // String useDefault = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_USE_DEFAULT, "true"); // String imagesPath = Objects.equals(useDefault, "true") ? null : PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PATH, null); - String straightImageFile = getTokenDescriptorImagePath(card); + String straightImageFile = buildImagePathToTokenDescriptor(card); TFile file = new TFile(straightImageFile); if (file.exists()) { return straightImageFile; diff --git a/Mage.Common/src/main/java/mage/interfaces/plugin/CardPlugin.java b/Mage.Common/src/main/java/mage/interfaces/plugin/CardPlugin.java index b1c43b508a..ac3c739f07 100644 --- a/Mage.Common/src/main/java/mage/interfaces/plugin/CardPlugin.java +++ b/Mage.Common/src/main/java/mage/interfaces/plugin/CardPlugin.java @@ -32,10 +32,9 @@ public interface CardPlugin extends Plugin { /** * Download various symbols (mana, tap, set). * - * @param imagesPath Path to check in and store symbols to. Can be null, in - * such case default path should be used. + * @param imagesDir Path to check in and store symbols to. Can't be null. */ - void downloadSymbols(String imagesPath); + void downloadSymbols(String imagesDir); void onAddCard(MagePermanent card, int count);