download: reworked connection:

- added shareable code with default proxy, headers and other settings for download tasks like images, symbols, mtgjson, etc;
- use XmageURLConnection.downloadText for text resources
- use XmageURLConnection.downloadBinary for any file resources
- added user agent with app version for all requests;
- added http logs and improved error messages;
This commit is contained in:
Oleg Agafonov 2024-07-31 16:24:59 +04:00
parent fad63389d0
commit e1cffbde40
35 changed files with 713 additions and 464 deletions

View file

@ -4,11 +4,16 @@ import mage.constants.Rarity;
import java.util.List;
/**
* MTGJSON v5: card class
* <p>
* Contains card related data nd only used fields, if you need more for tests then just add it here
* <p>
* API docs <a href="https://mtgjson.com/data-models/card/card-set/">here</a>
*
* @author JayDi85
*/
public final class MtgJsonCard {
// v5 support
// https://mtgjson.com/data-models/card-atomic/
// contains only used fields, if you need more for tests then just add it here
public String name;
public String asciiName; // mtgjson uses it for some cards like El-Hajjaj
public String number; // from sets source only, see https://mtgjson.com/data-models/card-set/
@ -44,7 +49,6 @@ public final class MtgJsonCard {
}
/**
*
* @return single side name like Ice from Fire // Ice
*/
public String getNameAsFace() {
@ -53,7 +57,6 @@ public final class MtgJsonCard {
}
/**
*
* @return full card name like Fire // Ice
*/
public String getNameAsFull() {

View file

@ -1,9 +1,15 @@
package mage.verify.mtgjson;
/**
* MTGJSON v5: metadata class
* <p>
* Contains version info
* <p>
* API docs <a href="https://mtgjson.com/file-models/meta/">here</a>
*
* @author JayDi85
*/
public final class MtgJsonMetadata {
// MTGJSON metadata
// https://mtgjson.com/file-models/meta/
public String date;
public String version;
}

View file

@ -1,10 +1,13 @@
package mage.verify.mtgjson;
import com.google.gson.Gson;
import mage.client.remote.XmageURLConnection;
import org.apache.log4j.Logger;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.text.Normalizer;
@ -12,8 +15,15 @@ import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.ZipInputStream;
/**
* MTGJSON v5: basic service to work with mtgjson data
*
* @author JayDi85
*/
public final class MtgJsonService {
private static final Logger logger = Logger.getLogger(MtgJsonService.class);
public static Map<String, String> mtgJsonToXMageCodes = new HashMap<>();
public static Map<String, String> xMageToMtgJsonCodes = new HashMap<>();
@ -36,23 +46,36 @@ public final class MtgJsonService {
}
private static <T> T readFromZip(String filename, Class<T> clazz) throws IOException {
// build-in file
InputStream stream = MtgJsonService.class.getResourceAsStream(filename);
if (stream == null) {
File file = new File(filename);
if (!file.exists()) {
String url = "https://mtgjson.com/api/v5/" + filename;
System.out.println("Downloading " + url + " to " + file.getAbsolutePath());
URLConnection connection = new URL(url).openConnection();
connection.setRequestProperty("user-agent", "xmage");
InputStream download = connection.getInputStream();
Files.copy(download, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
System.out.println("Downloading DONE");
} else {
System.out.println("Found file " + filename + " from " + file.getAbsolutePath());
}
stream = new FileInputStream(file);
if (stream != null) {
logger.info("mtgjson: use build-in file " + filename);
return readFromZip(stream, clazz);
}
// already downloaded file
File file = new File(filename);
if (file.exists()) {
logger.info("mtgjson: use existing file " + filename + " from " + file.getAbsolutePath());
return readFromZip(Files.newInputStream(file.toPath()), clazz);
}
// new download
String url = "https://mtgjson.com/api/v5/" + filename;
logger.info("mtgjson: downloading new file " + url);
// mtgjson site require user-agent in headers (otherwise it return 403)
stream = XmageURLConnection.downloadBinary(url);
if (stream != null) {
logger.info("mtgjson: download DONE, saved to " + file.getAbsolutePath());
Files.copy(stream, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
return readFromZip(Files.newInputStream(file.toPath()), clazz);
}
throw new IOException("mtgjson: can't found or download file, check your connection " + filename);
}
private static <T> T readFromZip(InputStream stream, Class<T> clazz) throws IOException {
try (ZipInputStream zipInputStream = new ZipInputStream(stream)) {
zipInputStream.getNextEntry();
return new Gson().fromJson(new InputStreamReader(zipInputStream), clazz);
@ -243,5 +266,4 @@ public final class MtgJsonService {
}
}
}
}

View file

@ -2,10 +2,17 @@ package mage.verify.mtgjson;
import java.util.List;
/**
* MTGJSON v5: set class
* <p>
* Contains set info and related cards list
* Only used fields, if you need more for tests then just add it here
* <p>
* API docs <a href="https://mtgjson.com/data-models/set/">here</a>
*
* @author JayDi85
*/
public final class MtgJsonSet {
// v5 support
// https://mtgjson.com/data-models/card-atomic/
// contains only used fields, if you need more for tests then just add it here
public List<MtgJsonCard> cards;
public String code;