mirror of
https://github.com/correl/mage.git
synced 2024-11-24 19:19:56 +00:00
* Images: added download support of localized images for double faces cards;
* Images: fixed wrong second side image after localized images download (you must re-download KHM and ZNR sets to fix it);
This commit is contained in:
parent
c9f4e949fa
commit
f9b840e3b5
3 changed files with 50 additions and 28 deletions
|
@ -27,7 +27,6 @@ public class CardImageUrls {
|
||||||
this.baseUrl = baseUrl;
|
this.baseUrl = baseUrl;
|
||||||
|
|
||||||
if (alternativeUrl != null
|
if (alternativeUrl != null
|
||||||
&& alternativeUrl != null
|
|
||||||
&& !alternativeUrl.isEmpty()
|
&& !alternativeUrl.isEmpty()
|
||||||
&& !Objects.equals(baseUrl, alternativeUrl)) {
|
&& !Objects.equals(baseUrl, alternativeUrl)) {
|
||||||
this.alternativeUrls.add(alternativeUrl);
|
this.alternativeUrls.add(alternativeUrl);
|
||||||
|
|
|
@ -4,11 +4,13 @@ import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
|
import mage.MageException;
|
||||||
import mage.client.util.CardLanguage;
|
import mage.client.util.CardLanguage;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.mage.plugins.card.dl.DownloadServiceInfo;
|
import org.mage.plugins.card.dl.DownloadServiceInfo;
|
||||||
import org.mage.plugins.card.images.CardDownloadData;
|
import org.mage.plugins.card.images.CardDownloadData;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
|
@ -87,13 +89,15 @@ public enum ScryfallImageSource implements CardImageSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
// double faced cards (modal double faces cards too)
|
// double faced cards (modal double faces cards too)
|
||||||
// the front face can be downloaded normally
|
if (card.isTwoFacedCard()) {
|
||||||
// the back face is prepared before hand
|
if (card.isSecondSide()) {
|
||||||
if (baseUrl == null && card.isTwoFacedCard() && !card.isSecondSide()) {
|
// back face - must be prepared before
|
||||||
baseUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
|
logger.warn("Can't find back face info in prepared list "
|
||||||
+ card.getCollectorId() + "/" + localizedCode + "?format=image";
|
+ card.getName() + " (" + card.getSet() + ") #" + card.getCollectorId());
|
||||||
alternativeUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
|
return new CardImageUrls(null, null);
|
||||||
+ card.getCollectorId() + "/" + defaultCode + "?format=image";
|
} else {
|
||||||
|
// front face - can be downloaded normally as basic card
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// basic cards by api call (redirect to img link)
|
// basic cards by api call (redirect to img link)
|
||||||
|
@ -117,19 +121,46 @@ public enum ScryfallImageSource implements CardImageSource {
|
||||||
return new CardImageUrls(baseUrl, alternativeUrl);
|
return new CardImageUrls(baseUrl, alternativeUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFaceImageUrl(Proxy proxy, CardDownloadData card, boolean isToken, String localizationCode) throws Exception {
|
private String getFaceImageUrl(Proxy proxy, CardDownloadData card, boolean isToken) throws Exception {
|
||||||
// connect to Scryfall API
|
final String defaultCode = CardLanguage.ENGLISH.getCode();
|
||||||
final URL cardUrl = new URL("https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
|
final String localizedCode = languageAliases.getOrDefault(this.getCurrentLanguage(), defaultCode);
|
||||||
+ card.getCollectorId() + "/" + localizationCode);
|
|
||||||
URLConnection request = proxy == null ? cardUrl.openConnection() : cardUrl.openConnection(proxy);
|
|
||||||
request.connect();
|
|
||||||
|
|
||||||
// parse the response and return the image URI from the correct card face
|
// licalized and default
|
||||||
|
List<String> needUrls = new ArrayList<>();
|
||||||
|
needUrls.add("https://api.scryfall.com/cards/"
|
||||||
|
+ formatSetName(card.getSet(), isToken) + "/" + card.getCollectorId() + "/" + localizedCode);
|
||||||
|
if (!localizedCode.equals(defaultCode)) {
|
||||||
|
needUrls.add("https://api.scryfall.com/cards/"
|
||||||
|
+ formatSetName(card.getSet(), isToken) + "/" + card.getCollectorId() + "/" + defaultCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream jsonStream = null;
|
||||||
|
String jsonUrl = null;
|
||||||
|
for (String currentUrl : needUrls) {
|
||||||
|
// connect to Scryfall API
|
||||||
|
URL cardUrl = new URL(currentUrl);
|
||||||
|
URLConnection request = (proxy == null ? cardUrl.openConnection() : cardUrl.openConnection(proxy));
|
||||||
|
request.connect();
|
||||||
|
try {
|
||||||
|
jsonStream = (InputStream) request.getContent();
|
||||||
|
jsonUrl = currentUrl;
|
||||||
|
// found good url, can stop
|
||||||
|
break;
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
// localized image doesn't exists, try next url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonStream == null) {
|
||||||
|
throw new MageException("Couldn't find card's JSON data on the server");
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK, found card data, parse it
|
||||||
JsonParser jp = new JsonParser();
|
JsonParser jp = new JsonParser();
|
||||||
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent()));
|
JsonElement root = jp.parse(new InputStreamReader(jsonStream));
|
||||||
JsonObject jsonCard = root.getAsJsonObject();
|
JsonObject jsonCard = root.getAsJsonObject();
|
||||||
if (!jsonCard.has("card_faces")) {
|
if (!jsonCard.has("card_faces")) {
|
||||||
throw new Exception("Couldn't find card_faces in Card JSON.: " + cardUrl.toString());
|
throw new MageException("Couldn't find card_faces in card's JSON data: " + jsonUrl);
|
||||||
}
|
}
|
||||||
JsonArray jsonCardFaces = jsonCard.getAsJsonArray("card_faces");
|
JsonArray jsonCardFaces = jsonCard.getAsJsonArray("card_faces");
|
||||||
JsonObject jsonCardFace = jsonCardFaces.get(card.isSecondSide() ? 1 : 0).getAsJsonObject();
|
JsonObject jsonCardFace = jsonCardFaces.get(card.isSecondSide() ? 1 : 0).getAsJsonObject();
|
||||||
|
@ -164,13 +195,8 @@ public enum ScryfallImageSource implements CardImageSource {
|
||||||
// prepare the back face URL
|
// prepare the back face URL
|
||||||
if (card.isTwoFacedCard() && card.isSecondSide()) {
|
if (card.isTwoFacedCard() && card.isSecondSide()) {
|
||||||
currentPrepareCount++;
|
currentPrepareCount++;
|
||||||
final String defaultCode = CardLanguage.ENGLISH.getCode();
|
|
||||||
final String localizedCode = languageAliases.getOrDefault(this.getCurrentLanguage(), defaultCode);
|
|
||||||
|
|
||||||
String url = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
url = getFaceImageUrl(proxy, card, card.isToken(), localizedCode);
|
String url = getFaceImageUrl(proxy, card, card.isToken());
|
||||||
preparedUrls.put(card, url);
|
preparedUrls.put(card, url);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.warn("Failed to prepare image URL (back face) for " + card.getName() + " (" + card.getSet() + ") #"
|
logger.warn("Failed to prepare image URL (back face) for " + card.getName() + " (" + card.getSet() + ") #"
|
||||||
|
@ -180,9 +206,6 @@ public enum ScryfallImageSource implements CardImageSource {
|
||||||
|
|
||||||
updatePrepareStats(downloadServiceInfo, needPrepareCount, currentPrepareCount);
|
updatePrepareStats(downloadServiceInfo, needPrepareCount, currentPrepareCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// inc error count to stop on too many errors
|
|
||||||
// downloadServiceInfo.incErrorCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -262,7 +285,7 @@ public enum ScryfallImageSource implements CardImageSource {
|
||||||
|
|
||||||
private String formatSetName(String setName, boolean isToken) {
|
private String formatSetName(String setName, boolean isToken) {
|
||||||
if (isToken) {
|
if (isToken) {
|
||||||
// token uses direct link download, not set
|
// tokens uses xmage codes to find direct link download
|
||||||
return setName.toLowerCase(Locale.ENGLISH);
|
return setName.toLowerCase(Locale.ENGLISH);
|
||||||
} else {
|
} else {
|
||||||
return ScryfallImageSupportCards.findScryfallSetCode(setName);
|
return ScryfallImageSupportCards.findScryfallSetCode(setName);
|
||||||
|
|
|
@ -138,7 +138,7 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
|
||||||
this.errorCount = this.errorCount + 1;
|
this.errorCount = this.errorCount + 1;
|
||||||
|
|
||||||
if (this.errorCount == MAX_ERRORS_COUNT_BEFORE_CANCEL + 1) {
|
if (this.errorCount == MAX_ERRORS_COUNT_BEFORE_CANCEL + 1) {
|
||||||
logger.warn("Too many errors (> " + MAX_ERRORS_COUNT_BEFORE_CANCEL + ") in images download");
|
logger.warn("Too many errors (> " + MAX_ERRORS_COUNT_BEFORE_CANCEL + ") in images download. Stop.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue