diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index d474fbd100..425172f7a6 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -44,8 +44,6 @@ import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import mage.cards.action.ActionCallback; import mage.cards.decks.Deck; -import mage.cards.repository.CardCriteria; -import mage.cards.repository.CardInfo; import mage.cards.repository.CardRepository; import mage.client.cards.BigCard; import mage.client.chat.ChatPanelBasic; @@ -134,8 +132,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { private final BalloonTip balloonTip; - private java.util.List missingCards; - /** * @return the session */ @@ -513,18 +509,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { } private void checkForNewImages() { - long beforeCall = System.currentTimeMillis(); - missingCards = CardRepository.instance.findCards(new CardCriteria()); - LOGGER.info("Card pool load time: " + ((System.currentTimeMillis() - beforeCall) / 1000 + " seconds")); - beforeCall = System.currentTimeMillis(); - if (DownloadPictures.checkForMissingCardImages(missingCards)) { - LOGGER.info("Card images checking time: " + ((System.currentTimeMillis() - beforeCall) / 1000 + " seconds")); - UserRequestMessage message = new UserRequestMessage("New images available", "Card images are missing (" + missingCards.size() + "). Do you want to download the images?" - + "

You can deactivate the image download check on application start in the preferences."); - message.setButton1("No", null); - message.setButton2("Yes", PlayerAction.CLIENT_DOWNLOAD_CARD_IMAGES); - showUserRequestDialog(message); - } + // Removed TODO: Remove related pref code } public static void setActive(MagePane frame) { @@ -978,8 +963,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { }//GEN-LAST:event_btnImagesActionPerformed public void downloadImages() { - java.util.List cards = CardRepository.instance.findCards(new CardCriteria()); - DownloadPictures.startDownload(null, cards); + DownloadPictures.startDownload(); } public void exitApp() { @@ -1317,7 +1301,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { Plugins.instance.downloadSymbols(); break; case CLIENT_DOWNLOAD_CARD_IMAGES: - DownloadPictures.startDownload(null, missingCards); + DownloadPictures.startDownload(); break; case CLIENT_DISCONNECT: if (SessionHandler.isConnected()) { diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java index f76aeb953d..ed125d6f2b 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/CardImageSource.java @@ -23,16 +23,17 @@ public interface CardImageSource { int getTotalImages(); - boolean isTokenSource(); + default int getTokenImages() { + return 0; + } + + default boolean isTokenSource() { + return false; + } void doPause(String httpImageUrl); default ArrayList getSupportedSets() { return null; } - - default boolean providesTokenImages() { - return false; - } -; } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java index 3052a2dc41..78f55e9b7a 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MagicCardsImageSource.java @@ -1,7 +1,10 @@ package org.mage.plugins.card.dl.sources; +import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.Map; +import java.util.Set; import mage.client.dialog.PreferencesDialog; import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.utils.CardImageUtils; @@ -13,6 +16,202 @@ import org.mage.plugins.card.utils.CardImageUtils; public enum MagicCardsImageSource implements CardImageSource { instance; + + private static final Set supportedSets = new LinkedHashSet() { + { + // add("PTC"); // Prerelease Events + add("LEA"); + add("LEB"); + add("2ED"); + add("ARN"); + add("ATQ"); + add("3ED"); + add("LEG"); + add("DRK"); + add("FEM"); + add("4ED"); + add("ICE"); + add("CHR"); + add("HML"); + add("ALL"); + add("MIR"); + add("VIS"); + add("5ED"); + add("POR"); + add("WTH"); + add("TMP"); + add("STH"); + add("EXO"); + add("P02"); + add("UGL"); + add("USG"); + add("DD3DVD"); + add("DD3EVG"); + add("DD3GVL"); + add("DD3JVC"); + + add("ULG"); + add("6ED"); + add("UDS"); + add("PTK"); + add("S99"); + add("MMQ"); + // add("BRB");Battle Royale Box Set + add("NEM"); + add("S00"); + add("PCY"); + add("INV"); + // add("BTD"); // Beatdown Boxset + add("PLS"); + add("7ED"); + add("APC"); + add("ODY"); + // add("DKM"); // Deckmasters 2001 + add("TOR"); + add("JUD"); + add("ONS"); + add("LGN"); + add("SCG"); + add("8ED"); + add("MRD"); + add("DST"); + add("5DN"); + add("CHK"); + add("UNH"); + add("BOK"); + add("SOK"); + add("9ED"); + add("RAV"); + add("GPT"); + add("DIS"); + add("CSP"); + add("TSP"); + add("TSB"); + add("PLC"); + add("FUT"); + add("10E"); + add("MED"); + add("LRW"); + add("EVG"); + add("MOR"); + add("SHM"); + add("EVE"); + add("DRB"); + add("ME2"); + add("ALA"); + add("DD2"); + add("CON"); + add("DDC"); + add("ARB"); + add("M10"); + // add("TD0"); // Magic Online Deck Series + add("V09"); + add("HOP"); + add("ME3"); + add("ZEN"); + add("DDD"); + add("H09"); + add("WWK"); + add("DDE"); + add("ROE"); + add("DPA"); + add("ARC"); + add("M11"); + add("V10"); + add("DDF"); + add("SOM"); + // add("TD0"); // Commander Theme Decks + add("PD2"); + add("ME4"); + add("MBS"); + add("DDG"); + add("NPH"); + add("CMD"); + add("M12"); + add("V11"); + add("DDH"); + add("ISD"); + add("PD3"); + add("DKA"); + add("DDI"); + add("AVR"); + add("PC2"); + add("M13"); + add("V12"); + add("DDJ"); + add("RTR"); + add("CM1"); + // add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia + add("GTC"); + add("DDK"); + add("DGM"); + add("MMA"); + add("M14"); + add("V13"); + add("DDL"); + add("THS"); + add("C13"); + add("BNG"); + add("DDM"); + add("JOU"); + // add("MD1"); // Modern Event Deck + add("CNS"); + add("VMA"); + add("M15"); + add("V14"); + add("DDN"); + add("KTK"); + add("C14"); + // add("DD3"); // Duel Decks Anthology + add("FRF"); + add("DDO"); + add("DTK"); + add("TPR"); + add("MM2"); + add("ORI"); + add("V15"); + add("DDP"); + add("BFZ"); + add("EXP"); + add("C15"); + // add("PZ1"); // Legendary Cube + add("OGW"); + add("DDQ"); + add("W16"); + add("SOI"); + add("EMA"); + add("EMN"); + add("V16"); + add("CN2"); + add("DDR"); + add("KLD"); + add("MPS"); + // add("PZ2"); // Treasure Chests + add("C16"); + add("PCA"); + add("AER"); + add("MM3"); + add("DDS"); + add("W17"); + add("AKH"); + add("MPS"); + add("CMA"); + add("E01"); + add("HOU"); + add("C17"); +// add("XLN"); +// add("DDT"); +// add("IMA"); +// add("E02"); +// add("V17"); +// add("UST"); +// add("RIX"); +// add("A25"); +// add("DOM"); +// add("M19"); + } + }; + private static final Map setNameTokenReplacement = new HashMap() { { put("10E", "tenth-edition"); @@ -146,12 +345,11 @@ public enum MagicCardsImageSource implements CardImageSource { return "magiccards.info"; } - @Override public String getNextHttpImageUrl() { return null; } - + @Override public String getFileForHttpImage(String httpImageUrl) { return null; @@ -210,18 +408,26 @@ public enum MagicCardsImageSource implements CardImageSource { public float getAverageSize() { return 70.0f; } - + @Override public int getTotalImages() { return -1; } - + @Override public boolean isTokenSource() { return true; } - + + @Override + public ArrayList getSupportedSets() { + ArrayList supportedSetsCopy = new ArrayList<>(); + supportedSetsCopy.addAll(supportedSets); + return supportedSetsCopy; + } + @Override public void doPause(String httpImageUrl) { } + } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java index 56f42fac5a..41207d6b9c 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MtgOnlTokensImageSource.java @@ -27,11 +27,10 @@ */ package org.mage.plugins.card.dl.sources; -import org.apache.log4j.Logger; -import org.mage.plugins.card.images.CardDownloadData; - import java.io.IOException; import java.util.HashMap; +import org.apache.log4j.Logger; +import org.mage.plugins.card.images.CardDownloadData; /** * @@ -368,12 +367,12 @@ public enum MtgOnlTokensImageSource implements CardImageSource { } return -1; } - + @Override public boolean isTokenSource() { return true; } - + @Override public void doPause(String httpImageUrl) { } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java index d8ceaf19f2..cf81ee5957 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/MythicspoilerComSource.java @@ -77,7 +77,7 @@ public enum MythicspoilerComSource implements CardImageSource { supportedSets.add("DDR"); supportedSets.add("KLD"); supportedSets.add("MPS"); - supportedSets.add("PZ2"); + // supportedSets.add("PZ2"); supportedSets.add("C16"); supportedSets.add("PCA"); supportedSets.add("AER"); diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java index 1166e40fc8..a54e5c0118 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/ScryfallImageSource.java @@ -1,18 +1,206 @@ package org.mage.plugins.card.dl.sources; -import org.mage.plugins.card.images.CardDownloadData; - +import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashSet; import java.util.Map; +import java.util.Set; +import org.mage.plugins.card.images.CardDownloadData; /** * @author Quercitron * */ -public enum ScryfallImageSource implements CardImageSource { +public enum ScryfallImageSource implements CardImageSource { instance; + private final Set supportedSets; + + ScryfallImageSource() { + supportedSets = new LinkedHashSet<>(); + // supportedSets.add("PTC"); // + supportedSets.add("LEA"); + supportedSets.add("LEB"); + supportedSets.add("2ED"); + supportedSets.add("ARN"); + supportedSets.add("ATQ"); + supportedSets.add("3ED"); + supportedSets.add("LEG"); + supportedSets.add("DRK"); + supportedSets.add("FEM"); + supportedSets.add("4ED"); + supportedSets.add("ICE"); + supportedSets.add("CHR"); + supportedSets.add("HML"); + supportedSets.add("ALL"); + supportedSets.add("MIR"); + supportedSets.add("VIS"); + supportedSets.add("5ED"); + supportedSets.add("POR"); + supportedSets.add("WTH"); + supportedSets.add("TMP"); + supportedSets.add("STH"); + supportedSets.add("EXO"); + supportedSets.add("P02"); + supportedSets.add("UGL"); + supportedSets.add("USG"); + supportedSets.add("DD3DVD"); + supportedSets.add("DD3EVG"); + supportedSets.add("DD3GVL"); + supportedSets.add("DD3JVC"); + + supportedSets.add("ULG"); + supportedSets.add("6ED"); + supportedSets.add("UDS"); + supportedSets.add("PTK"); + supportedSets.add("S99"); + supportedSets.add("MMQ"); + // supportedSets.add("BRB");Battle Royale Box Set + supportedSets.add("NEM"); + supportedSets.add("S00"); + supportedSets.add("PCY"); + supportedSets.add("INV"); + // supportedSets.add("BTD"); // Beatdown Boxset + supportedSets.add("PLS"); + supportedSets.add("7ED"); + supportedSets.add("APC"); + supportedSets.add("ODY"); + // supportedSets.add("DKM"); // Deckmasters 2001 + supportedSets.add("TOR"); + supportedSets.add("JUD"); + supportedSets.add("ONS"); + supportedSets.add("LGN"); + supportedSets.add("SCG"); + supportedSets.add("8ED"); + supportedSets.add("MRD"); + supportedSets.add("DST"); + supportedSets.add("5DN"); + supportedSets.add("CHK"); + supportedSets.add("UNH"); + supportedSets.add("BOK"); + supportedSets.add("SOK"); + supportedSets.add("9ED"); + supportedSets.add("RAV"); + supportedSets.add("GPT"); + supportedSets.add("DIS"); + supportedSets.add("CSP"); + supportedSets.add("TSP"); + supportedSets.add("TSB"); + supportedSets.add("PLC"); + supportedSets.add("FUT"); + supportedSets.add("10E"); + supportedSets.add("MED"); + supportedSets.add("LRW"); + supportedSets.add("EVG"); + supportedSets.add("MOR"); + supportedSets.add("SHM"); + supportedSets.add("EVE"); + supportedSets.add("DRB"); + supportedSets.add("ME2"); + supportedSets.add("ALA"); + supportedSets.add("DD2"); + supportedSets.add("CON"); + supportedSets.add("DDC"); + supportedSets.add("ARB"); + supportedSets.add("M10"); + // supportedSets.add("TD0"); // Magic Online Deck Series + supportedSets.add("V09"); + supportedSets.add("HOP"); + supportedSets.add("ME3"); + supportedSets.add("ZEN"); + supportedSets.add("DDD"); + supportedSets.add("H09"); + supportedSets.add("WWK"); + supportedSets.add("DDE"); + supportedSets.add("ROE"); + supportedSets.add("DPA"); + supportedSets.add("ARC"); + supportedSets.add("M11"); + supportedSets.add("V10"); + supportedSets.add("DDF"); + supportedSets.add("SOM"); + // supportedSets.add("TD0"); // Commander Theme Decks + supportedSets.add("PD2"); + supportedSets.add("ME4"); + supportedSets.add("MBS"); + supportedSets.add("DDG"); + supportedSets.add("NPH"); + supportedSets.add("CMD"); + supportedSets.add("M12"); + supportedSets.add("V11"); + supportedSets.add("DDH"); + supportedSets.add("ISD"); + supportedSets.add("PD3"); + supportedSets.add("DKA"); + supportedSets.add("DDI"); + supportedSets.add("AVR"); + supportedSets.add("PC2"); + supportedSets.add("M13"); + supportedSets.add("V12"); + supportedSets.add("DDJ"); + supportedSets.add("RTR"); + supportedSets.add("CM1"); + // supportedSets.add("TD2"); // Duel Decks: Mirrodin Pure vs. New Phyrexia + supportedSets.add("GTC"); + supportedSets.add("DDK"); + supportedSets.add("DGM"); + supportedSets.add("MMA"); + supportedSets.add("M14"); + supportedSets.add("V13"); + supportedSets.add("DDL"); + supportedSets.add("THS"); + supportedSets.add("C13"); + supportedSets.add("BNG"); + supportedSets.add("DDM"); + supportedSets.add("JOU"); + // supportedSets.add("MD1"); // Modern Event Deck + supportedSets.add("CNS"); + supportedSets.add("VMA"); + supportedSets.add("M15"); + supportedSets.add("V14"); + supportedSets.add("DDN"); + supportedSets.add("KTK"); + supportedSets.add("C14"); + // supportedSets.add("DD3"); // Duel Decks Anthology + supportedSets.add("FRF"); + supportedSets.add("DDO"); + supportedSets.add("DTK"); + supportedSets.add("TPR"); + supportedSets.add("MM2"); + supportedSets.add("ORI"); + supportedSets.add("V15"); + supportedSets.add("DDP"); + supportedSets.add("BFZ"); + supportedSets.add("EXP"); + supportedSets.add("C15"); + // supportedSets.add("PZ1"); // Legendary Cube + supportedSets.add("OGW"); + supportedSets.add("DDQ"); + supportedSets.add("W16"); + supportedSets.add("SOI"); + supportedSets.add("EMA"); + supportedSets.add("EMN"); + supportedSets.add("V16"); + supportedSets.add("CN2"); + supportedSets.add("DDR"); + supportedSets.add("KLD"); + supportedSets.add("MPS"); + // supportedSets.add("PZ2"); + supportedSets.add("C16"); + supportedSets.add("PCA"); + supportedSets.add("AER"); + supportedSets.add("MM3"); + supportedSets.add("DDS"); + supportedSets.add("W17"); + supportedSets.add("AKH"); + supportedSets.add("MPS"); + supportedSets.add("CMA"); + supportedSets.add("E01"); + supportedSets.add("HOU"); + supportedSets.add("C17"); + } + @Override public String generateURL(CardDownloadData card) throws Exception { return "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/" + card.getCollectorId() + "?format=image"; @@ -40,7 +228,7 @@ public enum ScryfallImageSource implements CardImageSource { @Override public float getAverageSize() { - return 240; + return 90; } @Override @@ -75,4 +263,11 @@ public enum ScryfallImageSource implements CardImageSource { put("MBP", "pmei"); } }; + + @Override + public ArrayList getSupportedSets() { + ArrayList supportedSetsCopy = new ArrayList<>(); + supportedSetsCopy.addAll(supportedSets); + return supportedSetsCopy; + } } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java index 2f58b13a2c..7f932f3536 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/TokensMtgImageSource.java @@ -27,9 +27,6 @@ */ package org.mage.plugins.card.dl.sources; -import org.apache.log4j.Logger; -import org.mage.plugins.card.images.CardDownloadData; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -39,6 +36,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.log4j.Logger; +import org.mage.plugins.card.images.CardDownloadData; /** * @@ -46,10 +45,9 @@ import java.util.Map; */ public enum TokensMtgImageSource implements CardImageSource { - instance; + instance; private static final Logger logger = Logger.getLogger(TokensMtgImageSource.class); - private List tokensData; private final Object tokensDataSync = new Object(); @@ -137,6 +135,7 @@ public enum TokensMtgImageSource implements CardImageSource { List newTokensData = getTokensData(); if (newTokensData.isEmpty()) { + logger.info("Source " + getSourceName() + " provides no token data."); return null; } @@ -146,17 +145,18 @@ public enum TokensMtgImageSource implements CardImageSource { matchedTokens.add(token); } } -// -// if (matchedTokens.isEmpty()) { -// logger.info("Could not find data for token " + name + ", set " + set + "."); -// return null; -// } + + if (matchedTokens.isEmpty()) { + logger.info("Could not find data for token " + name + ", set " + set + "."); + return null; + } TokenData tokenData; if (type == 0) { if (matchedTokens.size() > 1) { logger.info("Multiple images were found for token " + name + ", set " + set + '.'); } + logger.info("Token found: " + name + ", set " + set + '.'); tokenData = matchedTokens.get(0); } else { if (type > matchedTokens.size()) { @@ -178,7 +178,7 @@ public enum TokensMtgImageSource implements CardImageSource { tokensData = new ArrayList<>(); // get tokens data from resource file - try(InputStream inputStream = this.getClass().getResourceAsStream("/tokens-mtg-onl-list.csv")) { + try (InputStream inputStream = this.getClass().getResourceAsStream("/tokens-mtg-onl-list.csv")) { List fileTokensData = parseTokensData(inputStream); tokensData.addAll(fileTokensData); } catch (Exception exception) { @@ -188,7 +188,7 @@ public enum TokensMtgImageSource implements CardImageSource { // description on site may contain new information // try to add it URL url = new URL("http://tokens.mtg.onl/data/SetsWithTokens.csv"); - try(InputStream inputStream = url.openStream()) { + try (InputStream inputStream = url.openStream()) { List siteTokensData = parseTokensData(inputStream); List newTokensData = new ArrayList<>(); for (TokenData siteData : siteTokensData) { @@ -219,8 +219,8 @@ public enum TokensMtgImageSource implements CardImageSource { private List parseTokensData(InputStream inputStream) throws IOException { List newTokensData = new ArrayList<>(); - try(InputStreamReader inputReader = new InputStreamReader(inputStream, "Cp1252"); - BufferedReader reader = new BufferedReader(inputReader)) { + try (InputStreamReader inputReader = new InputStreamReader(inputStream, "Cp1252"); + BufferedReader reader = new BufferedReader(inputReader)) { // we have to specify encoding to read special comma reader.readLine(); // skip header @@ -285,7 +285,19 @@ public enum TokensMtgImageSource implements CardImageSource { @Override public int getTotalImages() { - return -1; + return getTokenImages(); + } + + @Override + public int getTokenImages() { + int number = 0; + try { + List newTokensData = getTokensData(); + number = newTokensData.size(); + } catch (IOException ex) { + logger.error(getSourceName() + ": Loading available data failed. " + ex.getMessage()); + } + return number; } @Override diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java index 4939fdcbe2..50bf2c99ca 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/dl/sources/WizardCardsImageSource.java @@ -77,6 +77,7 @@ public enum WizardCardsImageSource implements CardImageSource { WizardCardsImageSource() { supportedSets = new LinkedHashSet<>(); + // supportedSets.add("PTC"); // Prerelease Events supportedSets.add("LEA"); supportedSets.add("LEB"); supportedSets.add("2ED"); @@ -638,6 +639,9 @@ public enum WizardCardsImageSource implements CardImageSource { String setNames = setsAliases.get(cardSet); if (setNames != null) { Map setLinks = sets.computeIfAbsent(cardSet, k -> getSetLinks(cardSet)); + if (setLinks == null || setLinks.isEmpty()) { + return null; + } String link = setLinks.get(card.getDownloadName().toLowerCase()); if (link == null) { int length = collectorId.length(); @@ -663,6 +667,7 @@ public enum WizardCardsImageSource implements CardImageSource { return link; } return null; + } @Override 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 c9b9a25d1b..86a16bc15a 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 @@ -1,6 +1,7 @@ package org.mage.plugins.card.images; import java.awt.*; +import java.awt.event.ItemEvent; import java.awt.image.BufferedImage; import java.io.*; import java.net.*; @@ -14,7 +15,6 @@ import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriteParam; @@ -23,7 +23,9 @@ import javax.imageio.stream.FileImageOutputStream; import javax.swing.*; import mage.cards.ExpansionSet; import mage.cards.Sets; +import mage.cards.repository.CardCriteria; import mage.cards.repository.CardInfo; +import mage.cards.repository.CardRepository; import mage.client.constants.Constants; import mage.client.dialog.PreferencesDialog; import mage.client.util.sets.ConstructedFormats; @@ -75,28 +77,56 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab private Proxy p = Proxy.NO_PROXY; - // private ExecutorService executor = Executors.newFixedThreadPool(10); - public static void main(String[] args) { - startDownload(null, null); + enum DownloadSources { + WIZARDS("wizards.com", WizardCardsImageSource.instance), + MYTHICSPOILER("mythicspoiler.com", MythicspoilerComSource.instance), + TOKENS("tokens.mtg.onl", TokensMtgImageSource.instance), + MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), + ALTERNATIVE("alternative.mtg.onl", AltMtgOnlTokensImageSource.instance), + GRAB_BAG("GrabBag", GrabbagImageSource.instance), + MAGIDEX("magidex.com", MagidexImageSource.instance), + SCRYFALL("scryfall.com", ScryfallImageSource.instance), + MAGICCARDS("magiccards.info", MagicCardsImageSource.instance); + + private final String text; + private final CardImageSource source; + + DownloadSources(String text, CardImageSource sourceInstance) { + this.text = text; + this.source = sourceInstance; + } + + public CardImageSource getSource() { + return source; + } + + @Override + public String toString() { + return text; + } + } - public static void startDownload(JFrame frame, List allCards) { - List cards = getNeededCards(allCards); + public static void main(String[] args) { + startDownload(); + } + + public static void startDownload() { /* * if (cards == null || cards.isEmpty()) { * JOptionPane.showMessageDialog(null, * "All card pictures have been downloaded."); return; } */ - DownloadPictures download = new DownloadPictures(cards); - JDialog dlg = download.getDlg(frame); + DownloadPictures download = new DownloadPictures(); + JDialog dlg = download.getDlg(null); dlg.setVisible(true); dlg.dispose(); download.cancel = true; } public JDialog getDlg(JFrame frame) { - String title = "Downloading"; + String title = "Downloading images"; final JDialog dialog = this.dlg.createDialog(frame, title); closeButton.addActionListener(e -> dialog.setVisible(false)); @@ -107,11 +137,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab this.cancel = cancel; } - public DownloadPictures(List cards) { - this.allCardsMissingImage = cards; - - bar = new JProgressBar(this); - + public DownloadPictures() { JPanel p0 = new JPanel(); p0.setLayout(new BoxLayout(p0, BoxLayout.Y_AXIS)); @@ -120,61 +146,46 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab jLabelAllMissing = new JLabel(); jLabelAllMissing.setAlignmentX(Component.LEFT_ALIGNMENT); + // jLabelAllMissing.setText("Computing number of missing images..."); p0.add(jLabelAllMissing); p0.add(Box.createVerticalStrut(5)); jLabelServer = new JLabel(); - jLabelServer.setText("Please select server:"); + jLabelServer.setText("Please select image source:"); jLabelServer.setAlignmentX(Component.LEFT_ALIGNMENT); p0.add(jLabelServer); p0.add(Box.createVerticalStrut(5)); - ComboBoxModel jComboBoxDownloadSourcesModel = new DefaultComboBoxModel(new String[]{ - "wizards.com", - "mythicspoiler.com", - "tokens.mtg.onl", //"mtgimage.com (HQ)", - "mtg.onl", - "alternative.mtg.onl", - "GrabBag", - "magidex.com", - "scryfall.com", - "magiccards.info" - //"mtgathering.ru HQ", - //"mtgathering.ru MQ", - //"mtgathering.ru LQ", - }); jComboBoxServer = new JComboBox(); - - cardImageSource = WizardCardsImageSource.instance; - - jComboBoxServer.setModel(jComboBoxDownloadSourcesModel); + jComboBoxServer.setModel(new DefaultComboBoxModel(DownloadSources.values())); jComboBoxServer.setAlignmentX(Component.LEFT_ALIGNMENT); - jComboBoxServer.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(java.awt.event.ActionEvent evt) { - comboBoxServerActionPerformed(evt); + jComboBoxServer.addItemListener((ItemEvent event) -> { + if (event.getStateChange() == ItemEvent.SELECTED) { + comboBoxServerItemSelected(event); } }); p0.add(jComboBoxServer); + // set the first source as default + cardImageSource = WizardCardsImageSource.instance; p0.add(Box.createVerticalStrut(5)); // Set selection --------------------------------- jLabelSet = new JLabel(); - jLabelSet.setText("Please select sets to download images for:"); + jLabelSet.setText("Please select sets to download the images for:"); jLabelSet.setAlignmentX(Component.LEFT_ALIGNMENT); p0.add(jLabelSet); jComboBoxSet = new JComboBox(); jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); jComboBoxSet.setAlignmentX(Component.LEFT_ALIGNMENT); - jComboBoxSet.addActionListener(new java.awt.event.ActionListener() { - @Override - public void actionPerformed(java.awt.event.ActionEvent evt) { - comboBoxSetActionPerformed(evt); + jComboBoxSet.addItemListener((ItemEvent event) -> { + if (event.getStateChange() == ItemEvent.SELECTED) { + comboBoxSetItemSelected(event); } }); + p0.add(jComboBoxSet); p0.add(Box.createVerticalStrut(5)); @@ -188,8 +199,10 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab p0.add(Box.createVerticalStrut(5)); // Progress + bar = new JProgressBar(this); p0.add(bar); bar.setStringPainted(true); + Dimension d = bar.getPreferredSize(); d.width = 300; bar.setPreferredSize(d); @@ -198,68 +211,31 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab Object[] options = {startDownloadButton, closeButton = new JButton("Cancel")}; dlg = new JOptionPane(p0, JOptionPane.PLAIN_MESSAGE, JOptionPane.DEFAULT_OPTION, null, options, options[1]); - updateCardsToDownload(); + setAllMissingCards(); } - public static boolean checkForMissingCardImages(List allCards) { - AtomicBoolean missedCardTFiles = new AtomicBoolean(); - allCards.parallelStream().forEach(card -> { - if (!missedCardTFiles.get()) { - if (!card.getCardNumber().isEmpty() && !"0".equals(card.getCardNumber()) && !card.getSetCode().isEmpty()) { - CardDownloadData url = new CardDownloadData(card.getName(), card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), - 0, "", "", false, card.isDoubleFaced(), card.isNightCard()); - TFile file = new TFile(CardImageUtils.generateImagePath(url)); - if (!file.exists()) { - missedCardTFiles.set(true); - } - } - } - }); - return missedCardTFiles.get(); + public void setAllMissingCards() { + List cards = CardRepository.instance.findCards(new CardCriteria()); + this.allCardsMissingImage = getNeededCards(cards); + updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); } - private void comboBoxServerActionPerformed(java.awt.event.ActionEvent evt) { - JComboBox cb = (JComboBox) evt.getSource(); - switch (cb.getSelectedIndex()) { - case 0: - cardImageSource = WizardCardsImageSource.instance; - break; - case 1: - cardImageSource = MythicspoilerComSource.instance; - break; - case 2: - cardImageSource = TokensMtgImageSource.instance; - break; - case 3: - cardImageSource = MtgOnlTokensImageSource.instance; - break; - case 4: - cardImageSource = AltMtgOnlTokensImageSource.instance; - break; - case 5: - cardImageSource = GrabbagImageSource.instance; - break; - case 6: - cardImageSource = MagidexImageSource.instance; - break; - case 7: - cardImageSource = ScryfallImageSource.instance; - break; - case 8: - cardImageSource = MagicCardsImageSource.instance; - break; - } + private void comboBoxServerItemSelected(ItemEvent evt) { + cardImageSource = ((DownloadSources) evt.getItem()).getSource(); + // update the available sets / token comboBox jComboBoxSet.setModel(new DefaultComboBoxModel<>(getSetsForCurrentImageSource())); - updateCardsToDownload(); + updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); } private Object[] getSetsForCurrentImageSource() { // Set the available sets to the combo box ArrayList supportedSets = cardImageSource.getSupportedSets(); List setNames = new ArrayList<>(); - setNames.add(ALL_CARDS); - setNames.add(ALL_STANDARD_CARDS); - if (cardImageSource.providesTokenImages()) { + if (supportedSets != null) { + setNames.add(ALL_CARDS); + setNames.add(ALL_STANDARD_CARDS); + } + if (cardImageSource.isTokenSource()) { setNames.add(ALL_TOKENS); } if (supportedSets != null) { @@ -273,14 +249,17 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } } + if (setNames.isEmpty()) { + logger.error("Source " + cardImageSource.getSourceName() + " creates no selectable items."); + setNames.add("not avalable"); + } return setNames.toArray(new String[0]); } - private void updateCardsToDownload() { - String expansionSelection = jComboBoxSet.getSelectedItem().toString(); + private void updateCardsToDownload(String itemText) { selectedSetCodes.clear(); boolean tokens = false; - switch (expansionSelection) { + switch (itemText) { case ALL_CARDS: if (cardImageSource.getSupportedSets() == null) { selectedSetCodes = cardImageSource.getSupportedSets(); @@ -300,9 +279,13 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab break; case ALL_TOKENS: tokens = true; + break; default: - int nonSetEntries = 2; - if (cardImageSource.providesTokenImages()) { + int nonSetEntries = 0; + if (cardImageSource.getSupportedSets() != null) { + nonSetEntries = 2; + } + if (cardImageSource.isTokenSource()) { nonSetEntries++; } selectedSetCodes.add(cardImageSource.getSupportedSets().get(jComboBoxSet.getSelectedIndex() - nonSetEntries)); @@ -310,16 +293,20 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab cardsToDownload.clear(); for (CardDownloadData data : allCardsMissingImage) { if ((data.isToken() && tokens) - || (!data.isToken() && selectedSetCodes.contains(data.getSet()))) { + || (!data.isToken() && selectedSetCodes != null && selectedSetCodes.contains(data.getSet()))) { cardsToDownload.add(data); } } - updateProgressText(cardsToDownload.size()); + int numberTokenImagesAvailable = 0; + if (tokens) { + cardImageSource.getTokenImages(); + } + updateProgressText(cardsToDownload.size() + numberTokenImagesAvailable); } - private void comboBoxSetActionPerformed(java.awt.event.ActionEvent evt) { + private void comboBoxSetItemSelected(ItemEvent event) { // Update the cards to download related to the selected set - updateCardsToDownload(); + updateCardsToDownload(event.getItem().toString()); } private void updateProgressText(int cardCount) { @@ -330,11 +317,11 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } } missingCards = allCardsMissingImage.size() - missingTokens; - jLabelAllMissing.setText("Missing: " + missingCards + " cards / " + missingTokens + " tokens"); + jLabelAllMissing.setText("Missing: " + missingCards + " card images / " + missingTokens + " token images"); float mb = (cardCount * cardImageSource.getAverageSize()) / 1024; - bar.setString(String.format(cardIndex == cardCount ? "%d of %d cards finished! Please close!" - : "%d of %d cards finished! Please wait! [%.1f Mb]", 0, cardCount, mb)); + bar.setString(String.format(cardIndex == cardCount ? "%d of %d image downloads finished! Please close!" + : "%d of %d image downloads finished! Please wait! [%.1f Mb]", 0, cardCount, mb)); } private static String createDownloadName(CardInfo card) { @@ -530,7 +517,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab HashSet ignoreUrls = SettingsManager.getIntance().getIgnoreUrls(); update(0, cardsToDownload.size()); - logger.info("Started download of " + cardsToDownload.size() + " cards from source: " + cardImageSource.getSourceName()); + logger.info("Started download of " + cardsToDownload.size() + " images from source: " + cardImageSource.getSourceName()); int numberOfThreads = Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_THREADS, "10")); ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); @@ -539,7 +526,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab CardDownloadData card = cardsToDownload.get(i); - logger.debug("Downloading card: " + card.getName() + " (" + card.getSet() + ')'); + logger.debug("Downloading image: " + card.getName() + " (" + card.getSet() + ')'); String url; if (ignoreUrls.contains(card.getSet()) || card.isToken()) { @@ -564,7 +551,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } catch (Exception ex) { } } else if (cardImageSource.getTotalImages() == -1) { - logger.info("Card not available on " + cardImageSource.getSourceName() + ": " + card.getName() + " (" + card.getSet() + ')'); + logger.info("Image not available on " + cardImageSource.getSourceName() + ": " + card.getName() + " (" + card.getSet() + ')'); synchronized (sync) { update(cardIndex + 1, cardsToDownload.size()); } @@ -595,6 +582,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab System.gc(); } closeButton.setText("Close"); + updateCardsToDownload(jComboBoxSet.getSelectedItem().toString()); } static String convertStreamToString(java.io.InputStream is) { @@ -790,7 +778,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab if (cardIndex < count) { float mb = ((count - card) * cardImageSource.getAverageSize()) / 1024; - bar.setString(String.format("%d of %d cards finished! Please wait! [%.1f Mb]", + bar.setString(String.format("%d of %d image downloads finished! Please wait! [%.1f Mb]", card, count, mb)); } else { List remainingCards = Collections.synchronizedList(new ArrayList<>()); @@ -808,9 +796,9 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab count = remainingCards.size(); if (count == 0) { - bar.setString("0 cards remaining! Please close!"); + bar.setString("0 images remaining! Please close!"); } else { - bar.setString(String.format("%d cards remaining! Please choose another source!", count)); +// bar.setString(String.format("%d cards remaining! Please choose another source!", count)); startDownloadButton.setEnabled(true); } }