* Images: added localized card images download from scryfall source;

This commit is contained in:
Oleg Agafonov 2018-06-23 16:27:34 +04:00
parent 39075e000f
commit 6c20ee4a74
14 changed files with 230 additions and 93 deletions

View file

@ -8,7 +8,6 @@ import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public enum AltMtgOnlTokensImageSource implements CardImageSource { public enum AltMtgOnlTokensImageSource implements CardImageSource {
@ -60,7 +59,7 @@ public enum AltMtgOnlTokensImageSource implements CardImageSource {
} }
@Override @Override
public String generateURL(CardDownloadData card) throws Exception { public CardImageUrls generateURL(CardDownloadData card) throws Exception {
return null; return null;
} }
@ -122,7 +121,7 @@ public enum AltMtgOnlTokensImageSource implements CardImageSource {
} }
@Override @Override
public String generateTokenUrl(CardDownloadData card) throws IOException { public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
if (copyUrlToImage == null) { if (copyUrlToImage == null) {
setupLinks(); setupLinks();
} }

View file

@ -9,9 +9,9 @@ import org.mage.plugins.card.images.CardDownloadData;
*/ */
public interface CardImageSource { public interface CardImageSource {
String generateURL(CardDownloadData card) throws Exception; CardImageUrls generateURL(CardDownloadData card) throws Exception;
String generateTokenUrl(CardDownloadData card) throws Exception; CardImageUrls generateTokenUrl(CardDownloadData card) throws Exception;
String getNextHttpImageUrl(); String getNextHttpImageUrl();

View file

@ -0,0 +1,59 @@
package org.mage.plugins.card.dl.sources;
import java.util.ArrayList;
import java.util.List;
/**
* @author JayDi85
*/
public class CardImageUrls {
public String baseUrl;
public List<String> alternativeUrls;
public CardImageUrls() {
this.baseUrl = null;
this.alternativeUrls = new ArrayList<>();
}
public CardImageUrls(String baseUrl) {
this(baseUrl, null);
}
public CardImageUrls(String baseUrl, String alternativeUrl) {
this();
this.baseUrl = baseUrl;
if (alternativeUrl != null && !alternativeUrl.isEmpty()) {
this.alternativeUrls.add(alternativeUrl);
}
}
public List<String> getDownloadList() {
List<String> downloadUrls = new ArrayList<>();
if (this.baseUrl != null && !this.baseUrl.isEmpty()) {
downloadUrls.add(this.baseUrl);
}
// no needs in base url duplicate
if (this.alternativeUrls != null) {
for (String url : this.alternativeUrls) {
if (!url.equals(this.baseUrl)) {
downloadUrls.add(url);
}
}
}
return downloadUrls;
}
public void addAlternativeUrl(String url) {
if (url != null && !url.isEmpty()) {
this.alternativeUrls.add(url);
} else {
throw new IllegalArgumentException();
}
}
}

View file

@ -8,11 +8,11 @@ import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public enum GrabbagImageSource implements CardImageSource { public enum GrabbagImageSource implements CardImageSource {
@ -48,7 +48,7 @@ public enum GrabbagImageSource implements CardImageSource {
} }
@Override @Override
public String generateURL(CardDownloadData card) throws Exception { public CardImageUrls generateURL(CardDownloadData card) throws Exception {
if (singleLinks == null) { if (singleLinks == null) {
setupLinks(); setupLinks();
} }
@ -63,7 +63,7 @@ public enum GrabbagImageSource implements CardImageSource {
} }
if (url != null) { if (url != null) {
return getSourceName(card, url) + url; return new CardImageUrls(getSourceName(card, url) + url);
} }
return null; return null;
} }
@ -375,7 +375,7 @@ public enum GrabbagImageSource implements CardImageSource {
} }
@Override @Override
public String generateTokenUrl(CardDownloadData card) throws IOException { public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
try { try {
return generateURL(card); return generateURL(card);
} catch (Exception ex) { } catch (Exception ex) {

View file

@ -6,12 +6,12 @@ import java.util.LinkedHashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
import org.mage.plugins.card.utils.CardImageUtils; import org.mage.plugins.card.utils.CardImageUtils;
/** /**
*
* @author North * @author North
*/ */
public enum MagicCardsImageSource implements CardImageSource { public enum MagicCardsImageSource implements CardImageSource {
@ -342,6 +342,7 @@ public enum MagicCardsImageSource implements CardImageSource {
put("WWK", "worldwake"); put("WWK", "worldwake");
put("ZEN", "zendikar"); put("ZEN", "zendikar");
} }
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
}; };
@ -361,7 +362,7 @@ public enum MagicCardsImageSource implements CardImageSource {
} }
@Override @Override
public String generateURL(CardDownloadData card) throws Exception { public CardImageUrls generateURL(CardDownloadData card) throws Exception {
String collectorId = card.getCollectorId(); String collectorId = card.getCollectorId();
String cardSet = card.getSet(); String cardSet = card.getSet();
if (collectorId == null || cardSet == null) { if (collectorId == null || cardSet == null) {
@ -389,11 +390,11 @@ public enum MagicCardsImageSource implements CardImageSource {
} }
url.append(".jpg"); url.append(".jpg");
return url.toString(); return new CardImageUrls(url.toString());
} }
@Override @Override
public String generateTokenUrl(CardDownloadData card) { public CardImageUrls generateTokenUrl(CardDownloadData card) {
String name = card.getName(); String name = card.getName();
// add type to name if it's not 0 // add type to name if it's not 0
if (card.getType() > 0) { if (card.getType() > 0) {
@ -406,7 +407,7 @@ public enum MagicCardsImageSource implements CardImageSource {
} else { } else {
set += '-' + card.getSet(); set += '-' + card.getSet();
} }
return "http://magiccards.info/extras/token/" + set + '/' + name + ".jpg"; return new CardImageUrls("http://magiccards.info/extras/token/" + set + '/' + name + ".jpg");
} }
@Override @Override

View file

@ -8,10 +8,10 @@ import java.util.LinkedHashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
/** /**
*
* @author Pete Rossi * @author Pete Rossi
*/ */
public enum MagidexImageSource implements CardImageSource { public enum MagidexImageSource implements CardImageSource {
@ -233,7 +233,7 @@ public enum MagidexImageSource implements CardImageSource {
} }
@Override @Override
public String generateURL(CardDownloadData card) throws Exception { public CardImageUrls generateURL(CardDownloadData card) throws Exception {
String cardDownloadName = card.getDownloadName().toLowerCase(Locale.ENGLISH); String cardDownloadName = card.getDownloadName().toLowerCase(Locale.ENGLISH);
String cardSet = card.getSet(); String cardSet = card.getSet();
@ -247,7 +247,7 @@ public enum MagidexImageSource implements CardImageSource {
// This will properly escape the url // This will properly escape the url
URI uri = new URI("http", "magidex.com", "/extstatic/card/" + formatSetName(cardSet) + '/' + cardDownloadName + ".jpg", null, null); URI uri = new URI("http", "magidex.com", "/extstatic/card/" + formatSetName(cardSet) + '/' + cardDownloadName + ".jpg", null, null);
return uri.toASCIIString(); return new CardImageUrls(uri.toASCIIString());
} }
private String formatSetName(String setName) { private String formatSetName(String setName) {
@ -264,7 +264,7 @@ public enum MagidexImageSource implements CardImageSource {
}; };
@Override @Override
public String generateTokenUrl(CardDownloadData card) { public CardImageUrls generateTokenUrl(CardDownloadData card) {
return null; return null;
} }

View file

@ -2,14 +2,12 @@
package org.mage.plugins.card.dl.sources; package org.mage.plugins.card.dl.sources;
import java.util.Locale; import java.util.Locale;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
/** /**
* Site was shutdown by wizards Feb. 2015 * Site was shutdown by wizards Feb. 2015
* *
*
*
*
* @author LevelX2 * @author LevelX2
*/ */
public enum MtgImageSource implements CardImageSource { public enum MtgImageSource implements CardImageSource {
@ -32,7 +30,7 @@ public enum MtgImageSource implements CardImageSource {
} }
@Override @Override
public String generateURL(CardDownloadData card) throws Exception { public CardImageUrls generateURL(CardDownloadData card) throws Exception {
String collectorId = card.getCollectorId(); String collectorId = card.getCollectorId();
String cardSet = card.getSet(); String cardSet = card.getSet();
if (collectorId == null || cardSet == null) { if (collectorId == null || cardSet == null) {
@ -59,11 +57,11 @@ public enum MtgImageSource implements CardImageSource {
} }
url.append(".jpg"); url.append(".jpg");
return url.toString(); return new CardImageUrls(url.toString());
} }
@Override @Override
public String generateTokenUrl(CardDownloadData card) { public CardImageUrls generateTokenUrl(CardDownloadData card) {
return null; return null;
} }

View file

@ -3,11 +3,11 @@ package org.mage.plugins.card.dl.sources;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public enum MtgOnlTokensImageSource implements CardImageSource { public enum MtgOnlTokensImageSource implements CardImageSource {
@ -59,7 +59,7 @@ public enum MtgOnlTokensImageSource implements CardImageSource {
} }
@Override @Override
public String generateURL(CardDownloadData card) throws Exception { public CardImageUrls generateURL(CardDownloadData card) throws Exception {
return null; return null;
} }
@ -324,7 +324,7 @@ public enum MtgOnlTokensImageSource implements CardImageSource {
} }
@Override @Override
public String generateTokenUrl(CardDownloadData card) throws IOException { public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
if (copyUrlToImage == null) { if (copyUrlToImage == null) {
setupLinks(); setupLinks();
} }

View file

@ -18,6 +18,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.remote.Connection; import mage.remote.Connection;
import mage.remote.Connection.ProxyType; import mage.remote.Connection.ProxyType;
@ -28,7 +29,6 @@ import org.jsoup.select.Elements;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public enum MythicspoilerComSource implements CardImageSource { public enum MythicspoilerComSource implements CardImageSource {
@ -391,7 +391,7 @@ public enum MythicspoilerComSource implements CardImageSource {
} }
@Override @Override
public String generateURL(CardDownloadData card) throws Exception { public CardImageUrls generateURL(CardDownloadData card) throws Exception {
String collectorId = card.getCollectorId(); String collectorId = card.getCollectorId();
String cardSet = card.getSet(); String cardSet = card.getSet();
if (collectorId == null || cardSet == null) { if (collectorId == null || cardSet == null) {
@ -410,11 +410,11 @@ public enum MythicspoilerComSource implements CardImageSource {
.replaceAll(",", "") .replaceAll(",", "")
.replaceAll("/", ""); .replaceAll("/", "");
String link = setLinks.get(searchName); String link = setLinks.get(searchName);
return link; return new CardImageUrls(link);
} }
@Override @Override
public String generateTokenUrl(CardDownloadData card public CardImageUrls generateTokenUrl(CardDownloadData card
) { ) {
return null; return null;
} }

View file

@ -6,19 +6,34 @@ import java.util.LinkedHashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import mage.client.dialog.PreferencesDialog;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
/** /**
* @author Quercitron, JayDi85 * @author Quercitron, JayDi85
*
*/ */
public enum ScryfallImageSource implements CardImageSource { public enum ScryfallImageSource implements CardImageSource {
instance; instance;
private final Set<String> supportedSets; private final Set<String> supportedSets;
private final Map<String, String> languageAliases;
ScryfallImageSource() { ScryfallImageSource() {
// https://scryfall.com/docs/api/languages
languageAliases = new HashMap<>();
languageAliases.put("en", "en");
languageAliases.put("es", "es");
languageAliases.put("jp", "ja");
languageAliases.put("it", "it");
languageAliases.put("fr", "fr");
languageAliases.put("cn", "zhs"); // Simplified Chinese
languageAliases.put("de", "de");
languageAliases.put("ko", "ko");
languageAliases.put("pt", "pt");
languageAliases.put("ru", "ru");
supportedSets = new LinkedHashSet<>(); supportedSets = new LinkedHashSet<>();
// supportedSets.add("PTC"); // // supportedSets.add("PTC"); //
supportedSets.add("LEA"); supportedSets.add("LEA");
@ -214,33 +229,52 @@ public enum ScryfallImageSource implements CardImageSource {
supportedSets.add("BBD"); supportedSets.add("BBD");
// supportedSets.add("CM2"); // supportedSets.add("CM2");
supportedSets.add("M19"); supportedSets.add("M19");
} }
@Override @Override
public String generateURL(CardDownloadData card) throws Exception { public CardImageUrls generateURL(CardDownloadData card) throws Exception {
String preferredLanguage = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_CARD_IMAGES_PREF_LANGUAGE, "en");
String defaultCode = "en";
String localizedCode = languageAliases.getOrDefault(preferredLanguage, defaultCode);
// loc example: https://api.scryfall.com/cards/xln/121/ru?format=image
// TODO: do not use API at all? It's can help with scryfall request limits (1 request instead 2)
String baseUrl = null;
String alternativeUrl = null;
// special card number like "103a" already compatible // special card number like "103a" already compatible
if (card.isCollectorIdWithStr()) { if (baseUrl == null && card.isCollectorIdWithStr()) {
return "https://img.scryfall.com/cards/large/en/" + formatSetName(card.getSet()) + "/" baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet()) + "/"
+ card.getCollectorId() + ".jpg";
alternativeUrl = "https://img.scryfall.com/cards/large/" + defaultCode + "/" + formatSetName(card.getSet()) + "/"
+ card.getCollectorId() + ".jpg"; + card.getCollectorId() + ".jpg";
} }
// double faced cards do not supporte by API (need direct link for img) // double faced cards do not supports by API (need direct link for img)
// example: https://img.scryfall.com/cards/large/en/xln/173b.jpg // example: https://img.scryfall.com/cards/large/en/xln/173b.jpg
if (card.isTwoFacedCard()) { if (baseUrl == null && card.isTwoFacedCard()) {
return "https://img.scryfall.com/cards/large/en/" + formatSetName(card.getSet()) + "/" baseUrl = "https://img.scryfall.com/cards/large/" + localizedCode + "/" + formatSetName(card.getSet()) + "/"
+ card.getCollectorId() + (card.isSecondSide() ? "b" : "a") + ".jpg";
alternativeUrl = "https://img.scryfall.com/cards/large/" + defaultCode + "/" + formatSetName(card.getSet()) + "/"
+ card.getCollectorId() + (card.isSecondSide() ? "b" : "a") + ".jpg"; + card.getCollectorId() + (card.isSecondSide() ? "b" : "a") + ".jpg";
} }
// basic cards by api call (redirect to img link) // basic cards by api call (redirect to img link)
// example: https://api.scryfall.com/cards/xln/121?format=image // example: https://api.scryfall.com/cards/xln/121/en?format=image
return "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/" if (baseUrl == null) {
+ card.getCollectorId() + "?format=image"; baseUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/"
+ card.getCollectorId() + "/" + localizedCode + "?format=image";
alternativeUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet()) + "/"
+ card.getCollectorId() + "/" + defaultCode + "?format=image";
}
return new CardImageUrls(baseUrl, alternativeUrl);
} }
@Override @Override
public String generateTokenUrl(CardDownloadData card) throws Exception { public CardImageUrls generateTokenUrl(CardDownloadData card) throws Exception {
return null; return null;
} }

View file

@ -16,6 +16,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import mage.constants.SubType; import mage.constants.SubType;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
@ -23,7 +24,6 @@ import org.mage.plugins.card.images.DownloadPictures;
import org.mage.plugins.card.utils.CardImageUtils; import org.mage.plugins.card.utils.CardImageUtils;
/** /**
*
* @author Quercitron * @author Quercitron
*/ */
public enum TokensMtgImageSource implements CardImageSource { public enum TokensMtgImageSource implements CardImageSource {
@ -58,7 +58,7 @@ public enum TokensMtgImageSource implements CardImageSource {
} }
@Override @Override
public String generateURL(CardDownloadData card) throws Exception { public CardImageUrls generateURL(CardDownloadData card) throws Exception {
return null; return null;
} }
@ -80,7 +80,7 @@ public enum TokensMtgImageSource implements CardImageSource {
} }
@Override @Override
public String generateTokenUrl(CardDownloadData card) throws IOException { public CardImageUrls generateTokenUrl(CardDownloadData card) throws IOException {
String name = card.getName(); String name = card.getName();
String set = card.getSet(); String set = card.getSet();
int type = card.getType(); int type = card.getType();
@ -125,7 +125,7 @@ public enum TokensMtgImageSource implements CardImageSource {
String url = "http://tokens.mtg.onl/tokens/" + tokenData.getExpansionSetCode().trim() + '_' String url = "http://tokens.mtg.onl/tokens/" + tokenData.getExpansionSetCode().trim() + '_'
+ tokenData.getNumber().trim() + '-' + tokenData.getName().trim() + ".jpg"; + tokenData.getNumber().trim() + '-' + tokenData.getName().trim() + ".jpg";
url = url.replace(' ', '-'); url = url.replace(' ', '-');
return url; return new CardImageUrls(url);
} }
@Override @Override

View file

@ -20,6 +20,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.repository.CardCriteria; import mage.cards.repository.CardCriteria;
import mage.cards.repository.CardInfo; import mage.cards.repository.CardInfo;
@ -462,7 +463,7 @@ public enum WizardCardsImageSource implements CardImageSource {
} }
@Override @Override
public String generateURL(CardDownloadData card) throws Exception { public CardImageUrls generateURL(CardDownloadData card) throws Exception {
String collectorId = card.getCollectorId(); String collectorId = card.getCollectorId();
String cardSet = card.getSet(); String cardSet = card.getSet();
if (collectorId == null || cardSet == null) { if (collectorId == null || cardSet == null) {
@ -495,7 +496,7 @@ public enum WizardCardsImageSource implements CardImageSource {
List<String> l = new ArrayList<>(setLinks.values()); List<String> l = new ArrayList<>(setLinks.values());
if (l.size() >= number) { if (l.size() >= number) {
link = l.get(number - 1); link = l.get(number - 1);
} else {; } else {
link = l.get(number - 21); link = l.get(number - 21);
if (link != null) { if (link != null) {
link = link.replace(Integer.toString(number - 20), (Integer.toString(number - 20) + 'a')); link = link.replace(Integer.toString(number - 20), (Integer.toString(number - 20) + 'a'));
@ -508,8 +509,12 @@ public enum WizardCardsImageSource implements CardImageSource {
if (link != null && !link.startsWith("http://")) { if (link != null && !link.startsWith("http://")) {
link = "http://gatherer.wizards.com" + link; link = "http://gatherer.wizards.com" + link;
} }
return link;
if (link != null) {
return new CardImageUrls(link);
} else {
return null;
}
} }
private Map<String, String> getSetLinks(String cardSet) { private Map<String, String> getSetLinks(String cardSet) {
@ -703,7 +708,7 @@ public enum WizardCardsImageSource implements CardImageSource {
} }
@Override @Override
public String generateTokenUrl(CardDownloadData card) { public CardImageUrls generateTokenUrl(CardDownloadData card) {
return null; return null;
} }

View file

@ -15,6 +15,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.swing.*; import javax.swing.*;
import mage.cards.ExpansionSet; import mage.cards.ExpansionSet;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.repository.CardCriteria; import mage.cards.repository.CardCriteria;
@ -33,6 +34,7 @@ import org.apache.log4j.Logger;
import org.mage.plugins.card.dl.sources.*; import org.mage.plugins.card.dl.sources.*;
import org.mage.plugins.card.properties.SettingsManager; import org.mage.plugins.card.properties.SettingsManager;
import org.mage.plugins.card.utils.CardImageUtils; import org.mage.plugins.card.utils.CardImageUtils;
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir; import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
public class DownloadPictures extends DefaultBoundedRangeModel implements Runnable { public class DownloadPictures extends DefaultBoundedRangeModel implements Runnable {
@ -597,25 +599,25 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
logger.debug("Downloading image: " + card.getName() + " (" + card.getSet() + ')'); logger.debug("Downloading image: " + card.getName() + " (" + card.getSet() + ')');
String url; CardImageUrls urls;
if (ignoreUrls.contains(card.getSet()) || card.isToken()) { if (ignoreUrls.contains(card.getSet()) || card.isToken()) {
if (!"0".equals(card.getCollectorId())) { if (!"0".equals(card.getCollectorId())) {
continue; continue;
} }
url = cardImageSource.generateTokenUrl(card); urls = cardImageSource.generateTokenUrl(card);
} else { } else {
url = cardImageSource.generateURL(card); urls = cardImageSource.generateURL(card);
} }
if (url == null) { if (urls == null) {
String imageRef = cardImageSource.getNextHttpImageUrl(); String imageRef = cardImageSource.getNextHttpImageUrl();
String fileName = cardImageSource.getFileForHttpImage(imageRef); String fileName = cardImageSource.getFileForHttpImage(imageRef);
if (imageRef != null && fileName != null) { if (imageRef != null && fileName != null) {
imageRef = cardImageSource.getSourceName() + imageRef; imageRef = cardImageSource.getSourceName() + imageRef;
try { try {
URL imageUrl = new URL(imageRef);
card.setToken(cardImageSource.isTokenSource()); card.setToken(cardImageSource.isTokenSource());
Runnable task = new DownloadTask(card, imageUrl, fileName, cardImageSource.getTotalImages()); Runnable task = new DownloadTask(card, imageRef, fileName, cardImageSource.getTotalImages());
executor.execute(task); executor.execute(task);
} catch (Exception ex) { } catch (Exception ex) {
} }
@ -626,7 +628,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
} }
} else { } else {
Runnable task = new DownloadTask(card, new URL(url), cardsToDownload.size()); Runnable task = new DownloadTask(card, urls, cardsToDownload.size());
executor.execute(task); executor.execute(task);
} }
@ -662,22 +664,26 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
private final class DownloadTask implements Runnable { private final class DownloadTask implements Runnable {
private final CardDownloadData card; private final CardDownloadData card;
private final URL url; private final CardImageUrls urls;
private final int count; private final int count;
private final String actualFilename; private final String actualFilename;
private final boolean useSpecifiedPaths; private final boolean useSpecifiedPaths;
DownloadTask(CardDownloadData card, URL url, int count) { DownloadTask(CardDownloadData card, String baseUrl, int count) {
this(card, new CardImageUrls(baseUrl, null), count);
}
DownloadTask(CardDownloadData card, CardImageUrls urls, int count) {
this.card = card; this.card = card;
this.url = url; this.urls = urls;
this.count = count; this.count = count;
this.actualFilename = ""; this.actualFilename = "";
useSpecifiedPaths = false; useSpecifiedPaths = false;
} }
DownloadTask(CardDownloadData card, URL url, String actualFilename, int count) { DownloadTask(CardDownloadData card, String baseUrl, String actualFilename, int count) {
this.card = card; this.card = card;
this.url = url; this.urls = new CardImageUrls(baseUrl, null);
this.count = count; this.count = count;
this.actualFilename = actualFilename; this.actualFilename = actualFilename;
useSpecifiedPaths = true; useSpecifiedPaths = true;
@ -751,14 +757,55 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
} }
// can download images from many alternative urls
List<String> downloadUrls;
if (this.urls != null) {
downloadUrls = this.urls.getDownloadList();
} else {
downloadUrls = new ArrayList<>();
}
boolean isDownloadOK = false;
URLConnection httpConn = null;
List<String> errorsList = new ArrayList<>();
for (String currentUrl : downloadUrls) {
URL url = new URL(currentUrl);
// on download cancel need to stop
if (cancel) {
return;
}
// download
cardImageSource.doPause(url.getPath()); cardImageSource.doPause(url.getPath());
URLConnection httpConn = url.openConnection(p); httpConn = url.openConnection(p);
httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2"); httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2");
httpConn.connect(); httpConn.connect();
int responseCode = ((HttpURLConnection) httpConn).getResponseCode(); int responseCode = ((HttpURLConnection) httpConn).getResponseCode();
if (responseCode == 200) { // check result
// download OK if (responseCode != 200) {
// show errors only on full fail (all urls were not work)
errorsList.add("Image download for " + card.getName()
+ (!card.getDownloadName().equals(card.getName()) ? " downloadname: " + card.getDownloadName() : "")
+ " (" + card.getSet() + ") failed - responseCode: " + responseCode + " url: " + url.toString());
if (logger.isDebugEnabled()) {
// Shows the returned html from the request to the web server
logger.debug("Returned HTML ERROR:\n" + convertStreamToString(((HttpURLConnection) httpConn).getErrorStream()));
}
// go to next try
continue;
} else {
// all fine
isDownloadOK = true;
break;
}
}
// can save result
if (isDownloadOK & httpConn != null) {
// save data to temp // save data to temp
OutputStream out = null; OutputStream out = null;
OutputStream tfileout = null; OutputStream tfileout = null;
@ -792,8 +839,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
out.write(buf, 0, len); out.write(buf, 0, len);
} }
} } finally {
finally {
StreamUtils.closeQuietly(in); StreamUtils.closeQuietly(in);
StreamUtils.closeQuietly(out); StreamUtils.closeQuietly(out);
StreamUtils.closeQuietly(tfileout); StreamUtils.closeQuietly(tfileout);
@ -815,15 +861,9 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
} else { } else {
// download ERROR // download errors
logger.warn("Image download for " + card.getName() for (String err : errorsList) {
+ (!card.getDownloadName().equals(card.getName()) ? " downloadname: " + card.getDownloadName() : "") logger.warn(err);
+ " (" + card.getSet() + ") failed - responseCode: " + responseCode + " url: " + url.toString()
);
if (logger.isDebugEnabled()) {
// Shows the returned html from the request to the web server
logger.debug("Returned HTML ERROR:\n" + convertStreamToString(((HttpURLConnection) httpConn).getErrorStream()));
} }
} }

View file

@ -4,11 +4,11 @@ import org.junit.Assert;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.mage.plugins.card.dl.sources.CardImageSource; import org.mage.plugins.card.dl.sources.CardImageSource;
import org.mage.plugins.card.dl.sources.CardImageUrls;
import org.mage.plugins.card.dl.sources.TokensMtgImageSource; import org.mage.plugins.card.dl.sources.TokensMtgImageSource;
import org.mage.plugins.card.images.CardDownloadData; import org.mage.plugins.card.images.CardDownloadData;
/** /**
*
* @author Quercitron * @author Quercitron
*/ */
@Ignore @Ignore
@ -18,15 +18,16 @@ public class TokensMtgImageSourceTest {
public void generateTokenUrlTest() throws Exception { public void generateTokenUrlTest() throws Exception {
CardImageSource imageSource = TokensMtgImageSource.instance; CardImageSource imageSource = TokensMtgImageSource.instance;
String url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 1, "ORI", "")); CardImageUrls url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 1, "ORI", ""));
Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_010-Thopter.jpg", url); Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_010-Thopter.jpg", url.baseUrl);
url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 2, "ORI", "")); url = imageSource.generateTokenUrl(new CardDownloadData("Thopter", "ORI", "0", false, 2, "ORI", ""));
Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_011-Thopter.jpg", url); Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_011-Thopter.jpg", url.baseUrl);
url = imageSource.generateTokenUrl(new CardDownloadData("Ashaya, the Awoken World", "ORI", "0", false, 0, "ORI", "")); url = imageSource.generateTokenUrl(new CardDownloadData("Ashaya, the Awoken World", "ORI", "0", false, 0, "ORI", ""));
Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_007-Ashaya,-the-Awoken-World.jpg", url); Assert.assertEquals("http://tokens.mtg.onl/tokens/ORI_007-Ashaya,-the-Awoken-World.jpg", url.baseUrl);
url = imageSource.generateTokenUrl(new CardDownloadData("Emblem Gideon, Ally of Zendikar", "BFZ", "0", false, 0, null, "")); url = imageSource.generateTokenUrl(new CardDownloadData("Emblem Gideon, Ally of Zendikar", "BFZ", "0", false, 0, null, ""));
Assert.assertEquals("http://tokens.mtg.onl/tokens/BFZ_012-Gideon-Emblem.jpg", url); Assert.assertEquals("http://tokens.mtg.onl/tokens/BFZ_012-Gideon-Emblem.jpg", url.baseUrl);
} }
} }