GuiDownload uses map of (local_path -> url) as core object

Download code uses NIO
This commit is contained in:
Maxmtg
2013-03-17 18:20:16 +00:00
parent 6e482a84cf
commit 4280852e06
5 changed files with 117 additions and 141 deletions

View File

@@ -18,14 +18,14 @@
package forge.gui.download; package forge.gui.download;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.Map;
import java.util.HashSet; import java.util.TreeMap;
import java.util.Set;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import forge.ImageCache; import forge.ImageCache;
import forge.card.CardRules; import forge.card.CardRules;
import forge.card.CardSplitType;
import forge.item.CardDb; import forge.item.CardDb;
import forge.item.CardPrinted; import forge.item.CardPrinted;
import forge.properties.NewConstants; import forge.properties.NewConstants;
@@ -37,18 +37,17 @@ public class GuiDownloadPicturesLQ extends GuiDownloader {
} }
@Override @Override
protected final ArrayList<DownloadObject> getNeededImages() { protected final Map<String, String> getNeededImages() {
ArrayList<DownloadObject> downloads = new ArrayList<DownloadObject>(); Map<String, String> downloads = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
Set<String> filenames = new HashSet<String>();
for (CardPrinted c : CardDb.instance().getAllCards()) { for (CardPrinted c : CardDb.instance().getAllCards()) {
addDLObject(c, false, downloads, filenames); addDLObject(c, downloads, false);
addDLObject(c, true, downloads, filenames); if ( c.getRules().getSplitType() == CardSplitType.Transform)
addDLObject(c, downloads, true);
} }
for (CardPrinted c : CardDb.variants().getAllCards()) { for (CardPrinted c : CardDb.variants().getAllCards()) {
addDLObject(c, false, downloads, filenames); addDLObject(c, downloads, false);
addDLObject(c, true, downloads, filenames);
} }
// Add missing tokens to the list of things to download. // Add missing tokens to the list of things to download.
@@ -57,26 +56,37 @@ public class GuiDownloadPicturesLQ extends GuiDownloader {
return downloads; return downloads;
} }
private void addDLObject(CardPrinted c, boolean backFace, ArrayList<DownloadObject> downloads, Set<String> filenames) { private void addDLObject(CardPrinted c, Map<String, String> downloads, boolean backFace) {
CardRules cardRules = c.getRules(); CardRules cardRules = c.getRules();
String urls = backFace ? cardRules.getPictureOtherSideUrl() : cardRules.getPictureUrl(); String urls = backFace ? cardRules.getPictureOtherSideUrl() : cardRules.getPictureUrl();
if (StringUtils.isEmpty(urls)) { if (StringUtils.isEmpty(urls)) {
return; return;
} }
String filename = ImageCache.getImageKey(c, backFace, false);
for (String url : urls.split("\\\\")) { File destFile = new File(NewConstants.CACHE_CARD_PICS_DIR, filename + ".jpg");
if (destFile.exists())
String filename = ImageCache.getImageKey(c, backFace, false); return;
if (filenames.contains(filename)) {
continue; filename = destFile.getAbsolutePath();
}
filenames.add(filename); if (downloads.containsKey(filename)) {
return;
File destFile = new File(NewConstants.CACHE_CARD_PICS_DIR, filename + ".jpg");
if (!destFile.exists()) {
downloads.add(new DownloadObject(url, destFile));
}
} }
final String urlToDownload;
int urlIndex = 0;
int allUrlsLen = 1;
if (urls.indexOf("\\\\") < 0)
urlToDownload = urls;
else {
String[] allUrls = urls.split("\\\\");
allUrlsLen = allUrls.length;
urlIndex = c.getArtIndex() % allUrlsLen;
urlToDownload = allUrls[urlIndex];
}
//System.out.println(c.getName() + "|" + c.getEdition() + " - " + c.getArtIndex() + " -> " + urlIndex + "/" + allUrlsLen + " === " + filename + " <<< " + urlToDownload);
downloads.put(destFile.getAbsolutePath(), urlToDownload);
} }
} }

View File

@@ -17,10 +17,8 @@
*/ */
package forge.gui.download; package forge.gui.download;
import java.io.File; import java.util.HashMap;
import java.util.ArrayList; import java.util.Map;
import com.google.common.collect.Lists;
import forge.properties.NewConstants; import forge.properties.NewConstants;
@@ -31,8 +29,9 @@ public class GuiDownloadPrices extends GuiDownloader {
} }
@Override @Override
protected ArrayList<DownloadObject> getNeededImages() { protected Map<String, String> getNeededImages() {
final File f = new File(NewConstants.QUEST_CARD_PRICE_FILE); Map<String, String> result = new HashMap<String, String>();
return Lists.newArrayList(new DownloadObject(NewConstants.URL_PRICE_DOWNLOAD, f)); result.put(NewConstants.QUEST_CARD_PRICE_FILE, NewConstants.URL_PRICE_DOWNLOAD);
return result;
} }
} }

View File

@@ -17,7 +17,8 @@
*/ */
package forge.gui.download; package forge.gui.download;
import java.util.ArrayList; import java.util.Map;
import java.util.TreeMap;
import forge.properties.NewConstants; import forge.properties.NewConstants;
@@ -41,9 +42,9 @@ public class GuiDownloadQuestImages extends GuiDownloader {
* @return an array of {@link forge.gui.download.GuiDownloadSetPicturesLQ} objects. * @return an array of {@link forge.gui.download.GuiDownloadSetPicturesLQ} objects.
*/ */
@Override @Override
protected final ArrayList<DownloadObject> getNeededImages() { protected final Map<String, String> getNeededImages() {
// read all card names and urls // read all card names and urls
final ArrayList<DownloadObject> urls = new ArrayList<DownloadObject>(); final Map<String, String> urls = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
addMissingItems(urls, NewConstants.IMAGE_LIST_QUEST_OPPONENT_ICONS_FILE, NewConstants.CACHE_ICON_PICS_DIR); addMissingItems(urls, NewConstants.IMAGE_LIST_QUEST_OPPONENT_ICONS_FILE, NewConstants.CACHE_ICON_PICS_DIR);
addMissingItems(urls, NewConstants.IMAGE_LIST_QUEST_PET_SHOP_ICONS_FILE, NewConstants.CACHE_ICON_PICS_DIR); addMissingItems(urls, NewConstants.IMAGE_LIST_QUEST_PET_SHOP_ICONS_FILE, NewConstants.CACHE_ICON_PICS_DIR);

View File

@@ -18,7 +18,8 @@
package forge.gui.download; package forge.gui.download;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -38,8 +39,8 @@ public class GuiDownloadSetPicturesLQ extends GuiDownloader {
} }
@Override @Override
protected final ArrayList<DownloadObject> getNeededImages() { protected final Map<String, String> getNeededImages() {
ArrayList<DownloadObject> downloads = new ArrayList<DownloadObject>(); Map<String, String> downloads = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
for (final CardPrinted c : Iterables.concat(CardDb.instance().getAllCards(), CardDb.variants().getAllCards())) { for (final CardPrinted c : Iterables.concat(CardDb.instance().getAllCards(), CardDb.variants().getAllCards())) {
final String setCode3 = c.getEdition(); final String setCode3 = c.getEdition();
@@ -62,10 +63,11 @@ public class GuiDownloadSetPicturesLQ extends GuiDownloader {
return downloads; return downloads;
} }
private void addDLObject(String urlPath, String filename, ArrayList<DownloadObject> downloads) { private void addDLObject(String urlPath, String filename, Map<String, String> downloads) {
File destFile = new File(NewConstants.CACHE_CARD_PICS_DIR, filename + ".jpg"); File destFile = new File(NewConstants.CACHE_CARD_PICS_DIR, filename + ".jpg");
// System.out.println(filename);
if (!destFile.exists()) { if (!destFile.exists()) {
downloads.add(new DownloadObject(NewConstants.URL_PIC_DOWNLOAD + urlPath, destFile)); downloads.put(destFile.getAbsolutePath(), NewConstants.URL_PIC_DOWNLOAD + urlPath);
} }
} }
} }

View File

@@ -20,8 +20,6 @@ package forge.gui.download;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@@ -31,7 +29,10 @@ import java.net.InetSocketAddress;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.Proxy; import java.net.Proxy;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random; import java.util.Random;
import javax.swing.AbstractButton; import javax.swing.AbstractButton;
@@ -107,8 +108,7 @@ public abstract class GuiDownloader extends DefaultBoundedRangeModel implements
private int type; private int type;
// Progress variables // Progress variables
private ArrayList<DownloadObject> cards; private Map<String, String> cards; // local path -> url
private int card;
private boolean cancel; private boolean cancel;
private final long[] times = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; private final long[] times = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
private int tptr = 0; private int tptr = 0;
@@ -226,7 +226,6 @@ public abstract class GuiDownloader extends DefaultBoundedRangeModel implements
} }
private void update(final int card) { private void update(final int card) {
this.card = card;
final class Worker implements Runnable { final class Worker implements Runnable {
private final int card; private final int card;
@@ -248,22 +247,19 @@ public abstract class GuiDownloader extends DefaultBoundedRangeModel implements
long t2Go = (GuiDownloader.this.cards.size() - this.card) * a; long t2Go = (GuiDownloader.this.cards.size() - this.card) * a;
boolean secOnly = true;
if (t2Go > 3600000) { if (t2Go > 3600000) {
sb.append(String.format("%02d:", t2Go / 3600000)); sb.append(String.format("%02d:", t2Go / 3600000));
t2Go = t2Go % 3600000; t2Go = t2Go % 3600000;
secOnly = false;
} }
if (t2Go > 60000) { if (t2Go > 60000) {
sb.append(String.format("%02d:", t2Go / 60000)); sb.append(String.format("%02d:", t2Go / 60000));
t2Go = t2Go % 60000; t2Go = t2Go % 60000;
secOnly = false;
}
if (!secOnly) {
sb.append(String.format("%02d remaining.", t2Go / 1000));
} else { } else {
sb.append(String.format("0:%02d remaining.", t2Go / 1000)); sb.append("00:");
} }
sb.append(String.format("%02d remaining.", t2Go / 1000));
} else { } else {
sb.append(String.format("%d of %d items finished! Please close!", sb.append(String.format("%d of %d items finished! Please close!",
this.card, GuiDownloader.this.cards.size())); this.card, GuiDownloader.this.cards.size()));
@@ -281,11 +277,8 @@ public abstract class GuiDownloader extends DefaultBoundedRangeModel implements
} }
public final void run() { public final void run() {
BufferedInputStream in;
BufferedOutputStream out;
final Random r = MyRandom.getRandom(); final Random r = MyRandom.getRandom();
Proxy p = null; Proxy p = null;
if (this.type == 0) { if (this.type == 0) {
p = Proxy.NO_PROXY; p = Proxy.NO_PROXY;
@@ -301,81 +294,72 @@ public abstract class GuiDownloader extends DefaultBoundedRangeModel implements
} }
} }
if (p != null) { int iCard = 0;
final byte[] buf = new byte[1024]; for(Entry<String, String> kv : cards.entrySet()) {
int len; if( cancel )
for (this.update(0); (this.card < this.cards.size()) && !this.cancel; this.update(this.card + 1)) { break;
final String url = this.cards.get(this.card).getSource(); update(iCard++);
final File fileDest = this.cards.get(this.card).getDestination();
final File base = fileDest.getParentFile(); String url = kv.getValue();
final File fileDest = new File(kv.getKey());
final File base = fileDest.getParentFile();
try { try {
// test for folder existence // test for folder existence
if (!base.exists() && !base.mkdir()) { // create folder if not found if (!base.exists() && !base.mkdir()) { // create folder if not found
System.out.println("Can't create folder" + base.getAbsolutePath()); System.out.println("Can't create folder" + base.getAbsolutePath());
}
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
// don't allow redirections here -- they indicate 'file not found' on the server
conn.setInstanceFollowRedirects(false);
conn.connect();
if (conn.getResponseCode() != 200) {
conn.disconnect();
System.out.println("Skipped Download for: " + fileDest.getPath());
continue;
}
in = new BufferedInputStream(conn.getInputStream());
out = new BufferedOutputStream(new FileOutputStream(fileDest));
while ((len = in.read(buf)) != -1) {
// user cancelled
if (this.cancel) {
in.close();
out.flush();
out.close();
// delete what was written so far
fileDest.delete();
this.close();
return;
} // if - cancel
out.write(buf, 0, len);
} // while - read and write file
in.close();
out.flush();
out.close();
} catch (final ConnectException ce) {
System.out.println("Connection refused for url: " + url);
} catch (final MalformedURLException mURLe) {
System.out.println("Error - possibly missing URL for: " + fileDest.getName());
} catch (final FileNotFoundException fnfe) {
String formatStr = "Error - the LQ picture %s could not be found on the server. [%s] - %s";
System.out.println(String.format(formatStr, fileDest.getName(), url, fnfe.getMessage()));
} catch (final Exception ex) {
Log.error("LQ Pictures", "Error downloading pictures", ex);
} }
// throttle to reduce load on the server URL imageUrl = new URL(url);
try { HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection(p);
Thread.sleep(r.nextInt(250) + 250); // don't allow redirections here -- they indicate 'file not found' on the server
} catch (final InterruptedException e) { conn.setInstanceFollowRedirects(false);
Log.error("GuiDownloader", "Sleep Error", e); conn.connect();
if (conn.getResponseCode() != 200) {
conn.disconnect();
System.out.println("Skipped Download for: " + fileDest.getPath());
continue;
} }
} // for
} ReadableByteChannel rbc = Channels.newChannel(conn.getInputStream());
FileOutputStream fos = new FileOutputStream(fileDest);
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
fos.flush();
fos.close();
rbc.close();
} catch (final ConnectException ce) {
System.out.println("Connection refused for url: " + url);
} catch (final MalformedURLException mURLe) {
System.out.println("Error - possibly missing URL for: " + fileDest.getName());
} catch (final FileNotFoundException fnfe) {
String formatStr = "Error - the LQ picture %s could not be found on the server. [%s] - %s";
System.out.println(String.format(formatStr, fileDest.getName(), url, fnfe.getMessage()));
} catch (final Exception ex) {
Log.error("LQ Pictures", "Error downloading pictures", ex);
}
// throttle to reduce load on the server
try {
Thread.sleep(r.nextInt(50) + 50);
} catch (final InterruptedException e) {
Log.error("GuiDownloader", "Sleep Error", e);
}
} // for
if ( !cancel )
update(cards.size());
} }
protected abstract ArrayList<DownloadObject> getNeededImages(); protected abstract Map<String, String> getNeededImages();
protected static void addMissingItems(ArrayList<DownloadObject> list, String nameUrlFile, String dir) { protected static void addMissingItems(Map<String, String> list, String nameUrlFile, String dir) {
for (Pair<String, String> nameUrlPair : FileUtil.readNameUrlFile(nameUrlFile)) { for (Pair<String, String> nameUrlPair : FileUtil.readNameUrlFile(nameUrlFile)) {
File f = new File(dir, nameUrlPair.getLeft()); File f = new File(dir, nameUrlPair.getLeft());
//System.out.println(f.getAbsolutePath());
if (!f.exists()) { if (!f.exists()) {
list.add(new DownloadObject(nameUrlPair.getRight(), f)); list.put(f.getAbsolutePath(), nameUrlPair.getRight());
} }
} }
} }
@@ -397,24 +381,4 @@ public abstract class GuiDownloader extends DefaultBoundedRangeModel implements
} }
} }
protected static class DownloadObject {
private final String source;
private final File destination;
DownloadObject(final String srcUrl, final File destFile) {
source = srcUrl;
destination = destFile;
//System.out.println(String.format("downloading %s to %s", srcUrl, destFile));
System.out.println(String.format("Preparing to download %s", destFile));
}
public String getSource() {
return source;
}
public File getDestination() {
return destination;
}
}
} }