Add svg symbols download from scryfall

This commit is contained in:
Oleg Agafonov 2017-12-03 20:33:32 +04:00
parent b3a3e17aa2
commit 89fae4f33e
5 changed files with 186 additions and 11 deletions

View file

@ -291,11 +291,8 @@ public final class ManaSymbols {
};
t.setTranscodingHints(transcoderHints);
t.transcode(input, null);
}
catch (TranscoderException ex) {
// Requires Java 6
ex.printStackTrace();
throw new IOException("Couldn't convert " + svgFile);
} catch (Exception e) {
throw new IOException("Couldn't convert svg file: " + svgFile + " , reason: " + e.getMessage());
}
finally {
cssFile.delete();
@ -348,7 +345,7 @@ public final class ManaSymbols {
//imagePointer[0];
}
private static File getSymbolFileNameAsSVG(String symbol){
public static File getSymbolFileNameAsSVG(String symbol){
return new File(getResourceSymbolsPath(ResourceSymbolSize.SVG) + symbol + ".svg");
}
@ -364,7 +361,7 @@ public final class ManaSymbols {
return loadSVG(sourceFile, resizeToWidth, resizeToHeight, true);
} catch (Exception e) {
LOGGER.error("Can't load svg symbol: " + sourceFile.getPath());
LOGGER.error("Can't load svg symbol: " + sourceFile.getPath() + " , reason: " + e.getMessage());
return null;
}
}

View file

@ -21,6 +21,7 @@ import org.mage.plugins.card.dl.Downloader;
import org.mage.plugins.card.dl.sources.DirectLinksForDownload;
import org.mage.plugins.card.dl.sources.GathererSets;
import org.mage.plugins.card.dl.sources.GathererSymbols;
import org.mage.plugins.card.dl.sources.ScryfallSymbolsSource;
import org.mage.plugins.card.images.ImageCache;
import org.mage.plugins.card.info.CardInfoPaneImpl;
@ -529,7 +530,9 @@ public class CardPluginImpl implements CardPlugin {
public void downloadSymbols(String imagesDir) {
final DownloadGui g = new DownloadGui(new Downloader());
Iterable<DownloadJob> it = new GathererSymbols();
Iterable<DownloadJob> it;
it = new GathererSymbols();
for (DownloadJob job : it) {
g.getDownloader().add(job);
}
@ -539,6 +542,11 @@ public class CardPluginImpl implements CardPlugin {
g.getDownloader().add(job);
}
it = new ScryfallSymbolsSource();
for (DownloadJob job : it) {
g.getDownloader().add(job);
}
/*
it = new CardFrames(imagesDir); // TODO: delete frames download (not need now)
for (DownloadJob job : it) {
@ -551,7 +559,7 @@ public class CardPluginImpl implements CardPlugin {
g.getDownloader().add(job);
}
JDialog d = new JDialog((Frame) null, "Download pictures", false);
JDialog d = new JDialog((Frame) null, "Download symbols", false);
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
d.addWindowListener(new WindowAdapter() {
@Override

View file

@ -28,7 +28,6 @@ import org.mage.plugins.card.utils.CardImageUtils;
public class DownloadJob extends AbstractLaternaBean {
public enum State {
NEW, WORKING, FINISHED, ABORTED
}

View file

@ -313,4 +313,4 @@ public class GathererSets implements Iterable<DownloadJob> {
String url = "http://gatherer.wizards.com/Handlers/Image.ashx?type=symbol&set=" + set + "&size=small&rarity=" + urlRarity;
return new DownloadJob(set + '-' + rarity, fromURL(url), toFile(dst));
}
}
}

View file

@ -0,0 +1,171 @@
package org.mage.plugins.card.dl.sources;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.mage.plugins.card.dl.DownloadJob;
import static org.mage.card.arcane.ManaSymbols.getSymbolFileNameAsSVG;
import static org.mage.plugins.card.utils.CardImageUtils.getImagesDir;
// TODO: add force to download symbols (rewrite exist files)
/**
*
* @author jaydi85@gmail.com
*
*/
public class ScryfallSymbolsSource implements Iterable<DownloadJob> {
static final String SOURCE_URL = "https://assets.scryfall.com/assets/scryfall.css"; // search css-file on https://scryfall.com/docs/api/colors
static final String STATE_PROP_NAME = "state";
static final String DOWNLOAD_TEMP_FILE = getImagesDir() + File.separator + "temp" + File.separator + "scryfall-symbols-source.txt";
// card-symbol-(.{1,10}){background-image.+base64,(.+)("\)})
// see https://regex101.com/
static final String REGEXP_MANA_PATTERN = "card-symbol-(.{1,10})\\{background-image.+base64,(.+)(\"\\)\\})";
protected static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger.getLogger(ScryfallSymbolsSource.class);
private static final int SYMBOLS_NUMBER_START = 0;
private static final int SYMBOLS_NUMBER_END = 20;
// copy-past symbols list from gatherer download
private static final String[] SYMBOLS_LIST = {"W", "U", "B", "R", "G",
"W/U", "U/B", "B/R", "R/G", "G/W", "W/B", "U/R", "B/G", "R/W", "G/U",
"2/W", "2/U", "2/B", "2/R", "2/G",
"WP", "UP", "BP", "RP", "GP",
"X", "S", "T", "Q", "C", "E"};
@Override
public Iterator<DownloadJob> iterator() {
ArrayList<DownloadJob> jobs = new ArrayList<>();
// all symbols on one page
jobs.add(generateDownloadJob());
return jobs.iterator();
}
private void parseData(String sourcePath){
String sourceData = "";
try {
sourceData = new String(Files.readAllBytes(Paths.get(sourcePath)));
}catch (IOException e) {
LOGGER.error("Can't open file to parse data: " + sourcePath + " , reason: " + e.getMessage());
}
// gen symbols list
ArrayList<String> allMageSymbols = new ArrayList<>();
for(int i = 0; i < SYMBOLS_LIST.length; i++){
allMageSymbols.add(SYMBOLS_LIST[i]);
}
for(Integer i = SYMBOLS_NUMBER_START; i <= SYMBOLS_NUMBER_END; i++){
allMageSymbols.add(String.valueOf(SYMBOLS_NUMBER_START + i));
}
Map<String, String> foundedData = new HashMap<>();
// search raw data
sourceData = sourceData.replaceAll(".card-symbol", "\n.card-symbol"); // css as one line, but need multiline
Pattern regex = Pattern.compile(REGEXP_MANA_PATTERN);
Matcher regexMatcher = regex.matcher(sourceData);
while (regexMatcher.find()) {
String symbolCode = regexMatcher.group(1).trim();
String symbolData = regexMatcher.group(2).trim().replace(" ", "").replaceAll("\n", ""); // decoder need only wrapped text as one line
foundedData.put(symbolCode, symbolData);
}
// dirs maker
File dir = getSymbolFileNameAsSVG("W").getParentFile();
if(!dir.exists()){
dir.mkdirs();
}
// decode and save data (only if not exist)
for(String needCode: allMageSymbols){
String searchCode = needCode.replace("/", "");
if(!foundedData.containsKey(searchCode))
{
LOGGER.warn("Can't found symbol code from scryfall: " + searchCode);
continue;
}
File destFile = getSymbolFileNameAsSVG(searchCode);
if (destFile.exists() && (destFile.length() > 0)){
continue;
}
try {
// base64 transform
String data64 = foundedData.get(searchCode);
Base64.Decoder dec = Base64.getDecoder();
byte[] fileData = dec.decode(data64);
FileOutputStream stream = new FileOutputStream(destFile);
stream.write(fileData);
stream.close();
LOGGER.info("New svg symbol downloaded: " + needCode);
} catch (Exception e) {
LOGGER.error("Can't decode svg icon and save to file: " + destFile.getPath() + ", reason: " + e.getMessage());
}
}
}
private class ScryfallSymbolsDownloadJob extends DownloadJob{
// listener for data parse after download complete
private class ScryDownloadOnFinishedListener implements PropertyChangeListener {
private String downloadedFile;
public ScryDownloadOnFinishedListener(String ADestFile){
this.downloadedFile = ADestFile;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (!evt.getPropertyName().equals(STATE_PROP_NAME)){
throw new IllegalArgumentException("Unknown download property " + evt.getPropertyName());
}
if (evt.getNewValue() != State.FINISHED){
return;
}
// parse data and save to dest
parseData(this.downloadedFile);
}
}
private String destFile = "";
public ScryfallSymbolsDownloadJob() {
super("Scryfall symbols source", fromURL(SOURCE_URL), toFile(DOWNLOAD_TEMP_FILE));
this.destFile = DOWNLOAD_TEMP_FILE;
this.addPropertyChangeListener(STATE_PROP_NAME, new ScryDownloadOnFinishedListener(this.destFile));
// clear dest file (always download new data)
File file = new File(this.destFile);
if (file.exists()){
file.delete();
}
}
}
private DownloadJob generateDownloadJob() {
return new ScryfallSymbolsDownloadJob();
}
}