mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 04:52:07 -08:00
Images: added direct image links support in scryfall, added SLD's alternative images from second sides (example: Zndrsplt, Eye of Wisdom);
This commit is contained in:
parent
903a9215cc
commit
a6b2bea8af
8 changed files with 105 additions and 45 deletions
|
|
@ -74,16 +74,22 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
|
||||
// CARDS TRY
|
||||
|
||||
// direct links to images via hardcoded API path. Used for cards with non-ASCII collector numbers
|
||||
// direct links to images via hardcoded API path
|
||||
// used for cards with non-ASCII collector numbers or another use cases
|
||||
if (baseUrl == null) {
|
||||
String apiUrl = ScryfallImageSupportCards.findDirectDownloadLink(card.getSet(), card.getName(), card.getCollectorId());
|
||||
if (apiUrl != null) {
|
||||
baseUrl = apiUrl + localizedCode + "?format=image";
|
||||
alternativeUrl = apiUrl + defaultCode + "?format=image";
|
||||
|
||||
// workaround to use cards without english images (some promos or special cards)
|
||||
if (Objects.equals(baseUrl, alternativeUrl) && baseUrl.endsWith("/en?format=image")) {
|
||||
alternativeUrl = alternativeUrl.replace("/en?format=image", "/?format=image");
|
||||
String link = ScryfallImageSupportCards.findDirectDownloadLink(card.getSet(), card.getName(), card.getCollectorId());
|
||||
if (link != null) {
|
||||
if (ScryfallImageSupportCards.isApiLink(link)) {
|
||||
// api
|
||||
baseUrl = link + localizedCode + "?format=image";
|
||||
alternativeUrl = link + defaultCode + "?format=image";
|
||||
// workaround to use cards without english images (some promos or special cards)
|
||||
if (Objects.equals(baseUrl, alternativeUrl) && baseUrl.endsWith("/en?format=image")) {
|
||||
alternativeUrl = alternativeUrl.replace("/en?format=image", "/?format=image");
|
||||
}
|
||||
} else {
|
||||
// image
|
||||
baseUrl = link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -103,18 +109,22 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
// basic cards by api call (redirect to img link)
|
||||
// example: https://api.scryfall.com/cards/xln/121/en?format=image
|
||||
if (baseUrl == null) {
|
||||
baseUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
|
||||
+ card.getCollectorId() + "/" + localizedCode + "?format=image";
|
||||
alternativeUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
|
||||
+ card.getCollectorId() + "/" + defaultCode + "?format=image";
|
||||
|
||||
baseUrl = String.format("https://api.scryfall.com/cards/%s/%s/%s?format=image",
|
||||
formatSetName(card.getSet(), isToken),
|
||||
card.getCollectorId(),
|
||||
localizedCode);
|
||||
alternativeUrl = String.format("https://api.scryfall.com/cards/%s/%s/%s?format=image",
|
||||
formatSetName(card.getSet(), isToken),
|
||||
card.getCollectorId(),
|
||||
defaultCode);
|
||||
// workaround to use cards without english images (some promos or special cards)
|
||||
// bug: https://github.com/magefree/mage/issues/6829
|
||||
// example: Mysterious Egg from IKO https://api.scryfall.com/cards/iko/385/?format=image
|
||||
if (Objects.equals(baseUrl, alternativeUrl)) {
|
||||
// without loc code scryfall must return first available image
|
||||
alternativeUrl = "https://api.scryfall.com/cards/" + formatSetName(card.getSet(), isToken) + "/"
|
||||
+ card.getCollectorId() + "/?format=image";
|
||||
alternativeUrl = String.format("https://api.scryfall.com/cards/%s/%s/?format=image",
|
||||
formatSetName(card.getSet(), isToken),
|
||||
card.getCollectorId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,6 +136,7 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
final String localizedCode = languageAliases.getOrDefault(this.getCurrentLanguage(), defaultCode);
|
||||
|
||||
List<String> needUrls = new ArrayList<>();
|
||||
int needFaceIndex = card.isSecondSide() ? 1 : 0;
|
||||
|
||||
String apiUrl = ScryfallImageSupportCards.findDirectDownloadLink(card.getSet(), card.getName(), card.getCollectorId());
|
||||
if (apiUrl != null) {
|
||||
|
|
@ -143,11 +154,15 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
} else {
|
||||
// BY CARD NUMBER
|
||||
// localized and default
|
||||
needUrls.add("https://api.scryfall.com/cards/"
|
||||
+ formatSetName(card.getSet(), isToken) + "/" + card.getCollectorId() + "/" + localizedCode);
|
||||
needUrls.add(String.format("https://api.scryfall.com/cards/%s/%s/%s",
|
||||
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);
|
||||
needUrls.add(String.format("https://api.scryfall.com/cards/%s/%s/%s",
|
||||
formatSetName(card.getSet(), isToken),
|
||||
card.getCollectorId(),
|
||||
defaultCode));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,8 +193,11 @@ public enum ScryfallImageSource implements CardImageSource {
|
|||
if (jsonFaces == null) {
|
||||
throw new MageException("Couldn't find card_faces in card's JSON data: " + jsonUrl);
|
||||
}
|
||||
if (jsonFaces.size() < needFaceIndex + 1) {
|
||||
throw new MageException("card_faces doesn't contains face index in card's JSON data: " + jsonUrl);
|
||||
}
|
||||
|
||||
JsonObject jsonFace = jsonFaces.get(card.isSecondSide() ? 1 : 0).getAsJsonObject();
|
||||
JsonObject jsonFace = jsonFaces.get(needFaceIndex).getAsJsonObject();
|
||||
JsonObject jsonImages = JsonUtil.getAsObject(jsonFace, "image_uris");
|
||||
if (jsonImages == null) {
|
||||
throw new MageException("Couldn't find image_uris in card's JSON data: " + jsonUrl);
|
||||
|
|
|
|||
|
|
@ -508,21 +508,23 @@ public class ScryfallImageSupportCards {
|
|||
|
||||
private static final Map<String, String> directDownloadLinks = new HashMap<String, String>() {
|
||||
{
|
||||
// xmage card -> api link:
|
||||
// examples:
|
||||
// api example: https://api.scryfall.com/cards/trix/6/
|
||||
// api format is primary
|
||||
// xmage card -> api or image link
|
||||
// WARNING, try use api links as much as possible (it supports build-in translation)
|
||||
//
|
||||
// code form for one card:
|
||||
// example:
|
||||
// api link: https://api.scryfall.com/cards/trix/6/
|
||||
// image link: https://c1.scryfall.com/file/scryfall-cards/large/back/d/5/d5dfd236-b1da-4552-b94f-ebf6bb9dafdf.jpg
|
||||
//
|
||||
// key for one card:
|
||||
// set/card_name
|
||||
//
|
||||
// code form for same name cards (alternative images):
|
||||
// set/card_name/card_number
|
||||
// set/card_name/card_number
|
||||
|
||||
// key for same name cards (alternative images):
|
||||
// set/card_name/card_number_1
|
||||
// set/card_name/card_number_2
|
||||
//
|
||||
// Cards with non-ASCII collector numbers must use direct download (cause xmage uses different card number)
|
||||
// Verify checks must check and show missing data from that list
|
||||
// WARNING, must use as API link, not image
|
||||
|
||||
// 10E
|
||||
put("10E/Air Elemental/64*", "https://api.scryfall.com/cards/10e/64★/");
|
||||
put("10E/Anaba Bodyguard/187*", "https://api.scryfall.com/cards/10e/187★/");
|
||||
|
|
@ -786,10 +788,6 @@ public class ScryfallImageSupportCards {
|
|||
put("PM14/Hive Stirrings/21*", "https://api.scryfall.com/cards/pm14/21★/");
|
||||
put("PM14/Megantic Sliver/185*", "https://api.scryfall.com/cards/pm14/185★/");
|
||||
put("PM14/Ratchet Bomb/215*", "https://api.scryfall.com/cards/pm14/215★/");
|
||||
// PROE
|
||||
put("PROE/Emrakul, the Aeons Torn/4*", "https://api.scryfall.com/cards/proe/4★/");
|
||||
put("PROE/Lord of Shatterskull Pass/156*", "https://api.scryfall.com/cards/proe/156★/");
|
||||
//
|
||||
// PMBS
|
||||
put("PMBS/Glissa, the Traitor/96*", "https://api.scryfall.com/cards/pmbs/96★/");
|
||||
put("PMBS/Hero of Bladehold/8*", "https://api.scryfall.com/cards/pmbs/8★/");
|
||||
|
|
@ -948,6 +946,18 @@ public class ScryfallImageSupportCards {
|
|||
put("WAR/Ugin, the Ineffable/2*", "https://api.scryfall.com/cards/war/2★/");
|
||||
put("WAR/Vivien, Champion of the Wilds/180*", "https://api.scryfall.com/cards/war/180★/");
|
||||
put("WAR/Vraska, Swarm's Eminence/236*", "https://api.scryfall.com/cards/war/236★/");
|
||||
// SLD
|
||||
// TODO: update direct image links in 2022 for HQ images
|
||||
put("SLD/Zndrsplt, Eye of Wisdom/379", "https://api.scryfall.com/cards/sld/379/");
|
||||
put("SLD/Zndrsplt, Eye of Wisdom/379b", "https://c1.scryfall.com/file/scryfall-cards/large/back/d/5/d5dfd236-b1da-4552-b94f-ebf6bb9dafdf.jpg");
|
||||
put("SLD/Krark's Thumb/383", "https://api.scryfall.com/cards/sld/383/");
|
||||
put("SLD/Krark's Thumb/383b", "https://c1.scryfall.com/file/scryfall-cards/large/back/9/f/9f63277b-e139-46c8-b9e3-0cfb647f44cc.jpg");
|
||||
put("SLD/Okaun, Eye of Chaos/380", "https://api.scryfall.com/cards/sld/380/");
|
||||
put("SLD/Okaun, Eye of Chaos/380b", "https://c1.scryfall.com/file/scryfall-cards/large/back/9/4/94eea6e3-20bc-4dab-90ba-3113c120fb90.jpg");
|
||||
put("SLD/Propaganda/381", "https://api.scryfall.com/cards/sld/381/");
|
||||
put("SLD/Propaganda/381b", "https://c1.scryfall.com/file/scryfall-cards/large/back/3/e/3e3f0bcd-0796-494d-bf51-94b33c1671e9.jpg");
|
||||
put("SLD/Stitch in Time/382", "https://api.scryfall.com/cards/sld/382/");
|
||||
put("SLD/Stitch in Time/382b", "https://c1.scryfall.com/file/scryfall-cards/large/back/0/8/087c3a0d-c710-4451-989e-596b55352184.jpg");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1001,6 +1011,10 @@ public class ScryfallImageSupportCards {
|
|||
return "";
|
||||
}
|
||||
|
||||
public static boolean isApiLink(String link) {
|
||||
return !link.endsWith(".jpg") && !link.endsWith(".png");
|
||||
}
|
||||
|
||||
public static Map<String, String> getDirectDownloadLinks() {
|
||||
return directDownloadLinks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -436,6 +436,8 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
|
|||
String cardName = card.getName();
|
||||
boolean isType2 = type2SetsFilter.contains(card.getSetCode());
|
||||
CardDownloadData url = new CardDownloadData(cardName, card.getSetCode(), card.getCardNumber(), card.usesVariousArt(), 0, "", "", false, card.isDoubleFaced(), card.isNightCard());
|
||||
|
||||
// variations must have diff file names with additional postfix
|
||||
if (url.getUsesVariousArt()) {
|
||||
url.setDownloadName(createDownloadName(card));
|
||||
}
|
||||
|
|
@ -444,7 +446,10 @@ public class DownloadPicturesService extends DefaultBoundedRangeModel implements
|
|||
url.setSplitCard(card.isSplitCard());
|
||||
url.setType2(isType2);
|
||||
|
||||
// main side
|
||||
allCardsUrls.add(url);
|
||||
|
||||
// second side (xmage's set doesn't have info about it, so generate it here)
|
||||
if (card.isDoubleFaced()) {
|
||||
if (card.getSecondSideName() == null || card.getSecondSideName().trim().isEmpty()) {
|
||||
throw new IllegalStateException("Second side card can't have empty name.");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue