Multi thread image downloading. Fixed Issue 18.

This commit is contained in:
magenoxx 2011-05-17 02:38:48 +04:00
parent da574fa967
commit d32a8e041f
2 changed files with 87 additions and 73 deletions

View file

@ -20,6 +20,10 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import javax.swing.AbstractButton; import javax.swing.AbstractButton;
import javax.swing.Box; import javax.swing.Box;
@ -65,6 +69,11 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
private JLabel jLabel1; private JLabel jLabel1;
private static boolean offlineMode = false; private static boolean offlineMode = false;
private JCheckBox checkBox; private JCheckBox checkBox;
private Object sync = new Object();
private Proxy p;
private ExecutorService executor = Executors.newFixedThreadPool(10);
public static final Proxy.Type[] types = Proxy.Type.values(); public static final Proxy.Type[] types = Proxy.Type.values();
@ -401,7 +410,6 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
base.mkdir(); base.mkdir();
} }
Proxy p = null;
if (type == 0) if (type == 0)
p = Proxy.NO_PROXY; p = Proxy.NO_PROXY;
else else
@ -412,30 +420,52 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
if (p != null) { if (p != null) {
byte[] buf = new byte[1024];
int len;
HashSet<String> ignoreUrls = SettingsManager.getIntance().getIgnoreUrls(); HashSet<String> ignoreUrls = SettingsManager.getIntance().getIgnoreUrls();
for (update(0); (checkBox.isSelected() ? cardIndex < cardsInGame.size() : cardIndex < cards.size()) && !cancel; update(cardIndex + 1)) { update(0);
for (int i = 0; (checkBox.isSelected() ? i < cardsInGame.size() : i < cards.size()) && !cancel; i++) {
try { try {
CardUrl card = checkBox.isSelected() ? cardsInGame.get(cardIndex) : cards.get(cardIndex); CardUrl card = checkBox.isSelected() ? cardsInGame.get(i) : cards.get(i);
log.info("Downloading card: " + card.name + " (" + card.set + ")"); log.info("Downloading card: " + card.name + " (" + card.set + ")");
URL url = new URL(CardImageUtils.generateURL(card.collector, card.set)); URL url = new URL(CardImageUtils.generateURL(card.collector, card.set));
if (ignoreUrls.contains(card.set) || card.token) { if (ignoreUrls.contains(card.set) || card.token) {
// we have card in scripts, but we should ignore
// downloading image for it
// (e.g. for cards from custom or not released yet sets
// such urls should come from card-pictures files
// instead
if (card.collector != 0) { if (card.collector != 0) {
continue; continue;
} }
url = new URL(card.url); url = new URL(card.url);
} }
in = new BufferedInputStream(url.openConnection(p).getInputStream());
Runnable task = new DownloadTask(card, url);
executor.execute(task);
} catch (Exception ex) {
log.error(ex, ex);
}
}
executor.shutdown();
while (!executor.isTerminated()) {
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {}
}
}
close.setText("Close");
}
private final class DownloadTask implements Runnable {
private CardUrl card;
private URL url;
public DownloadTask(CardUrl card, URL url) {
this.card = card;
this.url = url;
}
public void run() {
try {
BufferedInputStream in = new BufferedInputStream(url.openConnection(p).getInputStream());
createDirForCard(card); createDirForCard(card);
@ -446,39 +476,34 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
} }
File fileOut = new File(CardImageUtils.getImagePath(card, withCollectorId)); File fileOut = new File(CardImageUtils.getImagePath(card, withCollectorId));
out = new BufferedOutputStream(new FileOutputStream(fileOut)); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileOut));
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) { while ((len = in.read(buf)) != -1) {
// user cancelled // user cancelled
if (cancel) { if (cancel) {
in.close(); in.close();
out.flush(); out.flush();
out.close(); out.close();
// delete what was written so far // delete what was written so far
fileOut.delete(); fileOut.delete();
return;
} }
out.write(buf, 0, len); out.write(buf, 0, len);
} }
in.close(); in.close();
out.flush(); out.flush();
out.close(); out.close();
} catch (Exception ex) {
log.error(ex, ex); synchronized (sync) {
/* update(cardIndex + 1);
* int more = JOptionPane.showConfirmDialog(null,
* "Some error occured. Continue downloading pictures?",
* "Error", JOptionPane.YES_NO_OPTION); if (more ==
* JOptionPane.NO_OPTION) { break; }
*/
} }
} catch (Exception e) {
log.error(e, e);
} }
} }
close.setText("Close");
} }
private static File createDirForCard(CardUrl card) throws Exception { private static File createDirForCard(CardUrl card) throws Exception {
@ -491,33 +516,22 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab
private void update(int card) { private void update(int card) {
this.cardIndex = card; this.cardIndex = card;
final class Worker implements Runnable {
private int card;
Worker(int card) {
this.card = card;
}
public void run() {
fireStateChanged();
if (checkBox.isSelected()) { if (checkBox.isSelected()) {
int count = DownloadPictures.this.cardsInGame.size(); int count = DownloadPictures.this.cardsInGame.size();
int countLeft = count - card; int countLeft = count - card;
float mb = (countLeft * 70.0f) / 1024; float mb = (countLeft * 70.0f) / 1024;
bar.setString(String.format(this.card == count ? "%d of %d cards finished! Please close!" bar.setString(String.format(card == count ? "%d of %d cards finished! Please close!"
: "%d of %d cards finished! Please wait! [%.1f Mb]", this.card, count, mb)); : "%d of %d cards finished! Please wait! [%.1f Mb]",
card, count, mb));
} else { } else {
int count = DownloadPictures.this.cards.size(); int count = DownloadPictures.this.cards.size();
int countLeft = count - card; int countLeft = count - card;
float mb = (countLeft * 70.0f) / 1024; float mb = (countLeft * 70.0f) / 1024;
bar.setString(String.format(cardIndex == count ? "%d of %d cards finished! Please close!" bar.setString(String.format(cardIndex == count ? "%d of %d cards finished! Please close!"
: "%d of %d cards finished! Please wait! [%.1f Mb]", this.card, count, mb)); : "%d of %d cards finished! Please wait! [%.1f Mb]",
card, count, mb));
} }
} }
}
EventQueue.invokeLater(new Worker(card));
}
private static final Logger log = Logger.getLogger(DownloadPictures.class); private static final Logger log = Logger.getLogger(DownloadPictures.class);