images: deleted outdated/closed images sources (closes #5767)

This commit is contained in:
Oleg Agafonov 2024-06-06 22:10:46 +04:00
parent 719ef1910e
commit 4635563f44
10 changed files with 12 additions and 2447 deletions

View file

@ -1,172 +0,0 @@
package org.mage.plugins.card.dl.sources;
import org.apache.log4j.Logger;
import org.mage.plugins.card.dl.DownloadServiceInfo;
import org.mage.plugins.card.images.CardDownloadData;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* * TODO: web site reworked and tokens doesn't work anymore,
* * but it can be used to download a proxy tokens (tokens that was miss by wizards),
* * see https://www.mtg.onl/mtg-missing-tokens/
*
* @author spjspj
*/
public enum AltMtgOnlTokensImageSource implements CardImageSource {
instance;
private static final Logger logger = Logger.getLogger(AltMtgOnlTokensImageSource.class);
private static int maxTimes = 0;
@Override
public String getSourceName() {
return "http://alternative.mtg.onl/tokens/";
}
@Override
public float getAverageSize() {
return 26.7f;
}
@Override
public String getNextHttpImageUrl() {
if (copyUrlToImage == null) {
setupLinks();
}
for (String key : copyUrlToImageDone.keySet()) {
if (copyUrlToImageDone.get(key) < maxTimes) {
copyUrlToImageDone.put(key, maxTimes);
return key;
}
}
if (maxTimes < 2) {
maxTimes++;
}
for (String key : copyUrlToImageDone.keySet()) {
if (copyUrlToImageDone.get(key) < maxTimes) {
copyUrlToImageDone.put(key, maxTimes);
return key;
}
}
return null;
}
@Override
public String getFileForHttpImage(String httpImageUrl) {
if (httpImageUrl != null) {
return copyUrlToImage.get(httpImageUrl);
}
return null;
}
@Override
public boolean prepareDownloadList(DownloadServiceInfo downloadServiceInfo, List<CardDownloadData> downloadList) {
return true;
}
@Override
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
return null;
}
Map<String, String> copyUrlToImage = null;
Map<String, String> copyImageToUrl = null;
Map<String, Integer> copyUrlToImageDone = null;
private void setupLinks() {
if (copyUrlToImage != null) {
return;
}
copyUrlToImage = new HashMap<>();
copyImageToUrl = new HashMap<>();
copyUrlToImageDone = new HashMap<>();
copyUrlToImage.put("SCG_CC_002-Penguin.jpg", "BIRD.WU.BIRD.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_CC_005-Vampire.jpg", "VAMPIRE.B.VAMPIRE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_CC_006-Panda.jpg", "BEAR.G.BEAR.CREATURE.2.2.full.jpg");
copyUrlToImage.put("SCG_CC_008-Force-of-Squirrel.jpg", "SQUIRREL.G.SQUIRREL.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_CC_013-Zombie.jpg", "ZOMBIE.B.ZOMBIE.CREATURE.2.2.full.jpg");
copyUrlToImage.put("SCG_GN_003-Ooze.jpg", "OOZE.G.OOZE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_GN_005-Mammoth.jpg", "ELEPHANT.G.ELEPHANT.CREATURE.3.3.full.jpg");
copyUrlToImage.put("SCG_GN_006-Wurm.jpg", "WURM.G.WURM.CREATURE.5.5.full.jpg");
copyUrlToImage.put("SCG_GN_007-Rat.jpg", "RAT.B.RAT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_GN_010-Wolf.jpg", "WOLF.G.WOLF.CREATURE.2.2.full.jpg");
copyUrlToImage.put("SCG_GN_011-Bee.jpg", "INSECT.G.INSECT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_GN_012-Bunny.jpg", "RABBIT.G.RABBIT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_GN_013-Piglet.jpg", "BOAR.G.BOAR.CREATURE.2.2.full.jpg");
copyUrlToImage.put("SCG_GN_014-Monkey.jpg", "APE.G.APE.CREATURE.3.3.full.jpg");
copyUrlToImage.put("SCG_GN_015-Kraken.jpg", "KRAKEN.U.KRAKEN.CREATURE.9.9.full.jpg");
copyUrlToImage.put("SCG_GN_016-Hippo.jpg", "HIPPO.G.HIPPO.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_GN_019-Reindeer.jpg", "CARIBOU.W.CARIBOU.CREATURE.0.1.full.jpg");
copyUrlToImage.put("SCG_GN_020-Grizzlybrand.jpg", "DEMON.B.DEMON.CREATURE.5.5.full.jpg");
copyUrlToImage.put("SCG_IP_002-Elemental.jpg", "ELEMENTAL.BR.ELEMENTAL.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_IP_003-Soldier.jpg", "SOLDIER.W.SOLDIER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_IP_005-Spirit.jpg ", "SPIRIT.W.SPIRIT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_IP_010-Golem.jpg", "GOLEM..GOLEM.ARTIFACTCREATURE.3.3.full.jpg");
copyUrlToImage.put("SCG_IP_011-Pegasus.jpg", "PEGASUS.W.PEGASUS.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_IP_012-Soldier.jpg", "SOLDIER.WR.SOLDIER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_IP_016-Rhino.jpg", "RHINO.G.RHINO.CREATURE.4.4.full.jpg");
copyUrlToImage.put("SCG_IP_017-Spider.jpg", "SPIDER.B.SPIDER.CREATURE.1.2.full.jpg");
copyUrlToImage.put("SCG_PO_003-Spirit.jpg", "SPIRIT..SPIRIT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_PO_007-Dragon.jpg", "DRAGON.R.DRAGON.CREATURE.2.2.full.jpg");
copyUrlToImage.put("SCG_PO_009-Faerie.jpg", "FAERIE.U.FAERIE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_PO_010-Goblin.jpg", "GOBLIN.R.GOBLIN.CREATURE.1.1.full.jpg");
copyUrlToImage.put("SCG_P_001-Angel.jpg", "ANGEL.W.ANGEL.CREATURE.4.4.full.jpg");
copyUrlToImage.put("SCG_P_002-Penguin.jpg", "BIRD.W.BIRD.CREATURE.3.4.full.jpg");
copyUrlToImage.put("SCG_RC_001-Kitten.jpg", "CAT.B.CAT.CREATURE.2.1.full.jpg");
copyUrlToImage.put("SCG_RC_002-Penguin.jpg", "BIRD.U.BIRD.CREATURE.2.2.full.jpg");
copyUrlToImage.put("SCG_RC_009-Aia,-Ascended.jpg", "AVATAR.W.AVATAR.CREATURE.S.S.full.jpg");
copyUrlToImage.put("SCG_SC_001-Cyclops.jpg", "BEAST.G.BEAST.CREATURE.3.3.full.jpg");
copyUrlToImage.put("SCG_SC_002-Soldier.jpg", "SOLDIER.R.SOLDIER.CREATURE.1.1.full.jpg");
for (String key : copyUrlToImage.keySet()) {
copyUrlToImageDone.put(key, maxTimes);
copyImageToUrl.put(copyUrlToImage.get(key), key);
}
}
@Override
public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
if (copyUrlToImage == null) {
setupLinks();
}
return null;
}
@Override
public int getTotalImages() {
if (copyUrlToImage == null) {
setupLinks();
}
if (copyUrlToImage != null) {
return copyImageToUrl.size();
}
return -1;
}
@Override
public boolean isTokenSource() {
return true;
}
@Override
public boolean isCardSource() {
return false;
}
@Override
public void doPause(String httpImageUrl) {
}
@Override
public boolean isCardImageProvided(String setCode, String cardName) {
// no cards support, only tokens
return false;
}
}

View file

@ -1,304 +0,0 @@
package org.mage.plugins.card.dl.sources;
import org.mage.plugins.card.dl.DownloadServiceInfo;
import org.mage.plugins.card.images.CardDownloadData;
import java.net.URI;
import java.util.*;
/**
* @author Pete Rossi
*/
public enum MagidexImageSource implements CardImageSource {
instance;
private final Set<String> supportedSets;
MagidexImageSource() {
supportedSets = new LinkedHashSet<>();
// supportedSets.add("JR"); // TODO: Set was split into the individual sets as listed on Scryfall
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("PZ2"); // Treasure Chests
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");
supportedSets.add("XLN");
supportedSets.add("DDT");
supportedSets.add("IMA");
supportedSets.add("E02");
supportedSets.add("V17");
supportedSets.add("UST");
supportedSets.add("DDU");
supportedSets.add("RIX");
supportedSets.add("A25");
supportedSets.add("DOM");
supportedSets.add("CM2");
supportedSets.add("M19");
//supportedSets.add("BBD");
//supportedSets.add("C18");
}
@Override
public String getSourceName() {
return "magidex.com";
}
@Override
public String getNextHttpImageUrl() {
return null;
}
@Override
public String getFileForHttpImage(String httpImageUrl) {
return null;
}
@Override
public boolean prepareDownloadList(DownloadServiceInfo downloadServiceInfo, List<CardDownloadData> downloadList) {
return true;
}
@Override
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
String cardDownloadName = card.getDownloadName().toLowerCase(Locale.ENGLISH);
String cardSet = card.getSet();
if (cardSet == null || cardSet.isEmpty() || cardDownloadName.isEmpty()) {
throw new Exception("Wrong parameters for image: cardDownloadName: " + cardDownloadName + ", card set: " + cardSet);
}
if (card.isSplitCard()) {
cardDownloadName = cardDownloadName.replaceAll(" // ", "");
}
// This will properly escape the url
URI uri = new URI("http", "magidex.com", "/extstatic/card/" + formatSetName(cardSet) + '/' + cardDownloadName + ".jpg", null, null);
return new CardImageUrls(uri.toASCIIString());
}
private String formatSetName(String setName) {
if (setNameReplacement.containsKey(setName)) {
setName = setNameReplacement.get(setName);
}
return setName;
}
private static final Map<String, String> setNameReplacement = new HashMap<String, String>() {
{
// put("JR", "pJGP"); // TODO: Set was split into the individual sets as listed on Scryfall
}
};
@Override
public CardImageUrls generateTokenUrl(CardDownloadData card) {
return null;
}
@Override
public float getAverageSize() {
return 62.0f;
}
@Override
public int getTotalImages() {
return -1;
}
@Override
public boolean isTokenSource() {
return false;
}
@Override
public boolean isCardSource() {
return true;
}
@Override
public void doPause(String httpImageUrl) {
}
@Override
public List<String> getSupportedSets() {
return new ArrayList<>(supportedSets);
}
@Override
public boolean isCardImageProvided(String setCode, String cardName) {
return supportedSets.contains(setCode);
}
}

View file

@ -1,379 +0,0 @@
package org.mage.plugins.card.dl.sources;
import org.apache.log4j.Logger;
import org.mage.plugins.card.dl.DownloadServiceInfo;
import org.mage.plugins.card.images.CardDownloadData;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* TODO: web site reworked and tokens doesn't work anymore,
* but it can be used to download a proxy tokens (tokens that was miss by wizards),
* see https://www.mtg.onl/mtg-missing-tokens/
*
* @author spjspj
*/
public enum MtgOnlTokensImageSource implements CardImageSource {
instance;
private static final Logger logger = Logger.getLogger(MtgOnlTokensImageSource.class);
private static int maxTimes = 0;
@Override
public String getSourceName() {
return "http://mtg.onl/token-list/tokens/";
}
@Override
public float getAverageSize() {
return 26.7f;
}
@Override
public String getNextHttpImageUrl() {
if (copyUrlToImage == null) {
setupLinks();
}
for (String key : copyUrlToImageDone.keySet()) {
if (copyUrlToImageDone.get(key) < maxTimes) {
copyUrlToImageDone.put(key, maxTimes);
return key;
}
}
if (maxTimes < 2) {
maxTimes++;
}
for (String key : copyUrlToImageDone.keySet()) {
if (copyUrlToImageDone.get(key) < maxTimes) {
copyUrlToImageDone.put(key, maxTimes);
return key;
}
}
return null;
}
@Override
public String getFileForHttpImage(String httpImageUrl) {
if (httpImageUrl != null) {
return copyUrlToImage.get(httpImageUrl);
}
return null;
}
@Override
public boolean prepareDownloadList(DownloadServiceInfo downloadServiceInfo, List<CardDownloadData> downloadList) {
return true;
}
@Override
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
return null;
}
Map<String, String> copyUrlToImage = null;
Map<String, String> copyImageToUrl = null;
Map<String, Integer> copyUrlToImageDone = null;
private void setupLinks() {
if (copyUrlToImage != null) {
return;
}
copyUrlToImage = new HashMap<>();
copyImageToUrl = new HashMap<>();
copyUrlToImageDone = new HashMap<>();
copyUrlToImage.put("Angel_B_3_3.jpg", "ANGEL.B.ANGEL.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Angel_W_3_3.jpg", "ANGEL.W.ANGEL.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Angel_W_4_4.jpg", "ANGEL.W.ANGEL.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Ape_G_2_2.jpg", "APE.G.APE.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Ape_G_3_3.jpg", "APE.G.APE.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Ashaya_the_Awoken_World_G_4_4.jpg", "ASHAYATHEAWOKENWORLD.G.ELEMENTAL.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Assassin_B_1_1.jpg", "ASSASSIN.B.ASSASSIN.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Assembly-Worker_2_2.jpg", "ASSEMBLYWORKER..ASSEMBLYWORKER.ARTIFACTCREATURE.2.2.full.jpg");
copyUrlToImage.put("Avatar_W_y_y.jpg", "AVATAR.W.AVATAR.CREATURE.S.S.full.jpg");
copyUrlToImage.put("Bat_B_1_1.jpg", "BAT.B.BAT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Bat_B_1_2.jpg", "BAT.B.BAT.CREATURE.1.2.full.jpg");
copyUrlToImage.put("Bear_G_2_2.jpg", "BEAR.G.BEAR.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Bear_G_4_4.jpg", "BEAR.G.BEAR.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Beast_B_3_3.jpg", "BEAST.B.BEAST.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Beast_G_3_3.jpg", "BEAST.G.BEAST.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Beast_G_2_2.jpg", "BEAST.G.BEAST.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Beast_G_4_4.jpg", "BEAST.G.BEAST.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Beast_G_5_5.jpg", "BEAST.G.BEAST.CREATURE.5.5.full.jpg");
copyUrlToImage.put("Beast_RGW_8_8.jpg", "BEAST.WRG.BEAST.CREATURE.8.8.full.jpg");
copyUrlToImage.put("Bird_Soldier_W_1_1.jpg", "BIRDSOLDIER.W.BIRD.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Bird_U_1_1.jpg", "BIRD.U.BIRD.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Bird_U_2_2.jpg", "BIRD.U.BIRD.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Bird_U_2_2_Enchantment.jpg", "BIRD.U.BIRD.ENCHANTMENTCREATURE.2.2.full.jpg");
copyUrlToImage.put("Bird_WU_1_1.jpg", "BIRD.WU.BIRD.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Bird_W_1_1.jpg", "BIRD.W.BIRD.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Bird_W_3_3.jpg", "BIRD.W.BIRD.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Bird_W_3_4.jpg", "BIRD.W.BIRD.CREATURE.3.4.full.jpg");
copyUrlToImage.put("Boar_G_2_2.jpg", "BOAR.G.BOAR.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Boar_G_3_3.jpg", "BOAR.G.BOAR.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Butterfly_G_1_1.jpg", "BUTTERFLY.G.INSECT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Camarid_U_1_1.jpg", "CAMARID.U.CAMARID.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Caribou_W_0_1.jpg", "CARIBOU.W.CARIBOU.CREATURE.0.1.full.jpg");
copyUrlToImage.put("Carnivore_R_3_1.jpg", "CARNIVORE.R.BEAST.CREATURE.3.1.full.jpg");
copyUrlToImage.put("Cat_B_2_1.jpg", "CAT.B.CAT.CREATURE.2.1.full.jpg");
copyUrlToImage.put("Cat_G_1_1.jpg", "CAT.G.CAT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Cat_R_1_1.jpg", "CAT.R.CAT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Cat_Soldier_W_1_1.jpg", "CATSOLDIER.W.CATSOLDIER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Cat_W_2_2.jpg", "CAT.W.CAT.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Cat_Warrior_G_2_2.jpg", "CATWARRIOR.G.CATWARRIOR.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Centaur_G_3_3.jpg", "CENTAUR.G.CENTAUR.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Centaur_G_3_3_Enchantment.jpg", "CENTAUR.G.CENTAUR.ENCHANTMENTCREATURE.3.3.full.jpg");
copyUrlToImage.put("Centaur_G_3_3_protection.jpg", "CENTAUR.G.CENTAUR.CREATURE.3.3a.full.jpg");
copyUrlToImage.put("Citizen_W_1_1.jpg", "CITIZEN.W.CITIZEN.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Cleric_WB_1_1.jpg", "CLERIC.WB.CLERIC.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Cleric_W_2_1.jpg", "CLERIC.W.CLERIC.CREATUREENCHANTMENT.2.1.full.jpg");
copyUrlToImage.put("Cloud_Sprite_U_1_1.jpg", "CLOUDSPRITE.U.FAERIE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Clue.jpg", "CLUE..CLUE.ARTIFACT.0.0.full.jpg");
copyUrlToImage.put("Construct_1_1.jpg", "CONSTRUCT..CONSTRUCT.ARTIFACTCREATURE.1.1.full.jpg");
copyUrlToImage.put("Construct_6_12.jpg", "CONSTRUCT..CONSTRUCT.CREATUREARTIFACT.6.12.full.jpg");
copyUrlToImage.put("Demon_B_5_5.jpg", "DEMON.B.DEMON.CREATURE.5.5.full.jpg");
copyUrlToImage.put("Demon_B_y_y.jpg", "DEMON.B.DEMON.CREATURE.S.S.full.jpg");
copyUrlToImage.put("Devil_R_1_1.jpg", "DEVIL.R.DEVIL.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Djinn_5_5.jpg", "DJINN..DJINN.ARTIFACTCREATURE.5.5.full.jpg");
copyUrlToImage.put("Djinn_Monk_U_2_2.jpg", "DJINNMONK.U.DJINNMONK.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Dragon_RG_1_1.jpg", "DRAGON.RG.DRAGON.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Dragon_R_2_2.jpg", "DRAGON.R.DRAGON.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Dragon_R_4_4.jpg", "DRAGON.R.DRAGON.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Dragon_R_5_5.jpg", "DRAGON.R.DRAGON.CREATURE.5.5.full.jpg");
copyUrlToImage.put("Dragon_R_6_6.jpg", "DRAGON.R.DRAGON.CREATURE.6.6.full.jpg");
copyUrlToImage.put("Dragon_Spirit_U_5_5.jpg", "DRAGONSPIRIT.U.DRAGONSPIRIT.CREATURE.5.5.full.jpg");
copyUrlToImage.put("Drake_UG_2_2.jpg", "DRAKE.UG.DRAKE.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Drake_U_2_2.jpg", "DRAKE.U.DRAKE.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Eldrazi_10_10.jpg", "ELDRAZI..ELDRAZI.CREATURE.10.10.full.jpg");
copyUrlToImage.put("Eldrazi_Scion_1_1.jpg", "ELDRAZISCION..ELDRAZISCION.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Eldrazi_Spawn_0_1.jpg", "ELDRAZISPAWN..ELDRAZISPAWN.CREATURE.0.1.full.jpg");
copyUrlToImage.put("Elemental_BR_5_5.jpg", "ELEMENTAL.BR.ELEMENTAL.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Elemental_GW_y_y.jpg", "ELEMENTAL.WG.ELEMENTAL.CREATURE.S.S.full.jpg");
copyUrlToImage.put("Elemental_G_2_2.jpg", "ELEMENTAL.G.ELEMENTAL.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Elemental_R_3_1.jpg", "ELEMENTAL.R.ELEMENTAL.CREATURE.3.1.full.jpg");
copyUrlToImage.put("Elemental_G_4_4.jpg", "ELEMENTAL.G.ELEMENTAL.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Elemental_G_5_3.jpg", "ELEMENTAL.G.ELEMENTAL.CREATURE.5.3.full.jpg");
copyUrlToImage.put("Elemental_G_7_7.jpg", "ELEMENTAL.G.ELEMENTAL.CREATURE.7.7.full.jpg");
copyUrlToImage.put("Elemental_R_7_1.jpg", "ELEMENTAL.R.ELEMENTAL.CREATURE.7.1.full.jpg");
copyUrlToImage.put("Elemental_Shaman_R_3_1.jpg", "ELEMENTALSHAMAN.R.ELEMENTALSHAMAN.CREATURE.3.1.full.jpg");
copyUrlToImage.put("Elephant_G_3_3.jpg", "ELEPHANT.G.ELEPHANT.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Elf_Druid_G_1_1.jpg", "ELFDRUID.G.ELFDRUID.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Elf_G_1_1.jpg", "ELFWARRIOR.G.ELFWARRIOR.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Elf_Warrior_GW_1_1.jpg", "ELFWARRIOR.WG.ELFWARRIOR.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Elf_Warrior_G_1_1.jpg", "ELFWARRIOR.G.ELFWARRIOR.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Faerie_Rogue_B_1_1.jpg", "FAERIEROGUE.B.FAERIEROGUE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Faerie_Rogue_UB_1_1.jpg", "FAERIEROGUE.UB.FAERIEROGUE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Faerie_U_1_1.jpg", "FAERIE.U.FAERIE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Festering_Goblin_B_1_1.jpg", "FESTERINGGOBLIN.B.ZOMBIEGOBLIN.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Fish_U_3_3.jpg", "FISH.U.FISH.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Frog_Lizard_G_3_3.jpg", "FROGLIZARD.G.FROGLIZARD.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Gargoyle_3_4.jpg", "GARGOYLE..GARGOYLE.CREATUREARTIFACT.3.4.full.jpg");
copyUrlToImage.put("Germ_B_0_0.jpg", "GERM.B.GERM.CREATURE.0.0.full.jpg");
copyUrlToImage.put("Giant_R_4_4.jpg", "GIANT.R.GIANT.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Giant_Warrior_RG_4_4.jpg", "GIANTWARRIOR.RG.GIANTWARRIOR.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Giant_Warrior_W_5_5.jpg", "GIANTWARRIOR.W.GIANTWARRIOR.CREATURE.5.5.full.jpg");
copyUrlToImage.put("Gnome_1_1.jpg", "GNOME..GNOME.ARTIFACTCREATURE.1.1.full.jpg");
copyUrlToImage.put("Goat_W_0_1.jpg", "GOAT.W.GOAT.CREATURE.0.1.full.jpg");
copyUrlToImage.put("Goblin_R_1_1.jpg", "GOBLIN.R.GOBLIN.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Goblin_R_2_1.jpg", "GOBLIN.R.GOBLIN.CREATURE.2.1.full.jpg");
copyUrlToImage.put("Goblin_Rogue_B_1_1.jpg", "GOBLINROGUE.B.GOBLINROGUE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Goblin_Scout_R_1_1.jpg", "GOBLINSCOUT.R.GOBLINSCOUT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Goblin_Soldier_RW_1_1.jpg", "GOBLINSOLDIER.WR.GOBLINSOLDIER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Goblin_Warrior_RG_1_1.jpg", "GOBLINWARRIOR.RG.GOBLINWARRIOR.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Gold_.jpg", "GOLD...ARTIFACT.0.0.full.jpg");
copyUrlToImage.put("Goldmeadow_Harrier_W_1_1.jpg", "GOLDMEADOWHARRIER.W.KITHKINSOLDIER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Golem_3_3.jpg", "GOLEM..GOLEM.ARTIFACTCREATURE.3.3.full.jpg");
copyUrlToImage.put("Golem_3_3_Enchantment.jpg", "GOLEM..GOLEM.ENCHANTMENTARTIFACTCREATURE.3.3.full.jpg");
copyUrlToImage.put("Golem_9_9.jpg", "GOLEM..GOLEM.ARTIFACTCREATURE.9.9.full.jpg");
copyUrlToImage.put("Graveborn_BR_3_1.jpg", "GRAVEBORN.BR.GRAVEBORN.CREATURE.3.1.full.jpg");
copyUrlToImage.put("Griffin_W_2_2.jpg", "GRIFFIN.W.GRIFFIN.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Harpy_B_1_1.jpg", "HARPY.B.HARPY.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Hellion_R_4_4.jpg", "HELLION.R.HELLION.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Hippo_G_1_1.jpg", "HIPPO.G.HIPPO.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Homunculus_U_0_1.jpg", "HOMUNCULUS.U.HOMUNCULUS.CREATUREARTIFACT.0.1.full.jpg");
copyUrlToImage.put("Homunculus_U_2_2.jpg", "HOMUNCULUS.U.HOMUNCULUS.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Hornet_1_1.jpg", "HORNET..INSECT.ARTIFACTCREATURE.1.1.full.jpg");
copyUrlToImage.put("Horror_B_4_4.jpg", "HORROR.B.HORROR.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Horror_B_X_X.jpg", "HORROR.B.HORROR.CREATURE.X.X.full.jpg");
copyUrlToImage.put("Horror_UB_1_1.jpg", "HORROR.UB.HORROR.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Horror_X_X.jpg", "HORROR..HORROR.ARTIFACTCREATURE.X.X.full.jpg");
copyUrlToImage.put("Hound_G_1_1.jpg", "HOUND.G.HOUND.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Human_Cleric_WB_1_1.jpg", "HUMANCLERIC.WB.HUMANCLERIC.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Human_R_1_1.jpg", "HUMAN.R.HUMAN.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Human_Soldier_W_1_1.jpg", "HUMANSOLDIER.W.HUMANSOLDIER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Human_W_1_1.jpg", "HUMAN.W.HUMAN.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Hydra_G_X_X.jpg", "HYDRA.G.HYDRA.CREATURE.X.X.full.jpg");
copyUrlToImage.put("Illusion_U_1_1.jpg", "ILLUSION.U.ILLUSION.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Illusion_U_2_2.jpg", "ILLUSION.U.ILLUSION.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Insect_G_1_1.jpg", "INSECT.G.INSECT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Insect_G_6_1.jpg", "INSECT.G.INSECT.CREATURE.6.1.full.jpg");
copyUrlToImage.put("Kaldra_4_4.jpg", "KALDRA..AVATAR.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Kavu_B_3_3.jpg", "KAVU.B.KAVU.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Kelp_U_0_1.jpg", "KELP.U.PLANTWALL.CREATURE.0.1.full.jpg");
copyUrlToImage.put("Kithkin_Soldier_W_1_1.jpg", "KITHKINSOLDIER.W.KITHKINSOLDIER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Knight_Ally_W_2_2.jpg", "KNIGHTALLY.W.KNIGHTALLY.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Knight_B_2_2.jpg", "KNIGHT.B.KNIGHT.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Knight_W_1_1.jpg", "KNIGHT.W.KNIGHT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Knight_W_2_2.jpg", "KNIGHT.W.KNIGHT.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Kobolds_of_Kher_Keep_R_0_1.jpg", "KOBOLDSOFKHERKEEP.R.KOBOLD.CREATURE.0.1.full.jpg");
copyUrlToImage.put("Kor_Ally_W_1_1.jpg", "KORALLY.W.KORALLY.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Kor_Soldier_W_1_1.jpg", "KORSOLDIER.W.KORSOLDIER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Kraken_U_9_9.jpg", "KRAKEN.U.KRAKEN.CREATURE.9.9.full.jpg");
copyUrlToImage.put("Landmine_.jpg", "LANDMINE...ARTIFACT.0.0.full.jpg");
copyUrlToImage.put("Lightning_Ranger_R_5_1.jpg", "LIGHTNINGRAGER.R.ELEMENTAL.CREATURE.5.1.full.jpg");
copyUrlToImage.put("Lizard_G_2_2.jpg", "LIZARD.G.LIZARD.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Llanowar_Elves_G_1_1.jpg", "LLANOWARELVES.G.ELFDRUID.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Manifest_2_2.jpg", "MANIFEST.....full.jpg");
copyUrlToImage.put("Marit_Lage_B_20_20.jpg", "MARITLAGE.B.AVATAR.CREATURE.20.20.full.jpg");
copyUrlToImage.put("Merfolk_U_1_1.jpg", "MERFOLK.U.MERFOLK.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Merfolk_Wizard_U_1_1.jpg", "MERFOLKWIZARD.U.MERFOLKWIZARD.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Metallic_Sliver_1_1.jpg", "METALLICSLIVER..SLIVER.CREATUREARTIFACT.1.1.full.jpg");
copyUrlToImage.put("Minion_B_1_1.jpg", "MINION.B.MINION.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Minion_B_X_X.jpg", "MINION.B.MINION.CREATURE.X.X.full.jpg");
copyUrlToImage.put("Minor_Demon_BR_1_1.jpg", "MINORDEMON.BR.DEMON.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Minotaur_R_2_3.jpg", "MINOTAUR.R.MINOTAUR.CREATURE.2.3.full.jpg");
copyUrlToImage.put("Monk_W_1_1.jpg", "MONK.W.MONK.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Morph_2_2.jpg", "MORPH.....full.jpg");
copyUrlToImage.put("Myr_1_1.jpg", "MYR..MYR.CREATUREARTIFACT.1.1.full.jpg");
copyUrlToImage.put("Octopus_U_8_8.jpg", "OCTOPUS.U.OCTOPUS.CREATURE.8.8.full.jpg");
copyUrlToImage.put("Ogre_R_3_3.jpg", "OGRE.R.OGRE.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Ogre_R_4_4.jpg", "OGRE.R.OGRE.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Ooze_G_1_1.jpg", "OOZE.G.OOZE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Ooze_G_2_2.jpg", "OOZE.G.OOZE.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Ooze_G_3_3.jpg", "OOZE.G.OOZE.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Orb_U_X_X.jpg", "ORB.U.ORB.CREATURE.X.X.jpg.full.jpg");
copyUrlToImage.put("Pegasus_W_1_1.jpg", "PEGASUS.W.PEGASUS.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Pentavite_1_1.jpg", "PENTAVITE..PENTAVITE.ARTIFACTCREATURE.1.1.full.jpg");
copyUrlToImage.put("Pest_0_1.jpg", "PEST..PEST.ARTIFACTCREATURE.0.1.full.jpg");
copyUrlToImage.put("Pincher_2_2.jpg", "PINCHER..PINCHER.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Plant_G_0_1.jpg", "PLANT.G.PLANT.CREATURE.0.1.full.jpg");
copyUrlToImage.put("Plant_G_1_1.jpg", "PLANT.G.PLANT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Rat_B_1_1.jpg", "RAT.B.RAT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Reflection_W_2_2.jpg", "REFLECTION.W.REFLECTION.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Rhino_G_4_4.jpg", "RHINO.G.RHINO.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Rukh_R_4_4.jpg", "BIRD.R.BIRD.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Sand_1_1.jpg", "SAND..SAND.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Sand_Warrior_RGW_1_1.jpg", "SANDWARRIOR.WRG.SANDWARRIOR.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Saporling_G_1_1.jpg", "SAPROLING.G.SAPROLING.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Satyr_RG_2_2.jpg", "SATYR.RG.SATYR.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Serf_B_0_1.jpg", "SERF.B.SERF.CREATURE.0.1.full.jpg");
copyUrlToImage.put("Shapeshifter_1_1.jpg", "SHAPESHIFTER..SHAPESHIFTER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Skeleton_B_1_1.jpg", "SKELETON.B.SKELETON.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Sliver_1_1.jpg", "SLIVER..SLIVER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Snake_1_1.jpg", "SNAKE..SNAKE.ARTIFACTCREATURE.1.1.full.jpg");
copyUrlToImage.put("Snake_B_1_1.jpg", "SNAKE.B.SNAKE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Snake_GB_1_1.jpg", "SNAKE.BG.SNAKE.ENCHANTMENTCREATURE.1.1.full.jpg");
copyUrlToImage.put("Snake_GU_1_1.jpg", "SNAKE.UG.SNAKE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Snake_G_1_1.jpg", "SNAKE.G.SNAKE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Soldier_Ally_W_1_1.jpg", "SOLDIERALLY.W.SOLDIERALLY.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Soldier_RW_1_1.jpg", "SOLDIER.WR.SOLDIER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Soldier_R_1_1.jpg", "SOLDIER.R.SOLDIER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Soldier_W_1_1.jpg", "SOLDIER.W.SOLDIER.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Soldier_W_1_1_Enchantment.jpg", "SOLDIER.W.SOLDIER.ENCHANTMENTCREATURE.1.1.full.jpg");
copyUrlToImage.put("Spark_Elemental_R_3_1.jpg", "SPARKELEMENTAL.R.ELEMENTAL.CREATURE.3.1.full.jpg");
copyUrlToImage.put("Spawn_2_2.jpg", "SPAWN..SPAWN.ARTIFACTCREATURE.2.2.full.jpg");
copyUrlToImage.put("Sphinx_U_4_4.jpg", "SPHINX.U.SPHINX.CREATURE.4.4.full.jpg");
copyUrlToImage.put("Spider_B_2_4.jpg", "SPIDER.B.SPIDER.CREATURE.2.4.full.jpg");
copyUrlToImage.put("Spider_G_1_2.jpg", "SPIDER.G.SPIDER.CREATURE.1.2.full.jpg");
copyUrlToImage.put("Spider_G_1_3.jpg", "SPIDER.G.SPIDER.ENCHANTMENTCREATURE.1.3.full.jpg");
copyUrlToImage.put("Spike_G_1_1.jpg", "SPIKE.G.SPIKE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Spirit_1_1.jpg", "SPIRIT..SPIRIT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Spirit_U_1_1.jpg", "SPIRIT.U.SPIRIT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Spirit_WB_1_1.jpg", "SPIRIT.WB.SPIRIT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Spirit_WB_y_y.jpg", "SPIRIT.WB.SPIRIT.ENCHANTMENTCREATURE.S.S.full.jpg");
copyUrlToImage.put("Spirit_W_1_1.jpg", "SPIRIT.W.SPIRIT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Spirit_W_3_3.jpg", "SPIRIT.W.SPIRIT.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Spirit_Warror_BG_y_y.jpg", "SPIRITWARRIOR.BG.SPIRITWARRIOR.CREATURE.S.S.full.jpg");
copyUrlToImage.put("Squid_U_1_1.jpg", "SQUID.U.SQUID.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Squirrel_G_1_1.jpg", "SQUIRREL.G.SQUIRREL.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Stoneforged_Blade_.jpg", "STONEFORGEDBLADE..EQUIPMENT.ARTIFACT.0.0.full.jpg");
copyUrlToImage.put("Tetravite_1_1.jpg", "TETRAVITE..TETRAVITE.CREATUREARTIFACT.1.1.full.jpg");
copyUrlToImage.put("Thopter_1_1.jpg", "THOPTER..THOPTER.ARTIFACTCREATURE.1.1.full.jpg");
copyUrlToImage.put("Thopter_U_1_1.jpg", "THOPTER.U.THOPTER.CREATUREARTIFACT.1.1.full.jpg");
copyUrlToImage.put("Thrull_B_0_1.jpg", "THRULL.B.THRULL.CREATURE.0.1.full.jpg");
copyUrlToImage.put("Thrull_B_1_1.jpg", "THRULL.B.THRULL.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Treefolk_G_X_X.jpg", "TREEFOLK.G.TREEFOLK.CREATURE.X.X.full.jpg");
copyUrlToImage.put("Treefolk_Shaman_G_2_5.jpg", "TREEFOLKSHAMAN.G.TREEFOLKSHAMAN.CREATURE.2.5.full.jpg");
copyUrlToImage.put("Treefolk_Warrior_G_y_y.jpg", "TREEFOLKWARRIOR.G.TREEFOLKWARRIOR.CREATURE.S.S.full.jpg");
copyUrlToImage.put("Triskelavite_1_1.jpg", "TRISKELAVITE..TRISKELAVITE.ARTIFACTCREATURE.1.1.full.jpg");
copyUrlToImage.put("Tuktuk_the_Returned_5_5.jpg", "TUKTUKTHERETURNED..GOBLIN.ARTIFACTCREATURE.5.5.full.jpg");
copyUrlToImage.put("Urami_B_5_5.jpg", "URAMI.B.DEMONSPIRIT.CREATURE.5.5.full.jpg");
copyUrlToImage.put("Vampire_B_1_1.jpg", "VAMPIRE.B.VAMPIRE.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Vampire_B_2_2.jpg", "VAMPIRE.B.VAMPIRE.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Vampire_B_X_X.jpg", "VAMPIRE.B.VAMPIRE.CREATURE.X.X.full.jpg");
copyUrlToImage.put("Vampire_Knight_B_1_1.jpg", "VAMPIREKNIGHT.B.VAMPIREKNIGHT.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Voja_GW_2_2.jpg", "VOJA.WG.WOLF.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Wall_U_5_5.jpg", "WALL.U.WALL.CREATURE.5.5.full.jpg");
copyUrlToImage.put("Warrior_B_2_1.jpg", "WARRIOR.B.WARRIOR.CREATURE.2.1.full.jpg");
copyUrlToImage.put("Warrior_R_1_1.jpg", "WARRIOR.R.WARRIOR.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Warrior_W_1_1.jpg", "WARRIOR.W.WARRIOR.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Wasp_1_1.jpg", "WASP..INSECT.ARTIFACTCREATURE.1.1.full.jpg");
copyUrlToImage.put("Weird_U_3_3.jpg", "WEIRD.U.WEIRD.CREATURE.3.3.full.jpg");
copyUrlToImage.put("Whale_U_6_6.jpg", "WHALE.U.WHALE.CREATURE.6.6.full.jpg");
copyUrlToImage.put("Wirefly_2_2.jpg", "WIREFLY..INSECT.ARTIFACTCREATURE.2.2.full.jpg");
copyUrlToImage.put("Wolf_G_2_2.jpg", "WOLF.G.WOLF.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Wood_G_0_1.jpg", "WOOD.G.WALL.CREATURE.0.1.full.jpg");
copyUrlToImage.put("Worm_BG_1_1.jpg", "WORM.BG.WORM.CREATURE.1.1.full.jpg");
copyUrlToImage.put("Wurm_3_3.jpg", "WURM..WURM.ARTIFACTCREATURE.3.3.full.jpg");
copyUrlToImage.put("Wurm_B_6_6.jpg", "WURM.B.WURM.CREATURE.6.6.full.jpg");
copyUrlToImage.put("Wurm_G_6_6.jpg", "WURM.G.WURM.CREATURE.6.6.full.jpg");
copyUrlToImage.put("Zombie_B_2_2.jpg", "ZOMBIE.B.ZOMBIE.CREATURE.2.2.full.jpg");
copyUrlToImage.put("Zombie_B_2_2_Enchantment.jpg", "ZOMBIE.B.ZOMBIE.ENCHANTMENTCREATURE.2.2.full.jpg");
copyUrlToImage.put("Zombie_B_5_5.jpg", "ZOMBIEGIANT.B.ZOMBIEGIANT.CREATURE.5.5.full.jpg");
copyUrlToImage.put("Zombie_B_X_X.jpg", "ZOMBIE.B.ZOMBIE.CREATURE.X.X.full.jpg");
copyUrlToImage.put("Zombie_Horror_B_X_X.jpg", "ZOMBIEHORROR.B.ZOMBIEHORROR.CREATURE.X.X.full.jpg");
copyUrlToImage.put("Zombie_U_X_X.jpg", "ZOMBIE.U.ZOMBIE.CREATURE.X.X.full.jpg");
copyUrlToImage.put("Zombie_Wizard_UB_1_1.jpg", "ZOMBIEWIZARD.UB.ZOMBIEWIZARD.CREATURE.1.1.full.jpg");
for (String key : copyUrlToImage.keySet()) {
copyUrlToImageDone.put(key, maxTimes);
copyImageToUrl.put(copyUrlToImage.get(key), key);
}
}
@Override
public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
if (copyUrlToImage == null) {
setupLinks();
}
return null;
}
@Override
public int getTotalImages() {
if (copyUrlToImage == null) {
setupLinks();
}
if (copyUrlToImage != null) {
return copyImageToUrl.size();
}
return -1;
}
@Override
public boolean isTokenSource() {
return true;
}
@Override
public boolean isCardSource() {
return false;
}
@Override
public void doPause(String httpImageUrl) {
}
@Override
public boolean isCardImageProvided(String setCode, String cardName) {
return false;
}
@Override
public boolean isTokenImageProvided(String setCode, String cardName, Integer tokenNumber) {
return true;
}
}

View file

@ -1,466 +0,0 @@
package org.mage.plugins.card.dl.sources;
import mage.client.MageFrame;
import mage.remote.Connection;
import mage.remote.Connection.ProxyType;
import mage.util.CardUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.mage.plugins.card.dl.DownloadServiceInfo;
import org.mage.plugins.card.images.CardDownloadData;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.*;
import java.util.prefs.Preferences;
/**
* @author LevelX2
*/
public enum MythicspoilerComSource implements CardImageSource {
instance;
private final Map<String, String> setsAliases;
private final Map<String, String> cardNameAliases;
private final Map<String, Set<String>> cardNameAliasesStart;
private final Map<String, Map<String, String>> sets;
private final Set<String> supportedSets;
private final Map<String, Map<String, String>> manualLinks;
@Override
public String getSourceName() {
return "mythicspoiler.com";
}
MythicspoilerComSource() {
supportedSets = new LinkedHashSet<>();
// 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("W17");
supportedSets.add("AKH");
supportedSets.add("MPS");
supportedSets.add("CMA");
supportedSets.add("E01");
supportedSets.add("HOU");
supportedSets.add("C17");
supportedSets.add("IMA");
supportedSets.add("XLN");
supportedSets.add("UST");
supportedSets.add("RIX");
supportedSets.add("DOM");
supportedSets.add("BBD");
supportedSets.add("M19");
supportedSets.add("C18");
supportedSets.add("CM2");
supportedSets.add("GRN");
sets = new LinkedHashMap<>();
setsAliases = new HashMap<>();
setsAliases.put("exp", "bfz");
setsAliases.put("xln", "ixa");
setsAliases.put("nem", "nms");
cardNameAliases = new HashMap<>();
// set+wrong name from web side => correct card name
cardNameAliases.put("MM2-otherwordlyjourney", "otherworldlyjourney");
cardNameAliases.put("THS-fellhideminotaur", "felhideminotaur");
cardNameAliases.put("THS-purphorosemissary", "purphorossemissary");
cardNameAliases.put("THS-soldierofpantheon", "soldierofthepantheon");
cardNameAliases.put("THS-vulpinegolaith", "vulpinegoliath");
cardNameAliases.put("ORI-kothopedhoarderofsouls", "kothophedsoulhoarder");
cardNameAliases.put("BFZ-kozliekschanneler", "kozilekschanneler");
cardNameAliases.put("OGW-wastes", "wastes1");
cardNameAliases.put("OGW-wastes2", "wastes2");
cardNameAliases.put("AER-aegisautomation", "aegisautomaton");
cardNameAliases.put("AKH-illusorywrappins", "illusorywrappings");
cardNameAliases.put("AKH-reducerumble", "reducerubble");
cardNameAliases.put("AKH-forsakethewordly", "forsaketheworldly");
cardNameAliases.put("AKH-kefnatsmonument", "kefnetsmonument");
cardNameAliases.put("XLN-kinjaliscaller", "kinjalliscaller");
cardNameAliases.put("XLN-lookoutsdecision", "lookoutsdispersal");
cardNameAliases.put("XLN-infuriatedgladiodon", "ragingswordtooth");
cardNameAliases.put("XLN-redoubledvolley", "repeatingbarrage");
cardNameAliases.put("UST-captialoffense", "capitaloffense");
cardNameAliases.put("RIX-tetzimocdeathprimordial", "tetzimocprimaldeath");
// <card name, card link>
manualLinks = new HashMap<>();
Map<String, String> links = new HashMap<>();
links.put("templeofaclazotz", "templeofaclazotz");
links.put("conquerorsfoothold", "conquerorsfoothold");
links.put("primalwellspring", "primalwellspring");
links.put("azcantathesunkenruin", "azcantathesunkenruin");
links.put("spiresoforazca", "spiresoforazca");
links.put("treasurecove", "treasurecove");
links.put("itlimoccradleofthesun", "itlimoccradleofthesun");
links.put("lostvale", "lostvale");
links.put("adantothefirstfort", "adantothefirstport");
links.put("spitfirebastion", "spitfirebastion");
manualLinks.put("XLN", links);
Map<String, String> linksRix = new HashMap<>();
linksRix.put("vaultofcatlacan", "vaultofcatlacan");
linksRix.put("atzalcaveofeternity", "atzalcaveofeternity");
linksRix.put("wingedtempleoforazca", "wingedtempleoforazca");
linksRix.put("metzalitoweroftriumph", "metzalitoweroftriumph");
linksRix.put("tomboftheduskrose", "tomboftheduskrose");
linksRix.put("sanctumofthesun", "sanctumofthesun");
linksRix.put("goldforgegarrison", "goldforgegarrison");
manualLinks.put("RIX", linksRix);
cardNameAliasesStart = new HashMap<>();
Set<String> names = new HashSet<>();
names.add("eldrazidevastator.jpg");
cardNameAliasesStart.put("BFZ", names);
}
private Map<String, String> getSetLinks(String cardSet) {
Map<String, String> setLinks = new HashMap<>();
try {
String setNames = setsAliases.get(cardSet.toLowerCase(Locale.ENGLISH));
Set<String> aliasesStart = new HashSet<>();
if (cardNameAliasesStart.containsKey(cardSet)) {
aliasesStart.addAll(cardNameAliasesStart.get(cardSet));
}
if (setNames == null) {
setNames = cardSet.toLowerCase(Locale.ENGLISH);
}
Preferences prefs = MageFrame.getPreferences();
Connection.ProxyType proxyType = Connection.ProxyType.valueByText(prefs.get("proxyType", "None"));
for (String setName : setNames.split("\\^")) {
String URLSetName = CardUtil.urlEncode(setName);
String baseUrl = "http://mythicspoiler.com/" + URLSetName + '/';
Map<String, String> pageLinks = getSetLinksFromPage(cardSet, aliasesStart, prefs, proxyType, baseUrl, baseUrl);
setLinks.putAll(pageLinks);
// try to download images for double-faced cards
try {
String doubleFacedUrl = baseUrl + "dfc.html";
pageLinks = getSetLinksFromPage(cardSet, aliasesStart, prefs, proxyType, baseUrl, doubleFacedUrl);
setLinks.putAll(pageLinks);
} catch (Exception ex) {
// that's ok if we cannot download double-faced cards for some sets
}
}
} catch (IOException ex) {
System.out.println("Exception when parsing the mythicspoiler page: " + ex.getMessage());
}
return setLinks;
}
private Map<String, String> getSetLinksFromPage(String cardSet, Set<String> aliasesStart, Preferences prefs,
ProxyType proxyType, String baseUrl, String pageUrl) throws IOException {
Map<String, String> pageLinks = new HashMap<>();
String urlDocument;
Document doc;
if (proxyType == ProxyType.NONE) {
urlDocument = pageUrl;
doc = Jsoup.connect(urlDocument).get();
} else {
String proxyServer = prefs.get("proxyAddress", "");
int proxyPort = Integer.parseInt(prefs.get("proxyPort", "0"));
URL url = new URL(pageUrl);
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, proxyPort));
HttpURLConnection uc = (HttpURLConnection) url.openConnection(proxy);
uc.connect();
String line;
StringBuffer tmp = new StringBuffer();
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
while ((line = in.readLine()) != null) {
tmp.append(line);
}
doc = Jsoup.parse(String.valueOf(tmp));
}
Elements cardsImages = doc.select("img[src^=cards/]"); // starts with cards/
if (!aliasesStart.isEmpty()) {
for (String text : aliasesStart) {
cardsImages.addAll(doc.select("img[src^=" + text + ']'));
}
}
for (Element cardsImage : cardsImages) {
String cardLink = cardsImage.attr("src");
String cardName = null;
if (cardLink.startsWith("cards/") && cardLink.endsWith(".jpg")) {
cardName = cardLink.substring(6, cardLink.length() - 4);
} else if (aliasesStart.contains(cardLink)) {
cardName = cardLink.substring(0, cardLink.length() - 4);
}
if (cardName != null && !cardName.isEmpty()) {
if (cardNameAliases.containsKey(cardSet + '-' + cardName)) {
cardName = cardNameAliases.get(cardSet + '-' + cardName);
} else if (cardName.endsWith("1") || cardName.endsWith("2") || cardName.endsWith("3") || cardName.endsWith("4") || cardName.endsWith("5")) {
cardName = cardName.substring(0, cardName.length() - 1);
} else if (cardName.endsWith("promo")) {
cardName = cardName.substring(0, cardName.length() - 5);
}
pageLinks.put(cardName, baseUrl + cardLink);
}
}
Map<String, String> linksToAdd = manualLinks.get(cardSet);
if (linksToAdd != null) {
for (Map.Entry<String, String> link : linksToAdd.entrySet()) {
pageLinks.put(link.getKey(), baseUrl + "cards/" + link.getValue() + ".jpg");
}
}
return pageLinks;
}
@Override
public boolean prepareDownloadList(DownloadServiceInfo downloadServiceInfo, List<CardDownloadData> downloadList) {
return true;
}
@Override
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
String collectorId = card.getCollectorId();
String cardSet = card.getSet();
if (collectorId == null || cardSet == null) {
throw new Exception("Wrong parameters for image: collector id: " + collectorId + ", card set: " + cardSet);
}
if (card.isFlippedSide()) { //doesn't support rotated images
return null;
}
Map<String, String> setLinks = sets.computeIfAbsent(cardSet, k -> getSetLinks(cardSet));
String searchName = card.getDownloadName().toLowerCase(Locale.ENGLISH)
.replaceAll(" ", "")
.replaceAll("\\.", "")
.replaceAll("&", "and")
.replaceAll("-", "")
.replaceAll("'", "")
.replaceAll(",", "")
.replaceAll("/", "");
String link = setLinks.get(searchName);
return new CardImageUrls(link);
}
@Override
public CardImageUrls generateTokenUrl(CardDownloadData card
) {
return null;
}
@Override
public float getAverageSize() {
return 50.0f;
}
@Override
public String getNextHttpImageUrl() {
return null;
}
@Override
public String getFileForHttpImage(String httpImageUrl) {
return null;
}
@Override
public int getTotalImages() {
return -1;
}
@Override
public boolean isTokenSource() {
return false;
}
@Override
public boolean isCardSource() {
return true;
}
@Override
public void doPause(String httpImageUrl) {
}
@Override
public List<String> getSupportedSets() {
return new ArrayList<>(supportedSets);
}
@Override
public boolean isCardImageProvided(String setCode, String cardName) {
return supportedSets.contains(setCode);
}
}

View file

@ -295,7 +295,7 @@ public class ScryfallImageSource implements CardImageSource {
@Override
public String getSourceName() {
return "scryfall.com";
return "scryfall.com - big";
}
@Override

View file

@ -27,6 +27,11 @@ public class ScryfallImageSourceSmall extends ScryfallImageSource {
return new CardImageUrls(downloadUrls);
}
@Override
public String getSourceName() {
return "scryfall.com - small";
}
@Override
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
return innerModifyUrl(super.generateCardUrl(card));

View file

@ -1,317 +0,0 @@
package org.mage.plugins.card.dl.sources;
import mage.constants.SubType;
import org.apache.log4j.Logger;
import org.mage.plugins.card.dl.DownloadServiceInfo;
import org.mage.plugins.card.images.CardDownloadData;
import org.mage.plugins.card.images.DownloadPicturesService;
import org.mage.plugins.card.utils.CardImageUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
/**
* @author Quercitron
*/
public enum TokensMtgImageSource implements CardImageSource {
instance;
private static final Logger LOGGER = Logger.getLogger(TokensMtgImageSource.class);
// [[EXP/Name, TokenData>
private HashMap<String, List<TokenData>> tokensData;
private static final Set<String> supportedSets = new LinkedHashSet<>();
private final Object tokensDataSync = new Object();
@Override
public String getSourceName() {
return "tokens.mtg.onl";
}
@Override
public float getAverageSize() {
return 26.7f;
}
@Override
public String getNextHttpImageUrl() {
return null;
}
@Override
public String getFileForHttpImage(String httpImageUrl) {
return null;
}
@Override
public boolean prepareDownloadList(DownloadServiceInfo downloadServiceInfo, List<CardDownloadData> downloadList) {
return true;
}
@Override
public CardImageUrls generateCardUrl(CardDownloadData card) throws Exception {
return null;
}
private static final Map<String, String> SET_NAMES_REPLACEMENT = new HashMap<String, String>() {
{
put("con", "CFX");
put("fnmp", "FNM");
}
};
private String getEmblemName(String originalName) {
for (SubType subType : SubType.getPlaneswalkerTypes()) {
if (originalName.toLowerCase(Locale.ENGLISH).contains(subType.toString().toLowerCase(Locale.ENGLISH))) {
return subType.getDescription() + " Emblem";
}
}
return null;
}
@Override
public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
String name = card.getName();
String set = card.getSet();
int imageNumber = card.getImageNumber();
// handle emblems
if (name.toLowerCase(Locale.ENGLISH).contains("emblem")) {
name = getEmblemName(name);
}
// we should replace some set names
if (SET_NAMES_REPLACEMENT.containsKey(set.toLowerCase(Locale.ENGLISH))) {
set = SET_NAMES_REPLACEMENT.get(set.toLowerCase(Locale.ENGLISH));
}
// Image URL contains token number
// e.g. https://tokens.mtg.onl/tokens/ORI_010-Thopter.jpg -- token number 010
// We don't know these numbers, but we can take them from a file
// with tokens information that can be downloaded from the site.
if (tokensData.isEmpty()) {
LOGGER.info("Source " + getSourceName() + " provides no token data.");
return null;
}
String key = set + "/" + name;
List<TokenData> list = tokensData.get(key);
if (list == null) {
LOGGER.warn("Could not find data for token " + name + ", set " + set + ".");
return null;
}
TokenData tokenData;
if (imageNumber == 0) {
tokenData = list.get(0);
} else {
if (imageNumber > list.size()) {
LOGGER.warn("Not enough images variants for token with type number " + imageNumber + ", name " + name + ", set " + set + '.');
return null;
}
tokenData = list.get(card.getImageNumber() - 1);
}
String url = "https://tokens.mtg.onl/tokens/" + tokenData.getExpansionSetCode().trim() + '_'
+ tokenData.getNumber().trim() + '-' + tokenData.getName().trim() + ".jpg";
url = url.replace(' ', '-');
return new CardImageUrls(url);
}
@Override
public int getTotalImages() {
return getTokenImages();
}
@Override
public int getTokenImages() {
try {
getTokensData();
} catch (IOException ex) {
LOGGER.error(getSourceName() + ": Loading available data failed. " + ex.getMessage());
}
return tokensData.size();
}
@Override
public boolean isTokenSource() {
return true;
}
@Override
public boolean isCardSource() {
return false;
}
@Override
public void doPause(String httpImageUrl) {
}
@Override
public List<String> getSupportedSets() {
return new ArrayList<>(supportedSets);
}
@Override
public boolean isCardImageProvided(String setCode, String cardName) {
// no cards support, only tokens
return false;
}
@Override
public boolean isTokenImageProvided(String setCode, String cardName, Integer tokenNumber) {
String searchName = cardName;
if (cardName.toLowerCase(Locale.ENGLISH).contains("emblem")) {
searchName = getEmblemName(cardName);
}
try {
getTokensData();
} catch (IOException ex) {
LOGGER.error(ex.getMessage(), ex);
}
String key = setCode + "/" + searchName;
return (tokensData.containsKey(key));
}
private HashMap<String, List<TokenData>> getTokensData() throws IOException {
synchronized (tokensDataSync) {
if (tokensData == null) {
DownloadPicturesService.getInstance().updateGlobalMessage("Find tokens data...");
tokensData = new HashMap<>();
// get tokens data from resource file
try (InputStream inputStream = this.getClass().getResourceAsStream("/tokens-mtg-onl-list.csv")) {
List<TokenData> fileTokensData = parseTokensData(inputStream);
for (TokenData tokenData : fileTokensData) {
String key = tokenData.getExpansionSetCode() + "/" + tokenData.getName();
List<TokenData> list = tokensData.get(key);
if (list == null) {
list = new ArrayList<>();
tokensData.put(key, list);
supportedSets.add(tokenData.getExpansionSetCode());
LOGGER.debug("Added key: " + key);
}
list.add(tokenData);
}
} catch (Exception exception) {
LOGGER.warn("Failed to get tokens description from resource file tokens-mtg-onl-list.csv", exception);
}
String urlString = "http://tokens.mtg.onl/data/SetsWithTokens.csv";
Proxy proxy = CardImageUtils.getProxyFromPreferences();
URLConnection conn = proxy == null ? new URL(urlString).openConnection() : new URL(urlString).openConnection(proxy);
// description on site may contain new information
// try to add it
try (InputStream inputStream = conn.getURL().openStream()) {
List<TokenData> siteTokensData = parseTokensData(inputStream);
for (TokenData siteData : siteTokensData) {
// logger.info("TOK: " + siteData.getExpansionSetCode() + "/" + siteData.getName());
String key = siteData.getExpansionSetCode() + "/" + siteData.getName();
supportedSets.add(siteData.getExpansionSetCode());
List<TokenData> list = tokensData.get(key);
if (list == null) {
list = new ArrayList<>();
tokensData.put(key, list);
list.add(siteData);
} else {
boolean newToken = true;
for (TokenData tokenData : list) {
if (siteData.getNumber().equals(tokenData.number)) {
newToken = false;
break;
}
}
if (newToken) {
list.add(siteData);
}
}
}
DownloadPicturesService.getInstance().updateGlobalMessage("");
DownloadPicturesService.getInstance().showDownloadControls(true);
} catch (Exception ex) {
LOGGER.warn("Failed to get tokens description from tokens.mtg.onl", ex);
DownloadPicturesService.getInstance().updateGlobalMessage(ex.getMessage());
}
}
}
return tokensData;
}
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)) {
// we have to specify encoding to read special comma
String header = reader.readLine(); // skip header
String line = reader.readLine();
// states
// 0 - wait set name
// 1 - wait cards
// 2 - process cards
int state = 0;
String set = null;
while (line != null) {
if (line.trim().isEmpty()) {
if (state == 2) {
state = 0;
}
} else if (state == 0) {
set = line.substring(0, 3);
state = 1;
} else {
if (state == 1) {
state = 2;
}
String[] split = line.split(",");
// replace special comma for cards like 'Ashaya the Awoken World'
String name = split[0].replace('', ',').replace("‚", ",");
String number = split[1];
TokenData token = new TokenData(name, number, set);
newTokensData.add(token);
}
line = reader.readLine();
}
}
return newTokensData;
}
static final class TokenData {
final private String name;
final private String number;
final private String expansionSetCode;
public TokenData(String name, String number, String expansionSetCode) {
this.name = name;
this.number = number;
this.expansionSetCode = expansionSetCode;
}
public String getName() {
return name;
}
public String getNumber() {
return number;
}
public String getExpansionSetCode() {
return expansionSetCode;
}
}
}

View file

@ -74,16 +74,11 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
private Proxy proxy = Proxy.NO_PROXY;
enum DownloadSources {
WIZARDS("1. wizards.com - low quality CARDS, multi-language, slow download", WizardCardsImageSource.instance),
TOKENS("2. tokens.mtg.onl - high quality TOKENS", TokensMtgImageSource.instance),
SCRYFALL("3. scryfall.com - high quality CARDS and TOKENS, multi-language", ScryfallImageSource.getInstance()),
SCRYFALL_SMALL("3a. scryfall.com small images - low quality CARDS and TOKENS, multi-language", ScryfallImageSourceSmall.getInstance()),
MAGIDEX("4. magidex.com - high quality CARDS", MagidexImageSource.instance),
GRAB_BAG("5. GrabBag - STAR WARS cards and tokens", GrabbagImageSource.instance),
MYTHICSPOILER("6. mythicspoiler.com", MythicspoilerComSource.instance),
ALTERNATIVE("7. alternative.mtg.onl", AltMtgOnlTokensImageSource.instance),
COPYPASTE("8. Copy and Paste Image URLs", CopyPasteImageSource.instance);
// MTG_ONL("mtg.onl", MtgOnlTokensImageSource.instance), Not working correctly yet
WIZARDS("1. wizards.com - low quality, cards only, multi-language", WizardCardsImageSource.instance),
SCRYFALL_BIG("2a. scryfall.com - BIG: high quality, multi-language", ScryfallImageSource.getInstance()),
SCRYFALL_SMALL("2b. scryfall.com - small: low quality, multi-language", ScryfallImageSourceSmall.getInstance()),
GRAB_BAG("3. GrabBag - unofficial STAR WARS cards and tokens", GrabbagImageSource.instance),
COPYPASTE("4. Experimental - copy and paste image URLs", CopyPasteImageSource.instance); // TODO: need rework for user friendly GUI
private final String text;
private final CardImageSource source;
@ -164,7 +159,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
// SOURCES - scryfall is default source
uiDialog.getSourcesCombo().setModel(new DefaultComboBoxModel(DownloadSources.values()));
uiDialog.getSourcesCombo().setSelectedItem(DownloadSources.SCRYFALL);
uiDialog.getSourcesCombo().setSelectedItem(DownloadSources.SCRYFALL_BIG);
selectedSource = ScryfallImageSource.getInstance();
uiDialog.getSourcesCombo().addItemListener((ItemEvent event) -> {
if (event.getStateChange() == ItemEvent.SELECTED) {