Updated image download handling.

This commit is contained in:
LevelX2 2017-09-04 18:25:31 +02:00
parent d003cd898f
commit 5a1544050c
9 changed files with 556 additions and 166 deletions

View file

@ -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<CardInfo> 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?"
+ "<br><br><i>You can deactivate the image download check on application start in the preferences.</i>");
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<CardInfo> 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()) {

View file

@ -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<String> getSupportedSets() {
return null;
}
default boolean providesTokenImages() {
return false;
}
;
}

View file

@ -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<String> supportedSets = new LinkedHashSet<String>() {
{
// 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<String, String> setNameTokenReplacement = new HashMap<String, String>() {
{
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<String> getSupportedSets() {
ArrayList<String> supportedSetsCopy = new ArrayList<>();
supportedSetsCopy.addAll(supportedSets);
return supportedSetsCopy;
}
@Override
public void doPause(String httpImageUrl) {
}
}

View file

@ -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) {
}

View file

@ -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");

View file

@ -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<String> 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<String> getSupportedSets() {
ArrayList<String> supportedSetsCopy = new ArrayList<>();
supportedSetsCopy.addAll(supportedSets);
return supportedSetsCopy;
}
}

View file

@ -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<TokenData> tokensData;
private final Object tokensDataSync = new Object();
@ -137,6 +135,7 @@ public enum TokensMtgImageSource implements CardImageSource {
List<TokenData> 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<TokenData> 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<TokenData> siteTokensData = parseTokensData(inputStream);
List<TokenData> newTokensData = new ArrayList<>();
for (TokenData siteData : siteTokensData) {
@ -219,8 +219,8 @@ public enum TokensMtgImageSource implements CardImageSource {
private List<TokenData> parseTokensData(InputStream inputStream) throws IOException {
List<TokenData> 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<TokenData> newTokensData = getTokensData();
number = newTokensData.size();
} catch (IOException ex) {
logger.error(getSourceName() + ": Loading available data failed. " + ex.getMessage());
}
return number;
}
@Override

View file

@ -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<String, String> 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

View file

@ -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<CardInfo> allCards) {
List<CardDownloadData> 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<CardDownloadData> 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<CardInfo> 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<CardInfo> 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<String> supportedSets = cardImageSource.getSupportedSets();
List<String> 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<String> 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<CardDownloadData> 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);
}
}